- backend.uri prefix (default /backend) mounts the admin API at {prefix}/api/v1
and the embedded SPA shell at {prefix} with an api/ JSON 404 fallback
- cookie transport: an X-Requested-With login sets the HttpOnly summer_admin
cookie and returns no token; the backend guard reads the cookie after Bearer
- CSRF wrapper refuses cookie-only POST/PUT/DELETE without X-Requested-With
- boardwalk package embeds boardwalk/dist, rewrites index.html once per prefix
and sets cache and security headers
- framework admin OpenAPI pipeline (swag, swagger2openapi, openapi-typescript)
with prefix-relative paths and typed envelopes for the tracer routes
- admin/ Vite SPA: login, plugin rail, section panel and read-only list
through the openapi-fetch client typed by the generated schema
- GET schema/form localizes the compiled form after the permission check
- relation: genre resolves to the exported Go field without changing the YAML key
- Reject an empty selection and dedupe ids before locking rows in pk order
- Return deleted 0 when every requested row is already gone, without hooks
- Roll back mixed, hook, and cancelled batches so no partial delete commits
- Empty selections are 422 and duplicates run once in primary-key order
- A completed retry and an all-absent selection delete nothing and skip hooks
- Mixed, hook, cancel, and concurrent requests keep the batch atomic
- Mount show, create, update, and delete behind the backend permission check
- Run controller and model hooks once per operation and roll back on failure
- Treat missing and out-of-scope records the same, including idempotent delete
- Record routes must enforce permission before ids or bodies and return D-10 envelopes
- Create, update, and delete run Before and After hooks once inside the transaction
- Out-of-scope and missing records are indistinguishable, and hook failure rolls back
- Search, sort, filters, and pagination use compiled selectors and bound values
- Equal sort keys break ties on the primary key so adjacent pages do not overlap
- Unknown identifiers return validation_failed before SQL
- Typed columns, actions, default sort, search term, and page sizes
- Omitted sortable defaults to true and empty collections marshal as arrays
- Unknown keys, bad defaults, and path escape fail before routes are served
- Refresh, logout, and me use a separate PostgreSQL jti blacklist and safe profile
- Login stamps last_login only after a successful check and throttles repeated attempts
- Audience-aware mint, verify, refresh, and backend guard keep frontend tokens compatible
- Cabana mounts raw admin login, list schema, and record list behind admin.jwt.secret
- Framework migration seeds Winter backend users and developer/publisher roles