diff --git a/server/src/config.ts b/server/src/config.ts index 64433b4..adb1852 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -1,4 +1,5 @@ import { resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; /** * Configuration runtime du serveur, dérivée des variables d'environnement. @@ -16,11 +17,18 @@ export interface ServerConfig { readonly maxConcurrentDownloads: number; } +// Dossier contenant ce module compilé (server/dist/ en prod, server/src/ sous +// tsx en dev - même profondeur sous server/ dans les deux cas). Sert de base +// aux chemins par défaut ci-dessous : contrairement à process.cwd(), invariant +// quel que soit le répertoire depuis lequel le process a été lancé (ex. `npm +// --prefix server run dev` depuis la racine du dépôt ne change pas le cwd). +const here = fileURLToPath(new URL('.', import.meta.url)); + /** * Construit la configuration du serveur à partir des variables d'environnement, * en appliquant des valeurs par défaut adaptées au développement local (le * client compilé et le dossier temporaire sont alors supposés voisins de - * `server/`). + * `server/`, indépendamment du répertoire de travail courant). * * @returns La configuration runtime résolue. */ @@ -31,8 +39,8 @@ export function loadConfig(): ServerConfig { return { port: Number.isNaN(parsedPort) ? 3000 : parsedPort, host: process.env.HOST ?? '0.0.0.0', - clientDistPath: process.env.CLIENT_DIST_PATH ?? resolve(process.cwd(), '../client/dist'), - tmpDir: process.env.TMP_DIR ?? resolve(process.cwd(), 'tmp'), + clientDistPath: process.env.CLIENT_DIST_PATH ?? resolve(here, '../../client/dist'), + tmpDir: process.env.TMP_DIR ?? resolve(here, '../tmp'), maxConcurrentDownloads: Number.isNaN(parsedConcurrency) || parsedConcurrency < 1 ? 2 : parsedConcurrency, }; diff --git a/spec/architecture.md b/spec/architecture.md index 5d48641..818c18b 100644 --- a/spec/architecture.md +++ b/spec/architecture.md @@ -18,7 +18,7 @@ Pas de `docker-compose.yml` pour l'instant (une seule image, pas encore de dépe - 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/config.ts` : configuration runtime depuis l'environnement (`PORT`, `HOST`, `CLIENT_DIST_PATH`, `TMP_DIR`, `MAX_CONCURRENT_DOWNLOADS`). Les valeurs par défaut de `CLIENT_DIST_PATH`/`TMP_DIR` sont résolues depuis l'emplacement du module (`import.meta.url`), pas `process.cwd()` : reste correct quel que soit le répertoire depuis lequel le process est lancé (ex. `npm --prefix server run dev` depuis la racine du dépôt, utilisé par `.claude/launch.json` pour la prévisualisation - non versionné, voir `.gitignore`). - `src/routes/` : routes Fastify enregistrées comme plugins (`health.ts`, `channel.ts`, `queue.ts`). Chaque domaine métier suit le même principe : un plugin de route fin sous `src/routes/`, qui délègue à un service sous `src/services/`. - `src/services/` : - `ytDlpRunner.ts` : exécution bas niveau de yt-dlp (`node:child_process.spawn`, jamais de shell - arguments toujours passés en tableau, jamais concaténés dans une chaîne, pour exclure toute injection de commande). Supporte le suivi ligne par ligne de stdout (`onStdoutLine`, pour la progression) et l'annulation via `AbortSignal`.