• contact@verticalserve.com
Home / Engineering / Post 95
Engineering Blog · Post #95

Seven Days, Then Fourteen, Then Twenty-One: How InsightUW Nudges UWs to Chase Quotes Without Forking the Email Stack

From "I sent the broker a $4M Cyber quote on Monday, it's now Friday-week, I genuinely forgot, the broker quietly bound elsewhere" to "the inbox dings on the seventh day, the panel on the quote shows 'next due in 7d', I snooze when I'm waiting on the CFO, mark done when I bind, and never re-author the cadence" — through one config table, the existing Follow Up infrastructure, and a generic worker that finally pays down a long-standing infrastructure debt.


The Problem

A UW writes a quote, sends the broker email, moves on. Cyber risks have a 7-day-or-less broker window — small clinics shop fast. D&O renewals run a 14–21 day broker cadence — boards meet on a quarterly schedule. Property nudges should fire after a week; Marine after three. The cadence varies per product, and no UW remembers all of them at once.

The carrier does what carriers do: weekly sales meetings to review the pipeline, a manager who pulls a spreadsheet of "quotes sent more than X days ago," ad-hoc reminders on personal calendars, the occasional "did we ever follow up on Acme?" Slack message. Quotes leak.

The usual fixes don't fix:

  • A field on Quote: next followup date. One row, one cadence — except the same cadence often has three nudges (7d, 14d, 21d) and a single field can't model all three.
  • Manager-by-manager spreadsheets. Drift the moment a UW changes desks; no audit; no notification routing; everyone reinvents.
  • Tasks created at quote-send time. Right shape, wrong vehicle — InsightUW's Follow Up infrastructure already exists for subjectivities, NDAs, and missing-info. Building a parallel "quote tasks" table forks the operational story.
  • Email reminders to the broker on the cadence. Wrong recipient. The UW is the one who needs the prompt; the UW decides whether to email the broker.

The root cause: there's a follow-up entity that's been quietly creating rows for years (subjectivity reminders, NDA renewals, missing-doc nudges) but nothing actually dispatches them in the background. They get created; they only fire when somebody opens the compliance dashboard and clicks "Send." Quote follow-ups need a real worker, and so does every other follow-up type.

Capability #14 fixes both.

The InsightUW Approach

A small per-product cadence config; reuse the existing Follow Up entity; build the worker that's been missing for everyone.

graph TD subgraph Config["Config (lob, product, sequence index)"] CFG["Quote Follow Up Config<br/>(Cyber, Clinic, 1, 5d)<br/>(Cyber, Clinic, 2, 12d)<br/>(Cyber, Clinic, 3, 21d)<br/>(Null, Null, 1, 7d) ← org default"] RES["resolve cadence(lob, product)<br/>1. exact match<br/>2. (lob, Null)<br/>3. (Null, Null)"] end subgraph Send["Quote send"] Send["Rating Service.send quote"] Sched["schedule for quote(quote guid)<br/>materialise Follow Up rows<br/>at sent date + offset"] Rows["Follow Up[3]<br/>scheduled date = +5d / +12d / +21d<br/>assigned to = originating UW"] end subgraph Worker["Generic worker"] Sweep["process due follow ups<br/>Where scheduled date ≤ now<br/> AND status='scheduled'"] Disp["_DISPATCHERS[type]<br/>quote followup → emit Notification<br/>(other types stay on-demand for now)"] end subgraph UI["UI"] Inbox["Inbox: 'Follow-ups' tab<br/>quote followup due notification"] Panel["quote-followup-panel<br/>scheduled / sent / cancelled<br/>+ snooze / mark done / reassign"] end subgraph Cancel["Auto-cancel hooks"] Status["update quote: status →<br/>accepted/declined/bound/expired"] EXP["expire quotes (cron)"] Cancel Call["cancel for quote(quote guid)<br/>future scheduled rows → cancelled"] end CFG --> RES RES --> Sched Send --> Sched Sched --> Rows Rows --> Sweep Sweep --> Disp Disp --> Inbox Inbox --> Panel Status --> Cancel Call EXP --> Cancel Call Cancel Call --> Rows

