// apps/hq/test/e2e.test.ts import { describe, it, expect, beforeAll, afterAll } from 'vitest' import express from 'express' import { openDb } from '../src/db' import { seedIfEmpty } from '../src/seed' import { createStaff } from '../src/auth' import { apiRouter } from '../src/api' const db = openDb(':memory:') const app = express(); app.use(express.json()); app.locals['db'] = db; app.use('/api', apiRouter(db)) let server: ReturnType let base = '' beforeAll(async () => { await seedIfEmpty(db) await createStaff(db, { email: 'e2e@test.in', displayName: 'E2E', role: 'owner', password: 'e2e-password' }) server = app.listen(0) base = `http://localhost:${(server.address() as { port: number }).port}/api` }) let token = '' const call = async (method: string, path: string, body?: unknown) => { const res = await fetch(base + path, { method, headers: { 'content-type': 'application/json', authorization: `Bearer ${token}` }, ...(body ? { body: JSON.stringify(body) } : {}) }) return { status: res.status, json: await res.json() as any } } describe('hq end to end', () => { afterAll(() => server.close()) it('walks quotation → invoice → payment → paid', async () => { token = (await call('POST', '/auth/login', { email: 'e2e@test.in', password: 'e2e-password' })).json.token const client = (await call('POST', '/clients', { name: 'Flow Mart', stateCode: '32' })).json.client const mod = (await call('POST', '/modules', { code: 'POS', name: 'POS Billing' })).json.module await call('POST', `/modules/${mod.id}/prices`, { kind: 'yearly', pricePaise: 10_000_00, effectiveFrom: '2026-04-01' }) const qt = (await call('POST', '/documents', { docType: 'QUOTATION', clientId: client.id, lines: [{ moduleId: mod.id, qty: 1, kind: 'yearly' }] })).json.document await call('POST', `/documents/${qt.id}/issue`) const inv = (await call('POST', `/documents/${qt.id}/convert`, { to: 'INVOICE' })).json.document await call('POST', `/documents/${inv.id}/issue`) await call('POST', '/payments', { clientId: client.id, receivedOn: '2026-07-10', mode: 'bank', amountPaise: 11_800_00 }) const after = (await call('GET', `/documents/${inv.id}`)).json.document expect(after.status).toBe('paid') const ledger = (await call('GET', `/clients/${client.id}/ledger`)).json expect(ledger.advancePaise).toBe(0) }) })