Skip to content

LEGAL

Tempo data retention policy

Locked 2026-05-27 (M-AUDIT-LOG-V1 Story 8). This document lists every retention window applied to workspace data, the legal/operational reason for the window, and the cron that enforces it.

audit_events — 7 years

What: every row in the audit_events table.

Why: financial / dispute defence + GDPR audit trail. Stripe disputes can land up to ~5 years after the original charge; chasing a dispute without an audit row means the operator can't reconstruct what staff or the customer did. 7 years is the standard financial-record window and aligns with EU/CA bookkeeping rules.

Enforcement: audit-retention-tick cron runs nightly at 03:30 UTC. Deletes any row where occurred_at < now() - interval '7 years'. Pure hard delete — no archival staging area; if a workspace needs longer retention, ops can pause the cron per-workspace via env toggle (V1.5+ backlog).

Source of truth:

  • lib/audit/retention.ts (cutoff calculation + delete query)
  • app/api/cron/audit-retention-tick/route.ts (cron entrypoint)
  • vercel.jsonaudit-retention-tick schedule entry

GDPR redaction (right-to-be-forgotten)

When a customer triggers self-delete via customer_account_self_deleted or an operator runs anonymize_customer, the cascade walks every customer-shaped JSON column on the workspace and replaces PII with the sentinel '[anonymized]'. The audit ROW itself is preserved (immutability invariant + the 7-year retention above) but the embedded PII is scrubbed.

Implementation:

  • lib/audit/redact-customer.ts — pure JSON walker + audit_events query
  • M-CUSTOMERS-V1 composes this helper with the equivalent walkers for bookings.metadata, customers.notes, etc.

Other retention windows (cross-references)

These windows live in other docs but are listed here for completeness so ops has a single retention surface to consult:

DomainWindowSource
Booking proof photos (close_outcome=clean)72 hours after booking closedocs/07-operations/05-v1-optimization-pass.md
Booking proof photos (close_outcome=with_issue)Operator-controlled, retained until manual deletesame
email_queue rows90 days (purged by data-retention-tick)M-NOTIFY epic
payment_intents / refunds7 years (matches audit_events)M-PAY epic
Workspace soft-delete grace window90 days before hard-purgeM10.8
magic_link_tokens / customer_portal_otps24 hours TTL + auto-purgeM-CA epic

Operator-visible retention controls

Workspace Admins can:

  • Adjust the per-workspace data-retention setting at Settings → Data & Privacy (within bounds enforced by privacy_retention_months_updated audit events — see M10.5).
  • Trigger a manual purge for their workspace (M10.5).

Audit-event retention is NOT operator-tunable in V1; it's a platform policy. If an operator needs longer retention for a legal hold, ops disables the cron for that workspace via support workflow.