Activity delete gating and staff overrides
For record keeping, activities are archived internally rather than deleted. Before archiving, the API evaluates delete gates and returns structured issues similar to enrolment gates.
Gates evaluated
Section titled “Gates evaluated”| Gate | Severity | When |
|---|---|---|
| Live enrolments | blocking | Waitlist rows, or active/casual/trial enrolments whose period still includes now |
| Enrolment history | warning | Any enrolment row exists for the activity (including ended or dropped) |
Counts appear in each issue’s meta (live_count, total_count).
Staff overrides
Section titled “Staff overrides”Staff with the correct permission can attest overrides by sending staff_overrides: a map from issue code to a truthy value.
Rules:
- Overrides apply per issue
code. - The server checks
required_permissionfor that code. If the user lacks it, the issue is replaced withenrollments.insufficient_permission_to_override(meta.original_coderecords the gate). - Blocking issues are dropped when attested and permitted.
- Warnings on delete also require attestation before
can_proceedis true (stricter than enrolment create, where warnings do not block).
Permissions on Activity:
| Gate area | Permission codename |
|---|---|
| Live enrolments | activities.override_delete_active_enrolments |
| Enrolment history | activities.override_delete_enrolment_history |
Preview vs enforce
Section titled “Preview vs enforce”Delete preview (HTTP 200)
Section titled “Delete preview (HTTP 200)”POST .../activities/{id}/delete-preview/ returns:
issues: annotated issue objects (same shape as problemerrors[]).can_proceed:truewhen there are no blocking issues and no unattested overridable warnings.
The preview does not archive the activity and does not apply staff_overrides.
Delete with overrides (enforce)
Section titled “Delete with overrides (enforce)”POST .../activities/{id}/delete/ accepts an optional body:
{ "staff_overrides": { "activities.delete.active_enrolments": true } }On success the API returns 204 and sets archived_at. If gates still block, the API responds with 422, Content-Type: application/problem+json, and problem type:
https://docs.keja.co/troubleshooting/status-codes/activities.delete_gates_failed
See Activity delete gates failed.
Legacy DELETE
Section titled “Legacy DELETE”DELETE .../activities/{id}/ still archives when allowed but does not accept staff_overrides. It blocks on live enrolments only (not on enrolment history warnings). Prefer POST .../delete/ for staff UI.
List behaviour
Section titled “List behaviour”Archived activities are hidden from default staff lists when the client passes archived=false on GET .../activities/. Omit archived to return both active and archived rows.
Client integration tips
Section titled “Client integration tips”- Open the delete dialog only after calling delete-preview (or refresh preview when the dialog opens).
- Drive checkboxes from
can_overrideandrequired_permission, not fromdetailtext. - After a successful delete, refetch activity lists with
archived=false.