Skip to main content

ktayl Underwriting & Pricing

Python modular-monolith service (FastAPI) that owns the underwriting lifecycle — submission intake → appetite/eligibility → rating → quote → bind — plus a Next.js underwriter workbench. It binds into the live ktayl Policy Service and emits a bound-risk event for downstream reinsurance/actuarial.

Board #12 (Insurance LOB). The full lifecycle + the workbench are LIVE on dev (dev-only by a need-first decision; prod is deliberately parked behind the Authentik auth gate).

Full documentation (in-repo): github.com/andrelair-platform/ktayl-underwriting — see Solution Architecture, ADR log, Threat model, NFR register, and UX DESIGN / EXPERIENCE. See also the Underwriting FDE Playbook for the domain + regulatory framing.


Responsibility​

In scopeOut of scope
Submission intake + local counterparty (ADR-002)Master data (MDM #20 — parked)
Appetite / eligibility (accept · refer · decline + reason codes)Claims (ktayl-claims #11)
Rating — versioned, immutable rate tables → explainable premiumPolicy admin / billing (Policy Service + ERPNext)
Bind → create/submit/activate a policy in the PAS + bound-risk eventReinsurance / actuarial (downstream consumers)
Underwriter workbench (triage referrals, price, bind)Autonomous AI action (assistive + human-verified only, ADR-003)

Stack​

BackendPython 3.12 + FastAPI + Pydantic (SQLAlchemy + Alembic) — ADR-007
FrontendNext.js 16 + React 19 + Tailwind v4 — a BFF (server components + server actions), ADR-008
DatabaseCNPG PostgreSQL (per-service); app self-migrates on startup
Registryharbor.10.0.0.200.nip.io/library/ktayl-underwriting (+ -frontend); prod → ghcr, cosign-signed
DeliveryGitOps (ArgoCD) + Kargo git-Warehouse (two images pinned to one source commit)

The underwriter workbench (frontend)​

An AI-native task inbox: the appetite engine auto-decides the rule (accept / decline); underwriters work the referrals. Inbox (outcome-tab triage) → submission detail (appetite decision + explainable rating breakdown + binding + audit trail) → assess / quote / bind actions → intake form.

It is a Backend-for-Frontend, not a browser SPA — the browser talks same-origin to Next.js; Next reaches the API server-side via a runtime API_URL, so the underwriting API is never exposed to the browser and one env-agnostic image serves dev and prod (ADR-008).

Lifecycle (summary)​

intake → assess (appetite) → rate → quote → bind (PAS: create → submit → activate) → bound-risk event

All money is eurocents (int64 minor units); the rating breakdown reconciles to the premium. The bind is idempotent (deterministic policy_number, 409-as-success). Proven end-to-end: active policy UW-369188ABE405 (€400) in the PAS.

Sprint status​

StoryStatusDeliverable
UW-01-S01✅ DoneIntake → appetite decision + append-only audit
UW-04-S01✅ DoneRating — versioned rate tables → explainable quote
UW-01-S02✅ DoneBind (ADR-006) — live PAS handoff + bound-risk event
Workbench✅ DoneNext.js BFF inbox / detail / actions — live on dev
Testing✅ DoneFull L0–L4 pyramid + a live L5 QA gate (backend + frontend)
Prod⏸ ParkedNeed-first; blocked on the Authentik prod-auth gate

Quality & delivery notes​

  • Full test pyramid enforced — L2 integration (real Postgres), L3 contract (against the Policy Service OpenAPI), L4 smoke, and a live L5 QA gate against the running dev service before any prod promotion. "Unit-only" is treated as an anti-pattern.
  • Governance: the Path-C artefact set (PRD, solution architecture, NFR register, threat model, ADR log, UX DESIGN/EXPERIENCE) lives in the repo; this page is the map.