// Bootstrap "stato di fabbrica" automatico all'avvio. // // Se all'avvio del server NON ci sono card in data/cards.txt (file mancante o `[]`) // E esiste factory/preset.zip, il preset viene estratto sopra a data/. // È quello che permette a una macchina appena clonata/distribuita di partire con // lo stato standard senza interventi manuali. import { readFile, access } from 'node:fs/promises'; import path from 'node:path'; import { restoreFromZipFile } from './restore-zip'; const PROJECT_ROOT = process.cwd(); const CARDS_FILE = path.join(PROJECT_ROOT, 'data', 'cards.txt'); const PRESET_PATH = path.join(PROJECT_ROOT, 'factory', 'preset.zip'); async function hasCards(): Promise { try { const raw = await readFile(CARDS_FILE, 'utf-8'); const parsed = JSON.parse(raw || '[]'); return Array.isArray(parsed) && parsed.length > 0; } catch { return false; } } export async function bootstrapFromFactoryPresetIfEmpty(): Promise { // Niente preset di fabbrica → niente da fare, sezione opzionale. try { await access(PRESET_PATH); } catch { return; } // Stato non vuoto → l'admin ha già contenuti, non sovrascriviamo. if (await hasCards()) return; console.log('[bootstrap] No cards found; restoring factory preset from factory/preset.zip'); const result = await restoreFromZipFile(PRESET_PATH); if (result.ok) { console.log(`[bootstrap] Restored ${result.cards} cards, ${result.portals} portals from factory preset`); } else { console.warn(`[bootstrap] Factory restore failed: ${result.error}${result.detail ? ` (${result.detail})` : ''}`); } }