Compliance Portal
Producer licensing, state filings, and compliance analytics.
The Finance Portal (apps/finance-portal, oi-sys-finance) is a dedicated Next.js application for the Finance / Accounting team. It surfaces TigerBeetle double-entry ledger data, accounts receivable aging, statutory financials, reconciliation workflows, and a flexible report builder — all scoped behind the finance_analyst JWT role.
| Environment | URL |
|---|---|
| Production | https://finance.openinsure.dev |
| Local dev | http://localhost:3006 |
Use the standard OpenInsure sign-in flow. The Finance Portal sets the oi_finance_token cookie, verified against FINANCE_JWT_SECRET.
GET https://auth-dev.openinsure.dev/api/auth/sign-in/microsoft ?callbackURL=https://finance.openinsure.dev/api/auth/callback| JWT role | SpiceDB org relation | Description |
|---|---|---|
finance_analyst | finance | Standard finance team access |
superadmin | — | Full access |
system | — | Machine-to-machine (M2M) |
The finance_analyst role is enforced in apps/finance-portal/lib/auth.ts. The middleware rejects any JWT that does not carry one of these three roles and redirects unauthenticated requests to /login.
| Section | Page | Route |
|---|---|---|
| Overview | Dashboard | / |
| Analytics | Entities | /analytics/entities |
| Analytics | Pipeline | /analytics/pipeline |
| Analytics | Captive | /analytics/captive |
| Reports | AR Aging | /reports/ar-aging |
| Reports | Financials | /reports/financials |
| Reports | Reconciliation | /reports/reconciliation |
| Reports | Statutory | /reports/statutory |
| Reports | Chart of Accounts | /reports/chart-of-accounts |
| Reports | Report Builder | /reports/builder |
/)Three-pane layout (flex h-full overflow-hidden) with period toggle and live non-pay queue:
Left pane (w-64) — KPI sidebar:
?period=ytd URL param), default ytdKPICard for GWP (Gross Written Premium) — neutral statusKPICard for AR Outstanding — status='warn' if balance > 0KPICard for Loss Ratio — status='warn' if > 65%, status='critical' if > 85%Center pane (flex-1) — AR Aging visualization:
> 90d → red, > 30d → amber, else mutedRight pane (w-72) — NonPayQueue client component:
refetchInterval: 60_000) with initialData from server renderAPI calls (parallel via Promise.all):
GET /v1/analytics/mga?period=${period} — GWP + loss ratioGET /v1/reports/ar-aging — bucket bars + top 5 overdue rows (amounts in cents)GET /v1/billing/non-pay-queue — non-pay entries for right pane (amountDue in dollars)Source: apps/finance-portal/app/(dashboard)/non-pay-queue.tsx (client island)
/reports/ar-aging)Accounts receivable aging report grouped into 30/60/90/90+ day buckets. Fetches from GET /v1/reports/ar-aging. Exportable as CSV via the ExportToolbar component.
/reports/financials)Income statement and balance sheet views sourced from the TigerBeetle ledger (GET /v1/reports/financials). Supports period selection (MTD, QTD, YTD, custom range). Income statement and balance sheet views are backed by getTrialBalance() from the TigerBeetle ledger client, which queries all 9 account types concurrently and returns debit/credit totals with a balanced boolean.
The 9 account types queried are: Carrier Payable (1), MGA Fiduciary (2), MGA Revenue (3), Producer Payable (4), Tax Authority Payable (5), Loss Fund (6), Claims Paid (7), Reserves (8), and Reinsurer Payable (9). Each row in the trial balance reports total debits, total credits, and net balance in integer cents.
/reports/reconciliation)Displays unreconciled ledger entries with status badges. Individual entries can be marked reconciled via PATCH /v1/reports/reconciliation/:id. Changes optimistically update the UI.
/reports/statutory)State statutory financial exhibits for regulatory filing. Data from GET /v1/reports/statutory. Read-only; the actual filing workflow lives in the Compliance Portal.
/reports/chart-of-accounts)Full account hierarchy from TigerBeetle. Sortable and searchable.
The TigerBeetle ledger client provides two audit-grade reporting methods:
Trial Balance (getTrialBalance()) — Queries all 9 account types concurrently via Promise.all. Each row contains the account ID, account type code (1-9), human-readable name, total credits, total debits, and net balance — all in integer cents. Returns a balanced flag confirming debits equal credits across the organization’s subledger.
| Code | Account Name |
|---|---|
| 1 | Carrier Payable |
| 2 | MGA Fiduciary |
| 3 | MGA Revenue |
| 4 | Producer Payable |
| 5 | Tax Authority Payable |
| 6 | Loss Fund |
| 7 | Claims Paid |
| 8 | Reserves |
| 9 | Reinsurer Payable |
Journal Entries (getJournalEntries()) — Filtered transfer history through the MGA fiduciary hub account. Supports from/to date-range filtering (converted to TigerBeetle nanosecond timestamps) and a limit parameter (default 100). Each entry includes the transfer ID, debit/credit account IDs, amount in cents, transfer code, and timestamp.
/reports/builder)Flexible pivot-style report builder. Saved report configurations are persisted via POST /v1/reports/builder. Results can be exported to CSV or PDF.
The Finance Portal proxies API requests through apps/finance-portal/app/api/[...path]/route.ts, gated by lib/proxy-allowlist.ts:
GET /v1/analytics/entitiesGET /v1/analytics/pipelineGET /v1/analytics/captiveGET /v1/reports/ar-agingGET /v1/reports/statutoryGET /v1/reports/financialsGET /v1/reports/reconciliationPATCH /v1/reports/reconciliation/:idGET /v1/reports/chart-of-accountsGET /v1/reports/builderPOST /v1/reports/builderGET /v1/billing/non-pay-queueGET /v1/ledger/accountsGET /v1/ledger/transfersGET /v1/ledger/trial-balanceGET /v1/ledger/journal-entriesGET /v1/ledger/lookup-transfersGET /v1/ledger/:orgId/transfersAny request not in the allowlist returns 403 Forbidden.
| Variable | Description |
|---|---|
FINANCE_JWT_SECRET | JWT signing secret — set via wrangler secret put |
API_URL | API worker base URL (e.g., https://api.openinsure.dev) |
NEXT_PUBLIC_APP_NAME | "Finance Portal" — set in wrangler.toml [vars] |
# Set the JWT secret (production)wrangler secret put FINANCE_JWT_SECRET --name oi-sys-finance
# Local dev (.env.local)FINANCE_JWT_SECRET=9d79c38aa7d57bd24a1afe213848b2b935519afb08a3923ac112aed71fd5bc21API_URL=http://localhost:8787DEMO_MODE=trueThe Finance Portal deploys as an OpenNext Cloudflare Worker (oi-sys-finance):
# Build + deploycd apps/finance-portalnpx opennextjs-cloudflare deploy -- --keep-vars
# Or via pnpm filterpnpm --filter @openinsure/finance-portal deployCI deploys automatically from master when apps/finance-portal/ or shared packages change. See CI/CD for the full pipeline.
Compliance Portal
Producer licensing, state filings, and compliance analytics.
Authentication
JWT roles, portal cookies, and SpiceDB authorization.