Files
summercms/.planning/phases/09-backend-admin-authentication-and-schema-pipeline/09-03-SUMMARY.md
2026-09-24 18:27:51 +02:00

11 KiB

phase, plan, subsystem, tags, requires, provides, affects, actuals, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, coverage, duration, completed, status, plan_head_before, plan_head_after
phase plan subsystem tags requires provides affects actuals tech-stack key-files key-decisions patterns-established requirements-completed coverage duration completed status plan_head_before plan_head_after
09-backend-admin-authentication-and-schema-pipeline 03 admin
yaml
goccy
phrasebook
cabana
admin-schema
scaffolding
phase provides
09-backend-admin-authentication-and-schema-pipeline cabana list compiler, admin controller registry, and phrasebook translator
Typed Winter form schema compiled at activation with source order and JSON scalar types
Per-request localization of labels, comments, tabs, emptyOption, and option labels
make:admin-controller output that matches the Winter controller/model YAML split
09-backend-admin-authentication-and-schema-pipeline
admin-api
phase-10-spa
tokens tasks commits
13818 3 6
added patterns
Form IR caches source phrase keys; Localize copies the schema per request
config_form.yaml is compiled only when the file is present, so list-only controllers still boot
Dropdown method names require DropdownOptions on the controller or its NewRecord model
created modified
cabana/schema_types.go
cabana/form_schema.go
cabana/form_schema_test.go
cabana/contracts.go
cabana/registry.go
cabana/schema.go
phrasebook/translator.go
internal/build/artifact.go
internal/build/stubs/artifacts.tmpl
internal/build/build_test.go
Cached form schemas keep source phrase keys; each response localizes a copy and records meta.locale
Absent config_form.yaml does not fail activation, so the 09-01 Genre list controller still boots
YAML option keys keep their JSON scalar type; method options call DropdownOptions(field) with the exact field name
make:admin-controller writes controllers/<name>/config_form.yaml and config_list.yaml pointing at models/<name>/fields.yaml and columns.yaml
Pattern: boot compiler walks the YAML AST so field order and option scalar types survive DisallowUnknownField
Pattern: a missing dropdown provider fails with plugin, controller, file, and the exact method name
ADMIN-01
id description requirement verification human_judgment
D1 Every locked form field and layout hint compiles in source order with Winter JSON keys and typed scalars. ADMIN-01
kind ref status
unit cabana/form_schema_test.go#TestFormSchemaCompile pass
false
id description requirement verification human_judgment
D2 Empty fields serialize as an array, a single field stays one element, and repeated compilation is byte-stable. ADMIN-01
kind ref status
unit cabana/form_schema_test.go#TestFormSchemaEmpty pass
kind ref status
unit cabana/form_schema_test.go#TestFormSchemaSingle pass
kind ref status
unit cabana/form_schema_test.go#TestFormSchemaOrdering pass
false
id description requirement verification human_judgment
D3 Unknown keys, unknown types, duplicates, path escape, a mismatched modelClass, partials, and missing assets fail with plugin, controller, and file context. ADMIN-01
kind ref status
unit cabana/form_schema_test.go#TestFormSchemaRejects pass
false
id description requirement verification human_judgment
D4 One cached schema localizes independently in pl and en, including Accept-Language parent fallback, app.locale, and raw-key fallback. ADMIN-01
kind ref status
unit cabana/form_schema_test.go#TestFormSchemaLocalization pass
kind ref status
unit cabana/form_schema_test.go#TestFormSchemaLocaleIsolation pass
false
id description requirement verification human_judgment
D5 YAML option maps keep order and scalar type, and a string options method requires DropdownOptions at boot. ADMIN-01
kind ref status
unit cabana/form_schema_test.go#TestFormSchemaDropdownOptions pass
false
id description requirement verification human_judgment
D6 summer make:admin-controller emits the Winter controller/model YAML split, compiles through the strict loader, and refuses a duplicate without partial files. ADMIN-01
kind ref status
unit internal/build/build_test.go#TestMakeAdminControllerLayout pass
false
25min 2026-09-24 complete af3312aa92 68715fc260

Phase 9 Plan 03: Typed Winter form schema Summary

Winter form YAML now compiles into an ordered typed JSON schema, each response localizes its own copy, and make:admin-controller emits that same layout.

Performance

  • Duration: 25 min
  • Started: 2026-09-24T16:01:20Z
  • Completed: 2026-09-24T16:25:51Z
  • Tasks: 3
  • Files modified: 10

Accomplishments

  • config_form.yaml and fields.yaml compile once at cabana activation into text, textarea, number, checkbox, switch, dropdown, relation, and relation-manager fields, in source order, with Winter JSON spelling.
  • Empty fields are [], option values keep string, number, and boolean JSON types, and type: partial plus unknown keys, types, path escape, and a mismatched modelClass fail before serving.
  • Labels, comments, tabs, emptyOption, and option labels resolve per request through phrasebook. The cache stays source keys. meta.locale is the selected request locale, or app.locale when the request has none.
  • summer make:admin-controller writes controllers/<name>/config_form.yaml and config_list.yaml that point at models/<name>/fields.yaml and columns.yaml. A duplicate asset fails before any new file is written.

Task Commits

