Files
HealthLog/src/hooks/use-analytics-range.ts
T
Marc-André Bombeck a87d6b94e4 fix(insights): keep the server-only rollup readers out of the insights client bundle
The v1.9.0 time-range work imported ANALYTICS_RANGES as a value into the
time-range pills and the insights layout-prefs hook from range-delta.ts.
That module also pulls the rollup readers and the Postgres client, so the
value import dragged pg (dns/fs/net/tls) into the browser bundle and broke
the production build with eight "Module not found" errors.

Move the client-safe pieces — the range list, its type, the per-range
window length, and the period-over-period result shapes — into a new
range-shared module that imports nothing server-side. The insights client
components import from there; range-delta.ts re-exports the same names so
the server route and the OpenAPI registry keep their import paths. The
window-composition logic and the rollup/db imports stay server-side.

No runtime behaviour change — a pure module-boundary split.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 75124e76c1e987d8a022fb39d891049340199b38)
2026-06-02 17:41:33 +02:00

57 lines
1.6 KiB
TypeScript

"use client";
import { useQuery } from "@tanstack/react-query";
import { useAuth } from "@/hooks/use-auth";
import { queryKeys } from "@/lib/query-keys";
import type { AnalyticsRange } from "@/lib/analytics/range-shared";
/**
* v1.9.0 — client reader for the single-metric period-over-period range
* read (`GET /api/analytics/range`). One cache slot per `(type, range)` via
* the centralised query-key factory, so switching the time-range pills is a
* cheap cache hit after first fetch and never collides with the shared
* `["analytics", "summaries"]` slot.
*/
export interface AnalyticsWindowAggregate {
count: number;
min: number | null;
max: number | null;
mean: number | null;
sum: number | null;
}
export interface AnalyticsRangeData {
range: AnalyticsRange;
windowDays: number;
granularity: string;
current: AnalyticsWindowAggregate;
previous: AnalyticsWindowAggregate;
delta: number | null;
deltaPct: number | null;
}
export function useAnalyticsRange(
type: string,
range: AnalyticsRange,
enabled = true,
) {
const { isAuthenticated } = useAuth();
return useQuery({
queryKey: queryKeys.analyticsRange(type, range),
queryFn: async (): Promise<AnalyticsRangeData> => {
const res = await fetch(
`/api/analytics/range?type=${encodeURIComponent(
type,
)}&range=${encodeURIComponent(range)}`,
);
if (!res.ok) throw new Error("Failed to load range");
const json = (await res.json()) as { data: AnalyticsRangeData };
return json.data;
},
enabled: isAuthenticated && enabled && type.length > 0,
staleTime: 60 * 1000,
});
}