From f5fd55f4196cb7b5d1daa327c55cac99b9211c51 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Sun, 20 Sep 2026 13:33:11 +0200 Subject: [PATCH] docs(06-06): update plan tracking --- .planning/REQUIREMENTS.md | 2 +- .planning/ROADMAP.md | 6 +++--- .planning/STATE.md | 23 +++++++++++++---------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index 1324495..22d75aa 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -53,7 +53,7 @@ Requirements for v1 (the Płytarium port). Each maps to roadmap phases. "User" b - [x] **HTTP-01**: Plugins register route groups on net/http ServeMux with typed params and regex constraints; unknown and malformed ids both return 404 on ownership-scoped resources - [x] **HTTP-02**: Plugins register named middleware that other plugins reference by name; the pipeline order is recover, CORS, locale, auth group, must-change-password, org context, rate limit, handler - [x] **HTTP-03**: Three mutually exclusive auth groups share the same handlers with different route subsets: JWT under /_fonoteka/api/v1, personal scoped token under /api/v1/fonoteka, and public groups (onboarding, public/{token}, public-wishlist/{token}, invitation inspection) -- [ ] **HTTP-04**: A rate limiter supports named buckets keyed by a resolver (token id, IP, route param), stacking two limiters on one route, and ports Płytarium's five named buckets and inline throttles 1:1 +- [x] **HTTP-04**: A rate limiter supports named buckets keyed by a resolver (token id, IP, route param), stacking two limiters on one route, and ports Płytarium's five named buckets and inline throttles 1:1 - [x] **HTTP-05**: An auth guard registry lets plugins add guards (JWT, personal token, OAuth bearer) that all resolve to the same current-user accessor - [x] **HTTP-06**: Response conventions are preserved: empty arrays serialize as [], timestamps as +00:00, tri-state booleans keep null, conditional keys are omitted not nulled, and no blanket envelope or error middleware wraps OAuth routes - [x] **HTTP-07**: A guarded outbound fetch helper enforces host allow-lists, byte caps and timeouts for user-supplied URLs (manual cover URL, Discogs cover) diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 37b128b..9521837 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -18,7 +18,7 @@ Decimal phases appear between their surrounding integers in numeric order. - [x] **Phase 3: First vertical slice — genres end to end** - `GET /_fonoteka/api/v1/genres` passes the parity diff through every layer (completed 2026-09-17) - [x] **Phase 4: CLI scaffolding, i18n and mail** - Scaffolding commands, translated/pluralized strings, mail templates (completed 2026-09-18) - [x] **Phase 5: Data layer full fidelity** - All 25 models and their squashed migrations with fillable/hidden/cast/soft-delete discipline (completed 2026-09-18) -- [ ] **Phase 6: HTTP routing, auth groups and rate limiting** - Three auth groups, named rate buckets, OAuth-safe middleware structure +- [x] **Phase 6: HTTP routing, auth groups and rate limiting** - Three auth groups, named rate buckets, OAuth-safe middleware structure (completed 2026-09-20) - [ ] **Phase 7: User plugin and authentication** - Registration, login, JWT, organizations, personal tokens, must-change-password - [ ] **Phase 8: OAuth2.1 authorization server** - zitadel/oidc server for fonoteka-mcp and the ChatGPT connector - [ ] **Phase 9: Backend admin authentication and schema pipeline** - Admin roles, fields.yaml/columns.yaml, relation manager @@ -245,7 +245,7 @@ Plans: **Wave 5** *(gap closure; blocked on 06-05)* -- [ ] 06-06-PLAN.md — Repair personal-token middleware order and prove unauthenticated request 61 is rate-limited +- [x] 06-06-PLAN.md — Repair personal-token middleware order and prove unauthenticated request 61 is rate-limited ### Phase 7: User plugin and authentication @@ -414,7 +414,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → | 3. First vertical slice — genres end to end | 4/4 | Complete | 2026-09-17 | | 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 | 5/5 | Gaps found | - | +| 6. HTTP routing, auth groups and rate limiting | 6/6 | Complete | 2026-09-20 | | 7. User plugin and authentication | 0/TBD | Not started | - | | 8. OAuth2.1 authorization server | 0/TBD | Not started | - | | 9. Backend admin authentication and schema pipeline | 0/TBD | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index e808a22..ac91d1c 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,15 +3,15 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: executing -stopped_at: Completed 06-05-PLAN.md -last_updated: "2026-09-19T22:19:43.824Z" -last_activity: 2026-09-19 -- Phase 6 planning complete +stopped_at: Completed 06-06-PLAN.md +last_updated: "2026-09-20T11:32:44.614Z" +last_activity: 2026-09-20 progress: total_phases: 15 - completed_phases: 5 + completed_phases: 6 total_plans: 29 - completed_plans: 28 - percent: 33 + completed_plans: 29 + percent: 40 --- # Project State @@ -26,9 +26,9 @@ See: .planning/PROJECT.md (updated 2026-09-16) ## Current Position Phase: 06 (http-routing-auth-groups-and-rate-limiting) — EXECUTING -Plan: 5 of 5 +Plan: 6 of 6 Status: Ready to execute -Last activity: 2026-09-19 -- Phase 6 planning complete +Last activity: 2026-09-20 Progress: [██████████] 100% @@ -74,6 +74,7 @@ Progress: [██████████] 100% | Phase 06 P02 | 14 min | 3 tasks | 16 files | | Phase 06 P03 | 20 min | 3 tasks | 24 files | | Phase 06 P05 | 13 min | 3 tasks | 13 files | +| Phase 06 P06 | 1h 29m | 2 tasks | 3 files | ## Accumulated Context @@ -171,6 +172,8 @@ Recent decisions affecting current work: - [Phase 06]: Full route-table isolation uses surf.BuildRouter of the real plugins; app.Handler returns http.Handler and cannot call Routes() — app.Handler assembles an http.Handler; Routes() is on *surf.Router - [Phase 06]: T-06-05 remains accept as originating 06-01 (the 06-05 plan three-accepts list omitted it) — Originating plan disposition is copied verbatim into 06-SECURITY-REVIEW.md - [Phase 06]: PublicOnlyMode any-host-when-public is proven via skipReservedCheck httptest, not a live public IP dial — Unit tests must not require outbound network +- [Phase 06]: Keep inv_token outermost so valid credentials populate bouncer.Credential before the limiter selects tok:. — The named bucket must retain per-token isolation for valid credentials instead of collapsing them onto the IP fallback. +- [Phase 06]: Place throttle:fonoteka-api-token before inv.scope:read in the personal-token middleware declaration. — Missing and invalid credentials must consume the 60/minute per-IP deny-path budget before InvScope returns its PHP-compatible 401 response. ### Pending Todos @@ -192,6 +195,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-09-19T19:21:17.950Z -Stopped at: Completed 06-05-PLAN.md +Last session: 2026-09-20T11:32:06.433Z +Stopped at: Completed 06-06-PLAN.md Resume file: None