Skip to content

Database Schema

OpenInsure uses PlanetScale (Vitess 22.0) as its primary database, accessed from Cloudflare Workers via Hyperdrive connection pooling. The ORM is Drizzle 0.45 with a schema-first approach — all tables are defined in TypeScript and migrations are generated by the Drizzle CLI.

Database schema, migrations, and query utilities live in packages/db:

packages/db/
├── src/
│ └── supabase/
│ └── schema/ # Table definitions (Drizzle)
│ ├── index.ts # Central re-export
│ ├── submissions.ts
│ ├── policies.ts
│ └── ...
├── migrations/
│ └── postgres/ # SQL migration files (0000–0081+)
│ ├── 0000_kind_famine.sql
│ ├── ...
│ └── meta/ # Drizzle migration journal
├── seeds/
│ └── demo-data.sql # Demo seed data
└── drizzle.config.ts # Drizzle CLI config
import { createDb } from '@openinsure/db';
// In a Cloudflare Worker handler:
const db = createDb(env.HYPERDRIVE);
// env.HYPERDRIVE is the Cloudflare Hyperdrive binding
// configured in wrangler.toml under [[hyperdrive]]

Hyperdrive pools TCP connections to PlanetScale, giving Workers the connection efficiency of a traditional server. Max 5 connections per client; Hyperdrive handles pooling across Worker instances.

All queries run inside a transaction that applies the orgId filter, ensuring every SELECT, INSERT, UPDATE, and DELETE is scoped to the authenticated user’s organization.

await db.transaction(async (tx) => {
await setOrgContext(tx, orgId); // MUST be called inside transaction
const policies = await tx.select().from(schema.policies);
// Only returns policies for this org
});

The schema is organized into domain groups. All 78+ tables are in packages/db/src/supabase/schema/.

TableDescription
organizationsTenant organizations
usersAuthenticated users (synced from oi-sys-auth D1)
api_keysAPI key credentials with role and org scoping
activitiesActivity diary — all user actions
notificationsNotification queue (in-app, email, SMS)
webhooksWebhook event delivery log
saved_viewsUser-defined data view configurations
chat_historyAI agent conversation transcripts
TableDescription
producersProducer/agency profiles and license status
programsUnderwriting program definitions
delegated_authorityDA agreement terms and authority limits
TableDescription
submissionsSubmission lifecycle (new → quoted → bound → declined)
submission_conditionsConditions attached to a submission
submission_notesNotes with visibility control (internal/external)
submission_eventsActivity timeline per submission
submission_documentsDocument attachments to submissions
quote_optionsQuote variants (coverage options, pricing tiers)
rulesUnderwriting rules configuration
underwriting_rulesRules engine evaluation results
approvalsApproval queue items with audit trail

Aspire Application Detail (Commercial Auto)

Section titled “Aspire Application Detail (Commercial Auto)”

These tables store the detailed application data entered through the Aspire form tab system. Each table has an application_id FK to submissions.