Cadence config: precedence, not lookup

Quote Follow Up Config carries one row per cadence offset:

resolve cadence walks three tiers:
1. Exact (lob, product) match — if any row, ONLY these are used.
2. (lob, product=NULL) — LOB-wide default.
3. (NULL, NULL) — org default.

All rows in the matched tier fire as a sequence. A Cyber/Clinic quote gets the 5d/12d/21d cadence; a Cyber/Hospital quote falls through to the LOB-wide 7d single-nudge.

Materialise on send, not on demand

When Rating Service.send_quote succeeds, schedule for quote runs:

Three rows. Three timestamps. Three assignees (default: the originating UW; reassignable later).

Why materialise upfront? A config edit after a quote sends shouldn't retroactively rewrite scheduled rows. The cadence captured at send time is the cadence the UW signs up to. Late edits affect future quotes only.

One worker, all follow-up types

This is the long-tail debt fix. Until capability #14, Follow Up rows accumulated for subjectivity reminders / NDA renewals / missing-info nudges, and nothing dispatched them in the background. They only fired when someone opened the compliance dashboard and manually clicked send.

process due follow ups:

_DISPATCHERS is a registry. Today only quote followup is registered (writes a Notification keyed at the assigned UW). Subjectivity / NDA / missing-info types stay on the on-demand path until each one is touched for other reasons; when they migrate, they each register a dispatcher. The worker pattern accommodates the gradual migration without holding the new feature hostage.

Auto-cancel only on terminal status

