Scheduled account deletion

An account queued for deletion keeps its data until the date passes, then a scheduled job cancels billing, removes the external sub-account, detaches the owner and wipes every account-scoped table in dependency order.

What it is

A full teardown routine reused by the daily deletion job and by anywhere an account must be removed. Each step is independent and reported: a failed step never blocks the rest, because deleting most of an account and retrying the stragglers is better than deleting none. The linked signup is archived rather than destroyed, so the billing and contract record survives.

Also called: delete an account · close my account · data removal · offboarding

See it
Scheduled account deletion
Apr
May
Jun
Jul
Sutter Kline — 40×64 Shop
Framing
Delia Yoder — 30×40 Garage
Concrete
Ivy Brubaker — Riding Arena
Trim
Delia Yoder — Barndominium
Framing
Sutter Kline — Equipment Storage
Concrete
Framing crewConcrete crewTrim crew
A deletion result panel listing each step with a tick or a note, and the scheduled date badge on the account row. src/lib/orgDeletion.ts. Sample data — no customer information appears here.
How it works
  1. 1The platform subscription is cancelled so billing stops.
  2. 2The external CRM sub-account is deleted; a 404 counts as success.
  3. 3The owner's login is unlinked from the account — the person's account is never deleted.
  4. 4Every account-scoped table is wiped in foreign-key-safe order, then settings singletons, then the account row.
  5. 5The linked signup is archived with reason 'account_deleted'.
  6. 6The table order list is the single source of truth, imported by the migration wizard's wipe too.
Why we built it

The header states the retry philosophy directly: 'a failed step never blocks the rest (we'd rather delete most of a tenant than none and retry the stragglers on the next cron pass — the run is idempotent).' Two decisions stand out as deliberate restraint: the owner's login is unlinked, not deleted, because a person may work at more than one company; and the signup is archived rather than hard-deleted 'unlike the test-junk hard-delete route', because the billing and contract history is a record the vendor still needs after the customer leaves.

The problem
  • Partial deletions leaving orphaned rows across dozens of tables.
  • A single failing external API call blocking the entire teardown.
  • Deleting a person's login when they may work for another company on the platform.
Sound familiar?
What you get
Data is retained until the scheduled date, then removed completely.
Deletion continues even if one external step fails, and retries cleanly.
Billing history survives the account for the records that need it.

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →