Skip to main content
OpenInsure uses a CircleCI-native CI/CD pipeline. GitHub is used exclusively as a version-control host — there is no GitHub Actions integration and no GitHub VCS link in CircleCI. All automated quality enforcement, testing, security scanning, and deployment runs in CircleCI.
Caution: CircleCI project slug: circleci/HW2RogsnMHUCC7jGBX9nec/Fuwa3GUWKCGnbJuUY6MJps
When adding environment variables via the CircleCI API use:
POST /api/v2/project/circleci/<org>/<project>/envvar
Not the github/<org>/<repo> path — that returns 404.

Pipeline Overview

The .circleci/config.yml defines five sequential jobs that form the full quality gate:
quick-checks → lint → test → quality-gate → security-scan

                                        (on tag) deploy
Additionally a renovate-deps job runs on a weekly schedule (Monday 06:00 ET) to open dependency update PRs via Renovate.

Job: quick-checks

Fast, cheap validation that runs first to catch obvious problems:
StepCommandPurpose
Type checktsp compile typespec/Validate TypeSpec API spec
Dead codepnpm exec knip --reporter compactDetect unused exports/deps
Workspace invariantspnpm exec sherifVerify pnpm workspace consistency
Unit smokepnpm --filter @openinsure/types testFast type-level sanity check

Job: lint

Code quality and formatting:
StepCommandPurpose
Biomebiome check .Lint + format all TypeScript/TSX
Oxlintpnpm turbo oxlintSecondary linter pass

Job: test

Full test suite with coverage reporting:
pnpm turbo test
Coverage is uploaded to Codecov after every green test run (requires CODECOV_TOKEN env var).

Job: quality-gate

Integration and end-to-end validation:
  • pnpm turbo build — verify all packages build cleanly
  • Database migration dry-run
  • Release smoke tests (scripts/release-smoke.sh)
  • SLO guardrail checks (scripts/check-slo-guardrails.sh)

Job: security-scan

Supply chain and dependency security:
StepToolPurpose
Auditpnpm audit --audit-level=highnpm advisory database
Supply chainSocket.dev CLIDeep package provenance + threat intel
Requires SOCKET_SECURITY_API_KEY env var. Enabled scopes: diff-scans, full-scans, packages, dependencies, triage, threat-feed, security-policy, fixes.

Job: deploy

Triggered on git tags (v*):
wrangler deploy   # All workers in dependency order
Workers deploy in this order: oi-sys-authoi-sys-api → frontends.

Jobs: deploy-finance-portal and deploy-compliance-portal

Each new portal has a dedicated deploy job that runs on master after build, test, lint, and typecheck pass. Both use path-based change detection — they only deploy when files in their respective apps/ directory or shared packages (auth-hooks, config, db, react-query, types, ui) change.
deploy-finance-portal:
  steps:
    - check-paths:
        pattern: '^(apps/finance-portal/|packages/(auth-hooks|config|db|react-query|types|ui)/)'
    - run: cd apps/finance-portal && npx opennextjs-cloudflare deploy -- --keep-vars

deploy-compliance-portal:
  steps:
    - check-paths:
        pattern: '^(apps/compliance-portal/|packages/(auth-hooks|config|db|react-query|types|ui)/)'
    - run: cd apps/compliance-portal && npx opennextjs-cloudflare deploy -- --keep-vars
Both use --keep-vars so Cloudflare retains existing secrets (FINANCE_JWT_SECRET, COMPLIANCE_JWT_SECRET) set via wrangler secret put.

Developer Tooling

Knip — Dead Code Detection

Knip scans every workspace for unused exports, files, and dependencies.
pnpm knip
# or with compact output:
pnpm exec knip --reporter compact
Knip is configured in knip.json at the repo root. It’s advisory in CI (|| true) — findings are surfaced as warnings, not failures, until the initial cleanup pass is complete. What Knip catches:
  • Exported functions/types that are never imported
  • Dependencies declared in package.json but never used
  • Files that are not reachable from entry points

Sherif — Workspace Invariants

Sherif enforces consistency rules across pnpm workspaces — no syncpack, no custom scripts.
pnpm sherif
What Sherif enforces:
  • All workspace packages that share a dependency use the same version
  • No duplicate package.json fields that conflict across workspaces
  • Package names match their directory structure
Sherif was chosen over Syncpack because Syncpack v13 crashes on Node.js v25+. Sherif is zero-config for pnpm workspaces and works correctly on all Node.js versions.

OpenTofu — Infrastructure as Code

Azure AD resources (the Microsoft SSO app registration for oi-sys-auth) are managed with OpenTofu (the open-source Terraform fork) using the azuread provider.
infra/azure-auth/
├── main.tf          # azuread_application, azuread_service_principal
├── variables.tf     # tenant_id, client_id, redirect_uris
├── outputs.tf       # application_id, client_secret
└── terraform.tfvars # NOT committed — contains Azure credentials
The Azure app registration “OpenInsure Auth” is single-tenant (AzureADMyOrg), restricted to the mhcis.com tenant (ebd58a52-c818-4230-b150-348ae1e17975). Infrastructure changes are applied manually by a platform engineer with Azure Owner rights — there is no automated tofu apply in CI at this time.
# Plan changes
cd infra/azure-auth
tofu init
tofu plan

