const backendUrl = process.env.BACKEND_URL ?? 'http://127.0.0.1:9876'; const frontendUrl = process.env.FRONTEND_URL ?? 'http://127.0.0.1:3100'; interface Ticket { id: number; subject: string; } interface Queue { id: string; name: string; } interface Transaction { id: string; ticket_id: number; transaction_type: string; } async function requestJson(url: string): Promise { const response = await fetch(url); if (!response.ok) { throw new Error(`${url} returned ${response.status} ${response.statusText}`); } return response.json() as Promise; } async function requestOk(url: string): Promise { const response = await fetch(url, { method: 'HEAD' }); if (!response.ok) { throw new Error(`${url} returned ${response.status} ${response.statusText}`); } } async function check(name: string, fn: () => Promise): Promise { try { await fn(); console.log(`ok ${name}`); } catch (err) { const message = err instanceof Error ? err.message : String(err); console.error(`fail ${name}`); console.error(` ${message}`); process.exitCode = 1; } } async function main() { let ticketForDetail: Ticket | null = null; await check('backend health', async () => { const health = await requestJson<{ status: string }>(`${backendUrl}/health`); if (health.status !== 'ok') { throw new Error(`expected status ok, got ${JSON.stringify(health)}`); } }); await check('queues exist', async () => { const queues = await requestJson(`${backendUrl}/queues`); if (queues.length < 1) { throw new Error('expected at least one queue'); } }); await check('tickets exist', async () => { const tickets = await requestJson(`${backendUrl}/tickets`); if (tickets.length < 1) { throw new Error('expected at least one ticket'); } ticketForDetail = tickets.find((ticket) => ticket.subject.includes('VPN access')) ?? tickets[0] ?? null; }); await check('ticket detail has activity', async () => { if (!ticketForDetail) { throw new Error('no ticket available for detail check'); } const transactions = await requestJson( `${backendUrl}/tickets/${ticketForDetail.id}/transactions`, ); if (transactions.length < 1) { throw new Error(`expected ticket ${ticketForDetail.id} to have transactions`); } }); await check('frontend index responds', async () => { await requestOk(frontendUrl); }); await check('frontend ticket detail responds', async () => { if (!ticketForDetail) { throw new Error('no ticket available for frontend detail check'); } await requestOk(`${frontendUrl}/tickets/${ticketForDetail.id}`); }); await check('frontend api proxy responds', async () => { const health = await requestJson<{ status: string }>(`${frontendUrl}/api/health`); if (health.status !== 'ok') { throw new Error(`expected status ok, got ${JSON.stringify(health)}`); } }); if (process.exitCode) { process.exit(process.exitCode); } console.log('Smoke test passed'); } main().catch((err) => { console.error(err); process.exit(1); });