← back to Dw Boardroom V2

frontend/src/api.ts

52 lines

const BASE = 'http://45.61.58.125:4040';
// NOTE: this Basic-Auth pair ships in the browser bundle; a build-time inject only
// obscures it, it is not a real secret boundary. Tracked source must not carry the
// literal — set VITE_BOARDROOM_AUTH_PASS at build time (see /secrets). Steve should
// move this UI behind a server-side auth proxy rather than client-side Basic Auth.
const AUTH = btoa(`admin:${import.meta.env.VITE_BOARDROOM_AUTH_PASS ?? ''}`);
const headers: Record<string, string> = {
  'Content-Type': 'application/json',
  'Authorization': `Basic ${AUTH}`,
};

async function apiFetch<T>(path: string, options: RequestInit = {}): Promise<T> {
  const res = await fetch(`${BASE}${path}`, { headers, ...options });
  if (!res.ok) {
    const text = await res.text();
    throw new Error(`${res.status}: ${text}`);
  }
  return res.json();
}

export const api = {
  // Meetings
  getMeetings: () => apiFetch<any[]>('/api/meetings'),
  getActiveMeeting: () => apiFetch<any>('/api/meetings/active'),
  getMeeting: (id: string) => apiFetch<any>(`/api/meetings/${id}`),
  startMeeting: (type: string) => apiFetch<any>(`/api/meetings/start/${type}`, { method: 'POST' }),
  haltMeeting: (id: string) => apiFetch<any>(`/api/meetings/${id}/halt`, { method: 'POST' }),
  advanceMeeting: (id: string) => apiFetch<any>(`/api/meetings/${id}/advance`, { method: 'POST' }),
  addMessage: (id: string, msg: any) => apiFetch<any>(`/api/meetings/${id}/message`, { method: 'POST', body: JSON.stringify(msg) }),
  getMessages: (id: string) => apiFetch<any[]>(`/api/meetings/${id}/messages`),

  // Agents
  getAgents: () => apiFetch<any>('/api/agents'),
  getTeams: () => apiFetch<any>('/api/agents/teams'),
  getAgent: (name: string) => apiFetch<any>(`/api/agents/${name}`),
  speakAgent: (name: string, topic: string, phase?: string) =>
    apiFetch<any>(`/api/agents/${name}/speak`, { method: 'POST', body: JSON.stringify({ topic, phase }) }),

  // Agenda
  getAgenda: (meetingId: string) => apiFetch<any[]>(`/api/agenda/${meetingId}`),
  addAgendaItem: (meetingId: string, item: any) => apiFetch<any>(`/api/agenda/${meetingId}`, { method: 'POST', body: JSON.stringify(item) }),
  updateAgendaItem: (meetingId: string, itemId: number, updates: any) => apiFetch<any>(`/api/agenda/${meetingId}/${itemId}`, { method: 'PUT', body: JSON.stringify(updates) }),
  deleteAgendaItem: (meetingId: string, itemId: number) => apiFetch<any>(`/api/agenda/${meetingId}/${itemId}`, { method: 'DELETE' }),

  // Voice
  getVoiceConfig: () => apiFetch<any>('/api/voice/config'),
  updateVoiceConfig: (cfg: any) => apiFetch<any>('/api/voice/config', { method: 'POST', body: JSON.stringify(cfg) }),

  // Status
  getStatus: () => apiFetch<any>('/api/status'),
};