fix(daily): keep the coach check-in constants out of the client bundle

The Today hero and the check-in hook imported the check-in intent constants
from digest.ts, which — since the milestone slice — transitively reaches the
database through the streak baseline engine. That pulled the Postgres driver
into the client bundle (a Turbopack 'Can't resolve net/tls/dns' build failure
the worktree build couldn't surface). Move the four constants to a tiny,
dependency-free coach-checkin-intents module; the client imports them from
there, and digest.ts (the server builder) stays server-only.
This commit is contained in:
Marc-André Bombeck committed 2026-07-17 09:37:39 +02:00
1 parent 2d9237fbad
commit ba5a17a54e
6 files changed
+47 -11

No files matched your search

+1 -1
View File
@@ -34,7 +34,7 @@ import { prisma } from "@/lib/db";
import { requireModuleEnabled } from "@/lib/modules/gate";
import { checkRateLimit, rateLimitHeaders } from "@/lib/rate-limit";
import { decryptFromBytes } from "@/lib/ai/coach/bytes-codec";
import { COACH_CHECKIN_REVIEW_DAYS } from "@/lib/daily/digest";
import { COACH_CHECKIN_REVIEW_DAYS } from "@/lib/daily/coach-checkin-intents";
import { coachPlanPatchSchema } from "@/lib/validations/coach-plan";
interface RouteCtx {
+2 -2
View File
@@ -46,11 +46,11 @@ import { useTranslations } from "@/lib/i18n/context";
import { cn } from "@/lib/utils";
import type { ScoreRingId } from "@/lib/dashboard-layout";
import type { DashboardScoreRing } from "@/lib/dashboard/score-rings";
import type { DailyDigest } from "@/lib/daily/digest";
import {
COACH_CHECKIN_KEEP_INTENT,
COACH_CHECKIN_LETGO_INTENT,
type DailyDigest,
} from "@/lib/daily/digest";
} from "@/lib/daily/coach-checkin-intents";
/**
* v1.29.0 — the selected score rings return to the hero. The maps mirror the
+1 -1
View File
@@ -22,7 +22,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { apiPatch } from "@/lib/api/api-fetch";
import { queryKeys } from "@/lib/query-keys";
import { COACH_CHECKIN_REVIEW_DAYS } from "@/lib/daily/digest";
import { COACH_CHECKIN_REVIEW_DAYS } from "@/lib/daily/coach-checkin-intents";
export function useCoachCheckinAction() {
const queryClient = useQueryClient();
+5 -3
View File
@@ -5,14 +5,16 @@ import type { DailyBriefing } from "@/lib/ai/schema";
import type { MedsTodayBlock } from "@/lib/dashboard/meds-today";
import {
buildDailyDigest,
COACH_CHECKIN_KEEP_INTENT,
COACH_CHECKIN_LETGO_INTENT,
COACH_CHECKIN_RESURFACE_DAYS,
COACH_CHECKIN_REVIEW_DAYS,
MAX_WORTH_A_LOOK,
type DailyDigestCoachPlan,
type DailyDigestInput,
} from "@/lib/daily/digest";
import {
COACH_CHECKIN_KEEP_INTENT,
COACH_CHECKIN_LETGO_INTENT,
COACH_CHECKIN_REVIEW_DAYS,
} from "@/lib/daily/coach-checkin-intents";
import type { Milestone } from "@/lib/daily/milestones";
import type { PriorityItem } from "@/lib/daily/priority-item";
+28
View File
@@ -0,0 +1,28 @@
/**
* Coach check-in constants shared by BOTH the server-side digest builder and
* the client Today surface + hooks.
*
* They live in this tiny, dependency-free module on purpose: `digest.ts` (their
* former home) transitively reaches the database through the milestone/streak
* baseline engine, so importing a constant from it would drag the whole server
* builder — and the Postgres driver — into a client bundle (a Turbopack
* `Can't resolve 'net'/'tls'/'dns'` build failure). Keeping the constants here
* lets the Today hero and the check-in hook import them with zero server reach.
*/
/**
* Days after a plan's activation / last review it becomes due for a look-back.
* One source of truth for the digest builder AND the PATCH route that re-arms it.
*/
export const COACH_CHECKIN_REVIEW_DAYS = 7;
/**
* Closed allowlist of the check-in card's two MUTATING intents. The generic,
* id-less `PriorityCard` forwards only a single `intent` string, so the target
* plan id is appended after the ":" — the Today handler recovers it and PATCHes
* the existing plan-lifecycle route. "Adjust" is navigation (an `href` into the
* coach), so it carries no plan id and never mutates.
*/
export const COACH_CHECKIN_KEEP_INTENT = "coach.checkin.keep";
export const COACH_CHECKIN_LETGO_INTENT = "coach.checkin.letGo";
export const COACH_CHECKIN_ADJUST_INTENT = "coach.checkin.adjust";
+10 -4
View File
@@ -32,6 +32,12 @@ import {
milestoneHref,
type Milestone,
} from "@/lib/daily/milestones";
import {
COACH_CHECKIN_REVIEW_DAYS,
COACH_CHECKIN_KEEP_INTENT,
COACH_CHECKIN_LETGO_INTENT,
COACH_CHECKIN_ADJUST_INTENT,
} from "@/lib/daily/coach-checkin-intents";
/** At most three rail items — a glance, never a wall (§2.5, never padded). */
export const MAX_WORTH_A_LOOK = 3;
@@ -47,7 +53,7 @@ const MS_PER_DAY = 86_400_000;
* ones the coach explicitly dated. The PATCH-to-`active` route defaults
* `reviewDate` to `+COACH_CHECKIN_REVIEW_DAYS`; this constant is the one source.
*/
export const COACH_CHECKIN_REVIEW_DAYS = 7;
// COACH_CHECKIN_REVIEW_DAYS lives in ./coach-checkin-intents (client-safe).
/**
* After a check-in comes due, it resurfaces for at most this many days before
@@ -65,9 +71,9 @@ export const COACH_CHECKIN_RESURFACE_DAYS = 14;
* and PATCHes the existing plan-lifecycle route. "Adjust" is navigation (an
* `href` into the coach), so it carries no plan id and never mutates here.
*/
export const COACH_CHECKIN_KEEP_INTENT = "coach.checkin.keep";
export const COACH_CHECKIN_LETGO_INTENT = "coach.checkin.letGo";
export const COACH_CHECKIN_ADJUST_INTENT = "coach.checkin.adjust";
// The check-in intents live in ./coach-checkin-intents (client-safe) and are
// imported above, so the client Today surface can use them without pulling this
// server-side builder into its bundle.
type Translate = ServerTranslator["t"];