Estimate: 70m · Type: code
Service + repository for permanent delete with subtree cascade. Add workItemsService.deleteWorkItem(id, ctx): permission-gated (a delete capability — mirror Jira "Delete Issues"; reuse the project-admin / 6.4 gate), in ONE $transaction: resolve the full descendant set (the kind-parent tree), remove all their work-item links (from + reciprocal), delete the rows (children-before-parent / DB cascade), and write an audit record (an activity/audit entry — the rows themselves are gone). Translate races (already-deleted / concurrent move) to typed errors. Repo methods are single-op (workItemRepository.deleteSubtree / findDescendantIds); service owns the transaction.
deleteWorkItem permanently removes the item + ALL descendants + their links in one transaction; permission-gated; typed errors for races; auditable.WorkItemNotFoundError).lib/services/workItemsService.ts (archiveWorkItem shape to mirror; updateWorkItem tx pattern), lib/repositories/workItemRepository.ts (descendant/forest reads), workItemLinkRepository.delete; CLAUDE.md 4-layer + lock-before-read-derived