import { Router } from 'express'; import { asyncWrap } from '../errors.js'; import { requireOwner } from '../cap.js'; import * as repo from '../../db/repos/improvements.js'; import { recordAudit } from '../../db/repos/audit.js'; export const router = Router(); router.get('/', asyncWrap(async (_req, res) => res.json(await repo.list()))); router.get('/:id', asyncWrap(async (req, res) => { const row = await repo.get(req.params.id); if (!row) return res.status(404).json({ error: 'not_found' }); res.json(row); })); for (const verb of ['approve', 'rollback', 'restore', 'reject']) { router.post(`/:id/${verb}`, requireOwner, asyncWrap(async (req, res) => { const row = await repo.transition(req.params.id, verb, 'owner'); if (!row) return res.status(409).json({ error: 'invalid_transition' }); const auditAction = { approve: 'approve', reject: 'reject', rollback: 'update', restore: 'update' }[verb]; await recordAudit({ kind: 'user' }, auditAction, 'improvement', row.id, null, { verb, summary: row.summary }); res.json(row); })); } // Public stylesheet of ACTIVE improvements. Unauthenticated by design: it carries // no secrets (owner-approved, exfil-sanitized CSS only) and can't send a // bearer token. Mounted on the app root, outside the /api auth wall. export async function cssHandler(_req, res) { res.set({ 'Content-Type': 'text/css; charset=utf-8', 'Cache-Control': 'no-cache' }); res.send(await repo.activeCss()); }