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 <cursoragent@cursor.com>
This commit is contained in:
Jakub Zych
2026-09-22 18:44:05 +02:00
parent 7d5d8659ec
commit fa7bdb5f71
3 changed files with 139 additions and 10 deletions

View File

@@ -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.