146 lines
9.2 KiB
Markdown
146 lines
9.2 KiB
Markdown
---
|
|
phase: 09-backend-admin-authentication-and-schema-pipeline
|
|
plan: 09
|
|
type: execute
|
|
wave: 7
|
|
depends_on: [09-06]
|
|
files_modified:
|
|
- ../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
|
|
autonomous: true
|
|
requirements: [ADMIN-01, ADMIN-02, ADMIN-04]
|
|
estimate:
|
|
tokens: 15000
|
|
raw_tokens: 15000
|
|
tasks: 2
|
|
confidence: low
|
|
must_haves:
|
|
truths:
|
|
- "The Styles backend controller strictly preserves its tracked Winter form/list contract, ordered schema output, request-time localization, and exact D-03 operation permissions."
|
|
- "Style filter and option values preserve their JSON scalar type and can invoke only the typed provider/scope declared at activation."
|
|
- "Style list/CRUD/bulk routes prove ADMIN-01/02/04 empty/single/equality/adjacency/order/encoding, writable projection, lifecycle, retry, rollback, and concurrency behavior."
|
|
artifacts:
|
|
- path: "../fonoteka.go/plugins/golem15/fonoteka/controllers/styles_admin_controller.go"
|
|
provides: "Styles controller registration and permissions"
|
|
- path: "../fonoteka.go/plugins/golem15/fonoteka/models/style/fields.yaml"
|
|
provides: "Complete style form schema"
|
|
- path: "../fonoteka.go/plugins/golem15/fonoteka/admin_styles_test.go"
|
|
provides: "Style schema/provider/route behavior suite"
|
|
key_links:
|
|
- from: "controllers/styles_admin_controller.go"
|
|
to: "cabana registry and RequiredPermissions"
|
|
via: "explicit controller metadata"
|
|
- from: "models/style/fields.yaml"
|
|
to: "typed option/scope capability"
|
|
via: "activation-resolved finite provider"
|
|
prohibitions:
|
|
- "[flagged-unverified] A Style schema value must not be coerced between string, number, and boolean representations to make a provider or filter appear compatible."
|
|
---
|
|
|
|
## Phase Goal
|
|
|
|
**As a** backend administrator, **I want to** authenticate separately and manage resources described by Winter-shaped schemas, **so that** the administration surface stays permission-gated and reusable without coupling it to frontend users.
|
|
|
|
<objective>
|
|
Port the complete Styles backend controller and verify typed provider/filter behavior through real routes.
|
|
|
|
Purpose: Finish the independent catalog controller breadth while proving the schema compiler never hides type mismatches.
|
|
Output: Embedded Style assets, explicit permissions/providers, and assembled list/CRUD/bulk tests.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@/home/jin/.codex/gsd-core/workflows/execute-plan.md
|
|
@/home/jin/.codex/gsd-core/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
@.planning/phases/09-backend-admin-authentication-and-schema-pipeline/09-CONTEXT.md
|
|
@.planning/phases/09-backend-admin-authentication-and-schema-pipeline/09-06-SUMMARY.md
|
|
@../fonoteka.go/plugins/golem15/fonoteka/models/style.go
|
|
@cabana/form_schema.go
|
|
@cabana/filter_schema.go
|
|
@cabana/crud.go
|
|
</context>
|
|
|
|
## Artifacts this phase produces
|
|
|
|
- `fonoteka.StylesAdminController`
|
|
- Style `config_form.yaml`, `config_list.yaml`, `fields.yaml`, and `columns.yaml`
|
|
- Assembled `TestStylesAdmin*` schema, provider, permission, list, CRUD, and bulk suite
|
|
|
|
<tasks>
|
|
|
|
<task type="auto" tdd="true">
|
|
<name>Task 1: Port Styles form schema with exact typed values</name>
|
|
<files>../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/models/style/fields.yaml, ../fonoteka.go/plugins/golem15/fonoteka/admin_styles_test.go</files>
|
|
<read_first>/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/controllers/styles/config_form.yaml, /media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/models/style/fields.yaml, ../fonoteka.go/plugins/golem15/fonoteka/models/style.go, cabana/form_schema.go, cabana/contracts.go</read_first>
|
|
<behavior>
|
|
- Test 1: every source Style form field and layout/localization key compiles in declaration order with correct JSON scalar values.
|
|
- Test 2: configured typed options/providers return compatible values; missing/mismatched provider capability fails activation rather than coercing.
|
|
- Test 3: form/create/update permissions deny before provider/model/database access and allowed writes use shared projection/validation/hooks.
|
|
</behavior>
|
|
<action>Create the Styles controller and complete embedded form/model assets from the tracked source. Register exact D-03 permissions and finite typed provider capabilities; preserve the YAML scalar kind in compiled options/defaults and reject provider output that cannot represent the declared field contract. Keep cached keys untranslated and rely on the shared localized serializer.</action>
|
|
<verify>
|
|
<automated>(cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^TestStylesAdmin(Form|TypedOptions|ProviderFailure|WritePermissions)$' -count=1)</automated>
|
|
<fails_when>The command exits non-zero, reports no matching test, a source form element is absent, a scalar is coerced, provider mismatch survives activation, locale cache mutates, or denial follows provider/database work.</fails_when>
|
|
</verify>
|
|
<acceptance_criteria>The full Style form schema retains source ordering/types and can call only activation-validated typed providers after permission success.</acceptance_criteria>
|
|
<done>Styles form/schema/write behavior is complete with exact value semantics.</done>
|
|
</task>
|
|
|
|
<task type="auto" tdd="true">
|
|
<name>Task 2: Port Styles list and verify shared behavior</name>
|
|
<files>../fonoteka.go/plugins/golem15/fonoteka/controllers/styles/config_list.yaml, ../fonoteka.go/plugins/golem15/fonoteka/models/style/columns.yaml, ../fonoteka.go/plugins/golem15/fonoteka/admin_styles_test.go</files>
|
|
<read_first>/media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/controllers/styles/config_list.yaml, /media/nvme/dev/golem15/fonoteka/plugins/golem15/fonoteka/models/style/columns.yaml, ../fonoteka.go/plugins/golem15/fonoteka/controllers/styles_admin_controller.go, cabana/query.go, cabana/crud.go</read_first>
|
|
<behavior>
|
|
- Test 1: every source Style column/filter/action/default compiles with stable order and localized display keys.
|
|
- Test 2: empty/single/equal/adjacent results and exact typed identifiers/values follow ADMIN-02.
|
|
- Test 3: Style CRUD/bulk follows ADMIN-04 protection, lifecycle, duplicate/empty ordering, idempotency, rollback, and concurrency semantics.
|
|
</behavior>
|
|
<action>Port the complete Style list/controller assets and route every query/filter/action through the shared compiled list and CRUD services. Exercise the ADMIN-02/04 edge matrix on assembled endpoints, including typed filter values and malicious case-changed identifiers, without adding controller-specific raw query or persistence shortcuts.</action>
|
|
<verify>
|
|
<automated>(cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^TestStylesAdmin(List|TypedFilters|Edges|CRUD|Bulk)$' -count=1)</automated>
|
|
<fails_when>The command exits non-zero, reports no matching test, a source list declaration is absent, a value changes type, exact identifier checks weaken, edge behavior drifts, or Style routes bypass shared query/lifecycle/transaction logic.</fails_when>
|
|
</verify>
|
|
<acceptance_criteria>Styles list, filters, records, and bulk actions preserve exact types and all shared ADMIN-02/04 guarantees.</acceptance_criteria>
|
|
<done>The Styles backend controller is complete and tested from embedded schema through PostgreSQL behavior.</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<threat_model>
|
|
## Trust Boundaries
|
|
|
|
| Boundary | Description |
|
|
|----------|-------------|
|
|
| YAML/provider→typed query/write | Declared and returned scalar kinds select data behavior |
|
|
|
|
## STRIDE Threat Register
|
|
|
|
| Threat ID | Category | Component | Severity | Disposition | Mitigation Plan |
|
|
|-----------|----------|-----------|----------|-------------|-----------------|
|
|
| T-09-15 | Tampering | Style option/filter provider values | medium | mitigate | Preserve YAML scalar kinds, validate provider output against field/filter types at activation, and reject coercion/case variants in assembled tests. |
|
|
| T-09-SC | Tampering | npm/pip/cargo installs | high | mitigate | No npm/pip/cargo install occurs; existing Go dependencies only, so the package-legitimacy gate remains closed. |
|
|
</threat_model>
|
|
|
|
<verification>
|
|
Run `(cd ../fonoteka.go && go test ./plugins/golem15/fonoteka -run '^TestStylesAdmin' -count=1)`; it fails on non-zero exit, zero matched tests, source omission, scalar coercion, permission/provider ordering drift, or shared edge/lifecycle failure.
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- Styles form/list assets preserve every tracked source declaration and scalar kind.
|
|
- Typed providers/scopes are resolved at activation and cannot be selected by arbitrary request text.
|
|
- ADMIN-01/02/04 edge contracts pass on assembled Style routes.
|
|
</success_criteria>
|
|
|
|
<output>
|
|
Create `.planning/phases/09-backend-admin-authentication-and-schema-pipeline/09-09-SUMMARY.md` when done.
|
|
</output>
|