docs(07): revise plans after checker review

This commit is contained in:
Jakub Zych
2026-09-22 12:37:08 +02:00
parent 57745e32a2
commit 3aed5c88c3
6 changed files with 65 additions and 22 deletions

View File

@@ -117,11 +117,13 @@ Output: green `go vet`/`go test -race` in both modules, and a `07-VALIDATION.md`
- A full sequence test (real Postgres): register → fetch → update → change-password → refresh → logout → the logged-out token gets 401 on a subsequent fetch — the Go-side mirror of the `nuxt-auth` fixture, run as a fast in-process `httptest` sequence independent of the PHP-recorded parity fixtures (this test must be able to run in CI without the isolated PHP instance).
- `TestMustChangePasswordLock`: a user with `must_change_password=true` gets 423 on `/_fonoteka/api/v1/genres` and `/_fonoteka/api/v1/tokens`, succeeds on `GET/PUT /_fonoteka/api/v1/me/locale`, succeeds on `/_user/api/v1/change-password`, and after that call the lock is cleared and `/_fonoteka/api/v1/genres` succeeds.
- `TestGetApiArray`: the full payload shape (base fields + organisation_id/role + must_change_password + preferred_locale) for a user with all of those set, run against a real boot of both plugins together (not a unit-level mock) — the definitive AUTH-02 acceptance test.
- Mail: `postcard`'s `memory` driver captures `mail.activate` (from `Register`'s user-mode branch), `mail.restore` (from `ForgotPassword`), and `mail.reactivate` (from `Login`'s soft-delete-restore branch, D-17) each with the expected `Vars` keys (`link`/`code`/`name` as applicable).
- Mail: `postcard`'s `memory` driver captures `mail.activate` (from `Register`'s user-mode branch), `mail.restore` (from `ForgotPassword`), and `mail.reactivate` (from `Login`'s soft-delete-restore branch, D-17) each with the expected `Vars` keys (`link`/`code`/`name` as applicable), AND re-confirms the pl/en locale-suffix routing 07-03 Task 3 already tests (`mailTemplate`/`resolveMailLocale`) still holds after any coverage-driven changes in this task -- do not let a coverage fix silently regress the locale-suffix wiring.
- `TestTokenApi`: mint with each of the three individual scopes plus a two-scope combination, then a scope-ceiling violation attempt (`"admin"`) is rejected before any row is persisted; `InvScope` middleware (Phase 6, unchanged) 403s a `write`-scoped route call made with a `read`-only token, proving the ceiling is enforced end-to-end through the ALREADY-SHIPPED Phase 6 gate, not just at mint time.
- `TestBlacklistSweepStarts`: booting the `golem15.user` plugin with a short test-only `golem15.user.jwt.blacklist_sweep_interval` and a pre-inserted expired `jwt_blacklist` row observes the row removed after waiting past the interval -- the test hook confirming 07-02 Task 2's sweep goroutine actually runs during a real plugin Boot, not just that `BlacklistStore.Sweep` works in isolation (07-01).
- `TestNoDeferredRoutesResolve` (D-05): booting both plugins and asserting the real route table has no entry whose path matches any of the deferred PIN-login, device-auth, 2FA, `GET /api/user/batch`, or `GET /_user/activate/{id}` paths -- and that `POST /_user/api/v1/login`'s success body never contains a `two_factor_required` key.
</behavior>
<action>
Run `go test ./plugins/golem15/... -cover -short` and `-race` in `fonoteka.go`, fill every coverage gap the report shows for Phase 7 files, and add the four cross-cutting tests described above. Where a gap traces to a real bug (not just missing coverage), fix it minimally and record the deviation. Confirm `go list -deps ./plugins/golem15/user/...` contains no `plugins/golem15/fonoteka` import (the AUTH-02 import-direction invariant) as an explicit, named test — not just an incidental compile-time fact.
Run `go test ./plugins/golem15/... -cover -short` and `-race` in `fonoteka.go`, fill every coverage gap the report shows for Phase 7 files, and add the six cross-cutting tests described above. Where a gap traces to a real bug (not just missing coverage), fix it minimally and record the deviation. Confirm `go list -deps ./plugins/golem15/user/...` contains no `plugins/golem15/fonoteka` import (the AUTH-02 import-direction invariant) as an explicit, named test — not just an incidental compile-time fact.
</action>
<verify>
<automated>go vet ./... && go test ./... -race -cover</automated>
@@ -130,9 +132,11 @@ Output: green `go vet`/`go test -race` in both modules, and a `07-VALIDATION.md`
- `go test ./... -race` exits 0 in fonoteka.go
- `TestMustChangePasswordLock` proves 423 on `/_fonoteka/api/v1/genres` and `/tokens`, 200 on `me/locale` and `/_user/api/v1/change-password`, and 200 on `/_fonoteka/api/v1/genres` again after the lock clears
- `TestGetApiArray` asserts the full payload shape against a real dual-plugin boot, not a mock
- The `postcard` memory driver captures all three mail sends (activate/restore/reactivate) with non-empty vars
- The `postcard` memory driver captures all three mail sends (activate/restore/reactivate) with non-empty vars, and the pl/en locale-suffix template names for all three
- `TestBlacklistSweepStarts` observes an expired `jwt_blacklist` row removed after a real plugin Boot with a short sweep interval
- `TestNoDeferredRoutesResolve` finds zero route-table matches for PIN/device/2FA/batch/activate-link paths, and login's success body never contains `two_factor_required`
</acceptance_criteria>
<done>go vet and go test -race are green across all of fonoteka.go; TestMustChangePasswordLock and TestGetApiArray both pass against a real dual-plugin boot; mail sends are asserted through the memory driver.</done>
<done>go vet and go test -race are green across all of fonoteka.go; TestMustChangePasswordLock and TestGetApiArray both pass against a real dual-plugin boot; mail sends (with locale suffixes) are asserted through the memory driver; the blacklist sweep goroutine and the D-05 deferred-route absence are both proven by a named test.</done>
</task>
<task type="auto">