import { json } from '@sveltejs/kit'; import { DriftPlanChanged, previewDrift, runDriftDeployment } from '$lib/server/fleet/drift.js'; import { kick } from '$lib/server/pipeline/worker.js'; // GET returns the current drift plan for the whole fleet without touching disk. export async function GET() { const plan = await previewDrift(); const entries = plan.files.map(file => ({ ...file, size: file.afterSize ?? file.beforeSize ?? 0, sha256: file.afterSha256 ?? file.beforeSha256 ?? '' })); const byServer = new Map< string, Array<{ relPath: string; size: number; sha256: string; kind: string; driftKind: string }> >(); for (const e of entries) { const arr = byServer.get(e.server) ?? []; arr.push({ relPath: e.relPath, size: e.size, sha256: e.sha256, kind: e.kind, driftKind: e.driftKind }); byServer.set(e.server, arr); } return json({ totalDrift: entries.length, scannedAt: plan.scannedAt, servers: [...byServer.entries()].map(([server, files]) => ({ server, files })) }); } // POST removes drift and creates a drift deployment. Body: { servers?: string[], dryRun?: boolean } export async function POST({ request }: { request: Request }) { const body = await request.json().catch(() => null); if (!body || (body.servers !== undefined && (!Array.isArray(body.servers) || !body.servers.every((server: unknown) => typeof server === 'string')))) { return json({ ok: false, error: 'Provide the server IDs to review.' }, { status: 400 }); } try { if (body.dryRun === true) return json({ ok: true, plan: await previewDrift(body.servers) }); if (typeof body.expectedFingerprint !== 'string' || !body.expectedFingerprint) return json({ ok: false, error: 'Review a reconciliation plan before applying changes.' }, { status: 400 }); const result = await runDriftDeployment({ servers: body.servers, expectedFingerprint: body.expectedFingerprint, triggeredBy: 'ui' }); if (result.deploymentId) void kick(); return json({ ok: true, result }); } catch (error) { if (error instanceof DriftPlanChanged) return json({ ok: false, error: error.message, plan: error.plan }, { status: 409 }); return json({ ok: false, error: (error as Error).message }, { status: 400 }); } }