1# Offboarding & Data Export 2 3Plyr.fm provides tools for users to export their data and manage their presence on the platform. This document outlines the architecture and workflows for these features. 4 5## Data Export 6 7Users can download a ZIP archive containing all their uploaded tracks in their original format. 8 9### Workflow 10 111. **Initiation**: 12 * User clicks "Export" in the portal. 13 * Frontend calls `POST /exports/media`. 14 * Backend creates a `Job` record (type: `export`) and starts a background task. 15 * Returns an `export_id`. 16 172. **Processing**: 18 * Backend queries all tracks for the user. 19 * Backend streams files from R2 storage into a ZIP archive in memory (using a stream buffer to minimize memory usage). 20 * As tracks are processed, the job progress is updated in the database. 21 * The final ZIP file is uploaded to R2 under the `exports/` prefix. 22 * The R2 object is tagged with `Content-Disposition` to ensure a friendly filename (e.g., `plyr-tracks-2024-03-20.zip`) upon download. 23 243. **Completion & Download**: 25 * Frontend polls the job status via SSE at `/exports/{export_id}/progress`. 26 * Once completed, the job result contains a direct `download_url` to the R2 object. 27 * Frontend triggers a browser download using this URL. 28 29### Storage & Cleanup 30 31* **Location**: Exports are stored in the `audio` bucket under the `exports/` prefix. 32* **Retention**: These files are temporary. An R2 Lifecycle Rule is configured to **automatically delete files in `exports/` after 24 hours**. 33 * This ensures we don't pay for indefinite storage of duplicate data. 34 * Users must download their export within this window. 35 36## Account Deletion 37 38Users can permanently delete their account and all associated data. This is a synchronous, interactive process. 39 40### What Gets Deleted 41 42#### Always Deleted (plyr.fm infrastructure) 43 44| Location | Data | 45|----------|------| 46| **PostgreSQL** | tracks, albums, likes (given), comments (made), preferences, sessions, queue entries, jobs | 47| **R2 Storage** | audio files, track cover images, album cover images | 48 49#### Optionally Deleted (user's ATProto PDS) 50 51If the user opts in, we delete records from their Personal Data Server: 52 53| Collection | Description | 54|------------|-------------| 55| `fm.plyr.track` / `fm.plyr.dev.track` | track metadata records | 56| `fm.plyr.like` / `fm.plyr.dev.like` | like records | 57| `fm.plyr.comment` / `fm.plyr.dev.comment` | comment records | 58 59> **Note**: ATProto deletion requires a valid authenticated session. If the session has expired or lacks required scopes, ATProto records will remain on the user's PDS but all plyr.fm data will still be deleted. 60 61### Workflow 62 631. **Confirmation**: User types their handle to confirm intent 642. **ATProto Option**: Checkbox to opt into deleting ATProto records 653. **Processing**: 66 - Delete R2 objects (audio, images) 67 - Delete database records in dependency order 68 - If opted in: delete ATProto records via PDS API 694. **Session Cleanup**: All sessions invalidated, user logged out 70 71### API 72 73``` 74DELETE /account/ 75``` 76 77**Request Body**: 78```json 79{ 80 "confirmation": "handle.bsky.social", 81 "delete_atproto_records": true 82} 83``` 84 85**Response** (success): 86```json 87{ 88 "deleted": { 89 "tracks": 5, 90 "albums": 1, 91 "likes": 12, 92 "comments": 3, 93 "r2_objects": 11, 94 "atproto_records": 20 95 } 96} 97``` 98 99### Important Notes 100 101- **Irreversible**: There is no undo. Export data first if needed. 102- **Likes received**: Likes from other users on your tracks are deleted when your tracks are deleted. 103- **Comments received**: Comments from other users on your tracks are deleted when your tracks are deleted. 104- **ATProto propagation**: Even after deletion from your PDS, cached copies may exist on relay servers temporarily.