youtubeDownloader/spec/architecture.md
Nicolas 29aadd28a4
All checks were successful
Publier l'image Docker / test (push) Successful in 30s
Publier l'image Docker / publish (push) Successful in 1m10s
feat: squelette serveur/client + Docker + CI de build/release
Pose l'infrastructure de base avant l'implémentation des fonctionnalités :
- server/ : Fastify + TypeScript (ESM), route /health, sert client/dist
- client/ : TypeScript vanilla + esbuild/sass, vue placeholder (shell)
- server/Dockerfile : image multi-étapes avec yt-dlp + ffmpeg embarqués
- .forgejo/workflows/publish-docker.yml : test puis publication sur le
  registre de conteneurs Forgejo (nécessite le secret REGISTRY_TOKEN)
- biome.json : lint du repo entier (downloader/ exclu)
- spec/architecture.md : documentation de ces choix

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 07:55:43 +02:00

3.7 KiB

Architecture

Contexte

Remplace une série de scripts .cmd (./downloader, non versionné) par une application web : parcourir une chaîne YouTube, mettre des vidéos/audios en file d'attente, les télécharger en parallèle avec suivi en temps réel, et les livrer au navigateur de l'utilisateur. Pas d'intégration Emby, pas d'authentification (usage LAN).

Structure du dépôt

server/   Backend Fastify (TypeScript, ESM)
client/   Frontend TypeScript vanilla (esbuild + sass)
.forgejo/workflows/   CI : lint + typecheck + tests + build, puis publication Docker

Pas de docker-compose.yml pour l'instant (une seule image, pas encore de dépendances externes type base de données).

Backend (server/)

  • Fastify 5, TypeScript strict, ESM ("type": "module", imports relatifs en .js, résolution NodeNext).
  • src/index.ts : bootstrap (plugins, écoute, arrêt propre SIGINT/SIGTERM).
  • src/config.ts : configuration runtime depuis l'environnement (PORT, HOST, CLIENT_DIST_PATH).
  • src/routes/ : routes Fastify enregistrées comme plugins (health.ts pour l'instant). Les futurs domaines métier (découverte de chaîne, file d'attente, téléchargement, notifications temps réel) suivront le même principe de service modulaire autonome, un fichier/dossier par domaine sous src/.
  • Le serveur sert aussi les fichiers statiques de client/dist via @fastify/static.
  • Tests : Vitest (server/test/), via app.inject() (pas de serveur HTTP réel démarré en test).

Frontend (client/)

  • TypeScript vanilla, pas de framework. Chaque vue = un dossier avec Vue.ts / Vue.html / Vue.scss (gabarit importé comme chaîne brute, style Sass importé et compilé). Voir src/shell/ pour l'exemple actuel (placeholder).
  • Build via build.mjs (esbuild), pas d'outil de build plus lourd (Vite, webpack) : le script compile src/app.ts en bundle ESM, copie src/index.html, et compile/regroupe les .scss importés en un app.css voisin (plugin esbuild maison qui délègue au paquet sass).
  • Pas encore de router : une seule vue (shell) pour l'instant. Un routeur sera introduit avec la première vraie vue (parcours de chaîne).

Lint

Biome.js à la racine (biome.json), applique aux deux paquets (server/src, client/src) - pas d'ESLint/Prettier. downloader/ (scripts legacy, non versionné) est explicitement exclu.

Docker / CI-CD

  • server/Dockerfile : image multi-étapes construite avec pour contexte la racine du dépôt (docker build -f server/Dockerfile .), car elle a besoin à la fois de server/ et client/. Étapes : build client (esbuild) → build serveur (tsc) → image runtime (Node 22 Alpine + ffmpeg + binaire autonome yt-dlp, utilisateur non-root node).
  • yt-dlp et ffmpeg sont installés dans l'image (pas vendorisés dans le dépôt, contrairement aux scripts .cmd d'origine qui embarquaient yt-dlp.exe et un build ffmpeg complet).
  • .forgejo/workflows/publish-docker.yml : job test (lint racine, typecheck/tests/build serveur, typecheck/build client) puis job publish (build + push de l'image vers git.dev.kyuno.fr/kyuno/youtubedownloader, seulement si test passe et hors PR). Tags : latest + sha court sur push main, X.Y.Z/X.Y/latest sur tag vX.Y.Z. Nécessite le secret de dépôt REGISTRY_TOKEN (à créer manuellement, voir l'en-tête du workflow - un jeton d'API n'a pas le droit d'écrire dans le registre de paquets).

Statut

Squelette d'infrastructure seulement : serveur qui répond, client placeholder, Docker, CI. Aucune des fonctionnalités métier (découverte de chaîne, file d'attente, téléchargement yt-dlp, notifications temps réel) n'est encore implémentée - elles arriveront par PR successives.