docs(09-08): complete genres admin controller plan
This commit is contained in:
@@ -375,7 +375,7 @@ Plans:
|
|||||||
4. The relation-manager schema supports search/link/unlink/manage-or-view lists for Collections' editors tab, replacing the `partial` field entirely.
|
4. The relation-manager schema supports search/link/unlink/manage-or-view lists for Collections' editors tab, replacing the `partial` field entirely.
|
||||||
5. Admin CRUD endpoints expose `listExtendQuery`/`formExtendQuery`/`formBeforeCreate`/`formBeforeUpdate`/`relationExtendManageQuery` hooks, bulk delete runs each record's lifecycle hooks, and the Settings model binds to a settings screen through the same schema pipeline.
|
5. Admin CRUD endpoints expose `listExtendQuery`/`formExtendQuery`/`formBeforeCreate`/`formBeforeUpdate`/`relationExtendManageQuery` hooks, bulk delete runs each record's lifecycle hooks, and the Settings model binds to a settings screen through the same schema pipeline.
|
||||||
|
|
||||||
**Plans**: 7/12 plans executed
|
**Plans**: 8/12 plans executed
|
||||||
**Research flag:** yes
|
**Research flag:** yes
|
||||||
|
|
||||||
Plans:
|
Plans:
|
||||||
@@ -400,7 +400,7 @@ Plans:
|
|||||||
|
|
||||||
**Wave 7** *(blocked on Wave 6 completion)*
|
**Wave 7** *(blocked on Wave 6 completion)*
|
||||||
- [x] 09-07-PLAN.md — Port the Artists backend controller
|
- [x] 09-07-PLAN.md — Port the Artists backend controller
|
||||||
- [ ] 09-08-PLAN.md — Complete the Genres controller with form/list parity
|
- [x] 09-08-PLAN.md — Complete the Genres controller with form/list parity
|
||||||
- [ ] 09-09-PLAN.md — Port the Styles controller and typed provider/filter behavior
|
- [ ] 09-09-PLAN.md — Port the Styles controller and typed provider/filter behavior
|
||||||
- [ ] 09-10-PLAN.md — Deliver Collections and the typed relation manager
|
- [ ] 09-10-PLAN.md — Deliver Collections and the typed relation manager
|
||||||
|
|
||||||
@@ -529,7 +529,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 →
|
|||||||
| 6. HTTP routing, auth groups and rate limiting | 14/14 | Complete | 2026-09-21 |
|
| 6. HTTP routing, auth groups and rate limiting | 14/14 | Complete | 2026-09-21 |
|
||||||
| 7. User plugin and authentication | 8/8 | Complete | 2026-09-23 |
|
| 7. User plugin and authentication | 8/8 | Complete | 2026-09-23 |
|
||||||
| 8. OAuth2.1 authorization server | 10/10 | Complete | 2026-09-23 |
|
| 8. OAuth2.1 authorization server | 10/10 | Complete | 2026-09-23 |
|
||||||
| 9. Backend admin authentication and schema pipeline | 7/12 | In Progress| |
|
| 9. Backend admin authentication and schema pipeline | 8/12 | In Progress| |
|
||||||
| 10. Admin Vue SPA | 0/TBD | Not started | - |
|
| 10. Admin Vue SPA | 0/TBD | Not started | - |
|
||||||
| 11. Jobs, realtime and search infrastructure | 0/TBD | Not started | - |
|
| 11. Jobs, realtime and search infrastructure | 0/TBD | Not started | - |
|
||||||
| 12. Płytarium API — Collections and Albums | 0/TBD | Not started | - |
|
| 12. Płytarium API — Collections and Albums | 0/TBD | Not started | - |
|
||||||
|
|||||||
@@ -4,16 +4,16 @@ milestone: v1.0
|
|||||||
current_phase: 09
|
current_phase: 09
|
||||||
current_phase_name: Backend admin authentication and schema pipeline
|
current_phase_name: Backend admin authentication and schema pipeline
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: Completed 09-07-PLAN.md
|
stopped_at: Completed 09-08-PLAN.md
|
||||||
last_updated: "2026-09-25T19:49:37.835Z"
|
last_updated: "2026-09-26T01:03:13.475Z"
|
||||||
last_activity: 2026-09-25
|
last_activity: 2026-09-25
|
||||||
last_activity_desc: Phase 09 execution started
|
last_activity_desc: Phase 09 execution started
|
||||||
state_head: fe639ac0d32a7a1c37d897f604fdf21f478b9854
|
state_head: e6d013717faf3d4ac1e63036877688ca0cbfc128
|
||||||
progress:
|
progress:
|
||||||
total_phases: 15
|
total_phases: 15
|
||||||
completed_phases: 8
|
completed_phases: 8
|
||||||
total_plans: 67
|
total_plans: 67
|
||||||
completed_plans: 62
|
completed_plans: 63
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@ See: .planning/PROJECT.md (updated 2026-09-16)
|
|||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 09 (Backend admin authentication and schema pipeline) — EXECUTING
|
Phase: 09 (Backend admin authentication and schema pipeline) — EXECUTING
|
||||||
Plan: 8 of 12
|
Plan: 9 of 12
|
||||||
Status: Ready to execute
|
Status: Ready to execute
|
||||||
Last activity: 2026-09-25 — Phase 09 execution started
|
Last activity: 2026-09-25 — Phase 09 execution started
|
||||||
|
|
||||||
@@ -116,6 +116,7 @@ Progress: [██████████] 100%
|
|||||||
| Phase 09 P05 | 25min | 3 tasks | 8 files |
|
| Phase 09 P05 | 25min | 3 tasks | 8 files |
|
||||||
| Phase 09 P06 | 29min | 3 tasks | 15 files |
|
| Phase 09 P06 | 29min | 3 tasks | 15 files |
|
||||||
| Phase 09 P07 | 2h20m | 2 tasks | 9 files |
|
| Phase 09 P07 | 2h20m | 2 tasks | 9 files |
|
||||||
|
| Phase 09 P08 | 2h28m | 2 tasks | 4 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -300,6 +301,8 @@ Recent decisions affecting current work:
|
|||||||
- [Phase 09]: Genre and style admin option values are decimal strings because pact.Option.Value is a string
|
- [Phase 09]: Genre and style admin option values are decimal strings because pact.Option.Value is a string
|
||||||
- [Phase 09]: Artists uses only the shared cabana list and CRUD engines; the controller contains identity, asset paths, model factory, and permission declaration only
|
- [Phase 09]: Artists uses only the shared cabana list and CRUD engines; the controller contains identity, asset paths, model factory, and permission declaration only
|
||||||
- [Phase 09]: Artist name_key and slug remain model-owned lifecycle fields and are not exposed by the admin writable projection
|
- [Phase 09]: Artist name_key and slug remain model-owned lifecycle fields and are not exposed by the admin writable projection
|
||||||
|
- [Phase 09]: The Phase 9 Genre tracer remains the one production controller; form capability was added without a parallel route or identity
|
||||||
|
- [Phase 09]: The tracer list and columns were already byte-equivalent to the tracked Winter source, so Task 2 added behavioral proof rather than rewriting them
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -322,6 +325,6 @@ Items acknowledged and carried forward from previous milestone close:
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-09-25T19:49:37.540Z
|
Last session: 2026-09-26T01:03:13.196Z
|
||||||
Stopped at: Completed 09-07-PLAN.md
|
Stopped at: Completed 09-08-PLAN.md
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
---
|
||||||
|
phase: 09-backend-admin-authentication-and-schema-pipeline
|
||||||
|
plan: 08
|
||||||
|
subsystem: admin
|
||||||
|
tags: [cabana, genres, winter-yaml, permissions, postgres, crud]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 09-backend-admin-authentication-and-schema-pipeline
|
||||||
|
provides: Genre list tracer, compiled schema registry, permission gates, and shared CRUD/bulk services
|
||||||
|
provides:
|
||||||
|
- Complete Genre form plus the tracer-proven list under the original controller identity
|
||||||
|
- Duplicate-controller rejection proof and permission-first form/write routing
|
||||||
|
- PostgreSQL list, projected CRUD, lifecycle, atomic bulk, and retry-safety coverage
|
||||||
|
affects: [09-backend-admin-authentication-and-schema-pipeline, admin-api, phase-10-spa]
|
||||||
|
|
||||||
|
actuals:
|
||||||
|
tokens: 3703
|
||||||
|
tasks: 2
|
||||||
|
commits: 0
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Tracer controllers are enriched in place; controller ID, model, route, and permission remain immutable"
|
||||||
|
- "Duplicate admin controller IDs fail activation before any last-write-wins replacement"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/genres/config_form.yaml
|
||||||
|
- ../fonoteka.go/plugins/golem15/fonoteka/models/genre/fields.yaml
|
||||||
|
- ../fonoteka.go/plugins/golem15/fonoteka/admin_genres_test.go
|
||||||
|
modified:
|
||||||
|
- ../fonoteka.go/plugins/golem15/fonoteka/admin.go
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "The Phase 9 Genre tracer remains the one production controller; form capability was added without a parallel route or identity"
|
||||||
|
- "The tracer list and columns were already byte-equivalent to the tracked Winter source, so Task 2 added behavioral proof rather than rewriting them"
|
||||||
|
- "Genre slug remains lifecycle-derived and outside the writable form projection"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Pattern: app-level duplicate registration tests invoke cabana activation with the same plugin twice and assert the first duplicate controller ID"
|
||||||
|
|
||||||
|
requirements-completed: [ADMIN-01, ADMIN-02, ADMIN-04]
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
- id: D1
|
||||||
|
description: Genre form fields, layout hints, and locale keys compile in source order under the original tracer identity.
|
||||||
|
requirement: ADMIN-01
|
||||||
|
verification:
|
||||||
|
- kind: integration
|
||||||
|
ref: plugins/golem15/fonoteka/admin_genres_test.go#TestGenresAdminForm
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: plugins/golem15/fonoteka/admin_genres_test.go#TestGenresAdminTracerIdentity
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D2
|
||||||
|
description: Duplicate Genre registrations fail activation and unauthorized form/create/update requests are denied before Genre SQL.
|
||||||
|
requirement: ADMIN-01
|
||||||
|
verification:
|
||||||
|
- kind: integration
|
||||||
|
ref: plugins/golem15/fonoteka/admin_genres_test.go#TestGenresAdminDuplicateRegistration
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: plugins/golem15/fonoteka/admin_genres_test.go#TestGenresAdminWritePermissions
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D3
|
||||||
|
description: Genre list routes preserve complete source columns, actions, exact identifiers, empty arrays, stable order, and adjacent pages.
|
||||||
|
requirement: ADMIN-02
|
||||||
|
verification:
|
||||||
|
- kind: integration
|
||||||
|
ref: plugins/golem15/fonoteka/admin_genres_test.go#TestGenresAdminList
|
||||||
|
status: pass
|
||||||
|
- kind: integration
|
||||||
|
ref: plugins/golem15/fonoteka/admin_genres_test.go#TestGenresAdminEdges
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D4
|
||||||
|
description: Genre CRUD projects form fields, derives slug through lifecycle hooks, and rejects protected request keys.
|
||||||
|
requirement: ADMIN-04
|
||||||
|
verification:
|
||||||
|
- kind: integration
|
||||||
|
ref: plugins/golem15/fonoteka/admin_genres_test.go#TestGenresAdminCRUD
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
- id: D5
|
||||||
|
description: Genre bulk deletion validates empty input, normalizes duplicates, rolls back mixed selections, runs AfterDelete, and is retry-safe.
|
||||||
|
requirement: ADMIN-04
|
||||||
|
verification:
|
||||||
|
- kind: integration
|
||||||
|
ref: plugins/golem15/fonoteka/admin_genres_test.go#TestGenresAdminBulk
|
||||||
|
status: pass
|
||||||
|
human_judgment: false
|
||||||
|
|
||||||
|
duration: 2h 28m
|
||||||
|
completed: 2026-09-26
|
||||||
|
status: complete
|
||||||
|
plan_head_before: e6d013717faf3d4ac1e63036877688ca0cbfc128
|
||||||
|
plan_head_after: e6d013717faf3d4ac1e63036877688ca0cbfc128
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 9 Plan 08: Complete Genres Controller Summary
|
||||||
|
|
||||||
|
**The production Genre tracer now serves the complete Winter form and its existing full list while preserving one permission-gated identity and inheriting shared CRUD/bulk guarantees.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 2h 28m
|
||||||
|
- **Started:** 2026-09-25T22:34:00Z
|
||||||
|
- **Completed:** 2026-09-26T01:02:16Z
|
||||||
|
- **Tasks:** 2
|
||||||
|
- **Files modified:** 4
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- Added the complete strict Genre form and field assets without changing the tracer controller ID, model, route, permission, or registry entry.
|
||||||
|
- Proved duplicate controller registration fails activation and denied form/write requests cannot reach Genre SQL.
|
||||||
|
- Proved source-complete list behavior plus projected CRUD, slug lifecycle, atomic rollback, delete hooks, duplicate normalization, and retry-safe bulk deletion.
|
||||||
|
|
||||||
|
## TDD Gate Compliance
|
||||||
|
|
||||||
|
`f74acad` established failing complete Genre contracts before `c62baaa` added the form assets. `40c4c45` finalized the real lifecycle fixture; the complete `^TestGenresAdmin` suite passes.
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
1. **Task 1: Expand the Genre tracer to complete form parity** - `f74acad` (test, fonoteka.go), `c62baaa` (feat, fonoteka.go)
|
||||||
|
2. **Task 2: Complete Genres list and exercise shared record behavior** - `f74acad` (test, fonoteka.go), `40c4c45` (test, fonoteka.go)
|
||||||
|
|
||||||
|
The framework repository required no production change, so its measured commit count is zero. Fonoteka commits span `f74acad..40c4c45`.
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `fonoteka.go/plugins/golem15/fonoteka/controllers/genres/config_form.yaml` - complete Winter form-controller contract
|
||||||
|
- `fonoteka.go/plugins/golem15/fonoteka/models/genre/fields.yaml` - name and description fields with all layout hints
|
||||||
|
- `fonoteka.go/plugins/golem15/fonoteka/admin_genres_test.go` - identity, security, schema, list, CRUD, lifecycle, and bulk acceptance suite
|
||||||
|
- `fonoteka.go/plugins/golem15/fonoteka/admin.go` - embeds the new Genre form assets
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- Enriched `genresAdminController` in place. No second controller or route was introduced.
|
||||||
|
- Left `config_list.yaml` and `columns.yaml` unchanged because the Phase 9 tracer already carried every tracked source declaration.
|
||||||
|
- Kept slug out of the form projection; `Genre.BeforeValidate` owns initial slug normalization.
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None - the complete source list was already present from the tracer, and the plan executed by adding form parity plus the required behavioral evidence.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
The bulk lifecycle fixture initially omitted the Albums table's required `collection_id`; the test was corrected to use an isolated real collection before acceptance was rerun. No production change was required.
|
||||||
|
|
||||||
|
`ADMIN-01`, `ADMIN-02`, and `ADMIN-04` remain pending because later Phase 9 plans also declare them.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
Ready for 09-09 and 09-10. Genres and Artists are complete Wave 7 catalog controllers.
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
- FOUND: `fonoteka.go` commits `f74acad`, `c62baaa`, and `40c4c45`
|
||||||
|
- FOUND: Genre form controller and fields assets; original list identity unchanged
|
||||||
|
- PASSED: `GOCACHE=/tmp/summercms-go-build go test ./plugins/golem15/fonoteka -run '^TestGenresAdmin' -count=1`
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 09-backend-admin-authentication-and-schema-pipeline*
|
||||||
|
*Completed: 2026-09-26*
|
||||||
Reference in New Issue
Block a user