From f0d53fb25c6d7808dd0f8ad85e4a89253a24be66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sat, 9 May 2026 17:57:30 +0200 Subject: [PATCH] chore(release): rebrand release artifacts as v1.4.14 (patch, not minor) The v1.5.0 release was redirected to v1.4.14 because it is bugfix-heavy with only additive features, so semver-patch is the correct increment. Rename the v15-* audit notes and the v15-1 backlog accordingly, and log the docs/landing rebrand (commits 06bc616 docs, 92c6588 landing) under Phase 9 in STATE.md. Co-Authored-By: Claude Opus 4.7 (1M context) --- .planning/STATE.md | 1 + .planning/v1415-backlog.md | 100 ++++++++++++++++++ ...15-performance.md => v1414-performance.md} | 28 ++--- ...15-ux-friction.md => v1414-ux-friction.md} | 20 ++-- 4 files changed, 125 insertions(+), 24 deletions(-) create mode 100644 .planning/v1415-backlog.md rename docs/audit/{v15-performance.md => v1414-performance.md} (94%) rename docs/audit/{v15-ux-friction.md => v1414-ux-friction.md} (93%) diff --git a/.planning/STATE.md b/.planning/STATE.md index 7ce2fc099..2bbcdbcbf 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -140,6 +140,7 @@ Last update: 2026-05-09T16:10:00+02:00 - [x] healthlog-landing updated — softwareVersion 1.4.6→1.5.0 in JSON-LD, AI-providers copy mentions one-click device-code flow - [x] both committed + pushed (docs `95a3523`, landing `0c62bb2`) +- [x] rebranded to v1.4.14 in commit `06bc616` (docs), `92c6588` (landing) - Result: ok / docs `95a3523` + landing `0c62bb2` — Coolify auto-redeploys docs.healthlog.dev on push - Detailed report: `.planning/phase-9-report.md` diff --git a/.planning/v1415-backlog.md b/.planning/v1415-backlog.md new file mode 100644 index 000000000..3583b6814 --- /dev/null +++ b/.planning/v1415-backlog.md @@ -0,0 +1,100 @@ +# v1.4.15 backlog + +Seeded from phase-6 multi-agent QA findings (code-review, security, +design, simplify). Severity-grouped, file:line, one-line recommendation. + +Phase 6 reconcile commits: + +- `refactor(v1.5): apply simplify-review safe-to-apply suggestions` (88c8db1) +- `fix(security): block force-logout from targeting the admin's own session` (b3f282a) +- `fix(admin): rate-limit /api/admin/backups/run to 3/min per admin` (8e17f22) +- `fix(security): redact standalone hlk_ / hlr_ native API tokens in logs` (f0cfd26) +- `fix(a11y): drop duplicate h2 inside single-section /admin/ routes` (bd24f13) +- `fix(a11y): bump /admin/users + /admin/login-overview tap targets to WCAG 2.5.5` (499cfad) +- `fix(admin): default api-tokens + login-overview routes to expanded` (ef96e87) + +--- + +## HIGH (deferred) + +- **H4+H5 design (StatusCardGrid i18n)** — `src/components/admin/status-card-grid.tsx:25-31, 53, 113-130, 139-223` — move SEVERITY_LABEL, card titles/CTAs, fmtRelative, fmtUptime, and StatusBadge aria-label to i18n keys with EN+DE parity (`admin.statusGrid.severity.*`, `admin.statusGrid.cards.*.{title,cta}`, `admin.statusGrid.statusAriaLabel`). Update `status-card-grid.test.tsx` accordingly. +- **H2 code-review (admin role check is client-only)** — `src/app/admin/[section]/page.tsx:35-50`, `src/app/admin/page.tsx:30`, `src/app/admin/[section]/renderer.tsx:46` — add `requireAdmin()` to the server-component page so non-admin users 403 before the shell paints (eliminates the "shell flashes briefly" hydration window). Document precedent matches API-route `requireAdmin()`. +- **H-1 security ("Wipe all data" leaves encrypted secrets and personal rows)** — `src/app/api/admin/data/route.ts:51-95` and `src/lib/jobs/reminder-worker.ts:1019-1032` — decision needed: (a) widen scope to clear `MoodEntry`, `RefreshToken`, `DataBackup`, `Device`, `UserAchievement`, `IdempotencyKey`, plus the encrypted Codex/AI/moodLog columns and `aiProvider/aiModel/aiBaseUrl/locale/displayName/...`, OR (b) rename the operation + i18n copy from "Wipe all data" to "Reset health data" with an explicit "preserved" list. Recommend (a) for GDPR Art 17 alignment. + +## MEDIUM + +### Code review + +- **M1** `/insights` TrendCard tile-strip not wired with `directionSentiment` — `src/app/insights/page.tsx:830-922` — propagate up-bad / up-good / neutral from dashboard. +- **M2** Legacy admin-anchor 301s leak slug existence to unauth'd hits — `src/proxy.ts:97-107` — move legacy-redirect block AFTER the session check. +- **M3** `BackupsSection` 2-second `setTimeout` for refetch is a guess — `src/components/admin/backups-section.tsx:59-61` — bump to 5–8s with double-invalidate, or poll job state. +- **M4** `dynamic = "force-dynamic"` missing on `/api/admin/users/[id]/force-logout` — `route.ts:18` — add for consistency. +- **M5** `formatBytes` types its second arg as `ReturnType` — `src/components/admin/backups-section.tsx:24-30` — define a local `Formatters` type. +- **M6** `weight-status.ts` synthesises a misleading `n: 1` for `bpMeanDaily` — `:251-264` — widen `DailyBucket.n` to optional or carry through `min(sysN, diaN)`. +- **M7** Dashboard console-error filter regex doesn't match 404s for SW manifest icons — `e2e/dashboard.spec.ts:175-181` — convert to allowlist with KNOWN_OK list. + +### Security + +- **M-2** `/api/admin/users/[id]/force-logout` has no rate limit and no last-admin guard — `route.ts:18-56` — add `checkRateLimit(`admin-force-logout:${admin.id}`, 30, 60_000)` and refuse to revoke the only active admin session. +- **M-3** Wide-Event `meta` entries are not redacted before egress — `src/lib/logging/event-builder.ts:104-108`, `context.ts:24-28`, `transports.ts:6-12` — run `redactSecrets()` over string values in `addMeta()`. +- **M-4** `redactSecrets` over-redacts MIME-type-like / path strings starting with `sk-` — `src/lib/logging/redact.ts:38` — add a regression test asserting current (over-redact) behaviour. +- **M-5** Wipe rate-limit checked BEFORE auth — unauth'd traffic mutates `rate_limits` — `src/app/api/admin/data/route.ts:16-24` — reorder so `requireAdmin()` runs first, key by `user.id`. + +### Design / UX + +- **M1 design** `IntegrationsGroupSection` h2 hierarchy needs JSDoc note on `` — `src/components/admin/integrations-group-section.tsx`. +- **M2 design** `BackupsSection` 2-second timeout (duplicate of code-review M3). +- **M3 design** `` lacks row-shaped skeleton — `:108-114` — replace `` block with 4 skeleton rows. +- **M4 design** `/admin/users` lacks row-shaped skeleton + filter empty-state — `user-management-section.tsx:316-322` — 5 skeleton rows + `noResultsForFilter` i18n key. +- **M5 design** `/insights` deferred Recharts skeleton vs rendered chart pixel-parity — `src/app/insights/page.tsx:59-62` — add Playwright pixel-size assertion in CI. +- **M6 design** `` `` lacks `overflow-x-auto` — `:92-105` — wrap in mobile-strip pattern. +- **M7 design** `text-green-400` / `text-red-400` / `text-yellow-400` raw Tailwind in reminders-section — `:242, 244, 285, 287, 289, 303` — swap to `--success` / `--warning` / `--destructive` (light-mode contrast fail). +- **M8 design** Broader `text-dracula-green` → `text-success` semantic-token sweep — covers danger-zone `:123`, api-token-overview `:120`, system-status `:48,86,107,123,133,141`, login-overview `:140`, glitchtip `:86`, umami `:89`, web-push-vapid `:64`, bug-report `:61`, user-management `:435`, plus the settings-side cards (telegram, ntfy, web-push, account, about, advanced, integrations, api, test-connection-button), and ai-section `:342, 413, 424` (still has dracula-purple). +- **M9 design** `/insights` sticky `