Zen Algorithms · Insurance Lab← All flows
Flow 1 · External · Customer

Customer / Quote — standalone architecture

Build just this flow: a customer (or producer — an insurance agent/broker) enters the property & product selection, the system prefills from data sources, scores perils via the cat-model, and emits a quote. It is the only externally-exposed flow, so it gets its own trust boundary (a hard line where outside traffic is checked before anything inside is reached). Advance the maturity stage to grow it.

Start: Vercel + Cloud Run + Cloud SQL — grow by stage (click any box)
Customer flow grown across stages: external user → edge → Vercel UI → Cloud Run quote API → Cloud SQL, adding WAF/prefill/cat-model, then a cache, then multi-region. Customer /Producer Vercel UIquote wizard? Cloud RunQuote API? Cloud SQLsubmission · outbox? Edge: WAF +rate limit? Property prefill? Cat-model? emits → QuoteRequested → (Underwriting picks it up)? Redis cache (address / characteristics)? Global HTTPS LB (multi-region) + CDN?
active later stage black-box service

📖 Flow story — what really happens

Every cross-flow arrow is the same async handoff — no flow calls another directly. 1. The sending flow commits its data row plus an outbox row in one transaction. 2. A relay publishes the event to the event bus (Pub/Sub on GCP · EventBridge→SQS on AWS). 3. The bus's push-subscription POSTs it to the receiving flow's Cloud Run API, which processes it idempotently (duplicates ignored, deduped on event_id). Synchronous reads (e.g. getProductVersion) are plain request/response.

  1. The customer/producer opens the portal — a Next.js app on Vercel behind the WAF; it holds no policy data and talks only to the BFF.
  2. They enter the address; the BFF makes a synchronous read to Groundwork, the prefill service (request/response), to fill year built, construction, roof, sq ft — facts to confirm, not type. (Full prefill integration spec — vendors, costs, storage, refresh criteria.)
  3. They pick a line + form (line of business + policy form — e.g. HO-3 homeowners); another sync read, getProductVersion(line, form, asOfDate), returns the immutable product and the quote workbench (the coverage-selection screen) renders its provisions/options. (How product versioning works — worked example.)
  4. The cat-model is called (POST /peril-scores, sync) for wildfire/flood/wind at that exact address; those scores + the prefilled property data set the coverage defaults — every defaulted provision/option traces back to a prefill field (field → provision mapping).
  5. The customer edits coverages; each change re-evaluates compliance + risk rules live on the screen (nothing saved yet).
  6. On submit, the Quote API (Cloud Run) writes two rows in one transaction: the first append-only record — a submission row (event-sourced: SubmissionCreated), stamped with the cat-model version + as-of date — and an outbox row holding QuoteRequested. Then it commits.
  7. The outbox relay publishes QuoteRequested {submission_id, property, coverages, geo} to the event bus.
  8. Underwriting's push-subscription delivers it to the Underwriting API (deduped on event_id) — the submission now sits in the underwriter's queue.

Interfaces (black-box contract)

DirectionContractWho
EmitsQuoteRequested {property, coverages, geo}Underwriting
Calls (read)getProductVersion(), POST /peril-scores, prefillProduct, Cat-model, Prefill (black boxes)
Consumes— (entry point of the lifecycle)
← All flowsNext: Underwriting →