// server/routes/actionRequests.ts import { Hono } from "hono"; import { createActionRequest, getActionRequest, listActionRequests, approveActionRequest, rejectActionRequest, } from "../services/actionRequests.js"; import type { ActionType } from "@shared/types.js"; export const actionRequestsRoutes = new Hono(); // Crée une demande d'action destructive (pending). Hermes/UI proposent ; aucune exécution ici. actionRequestsRoutes.post("/machines/:id/action-requests", async (c) => { const body = (await c.req.json()) as { action: ActionType; stackId?: string; aggressive?: boolean; summary?: string; requestedByType?: "user" | "hermes" | "schedule"; }; try { const req = createActionRequest({ machineId: c.req.param("id"), action: body.action, requestedByType: body.requestedByType, summary: body.summary, payload: { stackId: body.stackId, aggressive: body.aggressive }, }); return c.json(req, 201); } catch (err) { return c.json({ error: (err as Error).message }, 400); } }); actionRequestsRoutes.get("/machines/:id/action-requests", (c) => c.json(listActionRequests(c.req.param("id"))), ); actionRequestsRoutes.get("/action-requests/:reqId", (c) => { const req = getActionRequest(c.req.param("reqId")); return req ? c.json(req) : c.json({ error: "Demande introuvable" }, 404); }); // Validation opérateur → déclenche l'exécution en arrière-plan. actionRequestsRoutes.post("/action-requests/:reqId/approve", async (c) => { const body = (await c.req.json().catch(() => ({}))) as { approvedBy?: string }; try { return c.json(approveActionRequest(c.req.param("reqId"), body.approvedBy), 202); } catch (err) { return c.json({ error: (err as Error).message }, 400); } }); actionRequestsRoutes.post("/action-requests/:reqId/reject", async (c) => { const body = (await c.req.json().catch(() => ({}))) as { by?: string }; try { return c.json(rejectActionRequest(c.req.param("reqId"), body.by)); } catch (err) { return c.json({ error: (err as Error).message }, 400); } });