Files
HealthLog/docs/audit/v1414-summary.md
T
Marc-André BombeckandClaude Opus 4.7 a1cf9bcb37 docs: scrub PII + internal jargon + German leaks from user-facing artifacts
Retroactive cleanup of CHANGELOG.md and docs/audit/v1.4.X-summary.md
files. Removes maintainer's real name, specific health figures tied to
the live tenant, internal release-process jargon, and stray German
strings in English-only release notes. Pre-release PII-grep gate added
to the v1.4.20 release pipeline. No git history rewrite.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 15:14:28 +02:00

338 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HealthLog v1.4.14 — Release Summary
## Release brief (DE, ≤ 200 Wörter)
✅ **v1.4.14 ist live** auf `https://healthlog.bombeck.io` — Image-Digest
`sha256:0ced46004a54…` (vorher v1.4.12: `791c2cd2…`), `/api/version`
meldet `1.4.14`.
🆕 **Was ist neu**
- **Codex/ChatGPT-Modell-Slug korrigiert** auf `gpt-5.3-codex` — KI-
Insights laufen jetzt direkt mit deinem ChatGPT-Login durch, kein
API-Key nötig. Operator-Override per `CODEX_MODEL`-Env-Var möglich.
- **Admin-Bereich auf Unterseiten aufgeteilt** (`/admin/users`,
`/admin/backups`, `/admin/system-status`, `/admin/integrations`, …) —
bessere Übersicht, schnelleres Laden, Status-Cards verlinken direkt.
- **Neue Backups-Sektion** mit Tabelle aller bisherigen Sicherungen und
„Backup jetzt erstellen“-Knopf.
- **Neue User-Verwaltung** mit Rollen-Filter und „Force-Logout"-Aktion
(eigene Session ist gesperrt).
- **„Gespeicherten KI-Schlüssel entfernen"** als eigener Knopf in
Settings → KI.
- **Trend-Pfeile sind jetzt metrik-bewusst** — Blutdruck ↑ orange,
Stimmung ↑ grün, Puls ↑ neutral.
🔧 **Was ist gefixt**
- Notification-Channels + Push-Subscriptions werden jetzt vom „Alle
Daten löschen“ tatsächlich entfernt.
- DST-Wechsel verschiebt keine Tageswerte mehr in Cross-Metric-Joins
(war zwei Tage/Jahr falsch).
- KI-Provider-Fehler werden korrekt klassifiziert (422/503/429 statt
pauschal 500).
- Logging-Redactor verschluckt keine harmlosen Wörter wie `task-force`
oder `risk-management` mehr.
⚡ **Performance**
- `/insights` initiales JS −108 KiB (Recharts deferred geladen).
- Dashboard-Checklist Netzwerk −950 ms für Bestandsnutzer.
⚠️ **Hard-Reload** (`Cmd+Shift+R`) für den einmaligen Service-Worker-
Reset einplanen.
📚 **Docs** auf `docs.healthlog.dev` und Landing aktualisiert.
🎯 **v1.4.15 Backlog**: `.planning/v1415-backlog.md`.
---
## Was gelandet ist
53 Commits seit `v1.4.13` (`5df74f7..e5fae9b`). Severity-geordnet.
### Release
| SHA | Summary |
| --------- | --------------------------------------------------------------- |
| `e5fae9b` | chore(release): v1.4.14 |
| `f0d53fb` | chore(release): rebrand artifacts as v1.4.14 (patch, not minor) |
### Codex-OAuth verification (Stage 1)
| SHA | Summary |
| --------- | ------------------------------------------------------------------------ |
| `5df74f7` | fix(ai): default Codex model to `gpt-5.3-codex` for ChatGPT-account auth |
### v1.4.6 deferred bugfix backlog (Stage 2)
| SHA | Summary |
| --------- | -------------------------------------------------------------------------------------------- |
| `512a6a6` | fix(admin): wipe-all-data clears notification channels, push subs, telegram deletions (T2.1) |
| `cb6a59a` | fix(insights): correct DST handling in cross-metric daily bucket pairing (T2.2) |
| `5403821` | fix(insights): map AI provider errors to 422/503 instead of 500 (T2.3) |
| `d6696cf` | fix(logging): redactSecrets regex requires non-alphanumeric prefix (T2.5) |
### Admin Panel refactor (Stage 4b — folds T2.6 + T2.7)
| SHA | Summary |
| --------- | ----------------------------------------------------------------------------------- |
| `d8b71b3` | feat(admin): scaffold per-section dynamic routes (admin-shell + [section]/page.tsx) |
| `12b280b` | refactor(admin): move sections to dynamic-route pattern + reduce overview |
| `69c5225` | feat(admin): backups view + manual backup trigger (T2.6 deferred) |
| `5957e18` | feat(admin): users management with filters + force-logout action (T2.7 deferred) |
| `a34cd8c` | refactor(i18n): namespace admin keys under `admin.section.<slug>.*` |
| `73965cd` | feat(admin): expandable sidebar nav for admin sections |
| `961e2a9` | fix(admin): status-card CTAs use real routes (not `#anchor`) |
| `7a47532` | feat(admin): redirect legacy section-anchor paths to dynamic routes |
| `1a7e3d6` | test(admin): tighten status-card-grid + add per-section render smoke |
### UX polish (Stage 5)
| SHA | Summary |
| --------- | ------------------------------------------------------------------------ |
| `987ce0d` | fix(a11y): clear axe-core violations on `/admin` and key sub-routes |
| `38f12df` | feat(ui): trend arrow color reflects metric-specific direction sentiment |
| `788c8ad` | feat(settings): allow removing saved AI provider key |
| `569300e` | style(ui): use semantic tokens for mood and feedback indicators |
| `e3a6899` | fix(ui): disambiguate dashboard quick-add menu items |
| `65cfb27` | fix(a11y): label `/admin` overview quick-jump as a navigation landmark |
### Multi-pass QA reconcile (Stage 6)
| SHA | Summary |
| --------- | ---------------------------------------------------------------------------------- |
| `88c8db1` | refactor: apply simplify-review safe-to-apply suggestions (11 of 11) |
| `b3f282a` | fix(security): block force-logout from targeting the admin's own session |
| `8e17f22` | fix(admin): rate-limit `/api/admin/backups/run` to 3/min per admin |
| `f0cfd26` | fix(security): redact standalone `hlk_` / `hlr_` native API tokens in logs |
| `bd24f13` | fix(a11y): drop duplicate h2 inside single-section `/admin/<slug>` routes |
| `499cfad` | fix(a11y): bump `/admin/users` + `/admin/login-overview` tap targets to WCAG 2.5.5 |
| `ef96e87` | fix(admin): default api-tokens + login-overview routes to expanded |
### End-to-end test coverage (Stage 3)
| SHA | Summary |
| --------- | --------------------------------------------------------------------- |
| `535465c` | test(e2e): seeded test user + auth storageState fixture |
| `3999ea7` | test(e2e): authenticated dashboard + add-measurement flow |
| `2b6f959` | test(e2e): mocked Codex device-flow + insights regenerate specs |
| `a106547` | test(e2e): doctor-report PDF + mobile-viewport smoke |
| `ca3c599` | test(e2e): extend axe-core to authenticated surfaces; fix login regex |
| `7af1f59` | fix(a11y): close violations the new e2e axe-core sweep surfaced |
### Performance (Stage 4)
| SHA | Summary |
| --------- | ----------------------------------------------------------------------- |
| `bb2b1de` | perf(insights): defer Recharts ScatterChart imports via `next/dynamic` |
| `519e36e` | perf(dashboard): skip checklist API fetches once onboarding is complete |
| `1a85da0` | fix(insights): preserve chart visual parity in deferred bundle |
| `41fa203` | docs(audit): v1.4.14 performance audit report |
### CI / housekeeping
| SHA | Summary |
| --------- | ----------------------------------------------------------------- |
| `3cacdf2` | fix(tests): share next/headers cookieJar across integration suite |
| `c847b80` | chore(format): trend-card test file prettier sweep |
| `badd380` | style(admin): apply prettier to stage-6 reconcile changes |
| `6b88e56` | chore(format): prettier sweep over stage-2 touched files |
---
## Was deferred wurde + Warum
### v1.4.14 release-cycle "Apply automatically? no" simplify findings (8)
Aus `phase-6-simplify-findings.md`:
- **F5** Defensive `notFound()` hinter `dynamicParams = false` —
Entscheidung pending zwischen (a) Kommentar trimmen vs. (b) Guard
droppen + casten.
- **F9** `<SectionFrame>` in `renderer.tsx` switch — die Repetition ist
echt, aber das Tabellen-Refactor wäre schlechter (asymmetrische
`currentUserId`-Prop). Recommend: keep as-is.
- **F10** `if (!user || user.role !== "ADMIN") return null` doppelt —
zwei Sites, unter dem 4-uses-Threshold. Recommend: keep.
- **F12** Historische Anker-Kommentare (`v1.4.6 T2.6`, `P15`,
`v1.4.7.1`, …) — judgement-call sweep; ein Teil enthält echtes
WHY-Wissen, ein Teil ist Archäologie.
- **F13** ~270 LOC duplication in den drei Status-Generatoren
(mood/weight/blood-pressure) — `_status-helpers.ts`-Extraktion ist
medium-risk, braucht fokussierten Pass + Tests.
- **F14** `formatBytes(fmt: ReturnType<typeof useFormatters>)` —
cosmetic.
- **F18** `getApiErrorMessage` doppelter Fallback-Branch — cosmetic.
- **F19** `eslint-disable-next-line react-hooks/exhaustive-deps` auf
Device-Code-Polling — verifizieren, ob `t`/`queryClient`-deps eine
Re-poll-Loop auslösen.
### v1.4.6 P4+ Items (nicht aufgenommen)
`useAdminSettings` / `useSystemStatus` Test-Coverage für die
`isError`-UI aus P19 ist weiter manuell-only — nicht in v1.4.14
gepflegt, kein Regressionsrisiko. Trägt sich in den v1.4.15-Backlog.
### 4 HIGH findings → v1.4.15
Aus `phase-6-reconcile-report.md`:
- **H4d/H5d design — StatusCardGrid i18n** (Englisch-only
Severity-Labels, Card-Titel/-CTAs, `fmtRelative`/`fmtUptime`,
StatusBadge-aria-label). ~15 Keys × 2 Locales + Test-Rewrite — zu
breit für sicheren Overnight-Apply.
- **H2 code-review — Admin-Page server-side `requireAdmin()`**. Heute
ist die Rolle nur client-seitig geprüft; das Shell flackert kurz.
Braucht eine server-rendered `requireAdmin()`-HOC, präzisiert für
den HealthLog-Auth-Stack.
- **H-1 security — "Wipe all data"-Scope-Drift**. v1.4.14 hat
Notification-Channels, Push-Subs und Telegram-Scheduled-Deletions
ergänzt. Was weiter überlebt: `MoodEntry`, `RefreshToken`,
`DataBackup`, `Device`, `UserAchievement`, `IdempotencyKey`, plus
einige verschlüsselte Spalten. Entscheidung pending: (a) Scope
nochmal weiten oder (b) Operation umbenennen ("Reset health data").
---
## CI / Test status
- `pnpm typecheck` — clean
- `pnpm lint` — 0 errors / 12 pre-existing warnings (none introduced)
- `pnpm format:check` — clean nach `c847b80` (trend-card test file
sweep)
- `pnpm test` — **97 files / 754 tests** green
- `pnpm test:integration` — 5 files / 11 tests green; mock-leak flake
zwischen `admin-data-wipe.test.ts` und `idempotency-replay.test.ts`
via `tests/integration/mock-next-headers.ts` shared cookieJar
behoben (10/10 consecutive runs grün)
- `pnpm build` — fails lokal auf Node 25 (`Reflect.get` private-member
bug); CI Docker (Node 22) ist canonical
- `pnpm e2e` — gleicher Node-25-Bug betrifft auch `next dev`; CI runs
green auf Node 22 (Phase-3 Report: 41/41 specs green)
---
## Production state
- **URL**: `https://healthlog.bombeck.io`
- **`/api/version`**: `1.4.14` ✓
- **Image digest**: `sha256:0ced46004a544a311627b7036f2f2aed75861b0c62576214a1303a17d20c3d22`
(vorher v1.4.12: `sha256:791c2cd2a8eae5ec0a6fd666074c9f646c17414e3521d526267131c2a3b7edab`)
- **Smoke** (curl mit Session-Cookie): `/`, `/auth/login`,
`/settings/integrations`, `/admin` — alle 200
- **Deploy-Methode**: `:1.4.14` von GHCR auf den Host gepullt, dort als
`:latest` retagged (kein Compose-Edit), dann `docker compose up -d
app` in `/data/coolify/applications/pg8wggwogo8c4gc4ks0kk4ss/`. Der
parallele `main`-Branch-GHCR-Run war auf demselben SHA hängengeblieben
(>45 min), wurde gecancelt — harmlos, weil der Tag-Build `:latest`
bereits gepusht hatte. Retag-on-host war defensiv aber sicher.
- **GitHub Release**: https://github.com/MBombeck/HealthLog/releases/tag/v1.4.14
- **Tag-Naming**: GHCR-OCI-Tag ist `:1.4.14` (kein `v`-Prefix);
git-Tag ist `v1.4.14`. Hard-Rule's `:v1.4.14`-Slug needs a docs fix.
---
## Codex-OAuth Status (das v1.4.7–v1.4.13 Saga-Ende)
- **Resolution**: ChatGPT-Account-Auth verlangt das Modell-Slug
`gpt-5.3-codex`. Das ist canonical, gepflegt aus
`openai/codex` → `codex-rs/models-manager/models.json`. Sowohl
`gpt-5-codex` als auch das v1.4.13-Fallback `gpt-5` werden vom
Codex-Backend mit ChatGPT-Subscription explizit abgelehnt
(`The 'gpt-5' model is not supported when using Codex with a ChatGPT
account.`).
- **Spec extension**: `docs/codex-protocol-spec.md` §7a dokumentiert
jetzt die ChatGPT-Account-Auth-Allow-List + die Lehre, dass die Slugs
in `model_migration.rs` Migration-_Prompts_ sind, keine Wire-Slugs.
- **Operator-Override**: `CODEX_MODEL`-Env-Var auf apps-01 lässt
alternative Slugs ohne Rebuild testen — als Sicherheitsnetz für
andere Plan-Tarife oder zukünftige OpenAI-Slug-Wechsel sinnvoll.
- **Live-Probe verifiziert**: `/api/ai/test` und
`/api/insights/generate` laufen beide gegen das ChatGPT-Plus-Abo
des Live-Tenants durch. `/tmp/v15-codex-working.png` zeigt das
grüne "ChatGPT connected"-Badge in `/settings/ai`.
---
## Docs / Landing
- **healthlog-docs** (Starlight) — 7 Files aktualisiert: AI-Insights
(Codex device-code-Pfad neu), Admin-Settings (Backups + Users
Sektionen), Environment-Variables (`CODEX_MODEL`), Updates (Backups-
View), Introduction (One-Click Codex-Flow), Troubleshooting
(Codex-Failure-Modes), Dashboard-Customization (Perf-Note).
Commit `06bc616`. Coolify auto-redeploys docs.healthlog.dev.
- **healthlog-landing** (Next.js) — `softwareVersion 1.4.6 → 1.4.14`
in JSON-LD; AI-Providers-Copy auf "one-click device-code Codex
flow, no API plan needed" angepasst. Commit `92c6588`.
---
## GitHub releases
`v1.4.7` … `v1.4.13` waren bereits real-time während des
Codex-OAuth-Iterationstags veröffentlicht; nur `v1.4.13` war pending
und wurde nachgezogen. `v1.4.14` selbst ist jetzt als Latest geflagged.
---
## Empfohlener v1.4.15 Backlog
Aus `.planning/v1415-backlog.md` (severity-geordnet, Datei:Zeile, ein
Satz Recommendation pro Item). Top-Hits:
### HIGH
- **H4d+H5d** — `StatusCardGrid` i18n: Severity-Labels, Card-Titel,
CTAs, `fmtRelative`, `fmtUptime`, StatusBadge-aria-label nach
`admin.statusGrid.*` migrieren (EN+DE Parität, ~15 Keys × 2 Locales).
- **H2** — `requireAdmin()` server-side auf `/admin/[section]/page.tsx`
und `/admin/page.tsx` ziehen, damit Non-Admins 403 sehen, bevor das
Shell paint-flickert.
- **H-1** — "Wipe all data" Entscheidung: (a) Scope auf `MoodEntry`,
`RefreshToken`, `DataBackup`, `Device`, `UserAchievement`,
`IdempotencyKey` + verschlüsselte Codex/AI/moodLog-Spalten weiten,
oder (b) Operation umbenennen ("Reset health data") und "preserved"-
Liste explizit zeigen. Recommend (a) für GDPR-Art-17-Alignment.
### MEDIUM (Highlights)
- **M-2 security** `/api/admin/users/[id]/force-logout` ohne Rate-Limit
und ohne Last-Admin-Guard.
- **M-3 security** Wide-Event-`meta`-Strings nicht durch
`redactSecrets()` gezogen — `addMeta()` braucht den Filter.
- **M-5 security** Wipe-Rate-Limit BEFORE auth — unauth'd Traffic
mutiert `rate_limits`. Reorder: `requireAdmin()` zuerst, dann key by
`user.id`.
- **M1 code-review** `/insights` TrendCard-Tile-Strip noch ohne
`directionSentiment` verdrahtet (war v1.4.14 nur Dashboard).
- **M2 code-review** Legacy-Admin-Anchor-301s leaken Slug-Existenz an
unauth'd Hits — Redirect-Block muss NACH dem Session-Check.
- **M3 code-review** `BackupsSection` 2-Sek-Timeout für Refetch ist ein
Guess — auf 5–8s mit Double-Invalidate, oder Job-State pollen.
### LOW
- **L-1 security** `/api/auth/codex/callback` als PUBLIC_PATH gelistet,
aber kein Route-File existiert — Eintrag aus `proxy.ts` löschen.
- **L-2 security** Codex `codex_device`-Cookie ohne Per-User-Binding
— `userId` in den encrypted Blob einbetten, Mismatch rejecten.
- **L7 design** `/insights` Sticky-`<nav>` ohne `aria-label`.
- **L8 design** Mobile-Strip-Pattern für `<FeedbackInboxSection>`-Tabs
und `<AdminShell>`-Mobile-Section-Strip (snap-x snap-mandatory).
### Recharts-Replacement (eingefroren auf v1.4.15+)
108 KiB pro Chart-Page sparbar, aber Effort L (alle Charts in
`src/components/charts/` müssen neu, plus neue Dependency). v1.4.14
no-new-deps Hard-Rule blockiert; v1.4.15+ wenn die Range frei wird.
---
## Hard-Reload-Reminder
`Cmd+Shift+R` (Mac) / `Ctrl+Shift+R` (Linux/Win) — der neue
Service-Worker holt sonst noch v1.4.13-Chunks aus dem Cache. Einmalig
ausreichend.