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); unconfirmed PENDING uploads pruned by the existing cron within [7] days |
| 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) |
| 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) | [VERIFY plan retention, typically 1–30 days] | Provider TTL |
| Consent/acceptance records (ToS version, timestamp) | Life of account + [2] years (defense of legal claims) | Scheduled purge |
| Billing records [future] | [7] years (tax law) | Scheduled purge |
| DMCA notices, abuse reports | [3] years | Scheduled purge |
| Database backups (Neon PITR) | [VERIFY window, e.g., 7–30 days] | 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.