Entry from DA / GAQ
Customers land in Fastlane when DA/GAQ redirects them from the Progressive "Buy Online" call-to-action. Because Mulesoft issued the original Progressive quote under its own credentials, that quote is not visible in our agent portal. The landing flow looks up the Mulesoft quote in the CRN legacy database and recreates a new, goosehead-visible duplicate on the Progressive agent portal.
Entry URL
/?sessionId=<uuid>&carrierId=377&lob=Home&state=TX&q=Q84275244&config-driven=true
| Param | Required | Description |
|---|---|---|
sessionId | yes | Fastlane session UUID for the consumer |
carrierId | yes | 377 resolves to Progressive Home via ghcms-carrier-mappings.seed.ts |
lob | yes | Home |
state | yes | Two-letter state code (used as default product state) |
q | yes | Progressive Q-number issued by Mulesoft during DA/GAQ quoting |
config-driven | yes | Enables the config-driven micro-frontend shell (see below) |
quoteId, preFastlaneUrl / returnUrl / daUrl, dev-key | no | Optional session extras handled by useSessionInit |
Config-Driven Gate
useConfigDriven() (apps/fastlane-portal/.../dev/use-config-driven.ts) now enables the config-driven shell when config-driven=true alone is present. The mock=true + DEV combination is no longer required.
Landing Sequence
Why the Duplicate Is Required
Progressive does not share quotes across agent credentials. The original Mulesoft-issued Q-number is rated on Mulesoft's Progressive account; when we log into 62.qa.foragentsonly.com with our agent creds it does not appear. We therefore:
- Pull the ACORD quote request XML from CRN
public.sf_quote_response(bycompany_quote_number__c). - Translate the ACORD payload into our domain type (
CrnProgressiveHomeQuoteData). - Start a new Progressive session under our agent code and replay NamedInsured + Products eligibility. Progressive assigns a new Q-number on eligibility validation.
- Cache the origin-to-duplicate mapping in
carrier_quote_sessions.origin_carrier_quote_number.
API Endpoints
POST /api/v1/progressive/home/initial-quote
Body (InitialQuoteDto):
{
"sessionId": "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d",
"daQuoteNumber": "Q84275244",
"state": "TX",
"productCode": "HO3"
}
Success response:
{
"success": true,
"data": {
"sessionId": "9a8b7c6d-...",
"originCarrierQuoteNumber": "Q84275244",
"duplicateQuoteNumber": "Q90001234",
"syncId": "b8c7...",
"workflowNode": "ProductsHO",
"reused": false
}
}
Idempotency: if carrier_quote_sessions already has a row for (sessionId, carrier=PROGRESSIVE, lob=HOME, originCarrierQuoteNumber=daQuoteNumber), the endpoint short-circuits and returns the cached duplicate without touching CRN or Progressive. The reused flag indicates which path was taken.
Key Files
| File | Purpose |
|---|---|
libs/apis/crn-legacy-db/.../services/crn-progressive-home-lookup.service.ts | Queries sf_quote_response and parses ACORD |
libs/apis/crn-legacy-db/.../utils/progressive-home-acord-parser.ts | HomePolicyQuoteInqRq → applicant/address/dwelling/coverages |
libs/apis/carriers/progressive/.../services/crn-progressive-home-request.mapper.ts | Maps CRN → ProgressiveHomeQuoteRequest (ACORD codes → friendly labels) |
libs/apis/carriers/progressive/.../services/progressive-quote-duplicator.service.ts | Orchestrates RouteQuote → NamedInsured submit → eligibility |
apps/apis/fastlane-api-gateway/.../handlers/progressive-home-initial-quote.handler.ts | CRN cache + duplicator + Prisma persistence |
apps/apis/fastlane-api-gateway/.../controllers/progressive.controller.ts | POST /initial-quote route |
apps/fastlane-portal/.../home/config-driven/use-initial-quote-bootstrap.ts | Frontend hook: detects DA Q-number, calls endpoint, rewrites URL |
apps/fastlane-portal/.../home/config-driven/config-driven-flow-context.tsx | Waits for bootstrap before fetching step config |
prisma/schema.prisma | CarrierQuoteSession.originCarrierQuoteNumber column |
prisma/migrations/20260420160000_add_progressive_origin_quote_tracking/ | SQL migration for the column + index |
Session Init
useSessionInit handles the existing steps independently:
- Extract
sessionId,carrierId,lob,statefrom URL - Validate UUID/LOB/state
- Resolve carrier slug (
carrierId=377→progressive) - Call
GET /session/:sessionId/initialize(Redis → CRN fallback) - Store
sessionUuid,quoteId,lob,carrier,statein Zustand
The duplicate-bootstrap step runs inside the config-driven shell after sessionUuid is set in Zustand.
Isolation Rules (see also troubleshooting-config-driven.md)
- The Cursor IDE browser is the intended surface for exercising the active DA-duplicated quote end-to-end (code changes, UI validation, stepping through the config-driven flow with the quote Progressive just minted under our agent credentials).
- The Playwright MCP is exclusively for FAO parity captures and must continue to use
PROGRESSIVE_POC_PLAYWRIGHT_QUOTE_NUMBER. Never open a DA origin Q-number or a freshly-minted duplicate from this flow in the Playwright MCP — it will corrupt the server-side workflow cursor the config-driven backend depends on. - The Progressive agent portal is the source of truth. Use the Playwright MCP to dump real FAO behavior and bring parity into our code; never reshape the Progressive portal to match ours.
PROGRESSIVE_POC_QUOTE_NUMBERis deprecated. The config-driven flow no longer uses a default quote number from the environment — the active quote always comes from the DA landing URL and its Progressive-minted duplicate.- The duplicate flow starts a fresh Progressive session per DA landing. No session state is shared with the config-driven step endpoints until after the URL rewrite sets
syncId.
Failure Modes
| Error in response | Meaning |
|---|---|
Originating Progressive quote not found in CRN legacy database. | sf_quote_response has no row for the given daQuoteNumber |
CRN quote data is malformed and could not be parsed. | ACORD XML missing required sections; inspect quote_request_xml__c |
Could not authenticate to Progressive agent portal. Try again in a moment. | Progressive auth failed — usually QA being flaky (see troubleshooting #5), MFA timing out, or stale creds |
Failed to duplicate Progressive quote from CRN. Please try again. | Progressive rejected NamedInsured or eligibility; check gateway logs |