docs(09-09): complete styles admin controller plan

This commit is contained in:
Jakub Zych
2026-09-26 15:10:18 +02:00
parent e9c0722337
commit 53d59dbc92
3 changed files with 208 additions and 15 deletions

View File

@@ -401,7 +401,7 @@ Plans:
**Wave 7** *(blocked on Wave 6 completion)*
- [x] 09-07-PLAN.md — Port the Artists backend controller
- [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
- [x] 09-09-PLAN.md — Port the Styles controller and typed provider/filter behavior
- [ ] 09-10-PLAN.md — Deliver Collections and the typed relation manager
**Wave 8** *(blocked on Wave 7 completion)*
@@ -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 |
| 7. User plugin and authentication | 8/8 | Complete | 2026-09-23 |
| 8. OAuth2.1 authorization server | 10/10 | Complete | 2026-09-23 |
| 9. Backend admin authentication and schema pipeline | 8/12 | In Progress| |
| 9. Backend admin authentication and schema pipeline | 9/12 | In Progress| |
| 10. Admin Vue SPA | 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 | - |

View File

@@ -1,20 +1,21 @@
---
gsd_state_version: "1.0"
gsd_state_version: 1.0
milestone: v1.0
milestone_name: milestone
current_phase: 09
current_phase_name: Backend admin authentication and schema pipeline
status: executing
stopped_at: Completed 09-08-PLAN.md
last_updated: "2026-09-26T01:03:13.475Z"
last_activity: 2026-09-25
last_activity_desc: Phase 09 execution started
state_head: e6d013717faf3d4ac1e63036877688ca0cbfc128
stopped_at: Completed 09-09-PLAN.md
last_updated: "2026-09-26T13:09:59.401Z"
last_activity: 2026-09-26
last_activity_desc: Phase 09 execution continued through the Styles controller
state_head: e9c07223376519f1636dad557cccb6cf0ddd1604
progress:
total_phases: 15
completed_phases: 8
total_plans: 67
completed_plans: 63
milestone_name: milestone
completed_plans: 64
percent: 96
---
# Project State
@@ -29,11 +30,11 @@ See: .planning/PROJECT.md (updated 2026-09-16)
## Current Position
Phase: 09 (Backend admin authentication and schema pipeline) — EXECUTING
Plan: 9 of 12
Plan: 10 of 12
Status: Ready to execute
Last activity: 2026-09-25 — Phase 09 execution started
Last activity: 2026-09-26
Progress: [██████████] 100%
Progress: [██████████] 96%
## Performance Metrics
@@ -117,6 +118,7 @@ Progress: [██████████] 100%
| Phase 09 P06 | 29min | 3 tasks | 15 files |
| Phase 09 P07 | 2h20m | 2 tasks | 9 files |
| Phase 09 P08 | 2h28m | 2 tasks | 4 files |
| Phase 09 P09 | 11h 48m | 2 tasks | 9 files |
## Accumulated Context
@@ -303,6 +305,9 @@ Recent decisions affecting current work:
- [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
- [Phase 09]: The tracked Style source declares no dropdown provider or filter, so production YAML stays exact while isolated compiler fixtures prove typed scalars and provider rejection
- [Phase 09]: Style slug retains the tracked update-only readonly schema and is generated on create by the model lifecycle
- [Phase 09]: Style equal-value list ordering is explicitly stabilized by the shared primary-key tie-breaker
### Pending Todos
@@ -325,6 +330,6 @@ Items acknowledged and carried forward from previous milestone close:
## Session Continuity
Last session: 2026-09-26T01:03:13.196Z
Stopped at: Completed 09-08-PLAN.md
Last session: 2026-09-26T13:09:59.379Z
Stopped at: Completed 09-09-PLAN.md
Resume file: None

View File

@@ -0,0 +1,188 @@
---
phase: 09-backend-admin-authentication-and-schema-pipeline
plan: 09
subsystem: admin
tags: [cabana, styles, winter-yaml, typed-scalars, permissions, postgres, crud]
requires:
- phase: 09-backend-admin-authentication-and-schema-pipeline
provides: Compiled form/list schemas, permission gates, and shared CRUD/bulk services
provides:
- Complete Style form/list assets and registered permission-gated controller
- Exact YAML-to-JSON scalar preservation and activation-time missing-provider rejection proof
- 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: 10144
tasks: 2
commits: 0
tech-stack:
added: []
patterns:
- "Tracked Winter assets remain authoritative when a planning assumption mentions providers or filters absent from source"
- "Typed scalar behavior is proved with an isolated schema fixture while the production Style schema stays source-exact"
key-files:
created:
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/styles_admin_controller.go
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/styles/config_form.yaml
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/styles/config_list.yaml
- ../fonoteka.go/plugins/golem15/fonoteka/models/style/fields.yaml
- ../fonoteka.go/plugins/golem15/fonoteka/models/style/columns.yaml
- ../fonoteka.go/plugins/golem15/fonoteka/admin_styles_test.go
modified:
- ../fonoteka.go/plugins/golem15/fonoteka/admin.go
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/admin_registry.go
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/genres_admin_controller.go
key-decisions:
- "The tracked Style source declares no dropdown provider and no filters; production assets stay exact while isolated compiler fixtures prove typed scalars and missing-provider rejection"
- "Style slug retains its Winter update-only readonly schema and is generated on create by the existing model lifecycle"
- "Style list equal-value ordering is explicitly checked by the primary-key tie-breaker before adjacent-page coverage"
patterns-established:
- "Pattern: source-absent generic capabilities are tested through a minimal fstest schema rather than invented in production plugin YAML"
requirements-completed: [ADMIN-01, ADMIN-02, ADMIN-04]
coverage:
- id: D1
description: Style form fields, layout hints, context, readonly metadata, and locale keys compile in source order under the registered controller.
requirement: ADMIN-01
verification:
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminForm
status: pass
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminTracerIdentity
status: pass
human_judgment: false
- id: D2
description: Numeric, boolean, and string YAML scalars retain JSON type, and a method-backed option without the finite provider capability fails activation.
requirement: ADMIN-01
verification:
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminTypedOptions
status: pass
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminProviderFailure
status: pass
human_judgment: false
- id: D3
description: Unauthorized form/create/update requests fail before Style SQL and duplicate controller sets fail activation.
requirement: ADMIN-01
verification:
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminWritePermissions
status: pass
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminDuplicateRegistration
status: pass
human_judgment: false
- id: D4
description: Style list routes preserve source columns/actions, empty and single results, stable equal ordering, adjacent pages, exact identifiers, and reject undeclared filters.
requirement: ADMIN-02
verification:
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminList
status: pass
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminTypedFilters
status: pass
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminEdges
status: pass
human_judgment: false
- id: D5
description: Style CRUD uses compiled projection and lifecycle slug generation; bulk deletion validates empty input, rolls back mixed selections, runs pivot cleanup, normalizes duplicates, and is retry-safe.
requirement: ADMIN-04
verification:
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminCRUD
status: pass
- kind: integration
ref: plugins/golem15/fonoteka/admin_styles_test.go#TestStylesAdminBulk
status: pass
human_judgment: false
duration: 11h 48m
completed: 2026-09-26
status: complete
plan_head_before: e9c0722
plan_head_after: e9c0722
---
# Phase 9 Plan 09: Styles Controller and Typed Values Summary
**The registered Styles controller now serves its exact Winter form/list contract, preserves typed schema values, and inherits permission-first PostgreSQL CRUD and atomic bulk behavior.**
## Performance
- **Duration:** 11h 48m
- **Started:** 2026-09-26T01:03:13Z
- **Completed:** 2026-09-26T12:51:00Z
- **Tasks:** 2
- **Files modified:** 9
## Accomplishments
- Added the complete Style controller plus embedded form, list, field, and column assets with exact permission and model identities.
- Proved JSON scalar types remain intact and method-backed options fail activation when their finite provider capability is absent.
- Proved real PostgreSQL list stability, exact query identifiers, writable projection, slug lifecycle, pivot cleanup, atomic rollback, duplicate normalization, and retry-safe bulk deletion.
## TDD Gate Compliance
`36f3a32` established failing Style contracts before `8c9b5f7` registered the controller and source assets. `2eb6257` completed the stable-order and edge matrix. The complete `^TestStylesAdmin` suite passes.
## Task Commits
1. **Task 1: Port Styles form schema with exact typed values** - `36f3a32` (test, fonoteka.go), `8c9b5f7` (feat, fonoteka.go)
2. **Task 2: Port Styles list and verify shared behavior** - `36f3a32` (test, fonoteka.go), `8c9b5f7` (feat, fonoteka.go), `2eb6257` (test, fonoteka.go)
The framework repository required no production change, so its measured commit count is zero. Fonoteka commits span `36f3a32..2eb6257`.
## Files Created/Modified
- `fonoteka.go/plugins/golem15/fonoteka/controllers/styles_admin_controller.go` - exact controller identity, permission, and record source
- `fonoteka.go/plugins/golem15/fonoteka/controllers/styles/` - source-complete form/list controller YAML
- `fonoteka.go/plugins/golem15/fonoteka/models/style/` - ordered field/column YAML with typed readonly metadata
- `fonoteka.go/plugins/golem15/fonoteka/admin_styles_test.go` - typed schema, security, list, CRUD, lifecycle, and bulk acceptance suite
- `fonoteka.go/plugins/golem15/fonoteka/admin.go` - embeds Style schema assets
- `fonoteka.go/plugins/golem15/fonoteka/controllers/admin_registry.go` - compile-time capability assertions
- `fonoteka.go/plugins/golem15/fonoteka/controllers/genres_admin_controller.go` - appends Styles to the shared controller registry
## Decisions Made
- Did not invent a Style dropdown provider or filter absent from the tracked PHP source. Isolated schema fixtures cover the plan's generic typed-provider contract without changing production behavior.
- Preserved `slug` as an update-context readonly field. Create requests cannot inject it; `Style.BeforeValidate` generates it.
- Used real pivot rows to prove `Style.AfterDelete` clears `golem15_fonoteka_album_styles` during bulk operations.
## Deviations from Plan
The plan assumed the tracked Style schema declared typed options/providers and filters, but the source contains neither. Production YAML was kept source-exact. Typed scalar preservation, missing-provider activation failure, empty filter serialization, and undeclared-filter rejection were covered explicitly without fabricating app behavior.
## Issues Encountered
The app-level duplicate registration probe sees the first duplicated controller (`genres`) because a duplicated plugin contributes its whole controller set. The assertion therefore verifies fail-closed duplicate detection generically; exact Style identity is covered separately by the registry test.
`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-10. The independent catalog controllers are complete; the remaining Wave 7 work is the Collections relation-manager contract.
## Self-Check: PASSED
- FOUND: `fonoteka.go` commits `36f3a32`, `8c9b5f7`, and `2eb6257`
- FOUND: Style controller and all four embedded schema assets
- PASSED: `GOCACHE=/tmp/summercms-go-build go test ./plugins/golem15/fonoteka -run '^TestStylesAdmin' -count=1`
---
*Phase: 09-backend-admin-authentication-and-schema-pipeline*
*Completed: 2026-09-26*