myYouTube/AGENTS.md
vrubelroman fe16c08daa Implement Phase 6: MeTube download integration
- MeTubeClient encapsulates all MeTube HTTP/Socket.IO calls (verified against
  the real MeTube source: /add returns no job id, GET /history gives a queue
  snapshot for reconciliation, filenames arrive already relative, percent is
  a 0-100 float)
- download_jobs table + service: request/dedup active downloads, apply live
  Socket.IO events (added/updated/completed/canceled/cleared) matched by
  canonical YouTube URL, safe relative-path -> public media URL construction
- Reconciliation on startup against MeTube's live queue/done state (section 19):
  non-terminal jobs recovered where possible, else marked "unknown"; already
  completed jobs are left untouched
- POST/GET /api/videos/{id}/download(-status), recheck-local; feed/video
  detail now report real local availability instead of a stub
- Frontend: download button with live status polling (queued/downloading %/
  postprocessing/completed/failed+retry), local <video> playback with
  YouTube fallback on playback error
- health.py now delegates to MeTubeClient (single place for MeTube calls)

26 new backend tests (63 total). Verified live: Socket.IO connects
successfully to the real MeTube instance on deploy.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 18:56:17 +00:00

44 lines
4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AGENTS.md
Полное ТЗ: [`youtube_categories_metube_TZ.md`](./youtube_categories_metube_TZ.md). Перед любой существенной работой сверяйся с ним — этот файл лишь выжимка ограничений.
## Жёсткие ограничения (раздел 34 ТЗ)
1. Не форкать/копировать Tube Archivist.
2. Не встраивать yt-dlp в этот сервис — скачивание только через существующий MeTube (`mediaVM`).
3. Не дублировать функции скачивания MeTube.
4. Не монтировать media storage MeTube на `hermesVM` — видео не хранится локально, только проксируется/линкуется.
5. Не реализовывать YouTube Recommendations/Home.
6. Не делать multi-user — приложение строго single-user (`ALLOWED_GOOGLE_EMAIL`).
7. Frontend не должен напрямую вызывать Google API.
8. Frontend не должен напрямую вызывать MeTube write API (`POST /add` и т.п.) — только через наш backend.
9. Не восстанавливать filename скачанного видео из YouTube title — использовать только точное имя, пришедшее от MeTube по событию `completed`.
10. Не удалять существующие файлы MeTube.
11. Не менять исходный код MeTube.
12. Все внешние base URL (MeTube, Google) — через env/config, не хардкодить.
13. REST API должен оставаться пригодным для будущего mobile/PWA клиента.
## Порядок фаз (раздел 33 ТЗ)
Не реализовывать следующую фазу, пока не работает предыдущая:
1. Skeleton (текущая фаза) — FastAPI, PostgreSQL, Alembic, React, Docker Compose, healthcheck.
2. Google OAuth + subscriptions sync + channels UI.
3. Categories CRUD + many-to-many + фильтр по категориям.
4. Video sync/feed (uploads playlists, playlistItems, videos, background scheduler).
5. YouTube playback (embed).
6. MeTube integration (`/add`, download_jobs, Socket.IO consumer, media URL).
7. Hardening (retry/recovery, logging, quota handling, tests, README).
## Структура и соглашения
- `migrations/` — Alembic, живёт в корне репозитория (не внутри `backend/`), импортирует модели из `backend/app`.
- Схема БД добавляется миграциями инкрементально по фазам (см. раздел 11 ТЗ), а не одним махом в Phase 1.
- MeTube-специфичные HTTP/Socket.IO вызовы должны быть инкапсулированы в отдельный класс `MeTubeClient` (раздел 36 ТЗ) — не размазывать по backend.
- Секреты только через `.env` (см. `.env.example`), никогда не коммитить `.env`, refresh token, client secret.
- Backend тесты — `pytest`, лежат в `tests/` в корне. Integration-тесты против Google/MeTube — mocked по умолчанию; реальные вызовы к `http://192.168.8.177:8081` — только opt-in, не в обычном CI.
- **В unit-тестах не использовать `with TestClient(app) as client:`** — это запускает lifespan приложения, который с Phase 6 реально стучится в MeTube (Socket.IO) и в Postgres (`reconcile_on_startup`). Используй `TestClient(app)` без `with` (lifespan не запускается, дефолтное поведение starlette) — так и сделано во всех текущих тестах.
## Запуск/проверка
См. `README.md`. Быстрая проверка: `docker compose up -d --build` и `curl http://localhost:8080/api/health`.