13 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 | 04 | admin |
|
|
|
|
|
|
|
|
|
|
|
36min | 2026-09-24 | complete | db3d7222e9 |
3efdcc1c59 |
Phase 9 Plan 04: Deterministic admin list queries Summary
Winter list YAML now compiles to ordered columns and typed filters, and the admin index runs that schema through bound, tie-broken queries.
Performance
- Duration: 36 min
- Started: 2026-09-24T16:29:24Z
- Completed: 2026-09-24T17:05:17Z
- Tasks: 3
- Files modified: 13
Accomplishments
config_list.yamlandcolumns.yamlcompile to ordered columns, default sort,searchTerm: "search", page-size choices, toolbar create, row update, and bulk delete. Empty collections marshal as[].config_filter.yamlaccepts only switch, daterange, and a model scope named byFilterScopes(). Aconditionskey fails activation. Option values keep their JSON types.GET /_admin/api/v1/{vendor}/{plugin}/{controller}searches, sorts, filters, and pages through those selectors. Equal sort values break ties on the primary key. Unknown identifiers returnvalidation_failedafter the permission check.- The 09-01 genre list still compiles, including a controller with no
config_form.yaml.
Task Commits
Each task was committed atomically. commits: 7 is git rev-list --count from the plan ledger in summercms.go. The tracer expectation lives in fonoteka.go.
- Task 1: Ordered list columns and actions (RED) -
fd591ed(test) - Task 1: Ordered list columns and actions (GREEN) -
aab4398(feat) - Task 2: Typed filters (RED) -
cb832eb(test) - Task 2: Typed filters (GREEN) -
d3a9307(feat) - Task 3: Deterministic list queries (RED) -
7f451c3(test) - Task 3: Deterministic list queries (GREEN) -
6a57f63(feat) - Relation sort default (fix) -
3efdcc1(fix)
App tracer: d8fb9ac in fonoteka.go (test)
Plan metadata: included in the docs commit for this summary
Files Created/Modified
cabana/list_schema.go- strict list compiler, model column check, and request localizercabana/filter_schema.go- switch, daterange, and scope compilationcabana/query.go- allowlisted search, sort, filter, scope, and paginationcabana/schema_types.go- list, filter, and action JSON typescabana/schema.go- shared YAML helpers; list compilation moved outcabana/http.go- schema response and index handler use the compiled listcabana/contracts.go- D-10 error details for validationpact/capabilities.go-FilterScopes()catalog onFilterScopecabana/testdata/list/all_columns.yaml- column fixturecabana/testdata/list/all_filters.yaml- filter fixturefonoteka.go/plugins/golem15/fonoteka/admin_tracer_test.go- unknown sort expects 422
Decisions Made
- Omitted
sortablemeans true, matching Winter, except a relation column, which is not a local column and stays unsortable unless YAML setssortable. An explicit true orders the joinedselectcolumn, then the primary key. perPageOptionskeep source order.recordsPerPagemust be one of them. The query rejects any otherper_page.toolbar.buttons: list_toolbaris the create action.recordUrlis the update row action.showCheckboxesis bulk delete. Other button names fail activation.- The search query parameter is always
search. YAML cannot rename it. conditionsis rejected with the column-or-scope rule. Scope names must appear inFilterScope.FilterScopes()exactly.- D-11 meta is
page,per_page,total,last_page.lagoon.Paginatestill computeslast_page; itscurrent_pageis not the admin key. ADMIN-02stays shared with later plans in this phase, so REQUIREMENTS.md is not marked complete by this plan alone.
Deviations from Plan
Auto-fixed Issues
1. [Rule 2 - Missing Critical] Served the full list schema and validation details
- Found during: Task 1 and Task 3
- Issue: The schema handler copied a subset of
ListSchema, so new slices would marshal as null, andWriteErrorcould not attach field messages. - Fix: The schema handler returns the localized schema.
WriteErrorDetailswrites D-10validation_faileddetails. - Files modified:
cabana/http.go,cabana/contracts.go - Verification:
TestListSchemaEmptyandTestListQueryRejectsInjectionpassed - Committed in:
aab4398and6a57f63
2. [Rule 2 - Missing Critical] Added FilterScopes() to the model capability
- Found during: Task 2
- Issue:
FilterScopecould execute a name but could not declare the finite set, so an arbitrary method could not be rejected without reflection. - Fix:
FilterScopes() []stringis now part ofpact.FilterScope. Compilation accepts only those names. - Files modified:
pact/capabilities.go,cabana/filter_schema.go - Verification:
TestListSchemaScopeandTestListSchemaRejectsRawConditionpassed - Committed in:
d3a9307
3. [Rule 1 - Bug] Stopped treating relation columns as sortable by default
- Found during: Task 3
- Issue: Omitted
sortablebecame true for relation columns, while a sort on that key is not a local column. - Fix: Relation columns default to not sortable. Explicit
sortable: trueorders the joined select column and then the primary key. - Files modified:
cabana/list_schema.go,cabana/query.go - Verification:
go test ./cabana -run '^(TestListSchema|TestListQuery)' -count=1passed - Committed in:
3efdcc1
4. [Rule 1 - Bug] Updated the genre tracer for unknown sorts
- Found during: Task 3
- Issue:
TestAdminTracerGenreListexpectedsort=users.emailto return 200. The new contract rejects that identifier. - Fix: The persisted genre is still read without a caller sort. The unknown sort expects
validation_failedand the body does not echo the identifier. - Files modified:
fonoteka.go/plugins/golem15/fonoteka/admin_tracer_test.go - Verification:
go test ./plugins/golem15/fonoteka -run '^TestAdminTracerGenreList$' -count=1passed - Committed in:
d8fb9ac(fonoteka.go)
Total deviations: 4 auto-fixed (2 missing critical, 2 bug) Impact on plan: The extra capability and response fields are the locked list contract. No new dependency and no change to the frontend API.
TDD Gate Compliance
| Gate | Commit | Result |
|---|---|---|
| RED Task 1 | fd591ed |
TestListSchemaCompile failed because perPageOptions was unknown. TestListSchemaEmpty compared the old four-key JSON. |
| GREEN Task 1 | aab4398 |
TestListSchema(Compile|Empty|Single|Ordering|Rejects) passed |
| RED Task 2 | cb832eb |
TestListSchemaFilter failed on unknown field filter |
| GREEN Task 2 | d3a9307 |
TestListSchema(Filter|Scope|RejectsRawCondition) passed |
| RED Task 3 | 7f451c3 |
TestListQueryContract returned every row for search=Other |
| GREEN Task 3 | 6a57f63 |
TestListQuery(Contract|Empty|Single|Adjacent|Filters|RejectsInjection) passed |
Issues Encountered
None.
User Setup Required
None - no external service configuration required.
Next Phase Readiness
Ready for 09-05. List compilation and the index query are reusable by the later controller plans. ADMIN-02 remains pending until every plan that declares it has a summary.
Self-Check: PASSED
- FOUND: cabana/list_schema.go
- FOUND: cabana/filter_schema.go
- FOUND: cabana/query.go
- FOUND: cabana/testdata/list/all_columns.yaml
- FOUND: cabana/testdata/list/all_filters.yaml
- FOUND:
fd591ed - FOUND:
aab4398 - FOUND:
cb832eb - FOUND:
d3a9307 - FOUND:
7f451c3 - FOUND:
6a57f63 - FOUND:
3efdcc1 - FOUND: d8fb9ac
RED evidence for TestListSchemaCompile, TestListSchemaFilter, and TestListQueryContract was checked with gsd_run check tdd-red-evidence and returned RED_EVIDENCE_OK before each implementation commit.
Phase: 09-backend-admin-authentication-and-schema-pipeline Completed: 2026-09-24