music on atproto
plyr.fm
1# plyr.fm Developer Context
2
3**music streaming on AT Protocol**
4
5## Reminders
6- i am already hot-reloading the backend and frontend. i might also have ngrok exposing 8001
7- check the justfiles. there's a root one, one for the backend, one for the frontend, and one for the transcoder etc
8
9## 🚨 Critical Rules & Workflows
10* **Read `STATUS.md` First:** Always check for active tasks and known issues.
11* **Workflow:**
12 * Use **GitHub Issues** (not Linear).
13 * **PRs:** Always create for review; never push to main directly.
14 * **Deploy:** Automated via Actions (Backend: Fly.io, Frontend: Cloudflare Pages). Never deploy locally.
15* **ATProto NSIDs:** namespaces are environment-aware via settings (e.g., `fm.plyr.dev` (dev), `fm.plyr` (prod)). **Never** hardcode outside of scripts. these are fully-qualified hostname in Reverse Domain-Name Order, not urls.
16* **Auth Security:** Session IDs live in HttpOnly cookies. **Never** touch `localStorage` for auth.
17* **Async Everywhere:** Never block the event loop. Use `anyio`/`aiofiles`.
18* **Type Hints:** Required everywhere (Python & TypeScript).
19* **Communication:** Use emojis sparingly and strictly for emphasis.
20* **DO NOT UNNECESSARILY DEFER IMPORTS.** Put imports at the top of the file where they belong. Deferred imports inside functions are only acceptable for avoiding circular imports - not for "lazy loading" or other reasons.
21
22## 🛠️ Stack & Tooling
23* **Backend:** FastAPI, Neon (Postgres), Cloudflare R2, Fly.io.
24* **Frontend:** SvelteKit (Svelte 5 Runes), Bun, Cloudflare Pages.
25* **Observability:** Logfire.
26* **`just` use the justfiles!**
27* **use MCPs** for access to external systems, review docs/tools when needed
28
29### Neon Serverless Postgres
30- `plyr-prd` (cold-butterfly-11920742) - production (us-east-1)
31- `plyr-stg` (frosty-math-37367092) - staging (us-west-2)
32- `plyr-dev` (muddy-flower-98795112) - development (us-east-2)
33
34## 💻 Development Commands
35* **Backend:** `just backend run`
36* **Frontend:** `just frontend run`
37* **Tests:** `just backend test` (run from repo root, not from backend/)
38* **Linting:** `just backend lint` (Python) / `just frontend check` (Svelte)
39* **Migrations:** `just backend migrate "message"` (create), `just backend migrate-up` (apply)
40
41## 📂 Project Structure
42```
43plyr.fm/
44├── backend/
45│ └── src/backend/
46│ ├── api/ # Public endpoints
47│ ├── _internal/ # Auth, PDS, Uploads logic
48│ ├── models/ # SQLAlchemy schemas
49│ ├── storage/ # R2 and filesystem adapters
50│ └── utilities/ # Config, helpers
51├── frontend/ # SvelteKit app
52│ ├── src/routes/ # Pages (+page.svelte, +page.server.ts)
53│ └── src/lib/ # Components & State (.svelte.ts)
54├── scripts/ # Admin scripts (uv run scripts/...)
55├── docs/ # Architecture & Guides
56└── STATUS.md # Living status document
57```
58
59this file ("AGENTS.md") is symlinked to `CLAUDE.md` for maximal compatibility.