← back to Dw Boardroom Governance

src/api/routes/meetings.ts

110 lines

import { Router, Request, Response } from 'express';
import * as meetingEngine from '../../engine/meetingEngine';
import { validateAgenda, generateOpeningStatement } from '../../agents/president';

const router = Router();

// GET /api/meetings — list all meetings
router.get('/', async (_req: Request, res: Response) => {
  try {
    const meetings = await meetingEngine.listMeetings();
    res.json(meetings);
  } catch (err: any) {
    res.status(500).json({ error: err.message });
  }
});

// GET /api/meetings/active — get active meeting
router.get('/active', async (_req: Request, res: Response) => {
  try {
    const id = meetingEngine.getActiveMeetingId();
    if (!id) return res.json({ active: false });
    const meeting = await meetingEngine.getMeeting(id);
    const messages = await meetingEngine.getMessages(id);
    res.json({ active: true, meeting, messages });
  } catch (err: any) {
    res.status(500).json({ error: err.message });
  }
});

// GET /api/meetings/:id — meeting detail
router.get('/:id', async (req: Request, res: Response) => {
  try {
    const meeting = await meetingEngine.getMeeting(req.params.id);
    if (!meeting) return res.status(404).json({ error: 'Meeting not found' });
    const messages = await meetingEngine.getMessages(req.params.id);
    res.json({ ...meeting, messages });
  } catch (err: any) {
    res.status(500).json({ error: err.message });
  }
});

// POST /api/meetings/:type — trigger meeting
router.post('/:type', async (req: Request, res: Response) => {
  try {
    const meetingType = req.params.type;
    const agendaItems = req.body.agendaItems || [];

    // Validate agenda if items provided
    if (agendaItems.length > 0) {
      const validation = validateAgenda(agendaItems);
      if (!validation.valid) {
        return res.status(400).json({ error: validation.summary, details: validation.errors });
      }
    }

    const meeting = await meetingEngine.startMeeting(meetingType, agendaItems);

    // Add opening statement
    const opening = generateOpeningStatement(meetingType, agendaItems.length);
    await meetingEngine.addMessage(meeting.id, 'president', 'President', opening, 'opening');

    res.json(meeting);
  } catch (err: any) {
    res.status(400).json({ error: err.message });
  }
});

// POST /api/meetings/:id/halt — halt meeting
router.post('/:id/halt', async (req: Request, res: Response) => {
  try {
    await meetingEngine.haltMeeting(req.params.id);
    res.json({ status: 'halted' });
  } catch (err: any) {
    res.status(400).json({ error: err.message });
  }
});

// POST /api/meetings/:id/advance — advance to next phase
router.post('/:id/advance', async (req: Request, res: Response) => {
  try {
    const phase = await meetingEngine.advancePhase(req.params.id);
    res.json({ phase, completed: phase === null });
  } catch (err: any) {
    res.status(400).json({ error: err.message });
  }
});

// POST /api/meetings/:id/message — add message
router.post('/:id/message', async (req: Request, res: Response) => {
  try {
    const { agentId, agentName, message, messageType } = req.body;
    await meetingEngine.addMessage(req.params.id, agentId, agentName, message, messageType);
    res.json({ status: 'sent' });
  } catch (err: any) {
    res.status(400).json({ error: err.message });
  }
});

// GET /api/meetings/:id/messages — get messages
router.get('/:id/messages', async (req: Request, res: Response) => {
  try {
    const messages = await meetingEngine.getMessages(req.params.id);
    res.json(messages);
  } catch (err: any) {
    res.status(500).json({ error: err.message });
  }
});

export default router;