Data Deletion Policy
Last updated: 2026-04-01
Scope
This document covers two deletion scenarios:
- Organization offboarding — a tenant (brokerage) leaves the platform entirely
- Individual user removal — a single broker leaves an org that remains active
All business data (contacts, buildings, owners, call lists, activities) is org-scoped. It is entered and owned by the brokerage, not sourced from third parties. Individual contacts do not have accounts and are not data subjects with direct platform access.
1. Organization Offboarding (Full Purge)
When an org cancels their account, delete all data keyed to their organization_id.
Deletion order (respects FK constraints)
-- Replace $1 with the organization_id (bigint)
BEGIN;
-- Junction / child tables first
DELETE FROM contact_activities WHERE organization_id = $1;
DELETE FROM contact_owner_roles WHERE organization_id = $1;
DELETE FROM landlord_broker_assignments WHERE organization_id = $1;
DELETE FROM brokerage_firm_broker_assignments WHERE organization_id = $1;
DELETE FROM building_electrical WHERE organization_id = $1;
DELETE FROM building_addresses WHERE organization_id = $1;
DELETE FROM building_metrics WHERE organization_id = $1;
DELETE FROM comp_leases WHERE organization_id = $1;
DELETE FROM import_jobs WHERE organization_id = $1;
-- Core entity tables
DELETE FROM contacts WHERE organization_id = $1;
DELETE FROM buildings WHERE organization_id = $1;
DELETE FROM owner_lookup WHERE organization_id = $1;
DELETE FROM tenant_lookup WHERE organization_id = $1;
DELETE FROM brokerage_firm_lookup WHERE organization_id = $1;
-- Org config / auth
DELETE FROM api_keys WHERE organization_id = $1;
DELETE FROM user_org_memberships WHERE organization_id = $1;
-- Audit log — anonymize actor, keep action history for compliance
UPDATE audit_log
SET actor_user_id = 'deleted-org',
details = jsonb_set(details, '{org}', '"redacted"')
WHERE organization_id = $1;
-- Error log
DELETE FROM error_log WHERE organization_id = $1;
-- Finally, the org itself
DELETE FROM organizations WHERE id = $1;
COMMIT;
Post-deletion checklist
- Confirm row counts are zero for the org across all tables
- Revoke any BI/read-only database users created for the org
- Remove org from Clerk (via Clerk dashboard or API)
- Log the deletion in an internal record (who requested, date, ticket #)
2. Individual User Removal
When a single broker leaves an org that stays active, the business data stays with the org. Only user-specific references need cleanup.
Steps
-
Remove org membership
DELETE FROM user_org_memberships WHERE user_id = $1 AND organization_id = $2; -
Remove from Clerk — delete or deactivate the user in Clerk dashboard
What stays with the org
All business data — contacts, buildings, owners, call lists, comps, activities, and import history — belongs to the organization. Brokers enter this data as part of their work for the brokerage. It is not personal data subject to deletion on departure. The created_by column is retained as an internal audit trail.
Audit Log Retention
Audit logs are retained for 7 years per the data retention policy (see migration 000018). After retention expiry, pg_cron purges rows automatically. For org offboarding, audit rows are anonymized (not deleted) to preserve the compliance trail.
Requesting Deletion
Deletion requests should be submitted to the platform admin. Log every request with:
- Requester name and role
- Organization affected
- Date of request
- Date completed
- Whether full purge or user removal