Each task was committed atomically. commits: 6 is git rev-list --count from the plan ledger.

  1. Task 1: Strict ordered form compilation (RED) - ea3f070 (test)
  2. Task 1: Strict ordered form compilation (GREEN) - 4c814e5 (feat)
  3. Task 2: Locale and dropdown options (RED) - ad1b760 (test)
  4. Task 2: Locale and dropdown options (GREEN) - da8828e (feat)
  5. Task 3: Winter admin scaffolding (RED) - af8e58a (test)
  6. Task 3: Winter admin scaffolding (GREEN) - 68715fc (feat)

Plan metadata: pending docs commit

Files Created/Modified

  • cabana/schema_types.go - form schema, field, option, and localized view types
  • cabana/form_schema.go - strict boot compiler and request-time localizer
  • cabana/form_schema_test.go - golden, empty/single/order, rejection, locale, and dropdown tests
  • cabana/registry.go - compiles a form when config_form.yaml is present
  • cabana/contracts.go - compiled controllers carry the form schema
  • cabana/schema.go - exported CompileList for the same strict list loader
  • phrasebook/translator.go - Locale() reports the configured app locale
  • internal/build/artifact.go - Winter directory split and duplicate checks for the full file set
  • internal/build/stubs/artifacts.tmpl - config_form.yaml and config_list.yaml stubs
  • internal/build/build_test.go - layout, strict compile, registry stability, and partial-write tests

Decisions Made

  • The cached schema stores phrase keys. Localize copies fields and options, so one request's locale cannot change another's result or the boot cache.
  • meta.locale is the primary Accept-Language tag when the request has one (pl-PL,en;q=0.5 becomes pl-PL). Phrasebook still parent-falls back to pl. With no request locale, meta uses the translator's app locale.
  • A controller with only config_list.yaml keeps activating. The 09-01 Genre tracer has no form yet. A present but invalid form still fails activation.
  • Dropdown options: maps keep declaration order and key scalar type. A string such as getFormatOptions is a method name, compared exactly, and the controller or NewRecord() model must implement DropdownOptions. Only the label is translated.
  • Scaffolded modelClass is the controller ident (Albums), matching ModelName(), and ConfigDir() stays controllers/<name>.

Deviations from Plan

Auto-fixed Issues

1. [Rule 2 - Missing Critical] Exposed the configured app locale

  • Found during: Task 2 (locale and dropdown options)
  • Issue: phrasebook.Translator kept app.locale unexported, so a request with no Accept-Language could not put the real app locale in meta.locale.
  • Fix: Added Translator.Locale(). Cabana does not read config itself.
  • Files modified: phrasebook/translator.go, cabana/form_schema.go
  • Verification: TestFormSchemaLocalization/parent_and_app_locale passed
  • Committed in: da8828e

2. [Rule 3 - Blocking] Exported the list compiler for scaffold verification

  • Found during: Task 3 (Winter admin scaffolding)
  • Issue: Generated config_list.yaml had to compile through the strict loader, and compileList was unexported to the build tests.
  • Fix: Exported cabana.CompileList as a wrapper. No behavior change for activation.
  • Files modified: cabana/schema.go, internal/build/build_test.go
  • Verification: TestMakeAdminControllerLayout/winter_files passed
  • Committed in: af8e58a (export) and 68715fc (scaffold)

Total deviations: 2 auto-fixed (1 missing critical, 1 blocking) Impact on plan: Both keep the locked locale and loader contracts testable. No new dependency and no response-shape change outside the form schema this plan owns.

TDD Gate Compliance

Gate Commit Result
RED task 1 ea3f070 test(09-03) TestFormSchemaCompile failed because compilation was not implemented
GREEN task 1 4c814e5 feat(09-03) compile, empty, single, ordering, and reject tests passed
RED task 2 ad1b760 test(09-03) TestFormSchemaLocalization failed because localization was not implemented
GREEN task 2 da8828e feat(09-03) localization, dropdown, and race-isolated locale tests passed
RED task 3 af8e58a test(09-03) TestMakeAdminControllerLayout failed on the old controller-local YAML paths
GREEN task 3 68715fc feat(09-03) Winter layout, strict compile, and duplicate-without-partial-write passed

gsd_run check tdd-red-evidence returned RED_EVIDENCE_OK for all three RED runs. Go's test output is not TAP, so each evidence record appends a TAP trailer naming the test the go harness failed.

Authentication Gates

None.

Issues Encountered

None.

User Setup Required

None - no external service configuration required.

Next Phase Readiness

  • Ready for 09-04. Form compilation, localization, and the Winter scaffold layout are in place.
  • ADMIN-01 stays pending in REQUIREMENTS.md until the later plans that also declare it have summaries.
  • List-only controllers remain valid until those plans add config_form.yaml.

Self-Check: PASSED

  • FOUND: cabana/form_schema.go
  • FOUND: cabana/schema_types.go
  • FOUND: cabana/form_schema_test.go
  • FOUND: internal/build/stubs/artifacts.tmpl
  • FOUND: ea3f070
  • FOUND: 4c814e5
  • FOUND: ad1b760
  • FOUND: da8828e
  • FOUND: af8e58a
  • FOUND: 68715fc

Phase: 09-backend-admin-authentication-and-schema-pipeline Completed: 2026-09-24