123 lines
5.8 KiB
Markdown
123 lines
5.8 KiB
Markdown
# MyYouTube
|
||
|
||
Персональный YouTube-клиент с категориями подписок и интеграцией с существующим MeTube.
|
||
Работа агентской команды (opencode) описана в [руководстве по агентской команде](./AGENT_TEAM.md).
|
||
|
||
Текущий статус: **функционально готово** (основные этапы 1–6 и доработки по итогам тестирования). Развёрнуто и вручную протестировано на тестовом окружении (`testmyyoutube.vrubel.xyz` → hermesVM `192.168.8.173` → MeTube на mediaVM `192.168.8.177`).
|
||
|
||
### Что сделано
|
||
|
||
- Skeleton, Google OAuth (single-user allow-list), sync подписок/видео (APScheduler), категории (CRUD + many-to-many), лента с курсорной пагинацией, YouTube-плеер, полная MeTube-интеграция (download/delete, Socket.IO live-статусы, recovery после рестарта).
|
||
- Раздел **«На сервере»** — скачанные видео; `/saved` перенаправляет на `/local`.
|
||
- Тёмный адаптивный интерфейс: общая навигация, категории с постоянными URL, поиск по названиям видео и каналов, мобильное меню.
|
||
- Отписанные каналы скрываются из списка каналов.
|
||
- Реальная отписка от канала на YouTube (`subscriptions.delete`) реализована по запросу пользователя сверх исходного MVP. Из-за этого OAuth scope расширен с `youtube.readonly` до полного `youtube` (read/write) — см. `backend/app/services/google_oauth.py`.
|
||
- Удаление скачанного видео с сервера (`DELETE /api/videos/{id}/download`) — тоже сверх исходного MVP-скоупа, добавлено по запросу.
|
||
|
||
### Что осталось / сознательно отложено
|
||
|
||
- Дополнительные идеи после MVP пока не реализованы: PWA, watch later, Shorts-фильтр, SponsorBlock и т.д.
|
||
- Hardening (retry/recovery, тесты) выполнялся по факту находок в live-тестировании, а не отдельным проходом — см. `git log` для конкретных багфиксов (flapping статусов загрузки, неверный id в MeTube `/delete`, OAuth scope mismatch).
|
||
|
||
## Стек
|
||
|
||
- Backend: Python 3.13, FastAPI, SQLAlchemy 2.x, Alembic, Pydantic Settings
|
||
- Frontend: React, TypeScript, Vite, React Router, TanStack Query
|
||
- DB: PostgreSQL 16
|
||
- Deployment: Docker Compose
|
||
|
||
## Запуск в production (Docker Compose)
|
||
|
||
1. Скопируй `.env.example` в `.env` и заполни значения (Google OAuth credentials, секреты, MeTube URLs).
|
||
2. Собери и запусти:
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
3. Проверь health:
|
||
|
||
```bash
|
||
curl http://localhost:8080/api/health
|
||
```
|
||
|
||
Миграции Alembic применяются автоматически при старте контейнера `app` (см. `entrypoint.sh`).
|
||
|
||
## Локальная разработка
|
||
|
||
### Агентская команда (opencode)
|
||
|
||
Подробная инструкция: [AGENT_TEAM.md](./AGENT_TEAM.md).
|
||
|
||
Работа идёт в одной сессии opencode: она стартует агентом `orchestrator`
|
||
(`default_agent` в `opencode.json`). Orchestrator сам декомпозирует задачу и
|
||
вызывает субагентов через Task tool: `coder` (единственный меняет
|
||
отслеживаемые файлы), `reviewer` (read-only review, `edit: deny`) и `tester`
|
||
(проверки без правок, `edit: deny`). Роли описаны в
|
||
[`.opencode/agent/`](./.opencode/agent/).
|
||
|
||
```bash
|
||
opencode
|
||
```
|
||
|
||
Задачу пиши обычным сообщением: Orchestrator передаст её Coder'у, соберёт
|
||
review и QA, повторит цикл при находках и вернёт финальный отчёт. Вручную
|
||
писать субагентам не нужно.
|
||
|
||
### Backend
|
||
|
||
```bash
|
||
cd backend
|
||
uv venv .venv
|
||
uv pip install -p .venv -r requirements-dev.txt
|
||
source .venv/bin/activate
|
||
cd ..
|
||
DATABASE_URL=postgresql+psycopg://youtube_app:password@localhost:5432/youtube_app \
|
||
APP_SECRET_KEY=dev APP_SECRET_KEY=dev TOKEN_ENCRYPTION_KEY=dev \
|
||
alembic upgrade head
|
||
uvicorn app.main:app --reload --app-dir backend --port 8080
|
||
```
|
||
|
||
Тесты:
|
||
|
||
```bash
|
||
backend/.venv/bin/python -m pytest tests/ -v
|
||
```
|
||
|
||
### Frontend
|
||
|
||
```bash
|
||
cd frontend
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
Dev-сервер Vite проксирует `/api/*` на `http://127.0.0.1:8080` (см. `vite.config.ts`).
|
||
|
||
## Миграции
|
||
|
||
```bash
|
||
alembic revision -m "описание"
|
||
alembic upgrade head
|
||
```
|
||
|
||
`alembic.ini` и папка `migrations/` находятся в корне проекта и подключают модели из `backend/app`.
|
||
|
||
## Структура проекта
|
||
|
||
```text
|
||
myyoutube/
|
||
├── backend/ # FastAPI приложение
|
||
├── frontend/ # React SPA
|
||
├── migrations/ # Alembic migrations
|
||
├── tests/ # backend tests (pytest)
|
||
├── Dockerfile
|
||
├── compose.yml
|
||
├── .env / .env.example
|
||
├── .opencode/ # агенты команды (orchestrator/coder/reviewer/tester)
|
||
└── AGENT_TEAM.md # руководство по агентской команде opencode
|
||
```
|
||
|
||
## Секреты
|
||
|
||
`.env` в `.gitignore`, не коммитится. Обязательные секреты: `APP_SECRET_KEY`, `TOKEN_ENCRYPTION_KEY`, `GOOGLE_CLIENT_SECRET`, `POSTGRES_PASSWORD`.
|