Files
HealthLog/src/components
Marc-André Bombeck 8e9da490a9 test(tz): refuse a date formatter that does not name its calendar
A formatter with no timeZone follows the browser, which is a different
question from the one this app answers. Four surfaces had drifted apart that
way before anyone noticed, and one of them printed a shared report a day off
from the page it came from.

The admin host chart went with them rather than onto the allowlist. Server
samples are real instants, and an operator reading their own instance should
not find a spike at 14:20 here and 15:20 two screens away.

Two deliberate limits, both written into the test. It does not match
toLocaleString, which in this tree is overwhelmingly a number formatter, and
burying four real hits under every thousands separator is how a guard gets
silenced. And it cannot tell a Date built from calendar arithmetic — a month
label, a weekday header, no instant behind it — from one parsed out of stored
data, so those four sites carry a written reason instead. The value is the
ratchet: a new bare formatter has to be argued for before it ships.
2026-07-27 00:18:22 +02:00
..

src/components/

React components. The UI primitives are shadcn/ui (new-york style, zinc base) over Radix + Tailwind 4 + Lucide; everything above the primitives is feature-grouped by surface. Components are server components unless they need a hook, state, or browser API, in which case they open with "use client". Charts use Recharts 3 — replacing the chart library requires explicit approval.

Primitives and shell

  • ui/ — shadcn/ui primitives (button, dialog, sheet, table, …). Generated by the shadcn CLI; keep edits minimal and on-style.
  • layout/ — the app shell: sidebar, topbar, bottom nav.
  • providers.tsx, version-poller.tsx — top-level context providers and the self-healing stale-shell poller.
  • i18n/ — translation context + locale switcher.

Feature groups

  • insights/ — insight status, assessment cards, Coach surface, advisor cards (the largest group).
  • medications/ — medication cards, the schedule wizard, intake timeline, detail history.
  • settings/ — the section components behind each settings page.
  • measurements/, mood/, dashboard/ — entry forms, lists, dashboard tiles.
  • charts/ — Recharts wrappers.
  • monitoring/ — Umami / GlitchTip client bootstrap.
  • gamification/, targets/, comparison/, doctor-report/, clinician/, onboarding/, admin/ — the remaining per-surface groups.

Conventions

Kebab-case filenames; React component exports stay PascalCase regardless. (A handful of PascalCase-filename outliers under medications/ + onboarding/ are pre-existing drift, noted in ../../CLAUDE.md.) Every t() call needs a matching key in messages/en.json — guarded by i18n-call-site-coverage.test.ts. Data reads go through TanStack Query with keys from @/lib/query-keys and unwrap (await res.json()).data. Tests live in __tests__/.