ADR-002: Soft Deletes and Audit Strategy

Status: Accepted Owner: @bilal @deen Date: 2025-12-06

Context

Envo handles property maintenance records with long-term value. GDPR requires ability to delete personal data on request. We need audit trails for compliance and debugging.

Requirements

  1. Never accidentally lose data
  2. Maintain referential integrity
  3. Support GDPR deletion requests
  4. Track who changed what and when
  5. Keep audit overhead reasonable

Decision

Soft deletes with targeted event logging.

Soft Delete Implementation

All primary entities have deleted_at TIMESTAMPTZ DEFAULT NULL.

Tables with soft delete: organisations, properties, tenants, issues, vendors, user_organisation_access

Tables WITHOUT soft delete: users (Supabase Auth), events (audit, never deleted), attachments (hard-deleted for GDPR)

All queries must filter: WHERE deleted_at IS NULL. Views created for convenience.

Audit Events

Event TypeTriggerData Captured
issue_createdNew issueissue_id, channel, category
issue_status_changedStatus updateold_status, new_status
vendor_assignedVendor linkedissue_id, vendor_id
vendor_acceptedVendor acceptsissue_id, vendor_id
issue_completedResolutionresolution_notes
notification_sentSMS/emailchannel, recipient
user_loginAuth eventuser_id
user_access_granted/revokedAccess changeuser_id, org_id, by
csv_importBulk importrecord_count, user_id

GDPR Deletion Process

  1. Soft delete tenant record
  2. Retain issue records (property history, not personal data)
  3. Nullify personal data on issues if required ([REDACTED])
  4. Hard delete attachments containing personal images
  5. Log deletion event

Timestamps

All tables include created_at and updated_at (auto-updated via trigger). All timestamps stored as UTC (TIMESTAMPTZ), converted to user timezone in application layer.

Consequences

Positive

  • Data never accidentally lost
  • Clean audit trail for compliance
  • GDPR-compliant deletion path

Negative

  • All queries must remember WHERE deleted_at IS NULL
  • GDPR deletion is multi-step