# Cliq data retention and legal-hold policy

Policy version: `2026-07-22-v1`  
Effective date: 22 July 2026  
Production source of truth: Supabase project `gormehvuezrienkgmvav`

## Purpose and scope

This policy defines the maximum ordinary retention period for personal,
health-adjacent, operational, clinic-verification and financial data processed
by Cliq. It applies to production PostgreSQL records, Supabase Storage objects,
notification delivery records and operational logs.

Cliq is a discovery, booking and queue-management platform. It is not a clinic
and does not diagnose or treat patients. A clinic remains responsible for its
own statutory medical record. Cliq nevertheless retains the minimum booking
and queue evidence needed to operate the service, handle complaints and
support lawful claims.

The database catalog `public.data_retention_policies` is the executable source
of truth. Privacy copy and operational documentation must be reconciled to the
same policy version whenever a period changes.

## Retention matrix

| Data category | Ordinary retention | Expiry action | Account-deletion behavior |
| --- | ---: | --- | --- |
| Auth identity, sessions, direct profile identity, device registration | Until track-scoped account deletion | Delete immediately | Deleted immediately for the selected patient or clinic track |
| Raw symptom text and structured triage payload | 90 days | Delete | Delete immediately for a deleted patient track unless a lawful hold applies |
| Precise arrival latitude/longitude, accuracy and distance | 30 days | Delete | Delete immediately for a deleted patient track unless a lawful hold applies |
| In-app notifications, push outbox and provider delivery evidence | 180 days | Delete | Delete immediately for that account track |
| Inactive/denied push-device registration | 90 days after disable/last use | Delete | Delete immediately for that account track |
| Booking, appointment, queue and service-status history | 5 years after terminal status | Delete; de-identify first if the account is deleted | Direct identity is removed immediately; necessary service history remains under a de-identified subject reference |
| Clinic rating and review | Until patient deletion, and no longer than the linked 5-year booking period | Delete | Delete immediately when the reviewer deletes the patient track |
| Clinic/professional application, licence and verification evidence | While active, then 5 years after suspension/closure | Delete payload and Storage evidence | A deleted owner account does not transfer ownership; an ownerless clinic is suspended and evidence follows this period |
| Invoice, tax, billing event, payment and payment-slip evidence | 7 years after issue/payment/void | Delete | Retained under the clinic/business record for the stated period |
| Consent and account-deletion receipt | 5 years after the event | Delete or retain only a minimised hash until expiry | Direct identifiers are removed; the minimised compliance receipt remains |
| General operational events | 1 year | Delete | Actor UUID is replaced by a subject hash during deletion where applicable |
| Audit trail | 5 years; financial audit evidence 7 years | Delete or de-identify | Direct account access and identity are removed immediately |

These are maximum ordinary periods, not permission to retain every field for
the full period. Data that is no longer needed may be removed earlier when it
is safe and lawful to do so.

## Legal holds

A legal hold temporarily prevents automated expiry only when data is needed
for a documented dispute, complaint, fraud/security investigation, tax or
regulatory requirement, or preservation of a legal claim.

- Holds are created and released only by a production platform admin through
  audited RPCs.
- Every hold requires a scope, category, reason, opener and optional expiry.
- A hold may target all data, one clinic, one de-identified subject or one
  record. Broad global holds require an explicit reason.
- Expired or released holds stop blocking the next daily retention run.
- A hold does not restore app access, reactivate a deleted account, or expose
  retained records to normal product screens.
- The privacy contact reviews open holds periodically and records the release
  reason as soon as preservation is no longer required.

## Automated enforcement

Migration `202607220001_data_retention_and_legal_holds.sql` installs:

- the versioned policy catalog;
- legal-hold tables and audited create/release RPCs;
- legal-hold guards for raw triage, precise location and reviews;
- the service-role-only `run_data_retention` processor;
- a durable Storage deletion queue instead of unsafe direct writes to
  `storage.objects`;
- a read-only public policy RPC and an Admin retention dashboard RPC; and
- exact retention details on future account-deletion receipts.

Firebase function `dailyDataRetention` runs at 03:30 Asia/Bangkok. It calls the
production processor in bounded batches, deletes queued Storage objects using
the Supabase Storage API, retries transient failures with backoff and writes a
summary to `public.data_retention_runs` plus the private audit log.

The processor is idempotent, protected by an advisory lock and callable only
with the production service role. No mobile or browser client receives that
credential.

## Operating responsibilities

- Product/privacy owner: approves policy wording, responds to user requests
  and decides whether a documented legal hold is required.
- Platform admin: creates/releases holds through audited workflows and reviews
  failed Storage deletions or failed scheduled runs.
- Engineering: keeps the migration mirrors byte-identical, monitors the daily
  function, verifies policy/privacy copy after any schema change and never
  performs ad-hoc production deletion as a substitute for this workflow.
- Clinic: remains responsible for clinical records it creates or is legally
  required to maintain outside Cliq.

## Monitoring and incident handling

- A completed run records counts only; it must not log names, emails, symptom
  text, coordinates, document contents or Storage paths.
- A Storage failure records the queue ID, category, attempt number and compact
  provider error only. Object paths are not written to Firebase logs.
- A failed item retries with bounded exponential backoff and becomes `failed`
  after 20 attempts for manual, audited resolution.
- Any accidental over-retention, premature deletion or bypass of legal hold is
  handled as a privacy incident under the incident runbook.

## Legal and platform references

- Thai Revenue Code section 87/3: VAT reports, tax invoices and supporting
  records must be retained for at least five years and may be required for up
  to seven years: <https://www.rd.go.th/5209.html>
- Thai health-service inspection guidance includes a five-year medical-record
  retention baseline for clinics. Cliq uses five years for its narrower
  booking/queue evidence while leaving the clinic's statutory medical record
  responsibility with the clinic:
  <https://mrd.hss.moph.go.th/mrd1_hss/wp-content/uploads/2024/05/2.-%E0%B9%81%E0%B8%9A%E0%B8%9A%E0%B8%95%E0%B8%A3%E0%B8%A7%E0%B8%88%E0%B9%80%E0%B8%A2%E0%B8%B5%E0%B9%88%E0%B8%A2%E0%B8%A1%E0%B9%80%E0%B8%A7%E0%B8%8A%E0%B8%81%E0%B8%A3%E0%B8%A3%E0%B8%A1-up-date-%E0%B8%84%E0%B8%A3-2.pdf>
- Apple requires account data and user-generated content to be deleted unless
  retention is legally required, and users must be told what remains:
  <https://developer.apple.com/support/offering-account-deletion-in-your-app/>
- Google Play allows justified fraud/security/regulatory retention but
  requires the practice to be clearly disclosed:
  <https://support.google.com/googleplay/android-developer/answer/13327111>

This is Cliq's operational baseline, not a representation that external legal
counsel has approved every period. Before public launch or entry into a new
jurisdiction, the product owner must obtain Thai privacy/health/tax counsel
review and record any approved change through a new migration and policy
version; production code must not be changed from chat advice alone.
