Assembled avatar POST is 200. UAT is 12/12. AUTH-02 through AUTH-04 and I18N-02 are marked complete. Do not auto-advance. Co-authored-by: Cursor <cursoragent@cursor.com>
97 lines
4.6 KiB
Markdown
97 lines
4.6 KiB
Markdown
---
|
||
phase: 07-user-plugin-and-authentication
|
||
verified: 2026-09-23T08:52:00Z
|
||
status: passed
|
||
score: 4/4 must-haves verified
|
||
overrides_applied: 0
|
||
---
|
||
|
||
# Phase 7: User plugin and authentication Verification Report
|
||
|
||
**Phase Goal:** The user plugin is ported with registration, login, JWT issue/refresh, organizations, personal API tokens and the must-change-password lock.
|
||
**Verified:** 2026-09-23T08:52:00Z
|
||
**Status:** passed
|
||
|
||
## Goal Achievement
|
||
|
||
### Observable Truths
|
||
|
||
| # | Truth | Status | Evidence |
|
||
|---|-------|--------|----------|
|
||
| 1 | A user can register, log in, log out, reset a password, verify email, and receive a JWT the Nuxt app can use unchanged | ✓ VERIFIED | 15 `/_user/api/v1` routes and both nuxt-auth flows are `ported`. `TestParityCorpus` is recorded 169 / ported 22 / pending 147 / failing 0. UAT tests 1–4 and 12 passed. |
|
||
| 2 | Organization fields arrive through a fire-and-collect event, and the user module does not import fonoteka | ✓ VERIFIED | UAT test 6: login/register include organisation fields; `go list -deps` on the user module does not import `plugins/golem15/fonoteka`. |
|
||
| 3 | Personal tokens mint, list, and revoke inside the read/write/ai ceiling, and a read token is rejected on a write route | ✓ VERIFIED | UAT test 7; `TestTokenApi` and `TestInvScope`. |
|
||
| 4 | The password lock returns 423 except locale and change-password, and locale still resolves while locked | ✓ VERIFIED | UAT tests 8–9; `TestMustChangePasswordLock`. |
|
||
|
||
**Score:** 4/4 truths verified
|
||
|
||
### Required Artifacts
|
||
|
||
| Artifact | Expected | Status | Details |
|
||
|----------|----------|--------|---------|
|
||
| `bouncer` JWT mint/refresh/blacklist | Session tokens | ✓ EXISTS + SUBSTANTIVE | Logout blacklists; fetch after logout is 401 |
|
||
| `plugins/golem15/user` session and account handlers | Register through reset, activation, avatar | ✓ EXISTS + SUBSTANTIVE | Assembled avatar POST is 200 after 07-08 |
|
||
| `plugins/golem15/fonoteka` tokens and locale | AUTH-03 and the lock exemption | ✓ EXISTS + SUBSTANTIVE | Ported token and locale routes replay green |
|
||
| `parity` user-api fixtures | Byte-identical replay | ✓ REPLAYED | 15 user-api routes `ported`; both nuxt flows green |
|
||
| serve + Handler bucket publish | Avatar boot path | ✓ EXISTS + SUBSTANTIVE | `TestPublishUploads*`, `TestAvatarAssembled` |
|
||
|
||
**Artifacts:** 5/5 verified
|
||
|
||
### Key Link Verification
|
||
|
||
| From | To | Via | Status | Details |
|
||
|------|----|----|--------|---------|
|
||
| fonoteka `getApiArray` listener | user payload | fire-and-collect | ✓ WIRED | UAT test 6 |
|
||
| `InvScope` | token routes | Phase 6 middleware | ✓ WIRED | `TestInvScope` 403 for missing write |
|
||
| user API handlers | Nuxt contract | parity replay | ✓ WIRED | `TestUserAPINuxtFlows` |
|
||
| `attach.OpenBucket` | serve / Handler | `Publish` before Assemble | ✓ WIRED | `44900f0` / `bc1adf2` |
|
||
|
||
**Wiring:** 4/4 connections verified
|
||
|
||
## Requirements Coverage
|
||
|
||
| Requirement | Status | Blocking Issue |
|
||
|-------------|--------|----------------|
|
||
| AUTH-01 | ✓ SATISFIED | 07-07 flipped the 15 user-api routes and both nuxt flows to ported |
|
||
| AUTH-02 | ✓ SATISFIED | Organisation fields via event; user does not import fonoteka |
|
||
| AUTH-03 | ✓ SATISFIED | Mint, list, revoke, and scope ceiling |
|
||
| AUTH-04 | ✓ SATISFIED | 423 lock with locale exemption |
|
||
| I18N-02 | ✓ SATISFIED | preferred_locale then Accept-Language then app.locale, including while locked |
|
||
|
||
**Coverage:** 5/5 requirements satisfied.
|
||
|
||
## Anti-Patterns Found
|
||
|
||
None that block. Handler does not close the published `*blob.Bucket` (info in 07-REVIEW.md); CLI serve does.
|
||
|
||
## Human Verification Required
|
||
|
||
None — UAT was curl-verified on the assembled Handler. The avatar 500 is closed by 07-08 (`TestAvatarAssembled`).
|
||
|
||
## Gaps Summary
|
||
|
||
### Critical Gaps (Block Progress)
|
||
|
||
None.
|
||
|
||
### Non-Critical Gaps (Can Defer)
|
||
|
||
- `app.Handler` does not close the uploads bucket (CLI serve does). Fine for `mem://` tests.
|
||
- Static `/storage/uploads` is not mounted on Assemble; `avatar_url` is a path, not a served GET. Out of this phase's success criteria.
|
||
|
||
## Recommended Fix Plans
|
||
|
||
None.
|
||
|
||
## Verification Metadata
|
||
|
||
**Verification approach:** Goal-backward from ROADMAP Phase 7 success criteria after 07-08 gap closure
|
||
**Must-haves source:** ROADMAP.md Phase 7 success criteria + 07-08 PLAN must_haves
|
||
**Automated checks:** `go vet ./... && go test ./... -race` green in `summercms.go` and `fonoteka.go` plus nested plugin packages. `TestAvatarAssembled` green. Schema drift `drift_detected: false`.
|
||
**Human checks required:** 0
|
||
**Regression gate:** prior-phase suites are in the same `go test ./... -race` run and passed
|
||
|
||
---
|
||
*Verified: 2026-09-23T08:52:00Z*
|
||
*Verifier: inline goal check after 07-08*
|