Highlights
The closing web release before the v1.5 iOS-app sprint. Carries the v1.4.36 performance carry-over for the full /api/analytics route, consolidates Apple Health step samples into one daily row per day, restores IntakeHistoryListV2 to its pre-v1.4.28 contract, converges every Coach affordance behind a single feature gate, lifts the Mounjaro medication card to byte-equivalent parity with Ramipril, hardens the client-IP source chain behind a new env flag, ships the doctor-report as a hero card under Settings → Export, adds a medication-intake quick-add overlay to the dashboard, drops the timezone override for a silent browser-zone auto-seed, and fixes the v1.4.36 red CI workflows. Documentation refreshed across all three repos with five new architecture diagrams in the Dracula palette.
Performance
- Full
/api/analyticsroute on the rollup-coverage probe. Correlations, healthScore and bp_in_target each gained a rollup-fast-path that fires whenever every logged type has DAY coverage, with the live SQL path remaining the source of truth for partial-coverage accounts. Cold worst-case 111 s → ~1.5–3 s on power-user accounts. Per-branchpath:"rollup"|"live"annotate in the meta dict proves which branch fired. - Apple Health step consolidation. New
groupBy=day+dayKeymodes onGET /api/measurementscollapse the per-sample step rows into one daily total per row with a chevron drill-down. A nightlydrainPerSampleCumulativepg-boss job at 03:45 Europe/Berlin (36 h grace window) shrinks the underlying table by roughly 50× once it converges.
AI
IntakeHistoryListV2on the medication detail page hides planned/scheduled rows by default; the API gains an explicit?status=completedfilter. Skipped rows render distinctly.
UX
- HealthScoreCard fills the full Insights overview hero row height.
- Sidebar + top-bar overflow menus keep menu items single-line at
w-60. - Targets page card gap tightened to kill the dead band below each metric label.
- Select chevron right-margin matches the date-picker icon gutter.
- Mood mini chart byte-aligned with the BP and Weight minis.
- Dashboard "Hinzufügen" button centre-aligns with the title on mobile.
- Medication detail card symmetry — Mounjaro renders identically to Ramipril; GLP-1-specific data lives behind the header-actions kebab.
- Coach disable cascade — when the global Coach flag is OFF, every Coach affordance disappears. Six in-band surfaces pinned by an invariant test; cross-cut gates carry sibling tests.
- Settings → Export — Arztbericht hero card promotes the doctor report to a prominent CTA at the top of the page.
- Dashboard quick-add — new Medikamenteneinnahme action opens a ResponsiveSheet with a smart medication picker (auto-selects the medication with an open dosing window).
- Onboarding checklist toggle + dismiss button raised to the 44 px mobile touch floor (uncovered while wiring the e2e fix).
- Timezone override toggle removed in favour of a silent browser-zone auto-seed.
- Insights BMI status persists a sentinel cache row on the 20 s LLM timeout path so the spinner stops re-firing.
Security
- New
TRUST_CF_CONNECTING_IPenv flag (default off) lets Cloudflare-fronted deployments readcf-connecting-ipfor the rate-limit bucket and audit-log IP..env.exampledocuments the security implications: only set behind Cloudflare; nginx / Caddy / direct deployments must leave it off. - Hourly geo-backfill pg-boss job closes the gaps the v1.4.36 IP-whois UI fix surfaced.
Refactor
- Shared
window-status.ts+category-label.tshelpers collapse the previously duplicated medication-card logic. CUMULATIVE_DAY_SUM_TYPESderives fromCUMULATIVE_HK_TYPESso the cumulative-type registry is a single source of truth across the importer, drain, route, UI, and analytics metric-key mapping.getClientIpandgetClientIpOrTrustWarningshare one ladder.
Validation
dayKeyrejects impossible calendar values like2026-02-30.groupBy=day/dayKeyrequests withoffset > 0are rejected upfront.- Drill-down window honours DST transitions (Berlin Mar 30 + Oct 26 stop showing wrong hour-overlap counts).
CI
- Vitest 4 timeout-option signature corrected on the 5 MB payload guard test.
- Integration
isolate:truefor mock-state-sensitive notification dispatch tests. - e2e mobile-touch-target assertions updated to the 44 px floor.
Documentation
- README rewrite with hero, status block, How-it-works walkthrough, and inline architecture diagrams.
healthlog-docssite refresh: three new integration mirrors, three placeholder pages filled, two new concepts pages.healthlog-landingvalue-statement upgrade with two new sections.- Five new SVG diagrams in
docs/diagrams/(Dracula palette): data flow, Coach pipeline, self-hosting topology, source-priority ladder, security model.
Tests
- Unit suite 4354 → 4486 passing.
pnpm typecheck+pnpm lintclean. Integration suite stable at 230; the two pre-existing mock-isolation flakes (apns-dispatch/integration-status) stabilised by theisolate:truefix.
Operator notes
- Coolify auto-deploys main on tag push. First webhook may pull a stale
:latest; trigger a redeploy after the docker-publish workflow completes if so. - No new migrations.
TRUST_CF_CONNECTING_IPis opt-in; existing deployments are unaffected unless they explicitly set it.
Deferred to v1.4.38
See CHANGELOG.md for the full backlog table (~50 items). Headline carry-overs: cross-tz fragility in the rollup fast-paths (must land before iOS user base broadens beyond Berlin), real pagination on the collapsed groupBy=day branch, per-process singleton-guard on the hourly geo-backfill for multi-worker deployments, and several smaller drift-risk cleanups identified by the code-review pass.