import { Router } from 'express'; import { z } from 'zod'; import * as repo from '../../db/repos/conversations.js'; import { validate } from '../validate.js'; import { parsePagination } from '../pagination.js'; import { NotFoundError, asyncWrap } from '../errors.js'; const STATUSES = ['open', 'summarized', 'archived']; const createSchema = z.object({ title: z.string().nullable().optional(), agent_id: z.string().uuid().nullable().optional(), participants: z.array(z.string()).optional(), metadata: z.record(z.string(), z.any()).optional() }); const statusSchema = z.object({ status: z.enum(STATUSES) }); const summarySchema = z.object({ summary: z.string().min(1) }); const idParams = z.object({ id: z.string().uuid() }); export const router = Router(); router.get('/', validate({ query: z.object({ limit: z.string().optional(), offset: z.string().optional() }) }), asyncWrap(async (req, res) => { const { limit, offset } = parsePagination(req); res.json(await repo.list({ limit, offset })); }) ); router.post('/', validate({ body: createSchema }), asyncWrap(async (req, res) => { const row = await repo.create(req.body, req.actor); res.status(201).json(row); }) ); router.get('/:id', validate({ params: idParams }), asyncWrap(async (req, res) => { const row = await repo.getById(req.params.id); if (!row) throw new NotFoundError('conversation not found'); res.json(row); }) ); router.patch('/:id/status', validate({ params: idParams, body: statusSchema }), asyncWrap(async (req, res) => { const existing = await repo.getById(req.params.id); if (!existing) throw new NotFoundError('conversation not found'); res.json(await repo.setStatus(req.params.id, req.body.status, req.actor)); }) ); router.patch('/:id/summary', validate({ params: idParams, body: summarySchema }), asyncWrap(async (req, res) => { const existing = await repo.getById(req.params.id); if (!existing) throw new NotFoundError('conversation not found'); res.json(await repo.setSummary(req.params.id, req.body.summary)); }) );