# Account and data deletion completed within disclosed timeframe

- **Pattern:** `ab-000478` (`app-store-privacy-data.data-handling.deletion-timeframe-compliance`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000478
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000478)

## Why it matters

GDPR Art.17 requires that deletion requests be completed — not just acknowledged — within 30 days of a verified request. CCPA §1798.105 has the same 45-day window. Apps that soft-delete (set a `deleted_at` timestamp) without a scheduled hard-delete job leave personal data in the database indefinitely, making every policy claiming 'data deleted upon request' a false statement. Equally critical: third-party analytics and ad SDKs retain user data independently — if your deletion flow does not call their opt-out or data-deletion APIs, that data persists in external systems even after your database is clean.

## Severity rationale

High because a deletion mechanism that does not complete within the regulatory timeframe creates direct GDPR Art.17 and CCPA §1798.105 liability regardless of intent.

## Remediation

Implement deletion as a multi-step process: immediately revoke auth and sessions, queue a hard-delete job, execute within your stated timeframe. Call data deletion on all third-party services at the same time:

```ts
// Amplitude
amplitude.reset(); // Clears user ID and device ID
// For full deletion, use Amplitude's Privacy API
```

Keep your privacy policy's stated timeframe consistent with actual implementation — if you queue deletions, say '30 days' in the policy, not 'immediately.' Ensure your background deletion job actually runs and monitor it: a stalled queue means users who requested deletion are not being deleted, which is an active compliance failure.

## Detection

- **ID:** `deletion-timeframe-compliance`
- **Severity:** `high`
- **What to look for:** Count all relevant instances and enumerate each. Look for deletion timeframe declarations in the privacy policy (`privacy-policy.md`, `PRIVACY.md`, `docs/legal/privacy.md`). Search for wording like "deleted within X days", "within 30 days", "within 90 days", "immediately deleted". Then check the backend deletion implementation: is deletion immediate (synchronous DB delete) or queued (async job, soft-delete with a scheduled hard-delete)? Look for: soft-delete patterns (`deleted_at TIMESTAMPTZ`, `is_deleted BOOLEAN`, `status = 'pending_deletion'` in schema files or migrations); background job schedulers that process deletions (cron jobs, queued tasks, Supabase Edge Functions triggered by a schedule); any deletion queue table (`deletion_requests`, `pending_deletions`). Flag if the privacy policy states immediate deletion but the code only soft-deletes. Flag if a long timeframe (>90 days) is used when regulations like GDPR require responses within 30 days of a verified request. Also check whether third-party services (analytics, crash reporting, ad networks) are also instructed to delete user data — look for SDK calls like `Amplitude.getInstance().setOptOut(true)` or equivalent.
- **Pass criteria:** The deletion mechanism (immediate or queued) matches what the privacy policy states. At least 1 implementation must be verified. If queued, the timeframe is within regulatory requirements (≤30 days for GDPR). Third-party data deletion is addressed.
- **Fail criteria:** Privacy policy claims immediate deletion but code uses a 90-day soft-delete queue; GDPR compliance claimed but no mechanism to complete deletion within 30 days; third-party analytics/ad SDKs not instructed to delete user data on account deletion.
- **Skip (N/A) when:** App has no user accounts.
- **Detail on fail:** `"Privacy policy states 'data deleted immediately upon request' but account deletion only sets deleted_at timestamp — background hard-delete job not found in codebase"` or `"Account deletion API deletes auth record but does not call analytics SDK opt-out or data deletion — third-party data persists"`
- **Remediation:** GDPR, CCPA, and App Store policies all require deletion to be completed and effective, not just acknowledged.
  1. Implement deletion as a multi-step process: (1) immediately revoke auth/session, (2) queue a hard-delete job, (3) execute within your stated timeframe
  2. Call data deletion on all third-party services:
     ```ts
     // Example: Amplitude
     amplitude.reset(); // Clears user ID and device ID
     // For full deletion, use Amplitude's Privacy API
     ```
  3. Keep your privacy policy's stated timeframe consistent with your actual implementation
  4. For GDPR, ensure deletion can be triggered by a user request within 30 days

## External references

- gdpr Art.17
- ccpa §1798.105
- gdpr Art.12

Taxons: regulatory-conformance, data-integrity

HTML version: https://auditbuffet.com/patterns/ab-000478
