| 09-backend-admin-authentication-and-schema-pipeline |
05 |
admin |
| cabana |
| crud |
| bulk-delete |
| gorm |
| mass-assignment |
| lifecycle |
|
| phase |
provides |
| 09-backend-admin-authentication-and-schema-pipeline |
compiled form schema, backend permission gate, and D-10 envelopes |
|
|
| Schema-projected create and update through Fill then Validate |
| Permissioned show, create, update, and delete with scoped lookup |
| Transactional bulk delete with duplicate, empty, retry, and concurrency rules |
|
| 09-backend-admin-authentication-and-schema-pipeline |
| admin-api |
| phase-10-spa |
|
| tokens |
tasks |
commits |
| 17783 |
3 |
6 |
|
| added |
patterns |
|
|
| Writable fields are bound to gorm columns at activation and projected by exact key |
| Record mutations run Fill, BeforeValidate, Validate, then controller and model hooks in one transaction |
| Bulk delete locks the scoped set FOR UPDATE and commits every selected row or none |
|
|
| created |
modified |
| cabana/crud.go |
| cabana/crud_test.go |
| cabana/crud_lifecycle_test.go |
| cabana/bulk_test.go |
|
| cabana/http.go |
| cabana/registry.go |
| cabana/contracts.go |
| pact/capabilities.go |
|
|
| Writable admin fields are bound to gorm columns at activation; id, timestamps, scope, and system flags are never fillable |
| Show and update use one not-found body for missing and out-of-scope rows; delete of an absent row is deleted 0 and does not run hooks |
| A bulk selection that matches no scoped row is a no-op; a mixed present and absent selection is a 409 and rolls back |
| Controller hook failures return an opaque lifecycle error and do not echo the hook text |
|
| Pattern: ProjectWritableFields copies only activation bindings, so request key casing and nesting cannot reach Fill |
| Pattern: bulk ids are parsed, deduped, and sorted before a single locked transaction |
|
|
| id |
description |
requirement |
verification |
human_judgment |
| D1 |
Create and update project only schema-writable fields, call Fill then Validate, and return D-10 422 field errors. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/crud_test.go#TestCRUDFillValidate |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D2 |
Unknown, cased, nested, and protected keys never change id, timestamps, scope, or system flags. |
ADMIN-04 |
| kind |
ref |
status |
| unit |
cabana/crud_test.go#TestCRUDWritableProjection |
pass |
|
| kind |
ref |
status |
| integration |
cabana/crud_test.go#TestCRUDRejectsProtectedFields |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D3 |
A model missing Fillable or Rules, or a Validate provider error, fails closed with the controller id and persists nothing. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/crud_test.go#TestCRUDCapabilityFailure |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D4 |
Show, create, update, and delete are mounted behind the backend permission check and use D-10 envelopes. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/crud_lifecycle_test.go#TestCRUDRecordRoutes |
pass |
|
| kind |
ref |
status |
| integration |
cabana/crud_lifecycle_test.go#TestCRUDPermissions |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D5 |
Missing and out-of-scope records share one not-found or deleted-zero body, and in-scope rows stay unchanged. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/crud_lifecycle_test.go#TestCRUDScope |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D6 |
Create, update, and delete run Before and After hooks once, in order, inside the transaction. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/crud_lifecycle_test.go#TestCRUDHooks |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D7 |
A failing create, update, or delete hook rolls the transaction back and the HTTP body stays opaque. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/crud_lifecycle_test.go#TestCRUDRollback |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D8 |
Bulk delete rejects an empty selection, collapses duplicates, and deletes in ascending primary-key order. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/bulk_test.go#TestBulkDeleteEmpty |
pass |
|
| kind |
ref |
status |
| integration |
cabana/bulk_test.go#TestBulkDeleteDuplicates |
pass |
|
| kind |
ref |
status |
| integration |
cabana/bulk_test.go#TestBulkDeleteOrder |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D9 |
Repeating a completed bulk delete, or naming only out-of-scope rows, returns deleted 0 and does not run hooks. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/bulk_test.go#TestBulkDeleteIdempotent |
pass |
|
|
false |
|
| id |
description |
requirement |
verification |
human_judgment |
| D10 |
A mixed selection, hook error, or cancellation rolls the whole batch back, and two concurrent deletes remove each row once. |
ADMIN-04 |
| kind |
ref |
status |
| integration |
cabana/bulk_test.go#TestBulkDeleteRollback |
pass |
|
| kind |
ref |
status |
| integration |
cabana/bulk_test.go#TestBulkDeleteConcurrent |
pass |
|
|
false |
|
|
25min |
2026-09-24 |
complete |
040f3ef81c |
50754808f6 |