W015: Delete organization
Tears down a tenant organization and all its data. Triggered from the Organization page by the owner. This is the most destructive workflow in the platform; everything in the tenant goes, GCS objects included.
Steps
-
Reconfirm the caller is the owner. Authorization is enforced at the request boundary; the workflow re-checks because the blast radius is total.
-
Purge tenant rows in dependency order. Call each component's delete ops explicitly rather than relying on FK CASCADE. The order: PO receipts and items → PO headers → WO receipts and items → WO headers and recipe snapshots → SO documents → SO items, notes → SO headers → materials ledger entries → finished-goods ledger entries → BOM items → BOMs → contacts links and methods → contacts → SO channels and status types → PO and WO status types → SO fulfillment status types → customers (types, segments, brokers) → vendors → SKUs (types) → materials (types) → locations → organization settings. Each delete runs against this tenant only.
-
Delete the organization row. Call
Platform.deleteOrganizationonce the tenant tables are empty. -
Remove the org's GCS folder. Best-effort; failure is logged and does not roll the transaction back.
Returns
Nothing.
Business rules
- Owner only. Admins and members cannot delete the organization.
- Firebase users are not deleted. They keep their identities and may still belong to other orgs.
- Single-purpose multi-component sweep. This is the only L3 workflow that destructively touches every domain. The explicit ordering inside step 2 is the contract; FK CASCADE is not relied on so the dependency order stays under our control.
- Atomic. Steps 2 and 3 share a single transaction. GCS cleanup runs after the transaction commits and is best-effort.
Errors
ValidationError. The caller is not the owner.