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>
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ésolutionNodeNext). 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.tspour 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 soussrc/.- Le serveur sert aussi les fichiers statiques de
client/distvia@fastify/static. - Tests : Vitest (
server/test/), viaapp.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é). Voirsrc/shell/pour l'exemple actuel (placeholder). - Build via
build.mjs(esbuild), pas d'outil de build plus lourd (Vite, webpack) : le script compilesrc/app.tsen bundle ESM, copiesrc/index.html, et compile/regroupe les.scssimportés en unapp.cssvoisin (plugin esbuild maison qui délègue au paquetsass). - 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 deserver/etclient/. Étapes : build client (esbuild) → build serveur (tsc) → image runtime (Node 22 Alpine +ffmpeg+ binaire autonomeyt-dlp, utilisateur non-rootnode).yt-dlpetffmpegsont installés dans l'image (pas vendorisés dans le dépôt, contrairement aux scripts.cmdd'origine qui embarquaientyt-dlp.exeet un build ffmpeg complet)..forgejo/workflows/publish-docker.yml: jobtest(lint racine, typecheck/tests/build serveur, typecheck/build client) puis jobpublish(build + push de l'image versgit.dev.kyuno.fr/kyuno/youtubedownloader, seulement sitestpasse et hors PR). Tags :latest+ sha court sur pushmain,X.Y.Z/X.Y/latestsur tagvX.Y.Z. Nécessite le secret de dépôtREGISTRY_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.