diff --git a/Agent-Context.-.md b/Agent-Context.-.md new file mode 100644 index 0000000..ab52e00 --- /dev/null +++ b/Agent-Context.-.md @@ -0,0 +1,81 @@ +# Agent Context + +| Meta | Value | +|------|-------| +| **Repo** | `xpltdco/media-rip` | +| **Language** | Python 3.12 (backend), TypeScript (frontend) | +| **Framework** | FastAPI + Vue 3 + Vite + Pinia | +| **Entry Point** | `backend/start.py` → `backend/app/main.py` | +| **Test Command** | `cd backend && pytest tests/ -v -m "not integration"` | +| **Build Command** | `docker build -t media-rip .` | +| **Upstream Port** | `8000` | +| **Database** | SQLite (aiosqlite) | +| **Last Updated** | 2026-04-04 | + +## File Index + +| Priority | File | Purpose | +|----------|------|---------| +| 1 | `backend/app/main.py` | FastAPI app + lifespan (full init sequence) | +| 2 | `backend/app/core/config.py` | Pydantic Settings (env + YAML + defaults) | +| 3 | `backend/app/core/database.py` | SQLite schema, CRUD, WAL/DELETE detection | +| 4 | `backend/app/services/download.py` | yt-dlp wrapper, ThreadPoolExecutor, playlist handling | +| 5 | `backend/app/core/sse_broker.py` | Thread-safe pub/sub for SSE events | +| 6 | `backend/app/routers/downloads.py` | Download job CRUD endpoints | +| 7 | `backend/app/routers/sse.py` | EventSource stream endpoint | +| 8 | `backend/app/routers/admin.py` | Admin panel (auth, settings, purge) | +| 9 | `backend/app/middleware/session.py` | Cookie session middleware | +| 10 | `backend/app/services/purge.py` | Scheduled cleanup service | +| 11 | `backend/app/models/job.py` | Job, JobStatus, FormatInfo models | +| 12 | `frontend/src/stores/downloads.ts` | Job state management + SSE handlers | +| 13 | `frontend/src/composables/useSSE.ts` | EventSource lifecycle + reconnect | +| 14 | `frontend/src/api/client.ts` | Fetch-based API client | +| 15 | `Dockerfile` | 3-stage multi-arch build | + +## Common Modification Patterns + +### To add an API endpoint: +1. Create/edit router in `backend/app/routers/` +2. Add models in `backend/app/models/` +3. Register in `backend/app/main.py` +4. Add frontend call in `frontend/src/api/client.ts` + +### To add a database table: +1. Add CREATE TABLE in `backend/app/core/database.py` `_create_tables()` +2. Add CRUD functions in same file +3. Write tests in `backend/tests/` + +### To modify download behavior: +1. Edit `backend/app/services/download.py` +2. yt-dlp options are built per-job in `_run_download()` +3. Format extraction in `get_formats()` + +## Gotchas + +1. **yt-dlp is sync** — runs in ThreadPoolExecutor, never share YoutubeDL instances between threads +2. **SSE broker threading** — progress hooks run in worker threads, must use `loop.call_soon_threadsafe()` to publish +3. **Network FS detection** — reads `/proc/mounts` at startup, switches SQLite journal mode accordingly +4. **Admin password** — plaintext from env var is hashed with bcrypt at startup, then cleared from memory +5. **Session modes** — `isolated` creates separate queues per browser, `shared` shows all jobs, `open` uses fixed session ID +6. **Zombie recovery** — on startup, any jobs stuck in queued/downloading are marked failed +7. **Purge protection** — active jobs (queued/extracting/downloading) are never purged even if past retention + +## Verification Commands + +```bash +# Run backend tests +cd backend && pytest tests/ -v -m "not integration" + +# Run frontend tests +cd frontend && npx vitest run + +# Lint +cd backend && ruff check . +cd frontend && npx vue-tsc --noEmit + +# Docker build +docker build -t media-rip . + +# Health check +curl http://localhost:8000/api/health +``` \ No newline at end of file