321 Commits
Author SHA1 Message Date
Marc-André Bombeck 388c8b23dd chore(release): v1.21.2
Surfaces the Coach's existing intelligence as ambient presence: a per-metric
"Coach read", a visible scope handoff and a seeded opener, briefing callbacks,
a tension verdict and return-to-baseline note on the score, two motivational-
interviewing moves, and grounding parity on the local model path. No
migrations, no breaking changes.
2026-06-27 00:37:15 +02:00
Marc-André Bombeck f3ffafaae1 chore(release): v1.21.1
Patch release. Pins the action row in the centred dialog so the primary
button stays reachable without scrolling under long forms, browser zoom, or
display scaling. No migrations, no breaking changes.
2026-06-26 22:55:37 +02:00
Marc-André Bombeck e6ac604c83 chore(release): v1.21.0 2026-06-26 14:03:51 +02:00
Marc-André Bombeck cd6fff9730 chore(release): v1.20.2 2026-06-26 09:36:02 +02:00
Marc-André Bombeck 2c112c3323 fix(dashboard): stop the chart-row render loop on tab resume
A user reported the dashboard crashing on returning to a backgrounded
tab. The on-focus snapshot refetch re-rendered the page, and each chart
received a fresh inline `() => markChartReady(id)` handler every render;
the chart's data-ready notify effect, keyed on that ever-changing prop,
re-fired on every commit. That per-commit passive effect kept the chart
row's anchored popovers re-committing until the browser tripped its
render-depth guard and the page fell back to its error card.

