Commit Graph
7 Commits
Author SHA1 Message Date
Marc-André Bombeck 32a023dfff chore(ui): apply M7 + L1 + L3 + L4 polish across medication form, motion-reduce, details aria, therapy timeline
W10 design-review carry-over items. M7 lifts the medication-form
day-of-week buttons, the more-horizontal trigger, and the schedule
label-input gaps to the 44 px / space-y-2 standard used by every
other settings surface. L1 pairs every animate-spin/pulse/bounce
with motion-reduce:animate-none across the component tree so users
with prefers-reduced-motion get a still surface. L3 adds the
aria-controls + panel-id pairing to the inventory + coach-evidence
<details> blocks for parity with the Health Score provenance
accordion. L4 inserts a sr-only h4 per therapy-timeline entry so
screen-reader users can jump between medication blocks.
2026-05-15 17:13:42 +02:00
Marc-André Bombeck 15a72bb329 feat(notifications): personal-records push opt-in toggle (default OFF)
Adds the PERSONAL_RECORD event type to the dispatcher vocabulary
and flips its default policy to opt-in. Without an explicit
preference row the dispatcher now suppresses PR pushes — so a
multi-year Apple Health backfill writes the records but does not
saturate the lock-screen on first sync. Other events keep the
opt-out default they always had.

The /notifications matrix renders the new event automatically
because it iterates EVENT_TYPES; the per-event default helper
keeps the toggle in the right initial state across all six
locales (EN, DE, FR, ES, IT, PL).
2026-05-14 18:51:05 +02:00
Marc-André Bombeck ca03c6099f chore(release): v1.4.24
Security + accessibility hardening release. Closes the highest-priority
findings from a focused security audit of the v1.4.23 release:

- Bearer auth fail-closed when a route declares no scope (api-handler)
- Public /api/send Umami proxy now rate-limits 120 req/min/IP
- Proxy nonce generation switched to btoa(...) for Edge portability
- Session-expiry delete race uses deleteMany + catch (no more 500s)
- POST /api/import returns the standard apiError envelope on 422
- Runtime Docker image pins Prisma 7.8 + worker deps to minors
- Notifications page renders a real load-error alert
- Accessibility: switch aria-labels, htmlFor pairing, mobile admin
  Overview link, deep-link anchors on notification settings
- Chart overlays: per-chart comparisonBaseline pref, BMI/bodyFat/
  sleep/steps overlay keys, TrendCard layout tolerates long labels

Verification: pnpm typecheck && pnpm lint && pnpm test (2244/2244)
&& pnpm format:check all green.
2026-05-12 22:33:35 +02:00
Marc-André BombeckandClaude Opus 4.7 1499e6f83c i18n+ui: backlog quick-wins sweep (F-32/33/34/35/44/45/47/50/58/62 + 2 mediums)
Cluster of the v1.4.21 carry-over items that each landed in ≤5 LOC.

- F-32 — drop the duplicate help paragraph beneath the dashboard
  settings header; the page-level description already covers it
- F-33 / F-34 — replace `&` with "and"/"und" in the measurements and
  mood subtitles
- F-35 — unify the test-notification button label
  (notificationTestSend) with the user-facing notificationStatus.sendTest
- F-44 — drop the `LOKI_ENDPOINT` env-var name from the user-facing
  monitoring help text; reads as "Loki integration" instead
- F-45 — admin/users table column reads "Name" instead of repeating
  the page title "Users"
- F-47 — /notifications event-matrix first column reads "Event" instead
  of repeating the page title "Notifications" — new notifications.eventColumn key
- F-50 — soften every DE error-toast "Bitte erneut versuchen" to
  "Bitte versuche es erneut", matching the friendlier tone we already
  use in the Coach error path
- F-58 — admin/reminders section header swaps Clock for Bell so the
  card icon matches the admin-shell nav tile
- F-62 — DE dashboard `greetingSalutation` reads "Hallo, {name}"
  instead of the English "Hi, {name}"
- D-CR-M-03 — formatTokenName regex broadens to non-Z ISO offsets so a
  `+02:00` timestamp suffix renders as the locale-aware chunk like a
  `Z` suffix already does
- D-DSGN-M-04 — moodLog "Copy" button uses common.copy instead of
  stripping the `!` off common.copied

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 21:40:05 +02:00
Marc-André Bombeck 680b0019c1 fix(ui): defensive optional chains across summaries/medications/preferences/entries/measurements
Same anti-pattern as the v1.4.2 hotfix on /dashboard and /insights —
the optional chain protected only the outer object, so any field on
the inner object that didn't exist threw at access time. Marc's
reports flagged dashboard, insights, medications,
notification-preferences, admin login overview, mood list, and
measurement list. Applied 'data?.X?.Y' to every spot the regex
caught.
2026-05-08 18:36:13 +02:00
Marc-André BombeckandClaude Opus 4.7 3221f86eea feat(settings): introduce dynamic-route shell + redirect /settings → /settings/account (#139)
* feat(settings): introduce dynamic-route shell + redirect /settings → /settings/account

Splits the 3218-LOC /settings monolith into a routing surface only — no
section content moves in this PR. Each of the eight slugs (account,
integrations, notifications, dashboard, ai, api, advanced, about) now lives
at its own /settings/[section] route and renders inside a new
<SettingsShell> sidebar+main layout. Every section currently shows a
placeholder ("Moving here with the next release update") so reviewers can
validate the URL structure in isolation. The historic monolith is preserved
verbatim as page.legacy.tsx for section-by-section extraction by the
follow-up PRs (A2-account, A2-about, A2-ai, A2-integrations,
A2-notifications, A2-rest).

Behaviour change: existing entry points (sidebar nav, topbar dropdown,
onboarding hand-off, dashboard checklist, Withings callback, Codex
callback) now point at /settings/<slug> instead of /settings#anchor. The
/settings root is a 308 (permanentRedirect) to /settings/account so old
bookmarks and external links keep working.

Co-Authored-By: Marc-André Bombeck <mbombeck@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(settings): route every Codex OAuth callback redirect to /settings/integrations

Review-pass H1: only the late success/failure paths in the Codex OAuth
callback were updated to point at the new section route. The four early
branches — rate-limited, provider-supplied `?error=...`, missing params,
invalid state — still redirected to `/settings?codex_error=...`.

After the section split that path 308-redirects to `/settings/account`,
where the Codex error toast/banner doesn't live. Users hitting any of
those edge cases would land on the wrong screen with the error code
silently lost.

All six branches now go to `/settings/integrations?codex_error=...`,
matching the success and token-exchange-failure paths and the existing
Withings callback shape.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:15:15 +02:00
Marc-André Bombeck 38309932f3 Initial release v1.0.0
HealthLog — personal health-tracking PWA with weight, blood pressure,
pulse, mood tracking, medication compliance, Withings integration,
doctor report PDF export, and Dracula-themed UI.
2026-03-10 20:14:33 +01:00