From 03a6d55571e4a1acedf8665e4fa3135c27958b66 Mon Sep 17 00:00:00 2001 From: Manus Deploy Date: Fri, 24 Jul 2026 13:15:43 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20scan=20automatique=20des=20app.json=20a?= =?UTF-8?q?u=20d=C3=A9marrage=20(d=C3=A9couverte=20FALC=20et=20autres)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/app-creator.js | 49 ++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/backend/src/app-creator.js b/backend/src/app-creator.js index da870bd..0ec2901 100644 --- a/backend/src/app-creator.js +++ b/backend/src/app-creator.js @@ -434,7 +434,7 @@ function addDynamicApp(appDef) { } function initDynamicApps() { - // 1. Charger les apps depuis .dashboard-apps.json (créées via l'interface) + // 1. Charger les apps depuis .dashboard-apps.json (legacy) const dynamicApps = loadDynamicApps(); for (const app of dynamicApps) { const existingInConfig = config.apps.findIndex((a) => a.id === app.id); @@ -442,39 +442,32 @@ function initDynamicApps() { config.apps.push(app); } } - - // 2. Découverte automatique : scanner les dossiers apps/*.json - let discovered = 0; + // 2. Scanner les dossiers app.json (découverte automatique) try { - const appsBasePath = config.appsBasePath; - if (fs.existsSync(appsBasePath)) { - const entries = fs.readdirSync(appsBasePath, { withFileTypes: true }); - for (const entry of entries) { - if (!entry.isDirectory()) continue; - const appJsonPath = path.join(appsBasePath, entry.name, 'app.json'); - if (!fs.existsSync(appJsonPath)) continue; - try { - const appDef = JSON.parse(fs.readFileSync(appJsonPath, 'utf-8')); - if (!appDef.id) continue; - // Ne pas écraser une app déjà en config (statique ou dynamique) - const existingIdx = config.apps.findIndex((a) => a.id === appDef.id); - if (existingIdx >= 0) { - // Mettre à jour avec les données du app.json (source de vérité) - config.apps[existingIdx] = { ...config.apps[existingIdx], ...appDef }; - } else { - config.apps.push(appDef); - discovered++; - } - } catch (e) { - console.warn(`[discovery] Erreur lecture ${appJsonPath}:`, e.message); + const appsBasePath = config.appsBasePath || process.env.APPS_BASE_PATH || '/opt/manus-deploy/apps'; + const entries = fs.readdirSync(appsBasePath, { withFileTypes: true }); + let scanned = 0; + for (const entry of entries) { + if (!entry.isDirectory()) continue; + const appJsonPath = path.join(appsBasePath, entry.name, 'app.json'); + if (!fs.existsSync(appJsonPath)) continue; + try { + const appDef = JSON.parse(fs.readFileSync(appJsonPath, 'utf-8')); + if (!appDef.id) continue; + const existingInConfig = config.apps.findIndex((a) => a.id === appDef.id); + if (existingInConfig < 0) { + config.apps.push(appDef); + scanned++; } + } catch (e) { + console.error(`Erreur lecture app.json dans ${entry.name}:`, e.message); } } + console.log(`Apps découvertes via app.json: ${scanned}`); } catch (err) { - console.error('[discovery] Erreur scan apps:', err.message); + console.error('Erreur scan app.json:', err.message); } - - console.log(`Apps chargées: ${dynamicApps.length} dynamiques + ${discovered} découvertes (total: ${config.apps.length})`); + console.log(`Total apps chargées: ${config.apps.length}`); } // ============ CREATION D'APPLICATION ============