feat: M3 — automatic channel tagging (language + topic system tags)

- Tag and ChannelTag models + migration 0003 (partial unique indexes split
  system vs per-user tag names)
- Offline language detection (py3langid) constrained to a curated language set,
  with the channel's declared default language as a strong prior
- Topic tags mapped from YouTube topicDetails + dominant video category; the
  generic "Lifestyle" catch-all is intentionally dropped
- System (auto) tags are regenerated idempotently and never touch user tags;
  orphaned system tags are cleaned up
- GET /api/tags and admin POST /api/tags/recompute; scheduled autotag job
This commit is contained in:
npeter83 2026-06-11 01:57:19 +02:00
parent 64b18b3cc1
commit 68dad91e8a
9 changed files with 482 additions and 1 deletions

View file

@ -9,7 +9,7 @@ from starlette.middleware.sessions import SessionMiddleware
from app import auth
from app.config import settings
from app.routes import health, sync
from app.routes import health, sync, tags
from app.scheduler import shutdown_scheduler, start_scheduler
@ -43,6 +43,7 @@ if settings.frontend_origin:
app.include_router(health.router)
app.include_router(auth.router)
app.include_router(sync.router)
app.include_router(tags.router)
STATIC_DIR = Path(__file__).parent / "static"
app.mount("/assets", StaticFiles(directory=STATIC_DIR / "assets"), name="assets")