189 lines
9.4 KiB
Markdown
189 lines
9.4 KiB
Markdown
---
|
|
phase: 09-backend-admin-authentication-and-schema-pipeline
|
|
plan: 07
|
|
subsystem: admin
|
|
tags: [cabana, artists, winter-yaml, permissions, postgres, crud]
|
|
|
|
requires:
|
|
- phase: 09-backend-admin-authentication-and-schema-pipeline
|
|
provides: compiled form/list schemas, operation permission gates, and schema-projected CRUD/bulk services
|
|
provides:
|
|
- Registered Artists admin controller with complete embedded Winter form and list assets
|
|
- Permission-first Artist schema, list, create, update, show, delete, and bulk-delete routes
|
|
- PostgreSQL acceptance coverage for projection, lifecycle normalization, pagination, atomicity, and retry safety
|
|
affects: [09-backend-admin-authentication-and-schema-pipeline, admin-api, phase-10-spa]
|
|
|
|
actuals:
|
|
tokens: 5094
|
|
tasks: 2
|
|
commits: 0
|
|
|
|
tech-stack:
|
|
added: []
|
|
patterns:
|
|
- "Catalog admin controllers are declarative model/config adapters over cabana; they add no local SQL or write path"
|
|
- "Every generated Artist operation shares one explicit permission checked before schema or database work"
|
|
|
|
key-files:
|
|
created:
|
|
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/artists_admin_controller.go
|
|
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/artists/config_form.yaml
|
|
- ../fonoteka.go/plugins/golem15/fonoteka/controllers/artists/config_list.yaml
|
|
- ../fonoteka.go/plugins/golem15/fonoteka/models/artist/fields.yaml
|
|
- ../fonoteka.go/plugins/golem15/fonoteka/models/artist/columns.yaml
|
|
- ../fonoteka.go/plugins/golem15/fonoteka/admin_artists_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:
|
|
- "Artists uses only the shared cabana list and CRUD engines; the controller contains identity, asset paths, model factory, and permission declaration only"
|
|
- "Winter Artist YAML is copied without reducing fields, columns, toolbar behavior, labels, or layout hints"
|
|
- "Artist name_key and slug remain model-owned lifecycle fields and are not exposed by the admin writable projection"
|
|
|
|
patterns-established:
|
|
- "Pattern: global catalog resources register a zero-state AdminController with one operation permission and a typed NewRecord factory"
|
|
- "Pattern: activation embeds both list and form assets because registry compilation validates the complete controller contract at boot"
|
|
|
|
requirements-completed: [ADMIN-01, ADMIN-02, ADMIN-04]
|
|
|
|
coverage:
|
|
- id: D1
|
|
description: Artists form compilation preserves every Winter field, label, span, required/default hint, and declaration order for pl and en.
|
|
requirement: ADMIN-01
|
|
verification:
|
|
- kind: integration
|
|
ref: plugins/golem15/fonoteka/admin_artists_test.go#TestArtistsAdminForm
|
|
status: pass
|
|
- kind: integration
|
|
ref: plugins/golem15/fonoteka/admin_artists_test.go#TestArtistsAdminRegistration
|
|
status: pass
|
|
human_judgment: false
|
|
- id: D2
|
|
description: Artist form, create, and update operations deny unauthorized admins before Artist SQL or controller work.
|
|
requirement: ADMIN-01
|
|
verification:
|
|
- kind: integration
|
|
ref: plugins/golem15/fonoteka/admin_artists_test.go#TestArtistsAdminWritePermissions
|
|
status: pass
|
|
human_judgment: false
|
|
- id: D3
|
|
description: Artists list schema and routes retain source columns, actions, localization, empty arrays, stable ordering, adjacent pages, and exact identifiers.
|
|
requirement: ADMIN-02
|
|
verification:
|
|
- kind: integration
|
|
ref: plugins/golem15/fonoteka/admin_artists_test.go#TestArtistsAdminList
|
|
status: pass
|
|
human_judgment: false
|
|
- id: D4
|
|
description: Artist CRUD projects only form fields while model hooks derive name_key and slug and protected keys remain unchanged.
|
|
requirement: ADMIN-04
|
|
verification:
|
|
- kind: integration
|
|
ref: plugins/golem15/fonoteka/admin_artists_test.go#TestArtistsAdminCRUD
|
|
status: pass
|
|
human_judgment: false
|
|
- id: D5
|
|
description: Empty, duplicate, mixed-existing, successful, and repeated Artist bulk deletes preserve validation, transaction atomicity, lifecycle deletion, and retry safety.
|
|
requirement: ADMIN-04
|
|
verification:
|
|
- kind: integration
|
|
ref: plugins/golem15/fonoteka/admin_artists_test.go#TestArtistsAdminBulk
|
|
status: pass
|
|
human_judgment: false
|
|
|
|
duration: 2h 20m
|
|
completed: 2026-09-25
|
|
status: complete
|
|
plan_head_before: fe639ac0d32a7a1c37d897f604fdf21f478b9854
|
|
plan_head_after: fe639ac0d32a7a1c37d897f604fdf21f478b9854
|
|
---
|
|
|
|
# Phase 9 Plan 07: Artists Admin Controller Summary
|
|
|
|
**A complete permission-gated Artists admin controller now serves unchanged Winter form/list schemas and inherits the shared deterministic CRUD and atomic bulk contracts.**
|
|
|
|
## Performance
|
|
|
|
- **Duration:** 2h 20m (includes two stalled executor attempts before inline fallback)
|
|
- **Started:** 2026-09-25T17:28:00Z
|
|
- **Completed:** 2026-09-25T19:48:22Z
|
|
- **Tasks:** 2
|
|
- **Files modified:** 9
|
|
|
|
## Accomplishments
|
|
|
|
- Embedded and strictly compiled every tracked Artist form field, list column, toolbar action, locale key, layout hint, and default in source order.
|
|
- Registered `golem15.fonoteka.artists` with `golem15.fonoteka.access_artists`, enforced before schema localization or Artist database access.
|
|
- Proved shared list, projected CRUD, lifecycle normalization, atomic bulk deletion, duplicate normalization, and retry-safe repeated deletion on assembled PostgreSQL routes.
|
|
|
|
## TDD Gate Compliance
|
|
|
|
The RED commit `35b04e7` established failing form, registration, permission, list, CRUD, and bulk contracts before the GREEN controller/assets commit `e595617`. Task 2 edge refinements landed in `5964c8c`; the final `^TestArtistsAdmin` suite passes.
|
|
|
|
## Task Commits
|
|
|
|
1. **Task 1: Port Artists form schema and controller registration** - `35b04e7` (test, fonoteka.go), `e595617` (feat, fonoteka.go)
|
|
2. **Task 2: Port Artists list and prove inherited CRUD/bulk edges** - `35b04e7` (test, fonoteka.go), `5964c8c` (test, fonoteka.go)
|
|
|
|
The framework repository required no production change for this plan, so its measured commit count is zero. Fonoteka commits span `35b04e7..5964c8c`.
|
|
|
|
## Files Created/Modified
|
|
|
|
- `fonoteka.go/plugins/golem15/fonoteka/controllers/artists_admin_controller.go` - Artist controller identity, model factory, asset path, and permission map
|
|
- `fonoteka.go/plugins/golem15/fonoteka/controllers/artists/config_form.yaml` - unchanged Winter form-controller contract
|
|
- `fonoteka.go/plugins/golem15/fonoteka/controllers/artists/config_list.yaml` - unchanged Winter list-controller contract
|
|
- `fonoteka.go/plugins/golem15/fonoteka/models/artist/fields.yaml` - complete Artist form fields and layout hints
|
|
- `fonoteka.go/plugins/golem15/fonoteka/models/artist/columns.yaml` - complete Artist list columns
|
|
- `fonoteka.go/plugins/golem15/fonoteka/admin_artists_test.go` - assembled permission, schema, list, CRUD, and bulk acceptance suite
|
|
- `fonoteka.go/plugins/golem15/fonoteka/admin.go` - embeds the four Artist schema assets
|
|
- `fonoteka.go/plugins/golem15/fonoteka/controllers/genres_admin_controller.go` - adds Artists to the plugin controller roster
|
|
|
|
## Decisions Made
|
|
|
|
- Kept Artists as a zero-state controller. All query, projection, validation, lifecycle, transaction, and response behavior remains in the shared cabana engines.
|
|
- Kept `name_key` and `slug` out of the writable schema. `models.Artist.BeforeValidate` derives them, and hostile request values are dropped.
|
|
- Preserved raw phrase keys when translations are absent, matching the established phrasebook fallback contract.
|
|
|
|
## Deviations from Plan
|
|
|
|
### Auto-fixed Issues
|
|
|
|
**1. [Rule 3 - Blocking] Embedded list assets during form/controller registration**
|
|
- **Found during:** Task 1
|
|
- **Issue:** Cabana activation compiles a controller's list contract before its optional form contract, so registering Artists with only form files fails boot.
|
|
- **Fix:** Copied and embedded the unchanged Winter `config_list.yaml` and `columns.yaml` in the registration commit; Task 2 then exercised them through real routes.
|
|
- **Files modified:** `controllers/artists/config_list.yaml`, `models/artist/columns.yaml`, `admin.go`
|
|
- **Verification:** `TestArtistsAdminRegistration`, `TestArtistsAdminList`
|
|
- **Committed in:** `e595617`
|
|
|
|
---
|
|
|
|
**Total deviations:** 1 auto-fixed (1 blocking)
|
|
**Impact on plan:** The files were already Task 2 deliverables; only their activation timing moved earlier. No scope was added.
|
|
|
|
## Issues Encountered
|
|
|
|
The configured `gsd-executor` stalled twice without creating files or commits. Artifact reconciliation confirmed no partial plan work, so execution continued inline under the two-task threshold. Test fixtures were adjusted to respect the existing unique `name_key` constraint and PostgreSQL `int4` primary-key range.
|
|
|
|
`ADMIN-01`, `ADMIN-02`, and `ADMIN-04` remain pending in `REQUIREMENTS.md` because later Phase 9 plans also declare them.
|
|
|
|
## User Setup Required
|
|
|
|
None - no external service configuration required.
|
|
|
|
## Next Phase Readiness
|
|
|
|
Ready for 09-08 through 09-10. Artists is complete; Genres, Styles, and Collections remain the Wave 7 peers.
|
|
|
|
## Self-Check: PASSED
|
|
|
|
- FOUND: `fonoteka.go` commits `35b04e7`, `e595617`, and `5964c8c`
|
|
- FOUND: Artists controller plus all four embedded Winter schema assets
|
|
- PASSED: `GOCACHE=/tmp/summercms-go-build go test ./plugins/golem15/fonoteka -run '^TestArtistsAdmin' -count=1`
|
|
|
|
---
|
|
*Phase: 09-backend-admin-authentication-and-schema-pipeline*
|
|
*Completed: 2026-09-25*
|