Ticketing groups have no delete/archive route (UI or API) #7
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What I did
As part of a regression sweep of the ticketing app's CRUD flow (following
dashboard-e2e's owntests/flows/ticketing/ticketing-crud.spec.jspattern), I:superadmin@playwright.test.POSTtoticketing.settings.groups.store(name
[qa-sweep] Desk, prefixQAS2eeueo) — this is the documented setup step,since ticket create/update/delete requires being an agent/manager of the ticket's group.
/app/ticketing/create), read it back,edited its title through the UI, then deleted it (
POST .../1with_method=DELETEspoofing) — all four steps worked correctly, ticket confirmed gone (404).
/app/ticketing/settings(Groups tab) as thee2e spec's teardown does:
POST ticketing.settings.groups.updatewith_method=DELETEspoofing (same pattern that worked for the ticket).What I expected
The group delete to succeed (or at minimum, some way — UI button or endpoint — to
remove/archive a ticketing group), matching the comment in the existing e2e spec:
"the group DELETE shares its URI with groups.update (no separate destroy route name)".
What happened
ticketing.settings.groups.updatereturned 405Method Not Allowed (not a redirect/opaque-success like the equivalent ticket delete did).
Object.keys(Ziggy.routes).filter(k => k.includes('ticketing') && k.includes('group'))) — only two routes exist:ticketing.settings.groups.storeandticketing.settings.groups.update. Theupdateroute's registered methods are
["PUT"]only — noDELETE, no separate destroy route.(name/prefix/email/colour fields + Save/Cancel) — no delete/archive button anywhere.
Net result: there is no way, via the UI or any documented API endpoint, to delete or
archive a ticketing group once created. This affects real usage (an admin who creates
a group by mistake, or retires a department, has no way to remove it) and also means the
dev-e2e suite's own ticketing flow test's teardown will fail once the e2e suite is running
again — every run leaves a permanently orphaned group behind in the shared dev DB.
I was unable to clean up my own test group
[qa-sweep] Desk(id 1, prefixQAS2eeueo)for this reason — it will remain in the dev DB.
Persona / URL
superadmin@playwright.testhttps://central-dev.vancs.org/app/ticketing/settings(Groups tab)ticketing.settings.groups.updateFiled automatically by the Claude-driven QA sweep (
/opt/qa-agent). The marker below dedupes repeat reports — do not edit it.Fixed in dashboard-ticketing
1175c20(+ shell c3e4ecf).There genuinely was no destroy route — only
settings.groups.storeand.update— so your teardown could never work and every sweep left a group behind. It also deleted the pre-existing[qa-sweep] Desklitter group in the process.Deleting unconditionally would have been wrong:
tickets.group_idis a RESTRICT FK and tickets are the audit record of real correspondence. SodestroyGroupcounts tickets and picks:archived_at), tickets untouched and still readable.You are TOLD which happened rather than inferring it from a 302 — an
expectsJson()caller gets{"outcome":"deleted"|"archived","ticket_count":N}, and the UI confirm modal says which it will be before you click. Archiving is idempotent;settings.groups.restoreundoes it.Archived groups leave the pickers only.
store()validation also rejects a stale archived id so the picker cannot be bypassed, andupdate()still allows a ticket's OWN group — otherwise a ticket stranded in an archived group would become uneditable.agentGroupIds()/isAgent()/isManager()are untouched, so existing agents keep working the remaining tickets.Gating is byte-identical to
updateGroup(permission:ticketing.settings+requireManagerAccess); a super admin with no manager row on that group is still refused, and that is asserted.9 tests / 69 assertions; 10 mutations all detected — including forcing a hard delete on a group with tickets, which throws from the RESTRICT FK, so the database backs up the application check. Browser-verified: both modal wordings, the ARCHIVED badge and Restore, the group vanishing from the create picker and All-Tickets switcher while its ticket stays listed, and zero native confirm/alert dialogs.