import { NextRequest } from 'next/server'; import { FIRMS, findAutomation, automationKey, describeStep, resolveSteps } from '@/lib/automations'; import { createRun, getSetting } from '@/lib/db'; import { corsJson, corsPreflight } from '../cors'; /** The dashboard renders a tab per firm, and a button per automation inside it. */ export async function GET() { return corsJson({ firms: FIRMS.map((firm) => ({ id: firm.id, label: firm.label, urlPattern: firm.urlPattern, automations: firm.automations.map((a) => ({ key: automationKey(firm.id, a.id), id: a.id, label: a.label, description: a.description, confirm: a.confirm ?? null, inputs: a.inputs ?? [], steps: a.steps.map(describeStep), })), })), }); } /** Queue a run. The Python runner picks it up. */ export async function POST(req: NextRequest) { try { const body = await req.json() as { automationId?: unknown; inputs?: unknown }; if (typeof body.automationId !== 'string') { return corsJson({ error: '`automationId` is required' }, { status: 400 }); } const found = findAutomation(body.automationId); if (!found) { return corsJson({ error: `No automation "${body.automationId}"` }, { status: 404 }); } if (found.automation.steps.length === 0) { return corsJson({ error: `"${found.automation.label}" has no steps yet` }, { status: 400 }); } // The dashboard switch is the master arm for anything that drives the mouse. if (getSetting('autobuyer_enabled') !== '1') { return corsJson({ error: 'AutoBuyer is switched off' }, { status: 409 }); } // Clamp every input to what the automation declared. The count decides how // many times a purchase runs, so it is not taken on trust from the client. const supplied = (body.inputs ?? {}) as Record; const inputs: Record = {}; for (const declared of found.automation.inputs ?? []) { const raw = Number(supplied[declared.id]); const value = Number.isFinite(raw) ? Math.floor(raw) : declared.default; inputs[declared.id] = Math.min(declared.max, Math.max(declared.min, value)); } let resolved; try { resolved = resolveSteps(found.firm, found.automation, inputs); } catch (err: any) { return corsJson({ error: err?.message ?? 'Could not expand the steps' }, { status: 400 }); } const run = createRun(body.automationId, resolved.length, inputs); return corsJson({ runId: run.id, totalSteps: run.total_steps, inputs }); } catch (err: any) { return corsJson({ error: err?.message ?? 'Failed to queue run' }, { status: 500 }); } } export async function OPTIONS() { return corsPreflight(); }