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.