# Apply (requires Azure credentials in environment)
tofu apply
:::caution terraform.tfvars and any .tfstate files contain Azure client secrets and must never be committed to source control. The .gitignore at the repo root excludes *.tfvars and *.tfstate. :::

Renovate — Automated Dependency Updates

Renovate runs weekly (Monday 06:00 ET) via CircleCI and opens PRs for dependency updates. Requires RENOVATE_TOKEN env var (GitHub PAT with repo scope). Auto-merge policy (configured in renovate.json):
Update typePolicy
Patch versionsAuto-merge
Security vulnerabilitiesAuto-merge
Next.js / React majorManual review
Cloudflare WorkersManual review
Drizzle ORMManual review
TurboManual review
TanStack (all)Grouped, manual review
@radix-ui/*Grouped, manual review
Internal @openinsure/* packages are excluded from Renovate.

EAS Mobile Deploy

The deploy-mobile CircleCI job triggers on merge to master after all quality gates pass. It runs eas workflow:run .eas/workflows/production.yml which:
  1. Fingerprints native code for iOS and Android
  2. Checks if a compatible build already exists
  3. If native code changed → full EAS build + App Store / Play Store submit
  4. If only JS changed → OTA update to production channel (minutes, no store review)
Required env var: EXPO_CIRCLECI_ACCESS_TOKEN (mapped to EXPO_TOKEN at runtime). Generate at expo.dev → Account Settings → Access Tokens.

Codecov — Coverage Tracking

Coverage reports are uploaded after every passing test run. Reports are uploaded from the test CI job using codecov-action. To add coverage locally:
pnpm turbo test -- --coverage
Requires CODECOV_TOKEN set in CircleCI project environment variables.

Socket.dev — Supply Chain Security

Socket.dev performs deep analysis of every npm package in the dependency graph — beyond the advisory database. It detects:
  • Typosquatting — packages with names similar to popular ones
  • Malicious code injection — packages that execute code at install time
  • Dependency confusion — private package names published to the public registry
  • Unmaintained packages — packages with no recent activity or abandoned by their author
  • Protestware / env var exfiltration — behavioral analysis of install/postinstall scripts

Required CircleCI Environment Variables

VariablePurposeWhere to get
CLOUDFLARE_API_TOKENWorker deploymentsCloudflare dashboard → API Tokens
FLY_API_TOKENFly.io runners/servicesfly auth token
RENOVATE_TOKENGitHub PAT for Renovate PRsgithub.com/settings/tokens
CODECOV_TOKENCoverage uploadapp.codecov.io
SOCKET_SECURITY_API_KEYSupply chain scansocket.dev dashboard
TURBO_TOKEN + TURBO_TEAMTurbo remote cachevercel.com/account/tokens
PD_VERCEL_TOKENDeploy pushdown.ai to VercelVercel dashboard → pushdown team
DATABASE_URLMigration jobsPlanetScale dashboard (app.planetscale.com)
JWT_SECRETAPI test suite + admin/UW portalGenerate: openssl rand -hex 32
FINANCE_JWT_SECRETFinance portal authwrangler secret put FINANCE_JWT_SECRET --name oi-sys-finance
COMPLIANCE_JWT_SECRETCompliance portal authwrangler secret put COMPLIANCE_JWT_SECRET --name oi-sys-compliance
Note: Sanctions API credentials are Worker secrets, not CI env vars. OPENSANCTIONS_API_URL and OPENSANCTIONS_API_KEY are set via wrangler secret put on oi-sys-api. During CI, OPENSANCTIONS_API_URL is intentionally absent — the static SDN fallback activates automatically and all sanctions unit tests pass without a live endpoint.
Danger: All CI credentials must be rotated before any production deployment. Dev credentials were set during initial setup. See the PRE-LAUNCH REMINDER note in CLAUDE.md.

Local Quality Gate

Run the same checks locally before pushing:
# Type safety
pnpm exec tsc --noEmit

# Lint + format
biome check --write .

# Dead code audit
pnpm knip

# Workspace invariants
pnpm sherif

# Full test suite
pnpm turbo test

# Build verification
pnpm turbo build
Or run everything at once with the gauntlet script:
pnpm gauntlet

Commit Conventions

Commits follow the Conventional Commits spec, enforced by commitlint:
feat(claims): add reserve change audit trail
fix(billing): correct invoice balance calculation
chore(deps): bump drizzle-orm to 0.45.1
Scopes should match the affected package or app (e.g., api, billing, claims, portal).

Quickstart

Set up a local dev environment from scratch.

Architecture

Understand the edge/origin split and data flow.