import Fastify from "fastify"; import { z } from "zod"; import { renderPresentation } from "./render.js"; const app = Fastify({ logger: true }); const Slide = z.object({ layout: z.enum(["title", "section", "bullets", "chart_and_insight", "image_reference"]).default("bullets"), title: z.string(), subtitle: z.string().optional(), bullets: z.array(z.string()).default([]), insights: z.array(z.string()).default([]), notes: z.string().optional() }); const Presentation = z.object({ title: z.string(), theme: z.record(z.unknown()).default({}), slides: z.array(Slide).default([]), provenance: z.array(z.record(z.unknown())).default([]) }); app.get("/health", async () => ({ status: "ok" })); app.post("/render", async (request, reply) => { const spec = Presentation.parse(request.body); const pptx = await renderPresentation(spec); reply.header("content-type", "application/vnd.openxmlformats-officedocument.presentationml.presentation"); reply.header("content-disposition", "attachment; filename=\"visual-runtime-deck.pptx\""); return reply.send(pptx); }); const port = Number(process.env.PORT ?? 8787); await app.listen({ host: "0.0.0.0", port });