diff --git a/src/components/settings/dashboard-layout-section.tsx b/src/components/settings/dashboard-layout-section.tsx index 3c60ef775..3074d8ded 100644 --- a/src/components/settings/dashboard-layout-section.tsx +++ b/src/components/settings/dashboard-layout-section.tsx @@ -50,7 +50,7 @@ import { } from "@/components/ui/select"; import { apiDelete, apiGet, apiPut } from "@/lib/api/api-fetch"; import { useAuth } from "@/hooks/use-auth"; -import { WIDGET_MODULE_BY_ID } from "@/lib/dashboard/snapshot"; +import { WIDGET_MODULE_BY_ID } from "@/lib/dashboard/widget-modules"; /** * v1.4.47 W4 — pure reorder helper shared by the arrow buttons and the diff --git a/src/lib/dashboard/snapshot.ts b/src/lib/dashboard/snapshot.ts index 30835ef12..2fc0c682c 100644 --- a/src/lib/dashboard/snapshot.ts +++ b/src/lib/dashboard/snapshot.ts @@ -84,48 +84,20 @@ import { resolveModuleMap, type ModuleKey } from "@/lib/modules/gate"; const BRIEFING_TTL_MS = 24 * 60 * 60 * 1000; /** - * v1.18.0 — dashboard widget id → toggleable module key. When the user - * disables the module, the matching widget is forced invisible on both - * the web `layout` and the iOS `layoutCatalogue`, so the tile/chart never - * paints. Only the toggleable surfaces appear here; CORE widgets - * (weight / bp / pulse / bodyFat / medications / bpInTarget and the - * vital-derived HealthKit metrics) carry NO entry and are never hidden. + * v1.18.0 — the two dashboard module maps live in a client-safe module + * (`@/lib/dashboard/widget-modules`) so the settings client component can + * import them without pulling the server snapshot builder (and its + * `pg` / `dns` chain) into the browser bundle. Re-exported here for the + * server call sites and the existing tests. */ -export const WIDGET_MODULE_BY_ID: Partial> = { - mood: "mood", - sleep: "sleep", - glucose: "glucose", - achievements: "achievements", - recentWorkouts: "workouts", - // v1.18.0 B1 — recovery-domain HealthKit widgets belong to the recovery - // module; the per-night breathing-disturbance widget belongs to sleep. - cardioRecovery: "recovery", - sixMinuteWalk: "recovery", - stairAscentSpeed: "recovery", - stairDescentSpeed: "recovery", - breathingDisturbances: "sleep", -}; - -/** - * v1.18.0 — `MeasurementType` slim-summary keys that belong to a - * toggleable module. When the module is off the key is stripped from - * `tiles.summaries` / `tiles.lastSeenByType` (so `metricStates` and the - * client data-floor gates also drop it) before the snapshot leaves the - * server. Core vital types are absent here and always pass through. - */ -export const SUMMARY_TYPE_MODULE: Partial> = { - SLEEP_DURATION: "sleep", - BLOOD_GLUCOSE: "glucose", - // v1.18.0 B1 — recovery-domain HealthKit metrics. The recovery page + - // its tiles are the recovery module's surface; when it is off these - // device-native signals must drop from the dashboard snapshot too. - CARDIO_RECOVERY: "recovery", - SIX_MINUTE_WALK_DISTANCE: "recovery", - STAIR_ASCENT_SPEED: "recovery", - STAIR_DESCENT_SPEED: "recovery", - // Per-night breathing-disturbance index is a sleep-page signal. - BREATHING_DISTURBANCES: "sleep", -}; +export { + WIDGET_MODULE_BY_ID, + SUMMARY_TYPE_MODULE, +} from "@/lib/dashboard/widget-modules"; +import { + WIDGET_MODULE_BY_ID, + SUMMARY_TYPE_MODULE, +} from "@/lib/dashboard/widget-modules"; const GLUCOSE_CONTEXTS = [ "FASTING", diff --git a/src/lib/dashboard/widget-modules.ts b/src/lib/dashboard/widget-modules.ts new file mode 100644 index 000000000..80af8e63b --- /dev/null +++ b/src/lib/dashboard/widget-modules.ts @@ -0,0 +1,61 @@ +/** + * v1.18.0 — client-safe module maps for dashboard widgets / summary types. + * + * These two maps are pure data (string → ModuleKey) with no runtime + * dependency on the DB, Prisma, or the server-only module gate. They are + * factored out of `@/lib/dashboard/snapshot` so the settings client + * component (`dashboard-layout-section.tsx`) can import them without + * dragging the whole server snapshot builder — and its transitive + * `pg` / `dns` chain — into the browser bundle. `snapshot.ts` re-exports + * both for the server call sites and the existing tests. + * + * `ModuleKey` comes from `@/lib/modules/registry` (pure constants, no + * imports) and `MeasurementType` is a type-only import from the generated + * Prisma client, so this file stays browser-bundle-safe. + */ +import type { MeasurementType } from "@/generated/prisma/client"; +import type { ModuleKey } from "@/lib/modules/registry"; + +/** + * Dashboard widget id → toggleable module key. When the user disables the + * module, the matching widget is forced invisible on both the web `layout` + * and the iOS `layoutCatalogue`, so the tile/chart never paints. Only the + * toggleable surfaces appear here; CORE widgets (weight / bp / pulse / + * bodyFat / medications / bpInTarget and the vital-derived HealthKit + * metrics) carry NO entry and are never hidden. + */ +export const WIDGET_MODULE_BY_ID: Partial> = { + mood: "mood", + sleep: "sleep", + glucose: "glucose", + achievements: "achievements", + recentWorkouts: "workouts", + // v1.18.0 B1 — recovery-domain HealthKit widgets belong to the recovery + // module; the per-night breathing-disturbance widget belongs to sleep. + cardioRecovery: "recovery", + sixMinuteWalk: "recovery", + stairAscentSpeed: "recovery", + stairDescentSpeed: "recovery", + breathingDisturbances: "sleep", +}; + +/** + * `MeasurementType` slim-summary keys that belong to a toggleable module. + * When the module is off the key is stripped from `tiles.summaries` / + * `tiles.lastSeenByType` (so `metricStates` and the client data-floor + * gates also drop it) before the snapshot leaves the server. Core vital + * types are absent here and always pass through. + */ +export const SUMMARY_TYPE_MODULE: Partial> = { + SLEEP_DURATION: "sleep", + BLOOD_GLUCOSE: "glucose", + // v1.18.0 B1 — recovery-domain HealthKit metrics. The recovery page + + // its tiles are the recovery module's surface; when it is off these + // device-native signals must drop from the dashboard snapshot too. + CARDIO_RECOVERY: "recovery", + SIX_MINUTE_WALK_DISTANCE: "recovery", + STAIR_ASCENT_SPEED: "recovery", + STAIR_DESCENT_SPEED: "recovery", + // Per-night breathing-disturbance index is a sleep-page signal. + BREATHING_DISTURBANCES: "sleep", +};