import * as path from 'path'; function envInt(name: string, fallback: number): number { const v = process.env[name]; if (!v) return fallback; const n = Number(v); return Number.isFinite(n) ? n : fallback; } export const config = { port: envInt('PORT', 3000), dataDir: process.env.DATA_DIR ?? path.resolve(process.cwd(), 'data'), cloudCompareBin: process.env.CLOUDCOMPARE_BIN ?? 'CloudCompare', pythonBin: process.env.PYTHON_BIN ?? 'python3', // Pipeline constants (voir plan: facteur 2, 5 etapes) decimationFactor: 2, decimationSteps: 5, // Nombre max de points echantillonnes pour estimer la distance moyenne au plus proche voisin statsSampleCap: envInt('STATS_SAMPLE_CAP', 50000), // Grille de calcul du volume = pas spatial DE CHAQUE NIVEAU x ce multiplicateur (adaptee // dynamiquement a chaque niveau, pas figee sur la resolution du niveau 0 - voir CLAUDE.md). gridStepMultiplier: 2, // Remplissage des trous (occlusions de scan) avant -VOLUME : distance max d'interpolation // Delaunay = gridStep du niveau x ce multiplicateur. Empeche de combler les parties concaves // du contour de l'amas (qui doivent rester "vides") tout en bouchant les petits trous de scan. // Voir CLAUDE.md : -VOLUME n'a PAS d'option de remplissage native, on passe par -RASTERIZE. maxEdgeLengthMultiplier: 3, // En dessous de ce nombre de points, on arrete la decimation progressive (cloud devenu inexploitable) minPointsToContinue: 25, // Seuil d'alerte robustesse : si "matching cells %" du rapport CloudCompare passe sous ce seuil, // le resultat est signale comme peu fiable dans l'UI. matchingCellsWarnThreshold: 90, // Taille max d'upload (octets) maxUploadBytes: envInt('MAX_UPLOAD_MB', 2048) * 1024 * 1024, // Timeout par appel CloudCompare CLI (ms) ccTimeoutMs: envInt('CC_TIMEOUT_MS', 10 * 60 * 1000), // Auth HTTP Basic (UI + API). Si l'une des deux variables est absente, l'auth est desactivee // (pratique en dev local) - un warning est logge au demarrage dans ce cas, voir main.ts. authUsername: process.env.AUTH_USERNAME ?? null, authPasswordHash: process.env.AUTH_PASSWORD_HASH ?? null, }; export const uploadsDir = () => path.join(config.dataDir, 'uploads'); export const resultsDir = () => path.join(config.dataDir, 'results'); export const dbPath = () => path.join(config.dataDir, 'app.db');