Far — Data Retention & Deletion Policy
DRAFT — requires review by qualified counsel before publication. Dual-purpose: the user-facing schedule linked from the Privacy Policy §8, and the internal operating rule. If a row here doesn't match the code, the code is the bug.
Retention schedule
| Data | Retained | Deleted when |
|---|---|---|
| Account (email, name, photo ref, plan/trial state, AI-usage count) | Life of account | Account deletion — immediate hard delete |
| Trips, routes, waypoints, gear items, loadouts | Life of account or until user deletes them | User delete — immediate; account deletion cascades (verified: schema-level onDelete: Cascade) |
| Uploads (photos, GPX) — DB rows | Life of account | Cascade on account deletion |
| Uploads — R2 objects | Life of account | Removed synchronously on account deletion (Session 30). Known gap, not yet built: an unconfirmed PENDING upload (presigned but never confirmed) has no scheduled cleanup today — see docs/backlog.md. |
| Weather forecast cache | Per-trip cache | TTL expiry; cascade with trip |
| AI response caches (plans, summaries, alerts, permits) | Short-lived server cache | TTL expiry (unstable_cache) |
| Far AI conversation history | Life of account or until user clears it (Far AI panel → trash icon) | User-cleared — immediate hard delete; account deletion cascades |
| Rate-limit keys (email, IP in Upstash) | Hours | Automatic TTL |
| Auth verification tokens (magic links) | 24 h, single-use | Automatic expiry |
| Sessions | JWT, client-side | Cookie expiry; note: no server-side revocation short of secret rotation |
| Server/edge logs (Vercel) | Provider's standard operational retention, not a custom schedule we control | Provider TTL |
| Consent/acceptance records (ToS version, timestamp) | Life of account + 2 years (defense of legal claims) | Scheduled purge |
| Billing records (future, once payments launch) | 7 years (tax law) | Scheduled purge |
| DMCA notices, abuse reports | 3 years | Scheduled purge |
| Database backups (Neon PITR) | Provider's standard rolling backup window, not a custom schedule we control | Rolling window; deleted data ages out of backups automatically |
Account deletion — user-facing commitments
- Available in-product (Settings → Delete account), no email required, no retention dark patterns; also honored by email request for verified account holders.
- Immediate effect: sign-in disabled, R2 objects removed, all rows cascade-deleted.
- Data ages out of rolling database backups per the provider's retention window.
- What survives deletion: nothing about your trips or gear. We may retain the minimal legal-basis records above (consent log, billing, DMCA correspondence) where law requires, keyed to a hashed identifier, not your profile.
- Public share links die with the account (token rows cascade).
Shipped Session 30: DELETE /api/me + Settings → Delete account.
Data export — user-facing commitments
Settings → Export produces a single downloadable JSON file: account info, trips/routes/
waypoints (with GPX embedded per trip as an XML string via the existing buildGpxXml),
weather cache, gear inventory/loadouts, and a signed 1-hour download
link for each confirmed upload (photos/GPX files are not embedded as binary — this
avoids bundling large or non-text files inside a JSON document). Delivered synchronously
as a download. Shipped Session 30: GET /api/me/export.
Internal rules
- New features that store personal data must add a row to this table in the same PR.
- No new data store may launch without a deletion path (account deletion's R2 cleanup, added in Session 30, is the model to follow).
- Retention timers run server-side (cron/QStash) — never rely on client action.