diff --git a/.planning/phase-Fix-N-v1425-report.md b/.planning/phase-Fix-N-v1425-report.md new file mode 100644 index 000000000..d57dac79c --- /dev/null +++ b/.planning/phase-Fix-N-v1425-report.md @@ -0,0 +1,142 @@ +# Phase Fix-N — v1.4.25 reconcile (final bucket) + +**Branch**: `develop` +**Date**: 2026-05-14 +**Status**: COMPLETE — reconcile pass CLOSED. + +## Scope + +Fix-N is the largest bucket of the W21 reconcile pass: shared helper +modules, the medication-detail section wrapper, drift-guard tightening +on the side-effect taxonomy, and route-ownership hoisting across nine +medication sub-routes. All items applied; no scope deferred. + +Items landed (per `.planning/phase-W21-reconcile-plan.md`): + +- simp-H1 — onboarding `readError` helper hoisted (one source, four callers). +- simp-H2 — dropped the `templateFill` helper in TitrationSection; the + i18n `t()` already accepts the params bag. +- simp-H3 — extracted `researchModeStatusLabel` helper out of the + Settings advanced-section's nested ternary. +- simp-H4 — shared `ResearchModeStatus` DTO + tri-state gate classifier + consumed by DrugLevelChart and the Settings re-prompt banner. +- simp-H5 — added `findDrugIdByBrand` to the GLP-1 knowledge layer. +- simp-H6 — hoisted `assertMedicationOwnership` to a shared route-guard + module; rolled out across 9 medication sub-routes. +- simp-H7 — replaced the local `InventoryState` union with the canonical + Prisma `MedicationInventoryState` enum. +- simp-M1 + code-M1 — derived `SIDE_EFFECT_CATEGORY_VALUES` / + `SIDE_EFFECT_ENTRY_VALUES` via `z.nativeEnum`; drift-guard test asserts + Prisma enum, taxonomy map, and validator triangle stay aligned. +- simp-M3 — extracted `` wrapper across the + three Wave-4b sections (Titration, Scheduling, SideEffects). The + inventory disclosure stays on `
` (see Deviations). +- simp-M4 — collapsed the two near-identical dose-string parsers + (`parseDoseMg` in DrugLevelChart, `parseDoseString` in the titration + route) into a single module at `src/lib/medications/dose-string.ts`. + The `parseDose` helper in `medication-form.tsx` was left alone — its + contract is form-splitting (returns `{ amount, unit }`), not mg + extraction. +- simp-M5 — widened `daysRemainingInUse` in the inventory state-machine + to accept either the full `InventoryItemView` or a thin + `{ firstUseAt }` shape; the inventory-section client now calls the + pure helper instead of re-implementing it. +- simp-M8 — the three W19 routes (glp1, inventory, side-effects) now + use `apiError("Too many requests", 429, { headers: rateLimitHeaders(rl) })` + instead of the 4-line `for` loop. `apiError` was extended to accept + a `headers` key in its third-argument option bag. +- design-M1 — swapped the gender native `` in SideEffectsSection for the + shadcn-radix `