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