#!/usr/bin/env node // Capture un snapshot HA RÉEL depuis une exécution n8n récente du workflow EVCS // → tests/golden/fixture-snapshot.json (base des scénarios golden). // Usage: node tools/fetch-snapshot-fixture.mjs [executionId] import fs from 'fs'; import os from 'os'; import path from 'path'; const WORKFLOW_ID = 'ATswvGfG4KJUls0K'; const SNAPSHOT_NODE = 'HA Snapshot EVCS Surplus Controller V2.2'; const OUT = 'tests/golden/fixture-snapshot.json'; function loadApiConfig() { const cfgPath = path.join(os.homedir(), '.config/opencode/opencode.json'); const cfg = JSON.parse(fs.readFileSync(cfgPath, 'utf8')); const env = cfg?.mcp?.['n8n-mcp']?.environment || {}; return { url: (env.N8N_API_URL || '').replace(/\/api\/v1\/?$/, ''), key: env.N8N_API_KEY }; } const { url, key } = loadApiConfig(); const headers = { 'X-N8N-API-KEY': key }; let execId = process.argv[2]; if (!execId) { const res = await fetch(`${url}/api/v1/executions?workflowId=${WORKFLOW_ID}&status=success&limit=1`, { headers }); const list = await res.json(); execId = list.data?.[0]?.id; if (!execId) { console.error('Aucune exécution trouvée'); process.exit(1); } } const res = await fetch(`${url}/api/v1/executions/${execId}?includeData=true`, { headers }); if (!res.ok) { console.error(`GET exécution ${execId}: ${res.status}`); process.exit(1); } const exec = await res.json(); const runData = exec.data?.resultData?.runData; if (!runData?.[SNAPSHOT_NODE]) { console.error(`Node "${SNAPSHOT_NODE}" absent des données. Nodes dispo: ${Object.keys(runData || {}).join(', ')}`); process.exit(1); } const items = runData[SNAPSHOT_NODE][0]?.data?.main?.[0]; if (!items?.length) { console.error('Pas de données de sortie sur le node snapshot'); process.exit(1); } const snapshot = items[0].json; fs.mkdirSync(path.dirname(OUT), { recursive: true }); fs.writeFileSync(OUT, JSON.stringify(snapshot, null, 2) + '\n'); console.log(`Fixture écrite: ${OUT} (exécution ${execId}, ${Object.keys(snapshot).length} champs)`); console.log(`Champs: ${Object.keys(snapshot).sort().join(', ')}`);