Latch the notify behind a ref so it fires once, when the chart's initial
query settles, and depend on the load flag alone. The handler is read
through a ref so a late-arriving callback still fires without re-arming
the effect. Extract the pure fire-once decision into a small helper with
direct unit coverage (no DOM runner, per project convention).
2026-06-23 21:45:42 +02:00
Marc-André Bombeck b9368b9a69 chore(release): v1.20.0 2026-06-22 08:36:28 +02:00
Marc-André Bombeck 5cd4a5e6bd chore(deps): bump runtime + dev dependencies for v1.20.0
next 16.2.6->16.2.9, pg-boss 12.18.2->12.20.0, radix-ui 1.4.3->1.6.0,
@testcontainers/postgresql 12.0.1->12.0.3, pg 8.21.0->8.22.0.
2026-06-22 08:32:23 +02:00
Marc-André Bombeck b4bf31a8c9 chore(release): v1.19.2 2026-06-21 21:21:13 +02:00
Marc-André Bombeck 41dab24985 chore(release): v1.19.1 2026-06-21 14:24:39 +02:00
Marc-André Bombeck 31efb3e884 chore(release): v1.19.0 2026-06-21 12:46:32 +02:00
Marc-André Bombeck 3e578836cc chore(release): v1.18.11 2026-06-21 09:40:53 +02:00
Marc-André Bombeck 16759b4df8 chore(release): v1.18.10
Fix encrypted day-log data loss and the stalled cumulative-measurement drain;
capture Withings sleep vitals and Oura VO2max; harden AI grounding across the
briefing, Coach, narrative, and status cards; full-page Coach with history and a
working mic; on-device lab OCR; preventive-care, labs, and settings polish; BP
warm/cold parity, a statement timeout, and a covering measurements index.
2026-06-20 17:19:14 +02:00
Marc-André Bombeck 3d039d5220 feat(labs): add local-OCR text mode for image-blind AI providers
Add an opt-in in-browser OCR path so a user whose provider cannot read
images (ChatGPT-OAuth/Codex, a text-only model) can still scan a lab
report. The capability probe gains a `mode` field: `vision` when the
provider reads the image directly, `text` when local OCR is enabled and
any provider is configured, or null. The extract route grows a text
branch that accepts the in-browser-OCR'd text as JSON and structures it
through the existing schema + review/commit flow; the raw image never
reaches the server in text mode. New `labsLocalOcrEnabled` user column
(migration 0184, default off) gates it, with a dedicated PATCH endpoint.
2026-06-20 16:50:06 +02:00
Marc-André Bombeck 731714ebde chore(release): v1.18.9
Coach new-chat surface with streamed answers and a token footer; lab-report OCR
ingestion with a mandatory per-row review; qualitative lab results; labs list
default, sort, and delete; VO2max on the dashboard with Oura ingest; preventive-
care date and due-status polish; faster condition journal; honest report
staleness; dashboard freshness on background sync.
2026-06-20 13:05:34 +02:00
Marc-André Bombeck 3dd5b3dd5b chore(release): v1.18.8 — coded condition and lab terminology in the export 2026-06-20 09:51:10 +02:00
Marc-André Bombeck cdb76f1930 chore(release): v1.18.7 2026-06-19 20:03:28 +02:00
Marc-André Bombeck 155cedda50 chore(release): v1.18.6.1 2026-06-19 00:05:20 +02:00
Marc-André Bombeck 8b03fb450e fix(deps): patch undici and nodemailer high-severity advisories
Bump undici 8.4.1 -> 8.5.0 (GHSA-vmh5-mc38-953g, TLS certificate
validation bypass in the SOCKS5 ProxyAgent) and nodemailer 9.0.0 -> 9.0.1
(GHSA-p6gq-j5cr-w38f), both direct dependencies. Clears the production
high-severity dependency audit; no API change.
2026-06-18 23:04:27 +02:00
Marc-André Bombeck bb08aa42dc feat(pwa): real offline read value via SW data cache + query persistence
An installed PWA opened offline rendered empty skeletons forever: the
service worker hard-excluded every /api/* path and there was no client
query persistence. Close both gaps for read value.

Service worker: add a stale-while-revalidate branch for an allowlist of
safe GET /api/* reads (dashboard snapshot + widgets, measurements,
medications, insights, analytics, version) in a release-versioned
healthlog-data cache. Two-layer refusal — a path deny guard for any
auth/token/session/login segment plus a body-level secret refusal for
hlk_/hlr_/sk- shapes and no-store responses — so a secret-shaped body or
an auth surface can never be persisted. Mutations stay network-only.

Client: add a dependency-free IndexedDB query persister that hydrates the
last successful reads before the first authenticated paint, build-version
and age gated, debounced on cache change, with an auth/session/admin/token
denylist. Cleared on logout alongside the SW page and data caches so a
shared device never leaks one account's data.

Offline banner now states it is showing last-synced data when a cached
snapshot is present. Bump release to v1.18.6.
2026-06-18 15:18:48 +02:00
Marc-André Bombeck 474e99e0f8 chore(release): v1.18.5 2026-06-18 14:43:47 +02:00
Marc-André Bombeck f39b5541f5 chore: bump to 1.18.4 2026-06-18 11:40:00 +02:00
Marc-André Bombeck 8bc8b5765d chore(release): v1.18.3 2026-06-17 14:17:45 +02:00
Marc-André Bombeck ff5efb4234 chore(release): v1.18.2 2026-06-17 07:56:07 +02:00
Marc-André Bombeck e1e3cb6364 chore(release): v1.18.1
Maintenance patch clearing two transitive security advisories. Bump the
package version, record the changelog entry, and regenerate the OpenAPI
version line. No functional changes.
2026-06-16 19:22:33 +02:00
Marc-André Bombeck 97ddf2da79 build(deps): override hono and picomatch to clear transitive advisories
Pin hono to >=4.12.25 (GHSA-88fw-hqm2-52qc, CORS middleware reflects
any Origin) and picomatch to >=4.0.4 (CVE-2026-33671, ReDoS) through
pnpm overrides scoped to the vulnerable ranges. Both are build- and
dev-tooling transitives — hono via Prisma's dev tooling and the shadcn
CLI, picomatch via the build chain — and neither is on a runtime path:
the app is Next.js and sets no CORS headers. The prod audit drops from
one high to zero.
2026-06-16 19:22:25 +02:00
Marc-André Bombeck 0dbb70134c chore(release): v1.18.0 — module enable/disable and the settings IA redesign 2026-06-16 11:58:23 +02:00
Marc-André Bombeck 497982b4b4 chore(release): v1.17.1 — preventive care, lab results, and more of the data you already have 2026-06-15 01:40:36 +02:00
Marc-André Bombeck 909c2aa99e feat(notifications): add SMTP email channel
Alerts and reminders over email — the one channel every self-hoster
already has. The SMTP transport (host/port/auth/from) is operator-supplied
via SMTP_* env and loaded once per process like the APNs key; the only
per-user value is the recipient address, so SMTP credentials never enter a
user's encrypted channel blob. Absent SMTP env disables the channel
cleanly: the dispatcher skips it and the Settings card hides itself.

Bodies are plain text — HTML is stripped and routine reminders run through
the emoji-strip path; no markdown library is added. SMTP 5xx maps to a
hard reject (permanent — auto-disable); connection/4xx errors are
transient and ride the backoff schedule. Adds nodemailer (the standard,
well-audited mail transport) and its types.
2026-06-15 00:46:12 +02:00
Marc-André Bombeck 3f5b1a66a1 chore(release): v1.17.0 — clinical depth for glucose and sleep, three new sources
Add the blood-glucose clinical panel with Nightscout, sleep debt and chronotype,
Polar and Oura over OAuth, reorder-aware medication supply and an invite
deep-link. Every new metric is computed once on the server and read the same way
on the dashboard, the coach, the doctor-report and the companion app, each behind
a still-learning gate. The coach now reasons from the new signals, mood and cycle
entry is one sectioned sheet, and previously-hidden wearable data surfaces.
2026-06-14 21:29:45 +02:00
Marc-André Bombeck ed1766c0dc chore(deps): bump zod-openapi from 5.4.6 to 6.0.0
The v6 major leaves the createDocument API and the .meta() registry
annotations unchanged for this codebase; the generated
docs/api/openapi.yaml stays byte-identical and openapi:check passes
with no registry adjustment.
2026-06-14 21:12:20 +02:00
Marc-André Bombeck 158a79797f chore(deps): bump react and react-dom from 19.2.5 to 19.2.7
Patch bump within the pinned 19.2.x line. @types/react resolves to
19.2.17 under the existing ^19 range.
2026-06-14 21:11:57 +02:00
Marc-André Bombeck 2b240c5798 chore(deps): bump prettier, undici, lucide-react and two CI actions
- prettier 3.8.3 -> 3.8.4 (dev)
- undici 8.3.0 -> 8.4.1
- lucide-react 1.17.0 -> 1.18.0
- docker/metadata-action 6.0.0 -> 6.1.0
- dependabot/fetch-metadata 2.5.0 -> 3.1.0
2026-06-14 21:11:44 +02:00
Marc-André Bombeck 870ee01826 chore(release): v1.16.17 — restore the sleep timeline, clear the dashboard after a dose
Two daily-use fixes: the last-night hypnogram bar collapsed to its breakdown
for nights whose stages share an end instant, and the dashboard kept prompting
for a dose until a full reload after it was recorded. No breaking changes.
2026-06-14 20:21:31 +02:00
Marc-André Bombeck 04b09e2905 chore(release): v1.16.16 — one engine for sleep, recovery and glucose
Read sleep, recovery and blood glucose from a single source on every surface —
dashboard, coach, doctor-report, CSV and FHIR exports, and the companion app —
so the displayed figure agrees wherever it appears. Sleep nights reconstruct
once with source de-duplication; WHOOP-native recovery is canonical and resolves
to one row per night; glucose converts to the user's unit at the point it is
served. Hardens the consent receipt path and deepens WHOOP sync with per-resource
cursors, targeted refresh and full backfill. Several displayed numbers become
correct-but-different — flagged in the changelog.
2026-06-14 17:58:56 +02:00
Marc-André Bombeck 8511b0bed7 chore(release): v1.16.15 — an honest calendar that learns before it predicts 2026-06-14 15:53:01 +02:00
Marc-André Bombeck ae1373637f chore(release): v1.16.14 — one number everywhere across score, coach, and doctor-report
Coherence release: blood-pressure in-target unified on a labeled, thin-data-gated
90-day window across tile, health-score pillar and coach; the dashboard ring and
insights card built from one shared health-score input builder; the coach and the
doctor-report PDF/FHIR adherence drawn from the same dose ledger as the detail page;
and a shared entry-timestamp plausibility guard on measurement and mood. Several
displayed figures become correct-but-different (BP headline window, adherence).
2026-06-14 14:02:45 +02:00
Marc-André Bombeck 5aefcd59eb chore(release): v1.16.13 — installable offline, era-correct dose edits, steadier headers
App-wide service-worker registration (installable + offline, authenticated
pages kept out of the cache, logout wipe), era-correct historical dose-edit
attribution, CSV intake stock consumption, WHOOP late-workout ingest, web AI
consent-receipt minting, the layout partial-PUT section merge, the curated
mood-tag catalog, and a sweep of mobile header fixes.
2026-06-14 11:06:10 +02:00
Marc-André Bombeck 9cf609bae2 chore(release): v1.16.12 — split doses, steady cards, and a read that stays warm 2026-06-13 16:08:09 +02:00
Marc-André Bombeck 3189848ace chore(release): v1.16.11 — the supply speaks up, tags find their groups, and nothing asks twice 2026-06-12 23:49:06 +02:00
Marc-André Bombeck e9f776937d chore(deps): bump react-hook-form from 7.77.0 to 7.78.0 2026-06-12 22:17:11 +02:00
Marc-André Bombeck f4f3b75166 chore(release): v1.16.10 — the stock follows every dose, and the list takes your order 2026-06-12 19:47:49 +02:00
Marc-André Bombeck 12fce6fc14 chore(release): v1.16.9 — the day opens with a verdict, and every dose path tells the truth 2026-06-12 11:23:00 +02:00
Marc-André Bombeck 8fdf8597a2 chore(release): v1.16.8 — texts that follow your data, charts that never strand 2026-06-11 23:21:40 +02:00
Marc-André Bombeck 11a061c4a1 chore(release): v1.16.7 — insights answer instantly, every evening 2026-06-11 19:46:09 +02:00
Marc-André Bombeck 390a362d7a chore(release): v1.16.6 — corrected eras, an honest weekly status and a faster first paint 2026-06-11 16:15:30 +02:00
Marc-André Bombeck a4b3d2fcd0 chore(release): v1.16.5 — a guided coach dialog and a schedule that shows its past 2026-06-11 12:08:46 +02:00
Marc-André Bombeck d56cf70d7c chore(release): v1.16.4 — half the bundle, a typed client, and stock you can record 2026-06-11 03:30:51 +02:00
Marc-André Bombeck ce3b4c70c8 chore(ops): signed images, a secret gate before commit, and a monthly restore drill
Published manifests are now cosign-signed keyless with a documented
digest-pinning path, a lefthook pre-commit runs gitleaks over staged
changes, responses opt into a credentialless embedder policy, the
deploy webhook can require a fresh timestamp, and a monthly drill
decrypts and parses the newest offhost backup so a broken key or format
surfaces before an emergency does.
2026-06-11 00:10:01 +02:00
Marc-André Bombeck e9084410e2 chore(release): v1.16.3 — schedules remember their history 2026-06-10 22:22:05 +02:00
Marc-André Bombeck 6067d9176e chore(release): v1.16.1 — a chat worth using, honest sleep stages, stock you can record 2026-06-10 21:20:22 +02:00