Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback
- FastAPI + PostgreSQL + Alembic + React/Vite skeleton, Docker Compose, healthcheck
- Google OAuth (single allowed account), encrypted refresh token storage
- Subscriptions sync with pagination, uploads playlist batch fetch
- Categories CRUD, many-to-many channel assignment, category filtering
- Video sync (playlistItems + videos.list batching), cached feed with cursor
pagination, background scheduler (APScheduler)
- Video detail page with YouTube embed player
- SPA fallback routing, optimistic UI updates, client-side query caching
40 backend tests covering OAuth allow-list, sync idempotency, cascade deletes,
cursor pagination, and category filtering.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 18:44:30 +00:00
# MyYouTube
Персональный YouTube-клиент с категориями подписок и интеграцией с существующим MeTube.
2026-09-17 21:42:30 +00:00
Работа агентской команды (opencode) описана в секции «Агентская команда (opencode)» ниже; роли агентов — в `.opencode/agent/` .
Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback
- FastAPI + PostgreSQL + Alembic + React/Vite skeleton, Docker Compose, healthcheck
- Google OAuth (single allowed account), encrypted refresh token storage
- Subscriptions sync with pagination, uploads playlist batch fetch
- Categories CRUD, many-to-many channel assignment, category filtering
- Video sync (playlistItems + videos.list batching), cached feed with cursor
pagination, background scheduler (APScheduler)
- Video detail page with YouTube embed player
- SPA fallback routing, optimistic UI updates, client-side query caching
40 backend tests covering OAuth allow-list, sync idempotency, cascade deletes,
cursor pagination, and category filtering.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 18:44:30 +00:00
2026-09-16 23:08:21 +00:00
Текущий статус: **функционально готово** (основные этапы 1– 6 и доработки по итогам тестирования). Развёрнуто и вручную протестировано на тестовом окружении (`testmyyoutube.vrubel.xyz` → hermesVM `192.168.8.173` → MeTube на mediaVM `192.168.8.177` ).
2026-09-16 21:40:32 +00:00
### Что сделано
- Skeleton, Google OAuth (single-user allow-list), sync подписок/видео (APScheduler), категории (CRUD + many-to-many), лента с курсорной пагинацией, YouTube-плеер, полная MeTube-интеграция (download/delete, Socket.IO live-статусы, recovery после рестарта).
2026-09-18 12:13:32 +00:00
- Режим «Каналы» на главной (`?view=channels` ): переключатель «Лента | Каналы», список подписанных каналов по свежести последнего видео с тремя последними роликами в строке; фильтр категорий из сайдбара действует в обоих режимах.
2026-09-16 21:40:32 +00:00
- Раздел ** «На сервере»** — скачанные видео; `/saved` перенаправляет на `/local` .
2026-09-28 09:33:35 +00:00
- Разделение видео на **Shorts** и обычные по длительности (`SHORTS_MAX_DURATION_SECONDS` , по умолчанию 180 сек; неизвестная длительность — обычное видео): сегмент-фильтр «Обычные | Shorts» во всех списках видео (по умолчанию «Обычные», `?type=short` для Shorts; `?type=all` /`?type=long` /неизвестное трактуются как «Обычные») и вертикальная full-screen лента Shorts (`/shorts/:youtubeVideoId` ) с автоплеем активного ролика и бесконечной подгрузкой в контексте открытого фильтра. REST `GET /api/feed` по-прежнему поддерживает `type=all|long|short` (совместимость с будущим mobile/PWA-клиентом), UI вариант `all` не использует.
2026-09-16 21:40:32 +00:00
- Тёмный адаптивный интерфейс: общая навигация, категории с постоянными URL, поиск по названиям видео и каналов, мобильное меню.
- Отписанные каналы скрываются из списка каналов.
2026-09-16 23:08:21 +00:00
- Реальная отписка от канала на YouTube (`subscriptions.delete` ) реализована по запросу пользователя сверх исходного MVP. Из-за этого OAuth scope расширен с `youtube.readonly` до полного `youtube` (read/write) — см. `backend/app/services/google_oauth.py` .
2026-09-16 21:40:32 +00:00
- Удаление скачанного видео с сервера (`DELETE /api/videos/{id}/download` ) — тоже сверх исходного MVP-скоупа, добавлено по запросу.
### Что осталось / сознательно отложено
2026-09-28 09:33:35 +00:00
- Дополнительные идеи после MVP пока не реализованы: PWA, watch later, SponsorBlock и т.д.
2026-09-16 23:08:21 +00:00
- Hardening (retry/recovery, тесты) выполнялся по факту находок в live-тестировании, а не отдельным проходом — см. `git log` для конкретных багфиксов (flapping статусов загрузки, неверный id в MeTube `/delete` , OAuth scope mismatch).
Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback
- FastAPI + PostgreSQL + Alembic + React/Vite skeleton, Docker Compose, healthcheck
- Google OAuth (single allowed account), encrypted refresh token storage
- Subscriptions sync with pagination, uploads playlist batch fetch
- Categories CRUD, many-to-many channel assignment, category filtering
- Video sync (playlistItems + videos.list batching), cached feed with cursor
pagination, background scheduler (APScheduler)
- Video detail page with YouTube embed player
- SPA fallback routing, optimistic UI updates, client-side query caching
40 backend tests covering OAuth allow-list, sync idempotency, cascade deletes,
cursor pagination, and category filtering.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 18:44:30 +00:00
## Стек
- 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` ).
## Локальная разработка
2026-09-16 23:08:21 +00:00
### Агентская команда (opencode)
Работа идёт в одной сессии opencode: она стартует агентом `orchestrator`
2026-09-17 21:18:36 +00:00
(`default_agent` в `opencode.json` ). Порядок работы:
`orchestrator → analyst (аналитика/README) → coder → reviewer → tester` .
Orchestrator сам декомпозирует задачу и вызывает субагентов через Task tool:
`analyst` (до Coder'а фиксирует задачу в `analytics/*.md` и при необходимости
актуализирует README), `coder` (единственный меняет код продукта), `reviewer`
(read-only review, `edit: deny` ) и `tester` (проверки без правок, `edit: deny` ).
2026-09-17 21:42:30 +00:00
Роли описаны в [`.opencode/agent/` ](./.opencode/agent/ ). Аналитика задач
ведётся в [`analytics/` ](./analytics/ ) (см. `analytics/README.md` ).
2026-09-16 23:08:21 +00:00
```bash
opencode
```
2026-09-17 21:18:36 +00:00
Задачу пиши обычным сообщением: Orchestrator передаст её сначала Analyst'у
(аналитика и README), затем Coder'у , соберёт review и QA, повторит цикл при
находках и вернёт финальный отчёт. Вручную писать субагентам не нужно.
2026-09-16 23:08:21 +00:00
Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback
- FastAPI + PostgreSQL + Alembic + React/Vite skeleton, Docker Compose, healthcheck
- Google OAuth (single allowed account), encrypted refresh token storage
- Subscriptions sync with pagination, uploads playlist batch fetch
- Categories CRUD, many-to-many channel assignment, category filtering
- Video sync (playlistItems + videos.list batching), cached feed with cursor
pagination, background scheduler (APScheduler)
- Video detail page with YouTube embed player
- SPA fallback routing, optimistic UI updates, client-side query caching
40 backend tests covering OAuth allow-list, sync idempotency, cascade deletes,
cursor pagination, and category filtering.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 18:44:30 +00:00
### 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)
2026-09-17 21:18:36 +00:00
├── analytics/ # аналитика задач агентской команды
Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback
- FastAPI + PostgreSQL + Alembic + React/Vite skeleton, Docker Compose, healthcheck
- Google OAuth (single allowed account), encrypted refresh token storage
- Subscriptions sync with pagination, uploads playlist batch fetch
- Categories CRUD, many-to-many channel assignment, category filtering
- Video sync (playlistItems + videos.list batching), cached feed with cursor
pagination, background scheduler (APScheduler)
- Video detail page with YouTube embed player
- SPA fallback routing, optimistic UI updates, client-side query caching
40 backend tests covering OAuth allow-list, sync idempotency, cascade deletes,
cursor pagination, and category filtering.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 18:44:30 +00:00
├── Dockerfile
├── compose.yml
├── .env / .env.example
2026-09-17 21:42:30 +00:00
└── .opencode/ # агенты команды (orchestrator/analyst/coder/reviewer/tester)
Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback
- FastAPI + PostgreSQL + Alembic + React/Vite skeleton, Docker Compose, healthcheck
- Google OAuth (single allowed account), encrypted refresh token storage
- Subscriptions sync with pagination, uploads playlist batch fetch
- Categories CRUD, many-to-many channel assignment, category filtering
- Video sync (playlistItems + videos.list batching), cached feed with cursor
pagination, background scheduler (APScheduler)
- Video detail page with YouTube embed player
- SPA fallback routing, optimistic UI updates, client-side query caching
40 backend tests covering OAuth allow-list, sync idempotency, cascade deletes,
cursor pagination, and category filtering.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 18:44:30 +00:00
```
## Секреты
`.env` в `.gitignore` , не коммитится. Обязательные секреты: `APP_SECRET_KEY` , `TOKEN_ENCRYPTION_KEY` , `GOOGLE_CLIENT_SECRET` , `POSTGRES_PASSWORD` .