The Inspire big flow
One page, the whole product: how a risk becomes a policy, how a policy is served and claimed against, and how the money and the reinsurance follow. The flow is described as Inspire GI implements it — the most complete core — because the other cores follow the same skeleton with variations covered in The five cores.
The authoritative source is inspire-gi/docs/06-process-flows.md, which diagrams
every lifecycle with the tables each step writes. This page is the guided tour;
that page is the reference.
The whole flow on one diagram
Section titled “The whole flow on one diagram”flowchart TB
PF["Product factory<br/>define, rate, publish"] --> QU["Quotation<br/>rated, no commitment"]
QU --> PP["Proposal<br/>real risk, allocated number"]
PP --> UW{"Underwriting<br/>rules"}
UW -->|"pass"| IS["Issuance<br/>PolicyNo, version 1"]
UW -->|"refer"| MAN["Manual decision<br/>accept, decline, or terms"]
MAN -->|"accept"| IS
MAN -->|"decline"| DEC["Declined"]
IS --> IF["Policy in force"]
IS --> BIL["Billing<br/>bill, AR per installment"]
IS --> CES["Reinsurance<br/>cede the treaty share"]
IF --> END["Endorsement<br/>mid-term change, delta billed"]
IF --> REN["Renewal<br/>a new policy, linked"]
IF --> CAN["Cancellation<br/>refund, status TX"]
CAN --> REI["Reinstatement<br/>cover restored"]
IF --> CLM["Claim<br/>FNOL to settlement"]
BIL --> COL["Collection<br/>suspense, then offset"]
CLM --> PAY["Payment<br/>clears the AP directly"]
COL --> GL["GL posting<br/>voucher to journal"]
PAY --> GL
CLM --> RIR["RI recovery<br/>the ceded share of loss"]
GL --> PC["Period close<br/>trial balance"]
Read it as five stages, each expanded below: product setup, new business, servicing, claims, and money — billing, collection, the ledger and reinsurance. After issuance, the billing, cession, document and search work happens asynchronously from a durable outbox; the policyholder does not wait for it.
Stage 1 — Product configuration
Section titled “Stage 1 — Product configuration”Before anything can be quoted, a product must exist. This is configuration, not code:
flowchart TB
A["Components<br/>reusable parts library"] --> B["Technical product<br/>the superset for a LOB"]
B --> C["Market product<br/>what is actually sold"]
C --> D["Bind fields, clauses, channels<br/>rating topics, rules, plans"]
D --> E{"Review"}
E -->|"approved"| F["Publish version<br/>immutable, ACTIVE"]
E -->|"rejected"| D
F --> G["Quotable<br/>no DDL, no deployment"]
- No DDL at any step. A market product goes live because rows were inserted and a status column changed. A new product is a configuration exercise.
- A published version is immutable; changes create a new version, and in-force policies stay bound to the version they were written on.
- Publication invalidates the product, rule and rate caches.
Where it lives — inspire-gi: ProductsController, RateTablesController,
RulesController; tables tproduct, tproduct_element, tdd_field,
trate_table, trule; sql/04-product.sql, sql/05-dd-rules-rating.sql;
docs/09-configuration-guide.md for the worked example. Group’s equivalent is the
product-setup module (docs/04-module-specs/product-setup.md); credit life’s is
the policy-scheme module (tplan, tproduct_package, tpremium_rate).
Stage 2 — New business: quotation to issuance
Section titled “Stage 2 — New business: quotation to issuance”The main path. Everything else is a variation.
sequenceDiagram
autonumber
participant C as Client
participant API as Policy service
participant RATE as Rating engine
participant UW as Underwriting
C->>API: quotation
API->>RATE: rate the tree, bottom-up
RATE-->>C: premium at every level, with a trace
C->>API: proposal
API->>API: allocate ProposalNo, PolicyStatus PN
API->>API: blocklist screening, validation, RD
API->>UW: underwriting rule check
alt all rules pass and STP allowed
UW-->>API: pass, TV
else a rule refers
UW-->>API: referral with an SLA clock
Note over UW: underwriter accepts, declines,<br/>or accepts with terms
UW-->>API: decision, TV
end
C->>API: issue
API->>API: allocate PolicyNo, IF, policy version 1
API->>API: snapshot clause wording
API-->>C: policy issued
What makes this flow Inspire rather than a legacy core:
- Rating is explainable. The engine walks the policy tree bottom-up and writes a rating trace, so “why is this the premium?” always has an answer.
- Underwriting is rules plus people. The auto path is configured rules; the referral path carries an SLA and records the underwriter’s decision and terms.
- Issuance fans out after commit. Billing creates the bill and AR; reinsurance cedes; documents generate; search indexes — all from the outbox, so a briefly unavailable downstream cannot block issuing a policy.
Where it lives — inspire-gi: QuotationsController, ProposalsController
(POST {proposalNo}/rate, /underwrite, /decision, /issue),
PoliciesController; tables tquotation, tpolicy, tpolicy_element,
tunderwriting and friends; docs/06-process-flows.md §2. Group adds proposal
handling via GMPS/EBPS-style flows (docs/04-module-specs/policy.md).
Stage 3 — Servicing the policy
Section titled “Stage 3 — Servicing the policy”Endorsement — changing a policy mid-term
Section titled “Endorsement — changing a policy mid-term”flowchart TB
A["Load current policy version"] --> B["Apply the change<br/>to a working copy"]
B --> C{"Endorsement type"}
C -->|"non-financial"| D1["No re-rating"]
C -->|"sum insured, rate, cover, risk"| D2["Re-rate at new terms"]
C -->|"period extend or shorten"| D3["Recompute the period factor"]
D1 & D2 & D3 --> E["Validate, underwrite if required"]
E --> F["Compute the delta<br/>pro-rated for the unexpired period"]
F --> G["Version the changed elements only<br/>same ElementKey, new window"]
G --> H["Re-accumulate premium bottom-up"]
H --> I["Bill the delta, not the total"]
I --> J["Adjust the cessions"]
Two rules prevent the classic errors: the header keeps full-term premium while the endorsement carries the pro-rated delta (different quantities — adding them breaks reconciliation), and only changed elements are versioned (unchanged siblings stay live because the tree is keyed, not row-linked).
An endorsement can even be out of sequence — effective before one already issued. Because element rows carry explicit version windows, inserting v3 effective before v2 is a query over windows, and v2’s premium is rebuilt on the new basis with the net delta billed.
Seeded endorsement types include BIE (basic information, non-financial), TSI
(sum insured), RATE, ADDCOV / DELCOV, ADDRISK / DELRISK, period changes
(POIEXT / POISHORT / POIMOVE), CAN, REINSTATE, PC and UNDO.
Renewal — a new policy, not a new version
Section titled “Renewal — a new policy, not a new version”flowchart TB
A["Batch identifies policies<br/>expiring within the notice window"] --> B["Gather experience<br/>claims, incurred, loss ratio"]
B --> C{"Eligible?"}
C -->|"no"| D["Refer to underwriter<br/>with the reason"]
C -->|"yes"| E["Copy the expiring tree<br/>as a new proposal"]
E --> F["Apply the no-claim discount step"]
F --> G["Re-rate on current rates<br/>and product version"]
G --> H{"Premium variance within<br/>auto-renew tolerance?"}
H -->|"yes"| I["Auto-renew"]
H -->|"no"| D
I --> J["Issue<br/>linked both ways, RenewalCount plus one"]
The renewal is a new policy — a new contract period, a new number, its own
claims — linked in both directions (RenewedFromPolicyID / RenewedToPolicyID) so
continuous cover and no-claim-discount entitlement are provable.
Cancellation and reinstatement
Section titled “Cancellation and reinstatement”Cancellation is FROMINCEPTION (full refund, only with no claims) or MIDTERM
(short-rate or pro-rata refund on the unexpired period). It sets
ExpiryDate = EndoEffectiveDate so the policy period matches the premium actually
charged, produces a negative bill → AP (a refund payable), and reverses the
cessions. Reinstatement reverses all of it: cover restored from the
reinstatement date, reinstatement premium billed, the period re-ceded.
Where it lives — inspire-gi: PoliciesController endorsement endpoints,
RenewalsController; EndorsementProcessService, EndorsementRatingService;
docs/06-process-flows.md §3–5. Group’s renewal is a module of its own
(docs/04-module-specs/renewal.md) with an average-rate engine inherited from
Compass.
Stage 4 — Claims: FNOL to settlement
Section titled “Stage 4 — Claims: FNOL to settlement”sequenceDiagram
autonumber
participant R as Reporter
participant FNOL as Notification
participant CLM as Claim service
participant AUTH as Authority
participant BCP as Billing
R->>FNOL: report a loss, any channel
FNOL->>FNOL: insert the notification row, never lost
FNOL->>CLM: match to a policy
CLM->>CLM: resolve the version in force at the loss date
CLM->>CLM: snapshot it immutably, open claim items
CLM->>CLM: open reserves from matrix defaults
Note over CLM: investigate, survey, adjust
CLM->>CLM: revise reserves as movements
CLM->>CLM: calculate: gross minus deductible, depreciation,<br/>salvage, scaled by underinsurance and coinsurance
alt within authority
AUTH-->>CLM: approved
else exceeds
AUTH->>AUTH: approval up the matrix chain
end
CLM->>BCP: settlement, payable, payment
BCP-->>R: paid
CLM->>CLM: RI recovery per cession and layer, claim complete
Three things to internalise:
- The claim is assessed against the policy as at the loss date. The snapshot makes this true even if the policy is endorsed afterwards.
- Reserves are movements, not balances. Every change is an immutable row with
an accounting date; the invariant
current reserve − paid to date = outstandingis asserted in the schema checks. - Recovery is part of the claim, not an afterthought. After payment, the claim
looks for subrogation (third party at fault), salvage (damaged property),
reinsurance (the ceded share) and recoverable deductibles — each tracked from
expected to recovered and booked as a
RECOVERYmovement that reduces net incurred.
A declared catastrophe tags claims to an event with an hours clause, so accumulated incurred can be measured against catastrophe reinsurance layers, which are then consumed reinstatement by reinstatement.
Where it lives — inspire-gi: ClaimNotificationsController,
ClaimCalculationsController, ClaimSettlementsController,
ClaimPaymentsController, ClaimRecoveriesController, CatastrophesController;
ClaimRegistrationService, ClaimReserveService; tables tclaim_notification,
tclaim, tclaim_policy, tclaim_item, tclaim_reserve_movement; §6. Group’s
claims modules add adjudication edits and the provider network
(docs/04-module-specs/claims.md).
Stage 5 — Money: billing, collection, ledger, reinsurance
Section titled “Stage 5 — Money: billing, collection, ledger, reinsurance”Billing and collection
Section titled “Billing and collection”flowchart TB
EV["Business event<br/>issuance, endorsement, settlement"] --> B["Bill, immutable once created"]
B --> F["Fees: net premium, tax,<br/>commission, stamp"]
F --> AR["AR or AP<br/>one row per installment"]
M["Money arrives"] --> S["Suspense<br/>park now"]
S --> O["Offset<br/>allocate to AR"]
O --> OK["AR balance zero"]
P["Money goes out<br/>claim, refund, commission"] --> PAY["Payment<br/>clears the AP directly"]
Collection goes through suspense and offset; payment clears its payable directly — there is no offset step. Small residual balances clear by tolerance offset; uncollectible debt by write-off; both are authority-controlled. An agent’s or reinsurer’s many debits and credits net into one statement settlement.
The ledger
Section titled “The ledger”Fees flagged for the ledger match a posting template by transaction and fee type,
expand into balanced debit and credit legs with accounts and up to 12 dimensions,
stage as vouchers, then post as immutable journals per open accounting
period, updating the trial balance and — in EXTERNAL or BOTH mode — transmitting
to the external ledger. Vouchers are staged deliberately: a posting run can be
reviewed, corrected and re-run before it becomes immutable. Closing a period blocks
posting into it and triggers the statutory and IFRS 17 extracts.
Reinsurance
Section titled “Reinsurance”Proportional treaties cede at issuance — a share of sum insured and premium. Non-proportional treaties attach at claim — a share of loss above the attachment point. Everything downstream derives from cessions, so the retention calculation happens once:
flowchart TB
A["Policy issued or endorsed"] --> B["Determine retention<br/>by LOB, object type, SI band"]
B --> C{"Within treaty capacity?"}
C -->|"yes"| D["Cede to the treaty<br/>proportional"]
C -->|"no"| E["Place facultatively"]
D & E --> F["Split across participants<br/>shares total 100 percent"]
F --> G["RI premium<br/>ceded minus commission and brokerage"]
H["Claim settled"] --> I["Recover<br/>ceded share or layers above attachment"]
G & I --> J["Bordereaux, statements,<br/>accounts per reinsurer"]
Where it lives — billing: BillsController, BillingListsController,
ArapController, StatementsController (sql/08-finance-bcp.sql); ledger:
JournalPostingController, VouchersController, TrialBalanceController
(sql/09-gl.sql); reinsurance: TreatiesController, CessionsController,
FacultativesController, BordereauxController (sql/10-reinsurance.sql);
§7–9. Bulk variants — partner file in, certificates out, one consolidated AR — are
§10 and are central to credit life; see the next page.
- The five cores — this flow, per vertical
- Legacy to Inspire — where the migrated cores’ behaviour comes from
- Glossary