"""Single source of truth for filesystem paths used by MP Manager. Todo lo que genere la app (DB, reports, logs, screenshots, sesiones de Playwright, estado de runtime, exports descargables, snapshots de migración) vive bajo `generated/` con subcarpetas semánticas. Importa las constantes desde aquí en lugar de hardcodear rutas: cualquier cambio futuro se hace en un solo lugar. Al importarse, `ensure_dirs()` se ejecuta automáticamente para crear las carpetas que falten. Es idempotente. """ import os BASE_DIR = os.path.dirname(os.path.abspath(__file__)) GENERATED_DIR = os.path.join(BASE_DIR, "generated") # --- Base de datos SQLite local --- DATA_DIR = os.path.join(GENERATED_DIR, "data") DB_PATH = os.path.join(DATA_DIR, "mp_manager.sqlite") # --- Reports de scripts (auditorías, análisis, diffs) --- REPORTS_DIR = os.path.join(GENERATED_DIR, "reports") REPORT_AUDIT_CUSTOM_FIELDS = os.path.join(REPORTS_DIR, "audit_custom_fields") REPORT_DUPLICADOS = os.path.join(REPORTS_DIR, "duplicados") REPORT_DRIFT = os.path.join(REPORTS_DIR, "drift") REPORT_COVERAGE = os.path.join(REPORTS_DIR, "coverage") REPORT_WORKFLOW_ANOMALIES = os.path.join(REPORTS_DIR, "workflow_anomalies") # --- Exports servidos al dashboard vía /api/exports/{filename} --- EXPORTS_DIR = os.path.join(GENERATED_DIR, "exports") # --- Logs (errors centralizados + logs por run de script) --- LOGS_DIR = os.path.join(GENERATED_DIR, "logs") ERROR_LOG_PATH = os.path.join(LOGS_DIR, "errors.jsonl") SCRIPT_RUNS_DIR = os.path.join(LOGS_DIR, "script_runs") # --- Snapshots pre-destructive de scripts mutadores --- MIGRATIONS_DIR = os.path.join(GENERATED_DIR, "migrations") # --- Playwright: sesión shared, perfil persistente, screenshots de debug --- BROWSER_DIR = os.path.join(GENERATED_DIR, "browser") SESSION_FILE = os.path.join(BROWSER_DIR, "session.json") BROWSER_PROFILE_DEFAULT = os.path.join(BROWSER_DIR, "profile") SCREENSHOTS_DIR = os.path.join(BROWSER_DIR, "screenshots") # --- Estado de runtime del server (PID/puerto, modo activo, bulk batches en vuelo) --- RUNTIME_DIR = os.path.join(GENERATED_DIR, "runtime") SERVER_INFO = os.path.join(RUNTIME_DIR, "server_info.json") LAST_MODE = os.path.join(RUNTIME_DIR, "last_mode") BATCH_DIR = os.path.join(RUNTIME_DIR, "batch") # --- Archivo histórico (basura legacy y backups antiguos) --- ARCHIVE_DIR = os.path.join(GENERATED_DIR, "_archive") # --- Capa agentica (MCP): manifiesto, runs y auditoría de tools LLM --- AGENT_DIR = os.path.join(GENERATED_DIR, "agent") AGENT_RUNS_DIR = os.path.join(AGENT_DIR, "runs") AGENT_MANIFEST_PATH = os.path.join(AGENT_DIR, "tools_manifest.json") AGENT_AUDIT_REPORT = os.path.join(AGENT_DIR, "audit_report.json") _ALL_DIRS = ( DATA_DIR, REPORTS_DIR, REPORT_AUDIT_CUSTOM_FIELDS, REPORT_DUPLICADOS, REPORT_DRIFT, REPORT_COVERAGE, REPORT_WORKFLOW_ANOMALIES, EXPORTS_DIR, LOGS_DIR, SCRIPT_RUNS_DIR, MIGRATIONS_DIR, BROWSER_DIR, SCREENSHOTS_DIR, RUNTIME_DIR, BATCH_DIR, ARCHIVE_DIR, AGENT_DIR, AGENT_RUNS_DIR, ) def ensure_dirs(): """Crea las carpetas de `generated/` si no existen. Idempotente.""" for d in _ALL_DIRS: os.makedirs(d, exist_ok=True) ensure_dirs()