The one auto-action worth wiring: when quote status flips to accepted / declined / bound / expired, cancel all scheduled future follow-ups. Sent rows stay (they're history). The broker isn't deciding any more; future nudges are noise.

Same for expire quotes (the cron that flips passed-expiry rows to expired). The cancellation logs a reason on each cancelled row; the audit story has the full lifecycle.

Snooze + mark-done + reassign — three small mutations

The UW sees a "next due in N days" header on the quote detail. The follow-up panel lets them:

  • Snooze — push the scheduled_date forward N days; original sequence index and config guid stay so the audit shows "the 2nd reminder was snoozed by Sarah from Tue → Fri."
  • Mark done — flip status to cancelled with an optional reason. Subsequent rows in the cadence keep firing on schedule.
  • Reassign — rewrite assigned to for the row. Used when a UW goes OOO and another picks up coverage; the next dispatcher fire posts to the new assignee's inbox.

In-app notifications only for the prompt. Email-as-prompt is noise. The UW reads the in-app, opens the quote, decides whether to email the broker via the capability #4 composer. Email is for outbound — the prompt is internal.

Worked Example: Acme Clinic Cyber, Sarah's Cadence

Sarah quotes Acme Clinic — a small private clinic — for $4M Cyber. Her LOB is Cyber; the submission's product is Clinic.

Step 1 — Send the quote

Friday morning. Quote letter goes out via the broker email composer. Rating Service.send_quote succeeds:

The quote-manager detail view's follow-up panel renders:

Step 2 — Worker fires on day 5

Wednesday morning, the cron triggers process due follow ups:

Sarah's notification bell pings. Inbox tab "Follow-ups" shows the new row. She clicks. The inbox NOTIFICATION_TYPES registry routes quote followup due to /uw/submissions/{guid};followup={guid} — she lands on the Acme submission with the panel highlighted.

Step 3 — Snooze (waiting on the CFO)

Sarah remembers the broker said "the CFO is on vacation through next week." She doesn't want to nag; she wants the second reminder later. She clicks the snooze dropdown on row #2 → "7d."

Audit row written: action=updated, detail="2026-05-21 → 2026-05-28". The panel updates: row #2 shows a snoozed chip and the new due date.

Step 4 — Reassign (going OOO)

End of the week, Sarah's heading on PTO. She clicks reassign on rows #2 and #3 → types mike.rodriguez. Same UW, different desk; Mike picks up coverage. Future fires for those rows post to Mike's inbox.

Step 5 — Broker accepts (auto-cancel)

Two weeks later, Mike sees row #2 fire (rescheduled 2026-05-28 after Sarah's snooze). The broker emails: "Confirmed bind." Mike opens the quote, marks quote_status = 'accepted'. Rating Service.update_quote:

The panel now reads:
No further nudges. The audit story walks the lifecycle end-to-end.

Step 6 — Org config evolves later

A month later, the operations team decides Cyber/Clinic should shift to a 4d/9d/14d cadence (faster broker decision cycle in that segment). They open the Quote follow-up config admin page, edit the three rows. Acme Clinic's already-quoted business is unaffected — the cadence captured at send time is locked. New Cyber/Clinic quotes use the new cadence.

What This Means for Underwriters

  1. Cadence is per-product, not per-quote. Configure once; every Cyber/Clinic quote inherits the right cadence. No per-quote setup.
  2. Materialise on send, not on demand. A config edit days later doesn't retroactively rewrite scheduled rows. The cadence captured at send is the cadence the UW signs up to.
  3. In-app prompt only. UW reads → decides → emails the broker via cap #4 composer. Email-as-prompt is noise.
  4. Snooze keeps the audit clean. Original sequence index and config guid stay. "The 2nd reminder was snoozed by Sarah from Tue → Fri" is reconstructable.
  5. Auto-cancel on terminal status. Quote accepted / declined / bound / expired cancels future scheduled rows. Sent rows stay (history).
  6. One worker, all types. process due follow ups sweeps every Follow Up row regardless of type. Subjectivity / NDA / missing-info migrate when touched; the new pattern doesn't break legacy.
  7. Reassign costs nothing. OOO coverage is a one-click rewrite of assigned to. The next dispatcher fire posts to the new assignee.
  8. Inbox tabs are registry-driven. The "Follow-ups" tab is one entry in NOTIFICATION_TYPES. Adding new event types (acknowledged, response_received) costs one line each.
  9. Operational debt paid down. Until capability #14, no Follow Up row was background-dispatched. Now there's a worker that handles every type as adapters are registered. Future capabilities don't have to invent the wheel.

Closing the Quote Module

Capability #14 closes out the 14-capability Quote module. End-to-end: forms library, save-and-lock, manuscript editing, broker email, multi-option programs, template ranking, endorsement attachment, post-bind PAS push, manuscript review workflow, UW-side Legal tracking, manager notes with action items, line-level loss experience, multi-currency Phase 1, and now follow-up cadences.

The pattern across all 14: lean on infrastructure shipped earlier (manuscript templates, referrals, email platform, document generator); add a thin new entity or service per capability; resist the urge to fork. Each capability is independently shippable; the module reads as one architecture, not fourteen bolted-on features.

What's Next

The Quote module is the largest module in InsightUW. The patterns it established — generic workers with typed dispatchers, registry-driven inbox routing, partial-close audit columns, idempotent integration boundaries, native-storage with display-time conversion — show up in every subsequent module.

Coming next, in some order: Rating & CAT Modeling (14 capabilities across CAT, Integrated Rater, Decisions, Output, Renewals, Risk Assessment, Scenario Analysis), Notifications & Communications (workflow engine, Outlook send-as-UW, chat, email dedup, holidays, GenAI drafts), Phase 2 modules (Task Management, Team/Account Management, Pipeline, Workflow). Each gets its own design doc + blog series.


Want to see how a single follow-up cadence config ends "did we follow up on Acme?" without forking the email stack? Request a demo.

See InsightUW run on your data

A 45-minute working session with a real broker email and your LOBs.

Request a demo