- settingsSectionOf returns the current entry's category group (null for one-entry categories)
- SettingsPanel mirrors the plugin side menu, collapse included
- AppShell shows it on settings forms and settings-linked controllers without own navigation
- docs/backend/settings.md describes moving between settings pages
The docker stage must refuse a tree that drops TestRolesCodeDeclaredCodeRefused or TestActionExtensionOutranked.
Co-authored-by: Cursor <cursoragent@cursor.com>
- cabana, not the contributor, applies guardOutranked before a contributed Run
- A contribution to summercms.cabana.users is 403 user.outranked when the target outranks the caller
Co-authored-by: Cursor <cursoragent@cursor.com>
- Roles create and update refuse a submitted code that code-declared grants attach to
- compileActionExtensions wraps contributed Administrators Runs with guardOutranked
- Prove both holes on Postgres; keep the boot smoke callable with a superuser principal
Co-authored-by: Cursor <cursoragent@cursor.com>
- 19.6.1-VALIDATION.md: per-task map green, Wave 0 ticked with the files
as built, wave_0_complete true
- deferred-items.md: lagoon's model validator skips string min/max;
granted does not expand a held leading wildcard
Fail-closed stages go, docker, admin, docs and sc1 with the detectors of
check-phase19.5.sh: every Docker-free and Postgres rule test by required
name, the SC-1 regression tests, the vitest and browser files, the
OpenAPI and dist checks, the consuming-application name check and the
SC-1 commit check. --all reports NOT RUN docker only without a daemon
(a failure with PHASE1961_REQUIRE_DOCKER=1); --self-test proves the
detectors and that rule.
- trigger.test.ts: triggerState and applyTriggers
- FormView: disable, absent-controller and hide-tab backstops, the live
announcement
- PermissionEditorField and formState: record-locked rows, notes and the
payload omission, record lock over request lock, read-only screens
- PreviewView: hide removes, disable shows no note
- browser record-actions-wrap at 1024px; vitest.browser.config.ts gains
the Tailwind plugin so the footer is laid out with the admin's CSS
- TestFieldTriggerBoot (-short): every compileTrigger and checkTriggers
refusal names controller, field and trigger; disable and hide reach the
localized schema; settings and relation forms refuse the key
- TestPermissionRecordLocks (-short): the save rule in radio and checkbox
modes, no lock lookup on create, meta only for stored records with a
provider
- TestRolesCodeDeclaredLocks (Postgres): locked_by_code grants on a role,
a save without them, locked_self on the own record
- TestAdministratorsLastSuperuser (D-09): A and B reduce each other on the
five paths while a test transaction holds the guard's advisory lock until
pg_locks shows both requests waiting; one succeeds, one gets last_superuser
- TestAdministratorsLastSuperuserConcurrent: ten unsynchronized rounds
- TestAdministratorsLifecycle (D-10) and TestAdministratorsRevocation (D-12),
two-row bulk selections included
- TestActionExtensionBoot (-short) and TestActionExtensionRun (D-14, D-15)
- TestRolesLifecycle (D-16, D-17), TestRolesPermissionCeiling (D-07)
- TestBackendScreensActivation (-short, D-01, D-04)
actionDB returned the Unscoped instance of the action's session, whose
conditions accumulate, so a bulk activate, deactivate or restore of two
applicable rows wrote only the first (the second update matched
"id = A AND id = B") while still counting it. A bulk deactivate
therefore left the other administrators active and signed in (D-10,
D-12). actionDB now ends with a plain Session, so every query starts
anew. Found by TestAdministratorsLifecycle.
The form's min:4 rule never applied: the model validator skips string
min and max. storePassword now refuses a typed password under 4
characters with a 422 on the field, next to the 72-byte check (D-11).
Found by TestAdministratorsPasswordAndIdentity.
- administrators_harness_test.go: newScreensEnv with extra plugins, seedAdmin,
seedRole, login, isolateSuperusers, row snapshots and error decoders; the
harness moved out of backend_screens_smoke_test.go and gained cleanup
- export_test.go: SuperuserLockKey for the last-superuser race
- TestAdministratorsSuperuserFlag (D-05) through the assembled handler
- fields.yaml trigger (action disable|hide, field, condition checked|unchecked) compiled to FormField.Trigger
- boot errors for malformed triggers, controlling fields that are not a switch or checkbox, and triggers in repeater rows, settings and relation forms
- Administrators permissions overrides are disabled while Superuser is on (D-06)
- SPA: trigger.ts (triggerState, applyTriggers), FORM_TRIGGER_NOTES, the trigger note in FormField, FormView tabs/banner/payload after triggers, PreviewView hide only
- regenerated admin OpenAPI and schema.d.ts; rebuilt modules/boardwalk/dist; docs and README
- cabana.PermissionRecordLock and the optional PermissionRecordLockProvider
- RecordMeta.PermissionLocks (meta.permissionLocks) on show and save responses, notes localized
- save rule: a record-locked code keeps its stored value, a differing present value is 403
- Roles lock code-declared grants (locked_by_code); Administrators lock every override on your own record (locked_self)
- SPA: FORM_PERMISSION_LOCKS, locked codes never sent, record-locked rows in the permission editor
- regenerated admin OpenAPI and schema.d.ts; docs and README
- Settings -> System -> Roles (summercms.cabana.roles, backend.manage_roles,
order 110): name, code slugged from the name, description, checkbox
permission editor with the editor's ceiling
- system roles (is_system or code-declared grants) keep their code and
cannot be deleted; a role any admin holds (deleted ones included) cannot
be deleted, the refusal names the role and the count
- role codes unique among roles
- activate, deactivate and restore as record and bulk actions; delete is
the soft delete through deleted_at, never a hard delete
- deleted admins listed and opened (unscoped), deleted/deactivated row
states, Deleted filter (hide / only), preview status hint
- deactivate and delete bump tokens_valid_after; activate and restore do not
- self delete and self deactivate refused; outranking and last active
superuser guarded on delete, deactivate and bulk rows (whole selection
rolls back)