From fa7bdb5f710b6424c511ca3cd4961f0f17b94f31 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Tue, 22 Sep 2026 18:44:05 +0200 Subject: [PATCH] docs(07-05): complete the user API parity capture plan Record that the 15 user routes stay pending until Go matches the PHP bodies, including the HTML 500 on a bad activation code and the still-valid token after logout. Co-authored-by: Cursor --- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 17 +-- .../07-05-SUMMARY.md | 128 ++++++++++++++++++ 3 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 .planning/phases/07-user-plugin-and-authentication/07-05-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index cb6d4b8..a6e4d45 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -290,7 +290,7 @@ Plans: **Wave 4** *(blocked on 07-03, 07-04)* -- [ ] 07-05-PLAN.md — Parity evidence: record and replay the 15 /_user/api/v1 routes and the nuxt-auth flow +- [x] 07-05-PLAN.md — Parity evidence: record and replay the 15 /_user/api/v1 routes and the nuxt-auth flow **Wave 5** *(blocked on 07-05)* @@ -448,7 +448,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → | 4. CLI scaffolding, i18n and mail | 4/4 | Complete | 2026-09-18 | | 5. Data layer full fidelity | 6/6 | Complete | 2026-09-18 | | 6. HTTP routing, auth groups and rate limiting | 14/14 | Complete | 2026-09-21 | -| 7. User plugin and authentication | 4/6 | In Progress| | +| 7. User plugin and authentication | 5/6 | In Progress| | | 8. OAuth2.1 authorization server | 0/TBD | Not started | - | | 9. Backend admin authentication and schema pipeline | 0/TBD | Not started | - | | 10. Admin Vue SPA | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 39df322..9549de8 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: 07-05 blocked on isolated PHP instance -last_updated: "2026-09-22T16:09:31.611Z" +stopped_at: Completed 07-05-PLAN.md +last_updated: "2026-09-22T16:43:55.719Z" last_activity: 2026-09-22 progress: total_phases: 15 completed_phases: 6 total_plans: 43 - completed_plans: 41 + completed_plans: 42 percent: 40 --- @@ -26,11 +26,11 @@ See: .planning/PROJECT.md (updated 2026-09-16) ## Current Position Phase: 07 (user-plugin-and-authentication) — EXECUTING -Plan: 5 of 6 +Plan: 6 of 6 Status: Ready to execute Last activity: 2026-09-22 -Progress: [██████████] 95% +Progress: [██████████] 98% ## Performance Metrics @@ -85,6 +85,7 @@ Progress: [██████████] 95% | Phase 07 P02 | 83m | 3 tasks | 22 files | | Phase 07 P03 | 95m | 3 tasks | 28 files | | Phase 07 P04 | 75m | 3 tasks | 16 files | +| Phase 07 P05 | 45 | 3 tasks | 45 files | ## Accumulated Context @@ -217,6 +218,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-09-22T16:08:52.778Z -Stopped at: 07-05 blocked on isolated PHP instance -Resume file: 07-05-PLAN.md +Last session: 2026-09-22T16:43:55.704Z +Stopped at: Completed 07-05-PLAN.md +Resume file: None diff --git a/.planning/phases/07-user-plugin-and-authentication/07-05-SUMMARY.md b/.planning/phases/07-user-plugin-and-authentication/07-05-SUMMARY.md new file mode 100644 index 0000000..4720378 --- /dev/null +++ b/.planning/phases/07-user-plugin-and-authentication/07-05-SUMMARY.md @@ -0,0 +1,128 @@ +--- +phase: 07-user-plugin-and-authentication +plan: 05 +subsystem: auth +tags: [fonoteka, parity, user-api, php] + +requires: + - phase: 07-user-plugin-and-authentication + provides: user session, account, token, and locale handlers +provides: + - 15 recorded /_user/api/v1 routes in the parity manifest + - db_capture helper for reset and activation codes + - nuxt-auth and locked-user client flows +affects: [07-06] + +tech-stack: + added: [] + patterns: [user-api auth group beside the 154 fonoteka routes, code capture through artisan tinker] + +key-files: + created: + - ../fonoteka.go/parity/db_capture.go + - ../fonoteka.go/parity/fixtures/nuxt/nuxt-auth.yaml + - ../fonoteka.go/parity/fixtures/nuxt/nuxt-auth-lock.yaml + modified: + - ../fonoteka.go/parity/manifest.yaml + - ../fonoteka.go/parity/capture-rules.yaml + - tide/variables.go + +key-decisions: + - "The 15 user routes stay pending until a Go replay matches the recorded PHP body" + - "A sixth failed login is the same 401 as the first; this login path does not suspend" + - "Register disabled and register throttled both record as an opaque 500" + - "Authenticated activate with a wrong code records an HTML 500, and fetch after logout still returns 200" + +patterns-established: + - "Pattern: user-api routes are extra manifest IDs; the fonoteka routes.php digest stays the 154-route lock" + - "Pattern: reset and activation codes are read by db_capture and stored as {id}!{code}" + +requirements-completed: [] + +duration: 45min +completed: 2026-09-22 +--- + +# Phase 7 Plan 05: User API parity capture Summary + +**The 15 `/_user/api/v1` routes are recorded from the isolated PHP app. They stay pending because several PHP bodies differ from the current Go handlers.** + +## Performance + +- **Duration:** 45 min +- **Started:** 2026-09-22T16:11:00Z +- **Completed:** 2026-09-22T16:45:00Z +- **Tasks:** 3 +- **Files modified:** 45 + +## Accomplishments + +- Recorded login, logout, fetch, refresh, register, forgot-password, reset-password, activate, activate-by-code, update, change-password, avatar, avatar/remove, marketing-consent, and oauth-providers, including validation and auth failures. +- `db_capture` reads `reset_password_code` and `activation_code` through the isolated artisan tinker and stores `{id}!{code}`. +- `nuxt-auth.yaml` walks register, fetch, update, change-password, refresh, logout, and a following fetch. `nuxt-auth-lock.yaml` records 423 on genres, 200 on me/locale, then a successful change-password. +- The corpus audit prints `recorded 169/169`. Ported routes stay at 7. The new routes are pending. + +## Task Commits + +1. **Task 1–3: Record and verify the user API corpus** — `30984b6` in `fonoteka.go` +2. **Scrubber allow-list for the second test password** — `7d5d865` in `summercms.go` + +## Files Created/Modified + +- `parity/manifest.yaml` — 15 `auth_group: user-api` entries +- `parity/capture-rules.yaml` — register, refresh, and activate-by-code token capture +- `parity/db_capture.go` — PHP tinker and Postgres code readers +- `parity/fixtures/nuxt/nuxt-auth.yaml` — D-14 session flow +- `parity/fixtures/nuxt/nuxt-auth-lock.yaml` — locked-user 423 then me/locale +- `tide/variables.go` — `parity-alice-next` is an allow-listed test password + +## Decisions Made + +A2 is settled from the recording. Six rapid failed logins for `a2@parity.test` are all 401 `{"error":true,"message":"Nieprawidłowy email lub hasło"}`. The 6th body equals the 1st. This login path does not suspend the account. + +Register with `allow_registration=false` and register after the per-IP limit both record `{"error":"Internal server error"}` at status 500 under `APP_DEBUG=false`. + +Every recorded login, fetch, register, and update success user payload contains `feedback_widget_hidden: false`. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Authenticated activate with a wrong code is an HTML 500** +- **Found during:** Task 2 +- **Issue:** The plan expected 200 `{"user":...}` with `is_activated` unchanged. PHP `attemptActivation` throws outside the JSON catch, and the isolated app returns the generic HTML page titled "Błąd strony" at status 500. `POST activate-by-code` with `1!nope` does the same. +- **Fix:** The fixtures keep the recorded HTML. The Go handler's 200 is a gap for a later closure, not a fixture edit. +- **Files modified:** `parity/fixtures/routes/POST___user_api_v1_activate_user-api.yaml`, `parity/fixtures/routes/POST___user_api_v1_activate-by-code_user-api__invalid.yaml` +- **Committed in:** `30984b6` + +**2. [Rule 1 - Bug] Fetch after logout is still 200** +- **Found during:** Task 2 +- **Issue:** The plan expected the logged-out bearer to be refused. PHP logout returns `{"message":"Logged out"}` and a following `GET /fetch` with that bearer is still 200. The Go handler blacklists the token. +- **Fix:** `GET___user_api_v1_fetch_user-api__reused.yaml` and the last step of `nuxt-auth.yaml` record the 200. The routes stay `pending`. +- **Files modified:** `parity/fixtures/routes/GET___user_api_v1_fetch_user-api__reused.yaml`, `parity/fixtures/nuxt/nuxt-auth.yaml` +- **Committed in:** `30984b6` + +--- + +**Total deviations:** 2 recorded, not patched in Go +**Impact on plan:** The corpus matches PHP. Closing the activate and logout gaps is follow-up work, not a silent fixture rewrite. + +## Issues Encountered + +None + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +Ready for 07-06 unit coverage. AUTH-01, AUTH-02, AUTH-03, AUTH-04, and I18N-02 stay unchecked until phase sign-off. The user-api routes stay pending until Go matches the recorded bodies. + +## Self-Check: PASSED + +- Secret grep over the new fixtures found no live JWT or `inv_` token. +- `/tmp/summercms-parity/vars.yaml` is mode 0600 and outside the repo. +- `go run ./parity/check_corpus.go --require-recorded --require-clients --check-secrets` printed `recorded 169/169`. +- `go test ./parity/ -run 'TestParityCorpus|TestDBCapture'` passed with 7 ported and 162 pending. +- Commits `30984b6` and `7d5d865` are on master.