mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 12:32:43 +00:00
docs(planning): record phase-7 pre-release verification
- typecheck/lint/test/format clean (modulo the chart test file blocked by Marc constraint — pre-existing) - integration suite green after the test-isolation fix in the preceding commit (10/10 consecutive runs) - build + e2e blocked by the documented Node-25 Reflect.get bug on this workstation; CI Docker (Node 22) is canonical and Phase-3 already records 41/41 e2e specs green there - format sweep on .planning/*.md + e2e/measurement-flow.spec.ts to clear the warnings Phase 6 reconcile listed as pre-existing-out-of-scope Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
3cacdf294e
commit
a94a3eac45
6 files changed
+149
-65
No files matched your search
+15
-17
@@ -1,7 +1,7 @@
|
||||
# v1.5 marathon — state log
|
||||
|
||||
Status: phase-2-done
|
||||
Last update: 2026-05-09T16:10:00+02:00
|
||||
Status: phase-7-done
|
||||
Last update: 2026-05-09T18:15:00+02:00
|
||||
|
||||
> Previous milestone: see `docs/audit/v146-summary.md` (v1.4.6 marathon).
|
||||
> Codex-OAuth iteration v1.4.7 → v1.4.13 landed in CHANGELOG between
|
||||
@@ -87,17 +87,14 @@ Last update: 2026-05-09T16:10:00+02:00
|
||||
`docs/audit/v15-ux-friction.md`
|
||||
- [x] CRITICAL/HIGH triage — 6 inline fixes; LOW items deferred to
|
||||
v1.5.1 with backlog in the audit doc
|
||||
- [x] v1.4.6 deferred polish picked up:
|
||||
- trend-arrow direction-as-good metric-aware (`directionSentiment`
|
||||
prop, `up-good`/`up-bad`/`neutral`)
|
||||
- "Remove saved AI key" button with AlertDialog confirmation
|
||||
- semantic `--success`/`--warning`/`--info` tokens, migrated
|
||||
feedback BUG / published badges, medication status, AI section
|
||||
connection badges (charts untouched)
|
||||
- [x] v1.4.6 deferred polish picked up: - trend-arrow direction-as-good metric-aware (`directionSentiment`
|
||||
prop, `up-good`/`up-bad`/`neutral`) - "Remove saved AI key" button with AlertDialog confirmation - semantic `--success`/`--warning`/`--info` tokens, migrated
|
||||
feedback BUG / published badges, medication status, AI section
|
||||
connection badges (charts untouched)
|
||||
- [x] +2 inline friction items: dashboard quick-add menu disambiguation
|
||||
(`Add` collision from phase-3) and `/admin` overview nav landmark
|
||||
- Result: ok / commits `987ce0d 38f12df 788c8ad 569300e e3a6899
|
||||
5ffe750 65cfb27` — `pnpm typecheck && pnpm lint && pnpm test` green
|
||||
5ffe750 65cfb27` — `pnpm typecheck && pnpm lint && pnpm test` green
|
||||
(97 files / 752 tests)
|
||||
- Detailed report: `.planning/phase-5-report.md`
|
||||
|
||||
@@ -111,13 +108,14 @@ Last update: 2026-05-09T16:10:00+02:00
|
||||
|
||||
## Phase 7 — Pre-release verification
|
||||
|
||||
- [ ] pnpm typecheck
|
||||
- [ ] pnpm lint
|
||||
- [ ] pnpm format:check
|
||||
- [ ] pnpm test
|
||||
- [ ] pnpm test:integration
|
||||
- [ ] pnpm build (Node-25 bug documented if hit)
|
||||
- [ ] pnpm e2e
|
||||
- [x] pnpm typecheck — clean
|
||||
- [x] pnpm lint — 0 errors / 12 pre-existing warnings
|
||||
- [x] pnpm format:check — clean except `src/components/charts/__tests__/trend-card.test.tsx` (Marc constraint forbids editing charts)
|
||||
- [x] pnpm test — 97 files / 754 tests green
|
||||
- [x] pnpm test:integration — 5 files / 11 tests green; flake (mock-leak between `admin-data-wipe.test.ts` + `idempotency-replay.test.ts` under `isolate: false`) fixed via shared `tests/integration/mock-next-headers.ts`; 10/10 consecutive runs green
|
||||
- [-] pnpm build — Node-25 `Reflect.get` private-member bug; CI Docker (Node 22) canonical
|
||||
- [-] pnpm e2e — same Node-25 bug also affects `next dev`, so the local web-server start fails; CI runs green on Node 22 per Phase-3 report
|
||||
- Result: ok / commits TBD (integration flake fix + format sweep)
|
||||
- Detailed report: `.planning/phase-7-report.md`
|
||||
|
||||
## Phase 8 — Release v1.5.0
|
||||
|
||||
@@ -23,4 +23,4 @@ Built with Node 22 (Node 25 has the `Cannot read private member #state` regressi
|
||||
|
||||
## CI
|
||||
|
||||
`.github/workflows/e2e.yml` already supplies the env block we need (DATABASE_URL, ENCRYPTION_KEYS, AUTH_RP_*) and runs `next build` before `playwright test`. No workflow changes were necessary.
|
||||
`.github/workflows/e2e.yml` already supplies the env block we need (DATABASE*URL, ENCRYPTION_KEYS, AUTH_RP*\*) and runs `next build` before `playwright test`. No workflow changes were necessary.
|
||||
@@ -27,13 +27,13 @@ eagerly). `/admin` and `/settings/integrations` are lean (~290 KiB JS,
|
||||
## Wins implemented inline
|
||||
|
||||
1. **`bb2b1de` — `perf(insights): defer Recharts ScatterChart imports
|
||||
via next/dynamic`** — moves the seven recharts symbols (ScatterChart,
|
||||
via next/dynamic`** — moves the seven recharts symbols (ScatterChart,
|
||||
Scatter, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer)
|
||||
off the eager imports of `src/app/insights/page.tsx` and onto
|
||||
per-symbol `next/dynamic({ ssr: false })`. Same shape as the existing
|
||||
HealthChart/MoodChart pattern in the same file.
|
||||
2. **`519e36e` — `perf(dashboard): skip checklist API fetches once
|
||||
onboarding is complete`** — gates the `withings/status` and
|
||||
onboarding is complete`** — gates the `withings/status` and
|
||||
`notifications/preferences` queries inside
|
||||
`getting-started-checklist.tsx` on
|
||||
`user.onboardingCompletedAt == null`. Saves ~950 ms of network on
|
||||
|
||||
+42
-42
@@ -11,15 +11,15 @@ Status: done. 6 atomic commits + 1 audit doc. `pnpm typecheck`,
|
||||
`/admin/system-status`, and `/admin/users` as the two representative
|
||||
sub-routes called for in the Phase 5 spec. Done in commit
|
||||
`987ce0d fix(a11y): clear axe-core violations on /admin and key
|
||||
sub-routes`. The single commit also fixes the violations identified
|
||||
sub-routes`. The single commit also fixes the violations identified
|
||||
while reading the relevant components:
|
||||
- duplicate `<PasswordInput>` in `_shared.tsx` whose toggle had no
|
||||
accessible name → re-export the canonical one from
|
||||
`src/components/settings/password-input.tsx` (already aria-labelled
|
||||
in phase 3),
|
||||
- icon-only buttons in `user-management-section.tsx` got explicit
|
||||
`aria-label` and `aria-hidden` icons,
|
||||
- empty `<dd>` placeholder in the audit-log status card removed.
|
||||
- duplicate `<PasswordInput>` in `_shared.tsx` whose toggle had no
|
||||
accessible name → re-export the canonical one from
|
||||
`src/components/settings/password-input.tsx` (already aria-labelled
|
||||
in phase 3),
|
||||
- icon-only buttons in `user-management-section.tsx` got explicit
|
||||
`aria-label` and `aria-hidden` icons,
|
||||
- empty `<dd>` placeholder in the audit-log status card removed.
|
||||
|
||||
2. **Walk-through audit** — written up at
|
||||
`docs/audit/v15-ux-friction.md`. Top-10 with severity, file
|
||||
@@ -28,33 +28,33 @@ Status: done. 6 atomic commits + 1 audit doc. `pnpm typecheck`,
|
||||
will exercise the e2e suite).
|
||||
|
||||
3. **Triage** — applied. Three v1.4.6 deferred items closed inline:
|
||||
- `feat(ui): trend arrow color reflects metric-specific direction
|
||||
sentiment` (`38f12df`) — `directionSentiment` prop with `up-good`
|
||||
/ `up-bad` / `neutral` buckets; all 11 dashboard tile call sites
|
||||
wired; new `trend-card.test.tsx` covers all 3 sentiments × 3
|
||||
slope directions plus the back-compat default.
|
||||
- `feat(settings): allow removing saved AI provider key`
|
||||
(`788c8ad`) — `<AlertDialog>` confirmation + PATCH null. EN + DE
|
||||
i18n keys.
|
||||
- `style(ui): use semantic tokens for mood and feedback indicators`
|
||||
(`569300e`) — adds `--success` / `--warning` / `--info` to
|
||||
`globals.css`; dark-mode aliases over the Dracula palette so
|
||||
visuals stay pixel-identical, light-mode (Alucard) gets the
|
||||
higher-contrast counterparts. Migrated callers: feedback BUG
|
||||
badge (→ `destructive`), feedback published-to-GitHub badge,
|
||||
medication card status, AI section connection badges and
|
||||
success-toast colour.
|
||||
- `feat(ui): trend arrow color reflects metric-specific direction
|
||||
sentiment` (`38f12df`) — `directionSentiment` prop with `up-good`
|
||||
/ `up-bad` / `neutral` buckets; all 11 dashboard tile call sites
|
||||
wired; new `trend-card.test.tsx` covers all 3 sentiments × 3
|
||||
slope directions plus the back-compat default.
|
||||
- `feat(settings): allow removing saved AI provider key`
|
||||
(`788c8ad`) — `<AlertDialog>` confirmation + PATCH null. EN + DE
|
||||
i18n keys.
|
||||
- `style(ui): use semantic tokens for mood and feedback indicators`
|
||||
(`569300e`) — adds `--success` / `--warning` / `--info` to
|
||||
`globals.css`; dark-mode aliases over the Dracula palette so
|
||||
visuals stay pixel-identical, light-mode (Alucard) gets the
|
||||
higher-contrast counterparts. Migrated callers: feedback BUG
|
||||
badge (→ `destructive`), feedback published-to-GitHub badge,
|
||||
medication card status, AI section connection badges and
|
||||
success-toast colour.
|
||||
|
||||
4. **Two extra friction fixes inline** (both <50 LOC):
|
||||
- `fix(ui): disambiguate dashboard quick-add menu items`
|
||||
(`e3a6899`) — closes the Phase-3 i18n collision where both
|
||||
dropdown items rendered the literal "Add". New
|
||||
`dashboard.quickAddMeasurement` / `dashboard.quickAddMood` keys;
|
||||
e2e spec rewritten to target by name instead of `.first()`.
|
||||
- `fix(a11y): label /admin overview quick-jump as a navigation
|
||||
landmark` (`65cfb27`) — wraps the section list in `<nav
|
||||
aria-labelledby>` so the landmark is distinguishable from the
|
||||
sidebar.
|
||||
- `fix(ui): disambiguate dashboard quick-add menu items`
|
||||
(`e3a6899`) — closes the Phase-3 i18n collision where both
|
||||
dropdown items rendered the literal "Add". New
|
||||
`dashboard.quickAddMeasurement` / `dashboard.quickAddMood` keys;
|
||||
e2e spec rewritten to target by name instead of `.first()`.
|
||||
- `fix(a11y): label /admin overview quick-jump as a navigation
|
||||
landmark` (`65cfb27`) — wraps the section list in `<nav
|
||||
aria-labelledby>` so the landmark is distinguishable from the
|
||||
sidebar.
|
||||
|
||||
## Hard constraints honoured
|
||||
|
||||
@@ -71,15 +71,15 @@ Status: done. 6 atomic commits + 1 audit doc. `pnpm typecheck`,
|
||||
|
||||
## Atomic commit list
|
||||
|
||||
| SHA | Message |
|
||||
| --------- | -------------------------------------------------------------------------------- |
|
||||
| `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 |
|
||||
| `5ffe750` | docs(audit): file v1.5 phase-5 UX friction audit |
|
||||
| `65cfb27` | fix(a11y): label /admin overview quick-jump as a navigation landmark |
|
||||
| SHA | Message |
|
||||
| --------- | ------------------------------------------------------------------------ |
|
||||
| `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 |
|
||||
| `5ffe750` | docs(audit): file v1.5 phase-5 UX friction audit |
|
||||
| `65cfb27` | fix(a11y): label /admin overview quick-jump as a navigation landmark |
|
||||
|
||||
## v1.5.1 backlog (from this phase)
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
# Phase 7 — Pre-release verification
|
||||
|
||||
**Verification agent**: Opus 4.7 (1M context)
|
||||
**Date**: 2026-05-09 overnight (autonomous mode)
|
||||
**Node**: v25.9.0 (local) — Node 22 used in CI Docker image (canonical)
|
||||
|
||||
## Step-by-step results
|
||||
|
||||
| Step | Result | Notes |
|
||||
| ----------------------- | ------ | ---------------------------------------------------------------------------------- |
|
||||
| `pnpm typecheck` | PASS | 0 errors |
|
||||
| `pnpm lint` | PASS | 0 errors / 12 pre-existing warnings (unused `_request`/`_params`, none introduced) |
|
||||
| `pnpm format:check` | PASS\* | Only `src/components/charts/__tests__/trend-card.test.tsx` flagged — see below |
|
||||
| `pnpm test` | PASS | 97 files / 754 tests green |
|
||||
| `pnpm test:integration` | PASS | 5 files / 11 tests — flake fixed, 10 consecutive runs all green |
|
||||
| `pnpm build` | FAIL\* | Node-25 `Reflect.get` private-member bug on `/api/version` prerender — documented |
|
||||
| `pnpm e2e` | DEFER | Web-server step blocked by build failure; same Node-25 bug also hits `next dev` |
|
||||
|
||||
\*Pre-existing or environmental — see below.
|
||||
|
||||
## Fixes committed this phase
|
||||
|
||||
### `fix(tests): share next/headers cookieJar across integration suite`
|
||||
|
||||
The integration suite ran with `vitest isolate: false` (one worker, one
|
||||
container — the migration cost demands it). `idempotency-replay.test.ts`
|
||||
declared a top-level `vi.mock("next/headers", ...)` whose factory closed
|
||||
over a per-file `cookieJar` Map. `admin-data-wipe.test.ts` and
|
||||
`auth-flow.test.ts` did the same with their own per-file Maps. Vitest
|
||||
resolves a mock factory ONCE per worker — whichever file loaded first
|
||||
won the registration, and the other files' writes silently disappeared.
|
||||
|
||||
That made `admin-data-wipe.test.ts` flake intermittently when
|
||||
`idempotency-replay.test.ts` happened to load first (its
|
||||
`vi.mock("@/lib/auth/session", ...)` then leaked, returning a stub user
|
||||
without an admin role → `requireAdmin()` 401 → assertion failed).
|
||||
|
||||
Empirical flake rate before fix: ~12.5% (1/8 runs). After fix: 0/10.
|
||||
|
||||
**Fix**: `tests/integration/mock-next-headers.ts` exports module-singleton
|
||||
`cookieJar` + `headerJar` Maps. All three integration test files now
|
||||
share them by `await import("./mock-next-headers")` from inside the
|
||||
`vi.mock` factory body. The `vi.mock("@/lib/auth/session", ...)` stub
|
||||
in `idempotency-replay.test.ts` was removed in favour of seeding a real
|
||||
`Session` row via the cookieJar — same pattern the other two files use.
|
||||
|
||||
### Format sweep on planning + docs (no code changes)
|
||||
|
||||
`pnpm prettier --write` applied to `.planning/*.md`, `docs/audit/v1414-*.md`,
|
||||
and `e2e/measurement-flow.spec.ts` to clear the `format:check` warnings
|
||||
the Phase 6 reconcile-report flagged as pre-existing-out-of-scope.
|
||||
|
||||
## Known caveats (NOT regressions, deliberately not fixed)
|
||||
|
||||
1. **`pnpm build` Node-25 bug** — `TypeError: Cannot read private member
|
||||
#state from an object whose class did not declare it` at
|
||||
`Reflect.get` inside Turbopack's compiled chunk during
|
||||
`/api/version` prerender. Documented at the v1.5 phase-4b report.
|
||||
CI Docker uses Node 22 and is canonical; image digest still rolls
|
||||
on tag push. **Verified the same bug also affects `next dev`** on
|
||||
Node 25, so e2e cannot run locally either; it'll run green in CI
|
||||
on Node 22 (Phase-3 report records 41/41 specs green there).
|
||||
|
||||
2. **`src/components/charts/__tests__/trend-card.test.tsx` Prettier
|
||||
warning** — single test file flagged for line-collapse formatting
|
||||
(`<TrendCard ... />` JSX). Marc constraint forbids touching
|
||||
`src/components/charts/**`. Pre-existing per Phase 6 reconcile.
|
||||
Pure formatting, zero behavioural impact.
|
||||
|
||||
3. **Phase 4b open-state inheritance** — neither `pnpm test:integration`
|
||||
nor `pnpm e2e` was executed after Phase 6 reconcile (Phase 6's
|
||||
final-verify ran `typecheck/lint/test/format` only). The integration
|
||||
flake fixed here had been latent since v1.4 and surfaced now because
|
||||
`admin-data-wipe.test.ts` (added in commit `512a6a6`, Phase 2) loaded
|
||||
the right modules in the right order to expose it.
|
||||
|
||||
## Acceptance-criterion tally
|
||||
|
||||
- [x] typecheck clean
|
||||
- [x] lint 0 errors
|
||||
- [x] format:check clean (modulo the one chart-test file blocked by Marc constraint)
|
||||
- [x] vitest fully green
|
||||
- [x] integration tests fully green (flake fixed)
|
||||
- [-] build — Node-25 caveat documented; CI Docker (Node 22) is canonical
|
||||
- [-] e2e — same Node-25 caveat applies; CI runs the suite on Node 22
|
||||
|
||||
Phase 8 (release) can proceed: typecheck/lint/test/integration are
|
||||
canonical signal locally, and CI exercises build + e2e on Node 22.
|
||||
@@ -104,9 +104,7 @@ test.describe("add measurement flow", () => {
|
||||
// v1.5 phase-5: the menu items now have distinct labels — the
|
||||
// measurement entry says "Measurement" / "Messung" instead of "Add",
|
||||
// so we can target it directly.
|
||||
await page
|
||||
.getByRole("menuitem", { name: /measurement|messung/i })
|
||||
.click();
|
||||
await page.getByRole("menuitem", { name: /measurement|messung/i }).click();
|
||||
|
||||
// Form should be visible inside the dialog. Switch type to WEIGHT
|
||||
// (combo-box defaults to BLOOD_PRESSURE).
|
||||
|
||||
Reference in new issue
Block a user