TableDescription
application_insuredInsured company info (name, DBA, tax ID, contact details)
application_contactsContact records (corporate, inspection) with name, email, phone, cell
application_addressesMailing and physical addresses
application_coverageCoverage config (CSL limit, deductibles, hired auto, waivers)
application_operationsOperations (max radius, mileage distribution %, Canada/Mexico)
application_vehiclesVehicle schedule (VIN, year, make, model, body type, ownership, ACV)
application_vehicle_coveragesPer-vehicle comp/collision limits and deductibles
application_driversDriver roster (name, DOB, license, MVR points, violations, accidents)
application_driver_general_infoAggregate driver info (total employees, hiring rates, MVR review)
application_driver_violationsIndividual driver violation records
application_prior_carriersPrior carrier history (carrier, dates, coverage type, reason for change)
application_loss_recordsLoss history (per-year accidents, claims, incurred, loss ratio)
application_work_experienceWork experience (new ventures — company, role, dates, supervisor)
application_officersOfficers/stockholders (title, name, ownership %)
application_underwriting_qaKnockout questions (~23 yes/no fields for referral triggers)
application_cargoCargo coverage (limit, deductible, commodities)
application_physical_damagePhysical damage (comp/collision limits and deductibles)
application_trailer_interchangeTrailer interchange (limit, deductible, trailer types)
application_additional_coverageMisc coverages (rental reimbursement, towing, medical payments)
application_additional_interestsAdditional interests (mortgagee, loss payee, lienholder)
application_filingsRegulatory filings (BMC-91, BMC-34, Form E/H, MCS-90)
application_attachmentsFile attachments stored in Cloudflare R2
TableDescription
policiesPolicy header (number, status, dates, premium)
policyExtended policy detail (jacket data)
coveragesLine-level coverage records per policy
endorsementsPolicy modification history
interestsAdditional insureds, mortgagees, loss payees
driversDriver records (commercial auto)
vehiclesVehicle/equipment schedule
vehicle_coveragesPer-vehicle coverage elections
documentsPolicy documents with R2 key references
coiCertificate of Insurance records
esignE-signature audit trail (Documenso)
TableDescription
rate_tablesRate table definitions and factor matrices
ratingRating results with canonical payload and audit trail
rating_resultsSource-tagged rating outputs (manual vs system)
market_benchmarksPeer market pricing benchmarks
TableDescription
claimsClaim header (number, status, loss date)
claim_lifecycleClaim status transition history
claim_notesClaim notes with visibility
claim_tasksClaim work items and diary entries
claimantsClaimant party information
claim_transactionsFinancial transactions (payments, recoveries)
litigation_timersStatute of limitations countdown
disbursementsClaim payment disbursements
subrogationSubrogation tracking and recovery
fraud_feedbackFraud model feedback and outcome labels
TableDescription
billingInvoice and billing records
invoice_line_itemsLine-item detail for invoices
chart_of_accountsGeneral ledger account hierarchy
general_ledgerDouble-entry ledger transactions
reconciliationLedger reconciliation state
disbursementsPayment disbursement records
ap_transactionsAccounts payable transaction log
reinsuranceReinsurance placement, cession, and recovery
premium_financePremium finance contracts
loss_reservesActuarial loss reserve records
bordereauxBordereaux submission records
bordereaux_reviewsCarrier bordereaux review outcomes
TableDescription
complianceCompliance filing calendar
filingsIndividual regulatory filing records
blacklistBlocked entities and IP addresses
report_schedulesScheduled automated report configuration
statutory_reportingStatutory exhibit data
TableDescription
captive_accountingCaptive fund accounting records
loss_runsLoss history import and analysis
inspectionsRisk inspection records
smart_contractsBlockchain integration hooks
TableDescription
vectorsEmbedding vectors for semantic search
territoriesGeographic territory and radius-of-operations
commodity_mixCommodity exposure schedule
motor_carriersDOT/FMCSA motor carrier detail
telematicsGPS and driver safety score data
formsForm template library
document_requirementsRequired document checklists by program

Schema files live in packages/db/src/schema/ and are pushed to PlanetScale via Drizzle:

Terminal window
# Generate a new migration from schema changes
cd packages/db
pnpm drizzle-kit generate
# Apply migrations to the database
pnpm drizzle-kit push
# Or run via the migration job (CI/CD)
DATABASE_URL=$DATABASE_URL pnpm drizzle-kit migrate

The CircleCI db-migrate workflow runs on master push and applies pending migrations to the PlanetScale production branch.

MigrationPurpose
0010_row_level_security.sqlOrg-scoped tenant isolation setup
0023_performance_scaling_indexes.sqlComposite indexes for common query patterns
0071_rls_comprehensive.sqlComprehensive tenant isolation gap closure
0072_foreign_keys.sqlFK constraints across all domain tables
0074_general_ledger.sqlDouble-entry ledger table
0080_documents_r2_key.sqlR2 object key column on documents
0081_submissions_carrier_id.sqlCarrier ID on submissions for gateway routing

Demo data seeds a realistic policy portfolio for development and demos:

Terminal window
pscale shell openinsure main < packages/db/seeds/demo-data.sql

Seeded records:

TypeCountNotable IDs
Organization100000000-0000-4000-a000-000000000001
Programs2GL ...000011, WC ...000012
Rate Tables2GL ...000021, WC ...000022
Users4matt, michael, sean, jd (10000000-...000X)
Policies2WC Metro ...000201, GL Acme ...000202
Claims3Open ...000301, Closed ...000302, Pending ...000303

PlanetScale’s database branching lets developers create isolated database branches for feature development:

Terminal window
# Create a branch for a feature
pscale branch create openinsure feat/my-feature
# Run migrations against the branch
DATABASE_URL=$(pscale connect openinsure feat/my-feature --execute 'echo') pnpm drizzle-kit push
# Delete branch when done
pscale branch delete openinsure feat/my-feature

Manage branches via pscale CLI or the PlanetScale dashboard at app.planetscale.com.

Packages Overview

All @openinsure/* packages, exports, and consumers.

Architecture

Edge/origin split, Hyperdrive, and data flow.