No description
Find a file
vrubelroman 3089202316 Add delete-downloaded-video and real YouTube unsubscribe
Delete local copy:
- MeTubeClient.delete_download() -> POST /delete {ids, where: "done"}
- Only ever acts on a job our own app tracked (metube_job_id we stored from
  its own 'completed' event), never a pre-existing MeTube file
- New "deleted" terminal status; DELETE /api/videos/{id}/download
- Frontend: delete button next to "На сервере" badge, confirm dialog

Unsubscribe (deliberate deviation from the original TZ's MVP exclusion of
subscription management, per explicit user request after being shown the
tradeoff):
- OAuth scope widened from youtube.readonly to full youtube (read/write) --
  existing stored tokens only cover the old scope, so unsubscribing needs a
  fresh reconnect; reads keep working unchanged on the old token meanwhile
- channels.youtube_subscription_id (distinct from the channel id; that's
  what subscriptions.delete actually keys on) captured during subscriptions
  sync
- YouTubeInsufficientScope raised on 401/403 "insufficient authentication
  scopes" and surfaced as a clear 403 asking the user to reconnect, rather
  than a generic API error
- POST /api/channels/{id}/unsubscribe calls subscriptions.delete and marks
  the channel unsubscribed locally on success
- Frontend: "Отписаться" button on ChannelCard with confirm dialog

10 new backend tests (73 total).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 19:47:35 +00:00
backend Add delete-downloaded-video and real YouTube unsubscribe 2026-09-16 19:47:35 +00:00
frontend Add delete-downloaded-video and real YouTube unsubscribe 2026-09-16 19:47:35 +00:00
migrations Add delete-downloaded-video and real YouTube unsubscribe 2026-09-16 19:47:35 +00:00
tests Add delete-downloaded-video and real YouTube unsubscribe 2026-09-16 19:47:35 +00:00
.dockerignore Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
.env.example Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
.gitignore Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
AGENTS.md Implement Phase 6: MeTube download integration 2026-09-16 18:56:17 +00:00
alembic.ini Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
compose.yml Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
Dockerfile Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
entrypoint.sh Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
pyproject.toml Implement Phase 6: MeTube download integration 2026-09-16 18:56:17 +00:00
README.md Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
UI_UX_spec.md Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00
youtube_categories_metube_TZ.md Implement Phases 1-5: skeleton, OAuth, categories, video sync/feed, playback 2026-09-16 18:44:30 +00:00

MyYouTube

Персональный YouTube-клиент с категориями подписок и интеграцией с существующим MeTube. Полное техническое задание: youtube_categories_metube_TZ.md.

Текущий статус: Phase 1 — skeleton (FastAPI backend, PostgreSQL, Alembic, React frontend, Docker Compose, healthcheck).

Стек

  • 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. Собери и запусти:

    docker compose up -d --build
    
  3. Проверь health:

    curl http://localhost:8080/api/health
    

Миграции Alembic применяются автоматически при старте контейнера app (см. entrypoint.sh).

Локальная разработка

Backend

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

Тесты:

backend/.venv/bin/python -m pytest tests/ -v

Frontend

cd frontend
npm install
npm run dev

Dev-сервер Vite проксирует /api/* на http://127.0.0.1:8080 (см. vite.config.ts).

Миграции

alembic revision -m "описание"
alembic upgrade head

alembic.ini и папка migrations/ находятся в корне проекта и подключают модели из backend/app.

Структура проекта

myyoutube/
├── backend/      # FastAPI приложение
├── frontend/     # React SPA
├── migrations/   # Alembic migrations
├── tests/        # backend tests (pytest)
├── Dockerfile
├── compose.yml
├── .env / .env.example
└── youtube_categories_metube_TZ.md

Секреты

.env в .gitignore, не коммитится. Обязательные секреты: APP_SECRET_KEY, TOKEN_ENCRYPTION_KEY, GOOGLE_CLIENT_SECRET, POSTGRES_PASSWORD.