From 2982ed1f0b1298fda104ec2dabc9b033e3c103aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 17 May 2026 00:54:43 +0200 Subject: [PATCH] docs(planning): audit-marathon closure (v1.4.34.4 + v1.4.34.5) End-to-end summary of the eight-axis audit + the two consecutive hotfix releases that landed the hotfix-ready findings: security, UX/a11y, code quality, mobile-deep, docs depth, README + GitHub discoverability, perf, and test coverage. Lists what shipped, what got deferred to v1.5.x, the operator-action delta (one obsoleted), and the quantitative deltas (24 commits, 2 releases, 55 net new tests, 5 new user-facing docs). --- .planning/round-audit-marathon-closure.md | 144 ++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 .planning/round-audit-marathon-closure.md diff --git a/.planning/round-audit-marathon-closure.md b/.planning/round-audit-marathon-closure.md new file mode 100644 index 000000000..a0e75bbc9 --- /dev/null +++ b/.planning/round-audit-marathon-closure.md @@ -0,0 +1,144 @@ +# v1.4.34.4 + v1.4.34.5 — Audit-Marathon Closure + +Shipped: 2026-05-17 (consecutive releases on the same date as v1.4.34.3). + +| Tag | Highlights | Release | +| --- | --- | --- | +| v1.4.34.4 | Audit-driven hotfix bundle across security, UX, code quality, mobile-deep, docs, GitHub metadata | [v1.4.34.4](https://github.com/MBombeck/HealthLog/releases/tag/v1.4.34.4) | +| v1.4.34.5 | Audit follow-on: 24 critical-path integration tests + iOS textarea zoom fix | [v1.4.34.5](https://github.com/MBombeck/HealthLog/releases/tag/v1.4.34.5) | + +## Audit waves + +Eight axes, eight reports archived under `.planning/round-audit-*.md`: + +| Axis | Report | Findings (hotfix-ready / total) | +| --- | --- | --- | +| Mobile security | `round-audit-mobile-security.md` | 3 / 8 | +| UX + accessibility | `round-audit-ux.md` | 8 / 11 | +| Code quality + docs | `round-audit-code-quality.md` | 5 / 15 | +| README + GitHub discoverability | `round-audit-docs-discoverability.md` | 7 / 15 | +| Web performance (Lighthouse-grade) | `round-audit-perf.md` | 3 / 7 | +| Mobile-deep (viewport-by-viewport) | `round-audit-mobile-deep.md` | 5 / 16 | +| Test coverage gaps | `round-audit-test-coverage.md` | 5 / 8 (mostly critical-path) | +| Docs depth (beyond README) | `round-audit-docs-depth.md` | 5 / 14 | + +## What landed (v1.4.34.4 + v1.4.34.5) + +### Security (6 findings) + +- `destroyAllSessions` now wraps `prisma.session.deleteMany` plus `apiToken.updateMany({ revoked: true })` plus `refreshToken.updateMany({ revokedAt: now })` in one `$transaction`. A stolen iOS Bearer no longer survives a user-initiated password change or an admin reset. Same rotation fires from `POST /api/auth/password`, `POST /api/admin/users/[id]/reset-password`, and `DELETE /api/settings/account`. +- `/.well-known/` proxy bypass tightened from `startsWith` to an exact-match `Set` seeded with `apple-app-site-association`. Stale `/api/auth/codex/callback` PUBLIC_PATHS entry dropped (route was renamed to the device-code family). +- HSTS gains `; preload` (eligible for the Chromium preload list). +- Withings host removed from the global CSP and gated to the integration's own routes. +- `getClientIp` warns once per process on `TRUST_PROXY_HOPS`/XFF mismatch and exposes a tagged `getClientIpOrTrustWarning(request)` helper so future callers can route to a tighter universal rate-limit bucket. +- Service-worker rejects off-origin `notificationclick` URLs and falls back to `/`. Manifest gains `scope` / `id` / `display_override`. Offline fallback body switched to a locale-neutral icon. + +### UX + accessibility (8 findings) + +- Dialog / Sheet close-X, ChartSkeleton loading announcement, and notifications-section breadcrumb all read i18n keys instead of hardcoded English. All six locales updated. +- Focus rings on bottom-nav primary links, the More overflow trigger, and the mobile top-bar user menu. +- Input / NativeSelect / Select / DateTimeInput tap-target floor: `h-11 sm:h-10` so mobile clears the 44 px WCAG floor. +- Admin chip-strip auto-scroll-into-view (matches v1.4.33 settings-shell pattern). +- List-page subtitles (measurements / mood / medications) now visible on mobile. +- Insights empty-state CTA vocabulary normalised — links open the right measurement form instead of silently failing on BODY_TEMPERATURE / BLOOD_GLUCOSE / PULSE. + +### Mobile-deep responsive (4 findings) + +- `viewport.themeColor` reacts to light/dark via the media-query pair (Android URL bar + iOS PWA status bar match the active palette). +- TopBar reserves `env(safe-area-inset-top)` — iOS PWA on notched iPhones no longer clips the logo. +- Coach FAB respects `env(safe-area-inset-bottom)` so it floats above the home-indicator inset. +- Sonner toaster switches to `theme="system"`. +- Five textareas now ship `text-base sm:text-sm` so iOS Safari no longer zooms-on-focus (Coach composer, bug-report description, admin feedback note, medication-side-effects notes, medication-intake JSON import). + +### Code quality (5 findings) + +- Dead `SESSION_SECRET` env contract dropped from `.env.example`, `docker-entrypoint.sh`, `docker-compose.yml`, `CONTRIBUTING.md`, `docs/self-hosting/scaling.md`, and the README Quick Start (three secrets, not four). +- `toJson()` helper consolidates seven Prisma JSON-cast sites. +- `db-compat.ts` gains a header docstring naming it the schema-bootstrap path. +- Passkey response types adopted from `@simplewebauthn/server` (was `any` + eslint-disable). +- Zero-TODO CI gate at `.github/workflows/no-todo-markers.yml`. + +### Docs + discoverability + +- README rework: How-it-compares matrix vs Withings web / Apple Health / Oura / Garmin / generic CSV; Apple Health + AI Coach promoted to standalone Key-Features bullets; status block; latest-release + GHCR badges; OpenAPI pointer above the API table. +- openGraph + twitter cards now carry `images` and `summary_large_image`. +- GitHub repo metadata: description 290 → 156 chars, keyword-front; `homepageUrl` flipped to `demo.healthlog.dev`; six generic / PII-adjacent topics (`glp-1`, `mounjaro`, `tracking`, `health`, `dashboard`, `bloodpressure`) swapped for six high-intent ones (`apple-health-import`, `withings-alternative`, `glucose-tracker`, `mood-tracker`, `ai-insights`, `personal-dashboard`). +- Five new user-facing docs: + - `docs/self-hosting/getting-started.md` + - `docs/self-hosting/reverse-proxy.md` + - `docs/integrations/apple-health.md` + - `docs/integrations/withings.md` + - `docs/integrations/ai-providers.md` +- `docs/README.md` clarifies the in-repo docs tree role vs `docs.healthlog.dev`. + +### Tests (24 new integration cases) + +| Surface | File | Cases | +| --- | --- | --- | +| User-initiated password change | `tests/integration/auth-password-change.test.ts` | 5 | +| Admin reset-password | `tests/integration/admin-reset-password.test.ts` | 5 | +| Withings OAuth handshake | `tests/integration/withings-oauth.test.ts` | 5 | +| Passkey register | `tests/integration/passkey-register.test.ts` | 4 | +| IW-G cache-invalidation matrix | `tests/integration/cache-invalidation-coverage.test.ts` | 5 | + +Integration suite: 197/50 → 222/55. Unit suite: 4235 → 4266. tsc + lint clean throughout. + +## Findings deferred (not landing in v1.4.34.x) + +- **F-1 mobile-security**: Apple Health unzip OOM / zip-bomb (4-h streaming refactor). Real DoS, but the refactor is non-trivial — v1.5.x. +- **F-4 mobile-security**: Withings shared webhook secret. Rotation runbook + helper script, operator-side — v1.5.x. +- **F-8 mobile-security**: Audit-log coverage gap on Bearer mutation paths. Sweep + regression test — medium effort, v1.5.x. +- **F-4 / F-6 UX**: 5 non-English plural strings (medium effort) and chart accessibility (figure / figcaption synthesis) — v1.5.x. +- **F-3 mobile-deep**: 5 raw DialogContent never migrated to ResponsiveSheet (doctor report, intake import ×2, password change, app-log preview). Substantial UX touch — defer. +- **Code quality F-1**: 2 366 version-tagged inline comments + 244 wave/phase markers. Sweepable in one focused half-day; not blocking. +- **Code quality F-2**: 7-file domain-prompt factory refactor. +- **Code quality F-4**: 171 lib exports lack JSDoc. +- **Perf F-1 / F-3**: Insights/Dashboard fan-out queries → server-side `Promise.all` inside Suspense; `/api/insights/targets` SQL-aggregator gap. Higher-cost work; benchmark in a v1.5 perf pass. +- **Docs-depth F-7**: OpenAPI 14-documented vs 181-actual route divergence. Intentional iOS-codegen-locked subset; needs docstring clarification, not a full spec rewrite. + +## Coolify auto-deploy + +**Working in production.** v1.4.34.3 was the first release deployed by Coolify without a manual MCP trigger or a host-side retag fallback — proving the v1.4.34.2 `pull_policy: always` fix lands as designed. Every subsequent release (v1.4.34.4, v1.4.34.5) auto-pulls on tag push. + +The v1.4.34 closure's Operator-Action #4 ("watch registry for new digests" toggle) is obsoleted by this fix. + +## Operator actions still pending + +These remain environment-side, unchanged by v1.4.34.4/.5: + +1. edge01 Coolify-MCP daemon restart. +2. edge01 `DATABASE_URL` pool-bump (apps01 already drained). +3. Coolify resource-limits resize on apps01 (CPU=2, Memory=1g, Reservation=512m). +4. ~~Coolify "watch registry for new digests" toggle~~ — obsoleted by v1.4.34.2 `pull_policy: always`. +5. apps01 28 duplicate env-pairs prune. + +## Tests of note + +- 4266 unit tests pass (was 4235 — +31 new). +- 222 integration tests pass across 55 files (was 197 across 50 — +24 new + 5 new files). +- `tsc --noEmit` clean. +- `eslint` clean. +- Zero TODO/FIXME/XXX/HACK markers in product code, now CI-enforced. +- 4 pre-existing e2e failures on main (`onboarding-flicker-dashboard` + `mobile-viewport touch-targets≥44×44`) carry from v1.4.34 — not introduced by this work. +- 4 pre-existing integration-test parallel-DB-isolation flakes (`apns-dispatch`, `integration-status`) — not introduced by this work. + +## What changed quantitatively + +- **24 commits** since the v1.4.34.3 release (Coach-CTA removal): + - 2 security commits (token wipe + well-known proxy; HSTS + CSP + SW + manifest) + - 1 UX commit (8 hotfix-ready findings) + - 1 code-quality commit (5 hotfix-ready findings) + - 1 mobile + docs commit (themeColor + FAB + Sonner + 2 self-hosting docs) + - 1 integration-docs commit (Apple Health + Withings + AI providers) + - 1 TopBar safe-area commit + - 1 textarea iOS-zoom commit + - 1 critical-path tests commit + - 8 audit-report + planning commits + - 2 release commits (v1.4.34.4, v1.4.34.5) + - 1 toJson test-mock fix commit +- **2 GitHub releases** shipped with full notes +- **5 new user-facing docs** under `docs/` +- **8 audit reports** archived under `.planning/round-audit-*.md` +- **31 new unit tests + 24 new integration tests** = 55 net test gain + +End of audit marathon. The next layer of findings (perf fan-out queries, prompt-factory refactor, version-tag sweep, JSDoc gap, plural-i18n) is captured per-file in the audit reports for a future v1.5.x pass.