Pojistná doména pro vývojáře: produkty, aktéři a datové modely
Pokud jste vývojář softwaru nový ve světě pojištění, pravděpodobně budete čelit neproniknutelnému žargonu: upisování, schválení, FNOL, subrogace, bordereaux. Nebojte se: tato příručka překládá celou doménu pojištění do konceptů, datových modelů a architektonických vzorů, kterým může vývojář porozumět, realizovat a především správně modelovat v kódu.
Pojišťovnictví se celosvětově posouvá kupředu 7 bilionů dolarů v ročním pojistném (údaje 2025, Swiss Re Sigma) a je jedním z nejvíce regulovaných sektorů na světě. Přesto většina informační systémy, které jej podporují, pocházejí z 80. a 90. let: sálové počítače COBOL, noční dávky, rozhraní zelené obrazovky. Digitální transformace průmyslu, známá jako InsurTech, to vše předělává a vývojáři jsou ve středu změny.
Tento článek zahajuje sérii InsurTech Engineering s úplným přehledem domény: pojistné produkty, hráči hodnotového řetězce, základní datové modely, životní cyklus politiky a nároků a moderní architektonické vzory pro stavební platformy cloudové nativní pojištění.
Co se dozvíte v tomto článku
- Kategorie pojistných produktů (životní, neživotní, zdravotní, speciální) a jejich technické odlišnosti
- Hráči v hodnotovém řetězci: pojistník, pojistitel, makléř, agent, zajistitel, regulátor
- Hodnotový řetězec pojištění: distribuce, upisování, správa pojistných smluv, nároky, investice
- Základní datové modely: Policy, Claim, Premium, Coverage, Endorsement, Rider
- Kompletní životní cyklus pojistky: nabídka, vydání, změna, obnovení, zrušení
- Životní cyklus pohledávky: FNOL, vyhodnocení, vyřízení, vymáhání
- Domain-Driven Design aplikovaný na pojištění: ohraničený kontext a agregáty
- Architektura ratingového enginu a výpočet prémií
- Standardy ACORD a vzory API pro interoperabilitu
- Regulační prostředí: Solvency II, IFRS 17, GDPR
Pojišťovnictví: Přehled pro vývojáře
Před napsáním jediného řádku kódu je nezbytné porozumět jak obchod funguje pojištění. Na rozdíl od elektronického obchodu, kde je produkt hmatatelný, v pojištění "produkt" je a slib: výplata budoucí kompenzace při výskytu a nejistá událost. Díky tomu je doména z hlediska datového modelování ze své podstaty složitá.
"Pojištění je jediný produkt, který kupujete a doufáte, že ho nikdy nepoužijete. Tento paradox definuje celou architekturu systémů, které ji spravují."
Základní princip: Vzájemnost rizika
Klíčovým konceptem je vzájemnost rizika (sdružování rizik): skvělý skupina osob nebo firem přispívá pravidelné pojistné do společného fondu, ze kterého je čerpáno prostředky na odškodnění těch několika, kteří utrpěli škodu. Role pojistitele a toto řídit financovat pojistně matematicky udržitelným způsobem a zajistit, aby vybrané pojistné bylo dostatečné k pokrytí očekávané nároky plus provozní náklady a zisková marže.
Kategorie pojistných produktů
Pojistné produkty jsou rozděleny do makrokategorií se zcela odlišnými technickými vlastnostmi. Pochopení těchto rozdílů je klíčové pro správné modelování dat.
| Kategorie | Příklady | Typická doba trvání | Povaha rizika | Složitost dat |
|---|---|---|---|---|
| život (život) | Termín, Smíšený, Jednotný, Rada | 10-40 let | Úmrtnost, dlouhověkost | Vysoká (pojistně-matematické tabulky, matematické rezervy) |
| Škody (P&C) | Auto, domov, profesionální RC, oheň | 1 rok (obnovitelné) | Majetek, občanskoprávní odpovědnost | Průměr (frekvence reklamací, průměrné náklady) |
| zdraví (zdraví) | Náhrada výdajů, úrazů, LTC | 1 rok / více let | Nemocnost, invalidita | Vysoká (ICD, DRG, kódování zdravotních sítí) |
| Speciality | Námořní, letectví, kybernetické, D&O, E&O | Variabilní | Komplexní/katastrofická rizika | Velmi vysoká (modely CAT, akumulace) |
Důsledky pro vývojáře
Neexistuje žádný jednotný „univerzální“ datový model pro pojištění. Systém Life řídí mathematical reserves and mortality tables; a P&C system manages deductibles, limits and hodnocení; Zdravotní systém spravuje lékařské kódy a sítě poskytovatelů. Architektonická volba mezi a jednotný model e specializované modely pro LOB (Line of Business) je jedním z nejdůležitějších rozhodnutí při navrhování pojistné platformy.
Aktéři hodnotového řetězce
Pojišťovací ekosystém zahrnuje řadu aktérů s odlišnými rolemi. Každý z nich se stává entita v našem datovém modelu a často samostatný ohraničený kontext v architektuře.
Mapa hlavních aktérů
| Herec | Role v doméně | Entita klíčových dat | Hlavní interakce |
|---|---|---|---|
| Dodavatel (pojistník) | Kupte si pojistku, plaťte pojistné | Zákazník, účet, způsob platby | Kvóta, Bind, Pay Premium, File Claim |
| Pojištěný | Osoba/věc, na kterou se vztahuje pojistka | Pojištěná strana, RiskObject | Může se lišit od dodavatele |
| Pojistitel (pojistitel / dopravce) | Bere na sebe riziko, platí nároky | Společnost, Portfolio, Rezerva | Upsat, vydat, vyrovnat nároky |
| Činidlo | Zastupuje pojistitele, prodává pojistky | Agent, agentura, komise | Distribuované, kvóty, služba |
| Makléř | Zastupuje klienta, vyjednává podmínky | Broker, BrokerFirm, umístění | Místo rizika, vyjednávání podmínek |
| Zajišťovatel | Pojistí pojistitele (nadměrná rizika) | Smlouva, Postoupení, Vymáhání | Výnosy, ústupy, vyrovnání |
| Expert (seřizovač) | Posuzuje nároky a určuje náhradu | Hodnocení, odhad, zpráva | Zkontrolovat, posoudit, doporučit |
| Regulátor (regulátor) | Dohlíží na trh, ukládá pravidla | Podání, dodržování, zprávy | Schválit produkty, auditovat, dokončit |
Kritický vztah: dodavatel versus pojištěnec versus příjemce
Jednou z nejvíce podceňovaných složitostí je rozdíl mezi pojistníkem, pojištěným a příjemce. V nejjednodušším případě (individuální automobilová politika) se tyto tři údaje shodují. Ale ve firemním životním pojištění je dodavatel a společnost, pojištěný jsou zaměstnanci a příjemců jsou to určení členové rodiny. Datový model musí podporujte tuto flexibilitu pomocí vztahů many-to-many mezi těmito subjekty.
Pojistný hodnotový řetězec
Pojistný hodnotový řetězec popisuje celý tok obchodu od prvního kontaktu se společností zákazníkem až do vyřízení reklamace a obnovení pojistky. Každý článek v řetězu typicky odpovídá a ohraničený kontext v softwarové architektuře.
Distribution Underwriting Policy Admin Claims Investment
| | | | |
v v v v v
+-----------+ +-----------+ +------------+ +-----------+ +-----------+
| Marketing | | Risk | | Issue | | FNOL | | Asset |
| Lead Gen | | Selection | | Endorse | | Assess | | Mgmt |
| Quoting | | Pricing | | Renew | | Adjust | | ALM |
| Binding | | Approval | | Cancel | | Settle | | Reserves |
+-----------+ +-----------+ +------------+ +-----------+ +-----------+
| | | | |
+-------+-------+--------+-------+------+-------+-------+------+
| | | |
+---------+ +---------+ +---------+ +---------+
|Reinsur. | | Billing | | Fraud | | Report |
|Cessions | | Collect | | Detect | | Regulat.|
+---------+ +---------+ +---------+ +---------+
1. Distribuce
Distribuce zahrnuje všechny kanály, kterými se pojistné produkty dostávají k zákazníkovi: agenti (jedno- nebo více-firemní), makléř, bankopojištění, online srovnávače e přímé kanály (web, aplikace, call centrum). pro vývojáře, to se promítá do vícekanálových rozhraní API, integrovaných CRM a modulů pro konfiguraci produktů.
2. Upisování (předpoklad rizika)
Upisování je proces, při kterém pojistitel vyhodnocuje navrhované riziko a rozhoduje se, zda je přijme, za jakých podmínek a za jakou cenu. Je technickým srdcem pojišťovací činnosti a zahrnuje:
- Posouzení rizik: Vyhodnocení rizikových charakteristik (věk, zdravotní stav, lokalita, historie škod)
- Hodnocení: Výpočet pojistného přes hodnotící motor (pojistně-matematické algoritmy + obchodní pravidla)
- Výběr rizika: Rozhodnutí přijmout, odmítnout nebo upravit podmínky
- Doporučení: Eskalace na senior upisovatele pro rizika mimo automatické parametry
3. Správa zásad (správa zásad)
Il Systém správy zásad (PAS) je centrální systém, který řídí celek životní cyklus pojistky: vydání, změny (schválení), obnovení, zrušení a obnovení. Je to obvykle nejsložitější systém v ekosystému pojišťovacích IT.
4. Správa pohledávek
Správa reklamací pokrývá celý proces od oznámení reklamace (FNOL - První upozornění Ztráta) až do likvidace a případného vymáhání (subrogace). A ten proces přímo ovlivňuje spokojenost zákazníků a ziskovost pojišťovny.
5. Investice a správa rezerv
Pojistitelé investují vybrané pojistné v očekávání výplaty budoucích škod. Vedení investic (Asset-Liability Management) a výpočet rezervy techniky jsou to regulované procesy, které vyžadují sofistikované pojistně-matematické modely.
Základní datové modely
Pojďme k jádru toho, co musí vývojář modelovat. Následující jsou agregáty (ve smyslu DDD) základy jakékoli pojistné platformy.
Hlavní entity a vztahy
// ============================================
// Core Insurance Domain Model (TypeScript)
// ============================================
/** Tipologia di prodotto assicurativo */
type LineOfBusiness = 'LIFE' | 'PROPERTY' | 'CASUALTY' | 'HEALTH' | 'MARINE' | 'CYBER';
/** Stato della polizza nel suo ciclo di vita */
type PolicyStatus =
| 'QUOTE' // Preventivo
| 'APPLICATION' // Proposta
| 'BOUND' // Vincolata (impegno assunto)
| 'ISSUED' // Emessa
| 'IN_FORCE' // In vigore
| 'SUSPENDED' // Sospesa
| 'LAPSED' // Decaduta (mancato pagamento)
| 'CANCELLED' // Cancellata
| 'EXPIRED' // Scaduta
| 'NON_RENEWED'; // Non rinnovata
/** Aggregato principale: la Polizza */
interface Policy {
readonly id: string;
readonly policyNumber: string;
readonly version: number; // Versioning per endorsement
readonly lineOfBusiness: LineOfBusiness;
readonly status: PolicyStatus;
readonly effectiveDate: Date;
readonly expirationDate: Date;
readonly inceptionDate: Date; // Data prima emissione
readonly policyholder: Party; // Contraente
readonly insuredParties: readonly InsuredParty[];
readonly coverages: readonly Coverage[];
readonly premium: PremiumBreakdown;
readonly endorsements: readonly Endorsement[];
readonly documents: readonly Document[];
readonly underwritingInfo: UnderwritingInfo;
readonly createdAt: Date;
readonly updatedAt: Date;
}
/** Parte coinvolta (persona fisica o giuridica) */
interface Party {
readonly id: string;
readonly type: 'INDIVIDUAL' | 'ORGANIZATION';
readonly firstName?: string;
readonly lastName?: string;
readonly companyName?: string;
readonly taxId: string; // Codice fiscale / P.IVA
readonly dateOfBirth?: Date;
readonly addresses: readonly Address[];
readonly contacts: readonly ContactInfo[];
readonly riskProfile?: RiskProfile;
}
/** Soggetto assicurato con specifico ruolo */
interface InsuredParty {
readonly party: Party;
readonly role: 'PRIMARY' | 'ADDITIONAL' | 'NAMED_INSURED';
readonly relationship: string; // Relazione col contraente
}
/** Copertura: cosa e protetto e fino a quanto */
interface Coverage {
readonly id: string;
readonly code: string; // Es: "TPL", "CASCO", "FIRE"
readonly name: string;
readonly description: string;
readonly type: 'BASE' | 'OPTIONAL' | 'MANDATORY';
readonly limit: Money; // Massimale
readonly deductible: Deductible; // Franchigia
readonly premium: Money; // Premio per questa copertura
readonly effectiveDate: Date;
readonly expirationDate: Date;
readonly exclusions: readonly string[];
readonly conditions: readonly string[];
}
/** Franchigia con diverse modalità di applicazione */
interface Deductible {
readonly type: 'FIXED' | 'PERCENTAGE' | 'WAITING_PERIOD' | 'AGGREGATE';
readonly amount?: Money; // Per FIXED
readonly percentage?: number; // Per PERCENTAGE
readonly waitingDays?: number; // Per WAITING_PERIOD
readonly aggregateLimit?: Money; // Per AGGREGATE
readonly appliesToEach: 'CLAIM' | 'OCCURRENCE' | 'POLICY_PERIOD';
}
/** Scomposizione del premio */
interface PremiumBreakdown {
readonly grossPremium: Money; // Premio lordo
readonly netPremium: Money; // Premio netto (per l'assicuratore)
readonly taxes: Money; // Imposte
readonly fees: Money; // Diritti e commissioni
readonly commission: Money; // Provvigione intermediario
readonly components: readonly PremiumComponent[];
readonly paymentPlan: PaymentPlan;
}
/** Variazione contrattuale in corso di polizza */
interface Endorsement {
readonly id: string;
readonly endorsementNumber: number;
readonly type: 'COVERAGE_CHANGE' | 'LIMIT_CHANGE' | 'ADD_INSURED'
| 'REMOVE_INSURED' | 'ADDRESS_CHANGE' | 'VEHICLE_CHANGE'
| 'GENERAL_CHANGE';
readonly effectiveDate: Date;
readonly description: string;
readonly premiumAdjustment: Money; // Differenza premio (+/-)
readonly previousVersion: number;
readonly newVersion: number;
readonly changes: readonly FieldChange[];
readonly approvedBy?: string;
readonly approvedAt?: Date;
}
/** Valore monetario con valuta */
interface Money {
readonly amount: number;
readonly currency: string; // ISO 4217: "EUR", "USD", "GBP"
}
/** Singola modifica tracciata nell'endorsement */
interface FieldChange {
readonly field: string;
readonly oldValue: string;
readonly newValue: string;
}
Klíčový vzor: Neměnnost a verzování
Všimněte si, jak každé rozhraní používá readonly na všech nemovitostech. V oblasti pojištění,
a sledovatelnost a regulační požadavek: každá změna politiky vytváří
nový schválení což zvyšuje version. Nikdy se "nemění".
politika; je vytvořena nová verze. Tento vzor se dokonale hodí kzajišťování zdrojů událostí
a s architekturami CQRS.
Životní cyklus politiky
Politika během své existence prochází přesně definovanými stavy. Pojďme modelovat tento životní cyklus jako jeden státní automat, základní vzor v pojišťovacím softwaru.
// ============================================
// Policy Lifecycle State Machine
// ============================================
/** Transizioni valide nel ciclo di vita della polizza */
type PolicyTransition =
| { from: 'QUOTE'; to: 'APPLICATION'; action: 'SUBMIT_APPLICATION' }
| { from: 'QUOTE'; to: 'CANCELLED'; action: 'DECLINE_QUOTE' }
| { from: 'APPLICATION'; to: 'BOUND'; action: 'BIND_COVERAGE' }
| { from: 'APPLICATION'; to: 'CANCELLED'; action: 'DECLINE_APPLICATION' }
| { from: 'BOUND'; to: 'ISSUED'; action: 'ISSUE_POLICY' }
| { from: 'ISSUED'; to: 'IN_FORCE'; action: 'ACTIVATE' }
| { from: 'IN_FORCE'; to: 'IN_FORCE'; action: 'ENDORSE' }
| { from: 'IN_FORCE'; to: 'SUSPENDED'; action: 'SUSPEND' }
| { from: 'IN_FORCE'; to: 'CANCELLED'; action: 'CANCEL' }
| { from: 'IN_FORCE'; to: 'EXPIRED'; action: 'EXPIRE' }
| { from: 'IN_FORCE'; to: 'IN_FORCE'; action: 'RENEW' }
| { from: 'IN_FORCE'; to: 'NON_RENEWED'; action: 'NON_RENEW' }
| { from: 'SUSPENDED'; to: 'IN_FORCE'; action: 'REINSTATE' }
| { from: 'SUSPENDED'; to: 'LAPSED'; action: 'LAPSE' }
| { from: 'LAPSED'; to: 'IN_FORCE'; action: 'REINSTATE' }
| { from: 'LAPSED'; to: 'CANCELLED'; action: 'CANCEL' };
/** Mappa delle transizioni valide per validazione runtime */
const VALID_TRANSITIONS: ReadonlyMap<PolicyStatus, readonly PolicyTransition[]> = new Map([
['QUOTE', [
{ from: 'QUOTE', to: 'APPLICATION', action: 'SUBMIT_APPLICATION' },
{ from: 'QUOTE', to: 'CANCELLED', action: 'DECLINE_QUOTE' },
]],
['APPLICATION', [
{ from: 'APPLICATION', to: 'BOUND', action: 'BIND_COVERAGE' },
{ from: 'APPLICATION', to: 'CANCELLED', action: 'DECLINE_APPLICATION' },
]],
['IN_FORCE', [
{ from: 'IN_FORCE', to: 'IN_FORCE', action: 'ENDORSE' },
{ from: 'IN_FORCE', to: 'SUSPENDED', action: 'SUSPEND' },
{ from: 'IN_FORCE', to: 'CANCELLED', action: 'CANCEL' },
{ from: 'IN_FORCE', to: 'EXPIRED', action: 'EXPIRE' },
{ from: 'IN_FORCE', to: 'IN_FORCE', action: 'RENEW' },
{ from: 'IN_FORCE', to: 'NON_RENEWED', action: 'NON_RENEW' },
]],
]);
/** Funzione pura per la transizione di stato */
function transitionPolicy(
policy: Policy,
action: PolicyTransition['action'],
context: TransitionContext
): Policy {
const validTransitions = VALID_TRANSITIONS.get(policy.status);
const transition = validTransitions?.find(t => t.action === action);
if (!transition) {
throw new InvalidTransitionError(
`Cannot perform ${action} on policy in status ${policy.status}`
);
}
// Crea nuova versione immutabile della polizza
return {
...policy,
status: transition.to,
version: policy.version + 1,
updatedAt: new Date(),
endorsements: action === 'ENDORSE'
? [...policy.endorsements, context.endorsement!]
: policy.endorsements,
};
}
Klíčové fáze životního cyklu
Fáze před vydáním
- šance: Orientační odhad založený na minimálních údajích. Typická platnost: 30 dní
- Aplikace: Formální nabídka se všemi údaji nezbytnými pro upisování
- Svázat: Pojistitel souhlasí s poskytnutím krytí (ale pojistka ještě není vystavena)
- Problém: Vydání oficiálního dokumentu o politice
Fáze po vydání
- Podporuje: Úprava platných podmínek (nová verze)
- Obnovit: Obnovení po vypršení platnosti (může zahrnovat nové hodnocení)
- Pozastavit: Dočasné pozastavení (např. nezaplacení)
- Zrušit: Storno s výpočtem akruálního pojistného
- Resetovat: Obnovení po pozastavení nebo propadnutí
Životní cyklus nároků
Nehoda je událost, která aktivuje příslib pojištění. Jeho životní cyklus je stejný strukturovaný a dokonale se hodí k modelování jako stavový stroj.
// ============================================
// Claims Domain Model
// ============================================
type ClaimStatus =
| 'FNOL' // First Notice of Loss - notifica iniziale
| 'REGISTERED' // Registrato nel sistema
| 'UNDER_INVESTIGATION' // In fase di indagine/perizia
| 'ASSESSED' // Valutato dal perito
| 'APPROVED' // Approvato per liquidazione
| 'PARTIALLY_APPROVED'// Parzialmente approvato
| 'DENIED' // Rifiutato
| 'SETTLED' // Liquidato
| 'REOPENED' // Riaperto
| 'CLOSED' // Chiuso definitivamente
| 'SUBROGATION'; // In fase di recupero
interface Claim {
readonly id: string;
readonly claimNumber: string;
readonly policyId: string;
readonly policyNumber: string;
readonly status: ClaimStatus;
readonly lossDate: Date; // Data del sinistro
readonly reportDate: Date; // Data della denuncia
readonly lossType: string; // Tipo di danno
readonly lossDescription: string;
readonly lossLocation: Address;
readonly claimant: Party; // Chi richiede l'indennizzo
readonly reserves: readonly Reserve[];
readonly payments: readonly ClaimPayment[];
readonly assessments: readonly Assessment[];
readonly documents: readonly Document[];
readonly fraudIndicators: readonly FraudIndicator[];
readonly totalIncurred: Money; // Riserva + Pagato
readonly totalPaid: Money;
readonly totalReserve: Money;
}
/** Riserva: stima del costo futuro del sinistro */
interface Reserve {
readonly id: string;
readonly type: 'INDEMNITY' | 'EXPENSE' | 'LEGAL';
readonly amount: Money;
readonly setDate: Date;
readonly setBy: string;
readonly reason: string;
readonly history: readonly ReserveChange[];
}
/** Pagamento effettuato sul sinistro */
interface ClaimPayment {
readonly id: string;
readonly type: 'INDEMNITY' | 'EXPENSE' | 'LEGAL' | 'SALVAGE' | 'SUBROGATION';
readonly amount: Money;
readonly payee: Party;
readonly paymentDate: Date;
readonly paymentMethod: string;
readonly invoiceReference?: string;
readonly approvedBy: string;
}
/** Valutazione peritale */
interface Assessment {
readonly id: string;
readonly assessor: Party; // Perito
readonly assessmentDate: Date;
readonly damageEstimate: Money;
readonly findings: string;
readonly recommendation: 'APPROVE' | 'DENY' | 'FURTHER_INVESTIGATION';
readonly photos: readonly string[]; // URL delle foto
readonly report: Document;
}
/** Indicatore di potenziale frode */
interface FraudIndicator {
readonly rule: string;
readonly score: number; // 0-100
readonly description: string;
readonly triggeredAt: Date;
}
Fáze havárie v detailu
| Fáze | Aktivita | Zúčastnění herci | Vygenerovaná data |
|---|---|---|---|
| FNOL | Nahlaste nehodu telefonicky, webem, aplikací, e-mailem | Pojištěno, Call centrum | ClaimNotification, InitialReserve |
| Třídění | Klasifikace pohledávek, přiřazení priority, ověření krytí | Vyřizování pojistných událostí, automatický systém | Ověření pokrytí, priorita, přiřazení |
| Vyšetřování | Sběr dokumentace, oceňování, ověřování okolností | Expert, vyšetřovatel, soudní lékař | Hodnocení, fotografie, expertní zpráva |
| Rozhodnutí | Rozhodnutí: úplné, částečné přijetí nebo zamítnutí | Reklamační manažer, Reklamační výbor | Rozhodnutí, AdjustmentCalc |
| Osady | Výpočet náhrady a platby | Vyřizování reklamací, Platební úřad | Platba, dohoda o vyrovnání |
| Zotavení | Subrogace vůči odpovědným třetím stranám, zpětné získávání | Právní kancelář, kancelář pro vymáhání pohledávek | SubrogationClaim, zotavení |
Architektura ratingového nástroje
Il hodnotící motor a složka, která vypočítává pojistné. A jeden z nejkritičtější a nejvýkonnější systémy v ekosystému InsurTech: musí zpracovat tisíce nabídek za sekundu s pojistně-matematickou přesností a úplnou sledovatelností.
Jak funguje prémiová kalkulace
Výpočet pojistného se řídí dobře definovaným potrubím, které transformuje rizikové faktory na a konečná cena. Podívejme se na zjednodušený příklad pro Car TPL.
// ============================================
// Rating Engine - Esempio RC Auto
// ============================================
/** Fattori di rischio per la tariffazione auto */
interface AutoRatingFactors {
readonly driverAge: number;
readonly driverExperience: number; // Anni di patente
readonly vehicleGroup: number; // Gruppo tariffario 1-20
readonly vehicleAge: number;
readonly postalCode: string;
readonly claimsHistory: number; // Sinistri ultimi 5 anni
readonly bonusMalusClass: number; // Classe CU (1-18 in Italia)
readonly annualMileage: number;
readonly garaging: 'GARAGE' | 'STREET' | 'PARKING';
readonly usage: 'PERSONAL' | 'COMMUTE' | 'BUSINESS';
}
/** Risultato del calcolo tariffario */
interface RatingResult {
readonly baseRate: Money;
readonly factors: readonly AppliedFactor[];
readonly technicalPremium: Money; // Premio tecnico (puro rischio)
readonly loadings: readonly Loading[];
readonly grossPremium: Money; // Premio lordo finale
readonly taxes: Money;
readonly totalPremium: Money; // Totale da pagare
readonly ratingDate: Date;
readonly rateTableVersion: string;
readonly auditTrail: readonly string[];
}
interface AppliedFactor {
readonly name: string;
readonly inputValue: string | number;
readonly factor: number; // Moltiplicatore (es: 1.25 = +25%)
readonly source: string; // Tabella di riferimento
}
interface Loading {
readonly type: 'EXPENSE' | 'COMMISSION' | 'PROFIT' | 'CATASTROPHE' | 'REINSURANCE';
readonly percentage: number;
readonly amount: Money;
}
/** Rating Engine: funzione pura che calcola il premio */
function calculateAutoRate(
factors: AutoRatingFactors,
rateTables: RateTableSet
): RatingResult {
const auditTrail: string[] = [];
// 1. Base Rate dalla tabella territoriale
const baseRate = rateTables.territorial.lookup(factors.postalCode);
auditTrail.push(`Base rate for ${factors.postalCode}: ${baseRate}`);
// 2. Applicazione fattori moltiplicativi
const ageMultiplier = rateTables.ageFactors.lookup(factors.driverAge);
const vehicleMultiplier = rateTables.vehicleGroups.lookup(factors.vehicleGroup);
const bonusMalusMultiplier = rateTables.bonusMalus.lookup(factors.bonusMalusClass);
const experienceMultiplier = rateTables.experience.lookup(factors.driverExperience);
const mileageMultiplier = rateTables.mileage.lookup(factors.annualMileage);
const appliedFactors: AppliedFactor[] = [
{ name: 'Age', inputValue: factors.driverAge, factor: ageMultiplier, source: 'AGE_TABLE_v3' },
{ name: 'Vehicle Group', inputValue: factors.vehicleGroup, factor: vehicleMultiplier, source: 'VEH_TABLE_v2' },
{ name: 'Bonus/Malus', inputValue: factors.bonusMalusClass, factor: bonusMalusMultiplier, source: 'BM_TABLE_v1' },
{ name: 'Experience', inputValue: factors.driverExperience, factor: experienceMultiplier, source: 'EXP_TABLE_v1' },
{ name: 'Mileage', inputValue: factors.annualMileage, factor: mileageMultiplier, source: 'KM_TABLE_v2' },
];
// 3. Premio tecnico = base * prodotto dei fattori
const combinedFactor = appliedFactors.reduce((acc, f) => acc * f.factor, 1);
const technicalPremium = baseRate * combinedFactor;
auditTrail.push(`Technical premium: ${baseRate} * ${combinedFactor.toFixed(4)} = ${technicalPremium.toFixed(2)}`);
// 4. Caricamenti (expense loading, commissioni, profitto)
const loadings: Loading[] = [
{ type: 'EXPENSE', percentage: 0.15, amount: { amount: technicalPremium * 0.15, currency: 'EUR' } },
{ type: 'COMMISSION', percentage: 0.12, amount: { amount: technicalPremium * 0.12, currency: 'EUR' } },
{ type: 'PROFIT', percentage: 0.05, amount: { amount: technicalPremium * 0.05, currency: 'EUR' } },
{ type: 'CATASTROPHE', percentage: 0.02, amount: { amount: technicalPremium * 0.02, currency: 'EUR' } },
];
const totalLoadingPct = loadings.reduce((acc, l) => acc + l.percentage, 0);
const grossPremium = technicalPremium * (1 + totalLoadingPct);
// 5. Imposte (22.25% per RC Auto in Italia)
const taxRate = 0.2225;
const taxes = grossPremium * taxRate;
const totalPremium = grossPremium + taxes;
return {
baseRate: { amount: baseRate, currency: 'EUR' },
factors: appliedFactors,
technicalPremium: { amount: technicalPremium, currency: 'EUR' },
loadings,
grossPremium: { amount: grossPremium, currency: 'EUR' },
taxes: { amount: taxes, currency: 'EUR' },
totalPremium: { amount: totalPremium, currency: 'EUR' },
ratingDate: new Date(),
rateTableVersion: 'RC_AUTO_2026_Q1',
auditTrail,
};
}
Architektura moderního ratingového nástroje
Ratingový stroj ve výrobě je mnohem složitější než tento příklad. Mezi klíčové vlastnosti patří:
- Verze ceníků: Každá tarifní tabulka má datum účinnosti. Systém musí použít správnou tabulku na základě data účinnosti zásady, nikoli aktuálního data
- Samostatný modul pravidel: Obchodní pravidla (omezení, vyloučení, slevy) lze konfigurovat bez nasazení kódu, obvykle prostřednictvím modulu pravidel (založené na Drools, RETE nebo JSON)
- Kompletní auditní záznam: Každý krok výpočtu musí být sledovatelný z hlediska souladu s předpisy
- Horizontální škálovatelnost: Ratingový modul musí zvládat vrcholy tisíců kotací za sekundu (komparátory, otevřená registrace)
- Idempotence: Stejný vstup musí vždy produkovat stejný výstup (čistá funkce)
Doménový design pro pojištění
Domain-Driven Design (DDD) je nejvhodnější architektonický přístup pro oblast pojištění jeho vnitřní složitost a potřeba sladit software s jazykem podniku. Podívejme se, jak to konkrétně aplikovat.
Ohraničený kontext ekosystému pojištění
Každý ohraničený kontext má svůj vlastní všudypřítomný jazyk, jeho modely a vlastní pravidla. Pojem „politika“ má v kontextu upisování různé významy (návrh bude vyhodnocen) ve srovnání s Policy Administration (vydána smlouva).
// ============================================
// Bounded Context Map
// ============================================
//
// +------------------+ +------------------+ +------------------+
// | Distribution | | Underwriting | | Policy Admin |
// | | | | | |
// | - Lead | | - Submission | | - Policy |
// | - Opportunity |---->| - Risk |---->| - Coverage |
// | - Quote Request | | - Rating | | - Endorsement |
// | - Channel | | - Decision | | - Renewal |
// +------------------+ +------------------+ +------------------+
// | | |
// | | |
// v v v
// +------------------+ +------------------+ +------------------+
// | CRM / Party | | Reinsurance | | Claims |
// | | | | | |
// | - Customer | | - Treaty | | - Claim |
// | - Agent | | - Cession | | - Reserve |
// | - Broker | | - Recovery | | - Payment |
// | - Address | | - Bordereaux | | - Assessment |
// +------------------+ +------------------+ +------------------+
// | | |
// v v v
// +------------------+ +------------------+ +------------------+
// | Billing | | Compliance | | Fraud Detection |
// | | | | | |
// | - Invoice | | - Filing | | - Alert |
// | - Payment | | - Report | | - Investigation |
// | - Collection | | - Audit | | - Score |
// | - Installment | | - Solvency | | - Rule |
// +------------------+ +------------------+ +------------------+
// Context Mapping Relationships:
// Distribution --[Conformist]--> Underwriting
// Underwriting --[Published Language]--> Policy Admin
// Policy Admin --[Shared Kernel]--> Billing
// Policy Admin --[Customer/Supplier]--> Claims
// Claims --[Anti-Corruption Layer]--> Fraud Detection
// Underwriting --[Partnership]--> Reinsurance
// All Contexts --[Conformist]--> Compliance
Agregáty a invarianty
V DDD, každý agregát chrání své obchodní invarianty. Tady jsou hlavní invarianty pro dva klíčové agregáty:
Souhrnná politika
- Zásada musí mít alespoň jedno aktivní pokrytí
- Datum vypršení platnosti musí být po datu účinnosti
- Celkové pojistné musí být součtem pojistného na krytí + zatížení
- Každé potvrzení musí zvýšit verzi
- Stavové přechody musí respektovat stavový automat
- Zásadu nelze zrušit otevřenými nároky
Souhrn nároků
- Datum nehody musí spadat do období pojištění
- Rezerva nemůže být záporná
- Celková zaplacená částka nesmí překročit limit pokrytí
- Uzavřená žádost nemůže přijímat nové platby (musí být znovu otevřena)
- Rozhodnutí vyžaduje minimálně odborné posouzení
- Platba vyžaduje schválení, pokud překročí limit autority
Doménové události
I doménové události jsou mechanismem, kterým ohraničené kontexty určitým způsobem komunikují oddělené. Každá událost představuje něco významného, co se v doméně stalo.
// ============================================
// Insurance Domain Events
// ============================================
interface DomainEvent {
readonly eventId: string;
readonly eventType: string;
readonly occurredAt: Date;
readonly aggregateId: string;
readonly aggregateType: string;
readonly version: number;
readonly correlationId: string;
readonly causationId?: string;
}
// --- Policy Events ---
interface PolicyQuoted extends DomainEvent {
readonly eventType: 'POLICY_QUOTED';
readonly aggregateType: 'Policy';
readonly quoteNumber: string;
readonly premium: Money;
readonly validUntil: Date;
}
interface PolicyIssued extends DomainEvent {
readonly eventType: 'POLICY_ISSUED';
readonly aggregateType: 'Policy';
readonly policyNumber: string;
readonly effectiveDate: Date;
readonly premium: Money;
readonly coverages: readonly string[];
}
interface PolicyEndorsed extends DomainEvent {
readonly eventType: 'POLICY_ENDORSED';
readonly aggregateType: 'Policy';
readonly endorsementNumber: number;
readonly changes: readonly FieldChange[];
readonly premiumAdjustment: Money;
}
// --- Claim Events ---
interface ClaimFiled extends DomainEvent {
readonly eventType: 'CLAIM_FILED';
readonly aggregateType: 'Claim';
readonly policyNumber: string;
readonly lossDate: Date;
readonly lossType: string;
readonly initialReserve: Money;
}
interface ClaimSettled extends DomainEvent {
readonly eventType: 'CLAIM_SETTLED';
readonly aggregateType: 'Claim';
readonly settlementAmount: Money;
readonly payee: string;
}
// --- Cross-Context Reactions ---
// PolicyIssued -> Billing: createInvoice()
// PolicyIssued -> Reinsurance: calculateCession()
// ClaimFiled -> FraudDetection: screenClaim()
// ClaimFiled -> Reinsurance: notifyCession()
// ClaimSettled -> Billing: adjustReserve()
// ClaimSettled -> Reinsurance: calculateRecovery()
Standardy ACORD a interoperabilita
ACORD (Asociace pro kooperativní operační výzkum a vývoj) e organizace, která stanovuje datové standardy pro globální pojišťovací průmysl. Pro vývojáře je ACORD ekvivalentem HL7/FHIR pro zdravotnictví nebo SWIFT pro finance.
Datové standardy ACORD: co jsou
ACORD poskytuje granulární datové modely, formáty zpráv (XML a JSON) a schémata navrženo speciálně pro pojišťovací procesy. Cílem je zajistit plynulost efektivní zpracování dat mezi všemi hráči v ekosystému: pojistitelé, makléři, agenti, zajistitelů a regulátorů.
| Standardní ACORD | Formát | Používání | Sektor |
|---|---|---|---|
| ACORD AL3 | Vlastník (pevná délka) | Výměna dat mezi agentem a pojišťovnou (USA) | Osobní linky P&C |
| ACORD XML | Schéma XML | Nabídka, vystavení, reklamace, vyúčtování | P&C, život, zdraví |
| ACORD GRLC 2.0 | JSON/XML | Zajištění a velké komerční (globální) | Zajištění, Specialita |
| ACORD Next-Gen | JSON (API-first) | Mikroslužby, REST API, asynchronní události | Meziodvětvový |
| Formuláře ACORD | PDF/XML | Standardizované formuláře (certifikáty, přílohy) | P&C (USA) |
GRLC Generation 2.0 (duben 2025)
Nejvýznamnější aktualizace posledních let a uvedení na trh GRLC generace 2.0, digitální standard založený na JSON optimalizovaný pro jemnozrnné transakce, jako jsou mikroslužby a API. Podporuje komplexní přímé zpracování celého životního cyklu politiky v globálním ekosystému zajištění, což umožňuje moderní integrace, aniž by procházely starými Dávkové formáty XML.
Vzor API pro pojištění
Moderní API pro pojištění se řídí specifickými vzory, které odrážejí složitost domény:
- Asynchronní citace: Složité nabídky (komerční, speciální) vyžadují asynchronní zpracování. API vrací a
quoteRequestIda po dokončení informovat prostřednictvím webhooku - Dočasné verzování: Každý zdroj (politika, pokrytí) má časový rozměr. API podporuje dotazy pro
asOfDateobnovit historický stav - Idempotence: Vazba a platební operace musí být přes idempotent
idempotencyKeyaby nedošlo k duplicitě - Streamování události: Změny stavu jsou oznamovány prostřednictvím událostí (webhook nebo zprostředkovatel zpráv) pro integraci s navazujícími systémy
Regulační krajina
Pojišťovnictví je jedním z nejvíce regulovaných na světě. Pro vývojáře to znamená což je mnoho architektonických rozhodnutí diktováno dodržováním, nejen z inženýrské osvědčené postupy.
Klíčové předpisy a dopad na software
| Nařízení | Rozsah | Dopad na software |
|---|---|---|
| Solventnost II | EU - Požadavky na kapitál a solventnost | Rizikové modely, výpočet SCR (Solvency Capital Requirement), XBRL reporting, rámec kvality dat |
| IFRS 17 | Global - Účtování pojistných smluv | CSM (Contractual Service Margin) kalkulace, seskupování smluv, modely měření (BBA, VFA, PAA) |
| GDPR / Ochrana osobních údajů | EU - Ochrana osobních údajů | Podrobný souhlas, právo být zapomenut vs povinné uchování (konflikt), pseudonymizace, DPIA |
| IDD | EU - Distribuce pojištění | Sledovatelnost poradenství, přiměřenost produktů, střety zájmů, předsmluvní dokumentace |
| DORA | EU - Digitální operační odolnost | Řízení rizik ICT, hlášení incidentů, testování odolnosti, riziko třetích stran (poskytovatel cloudu) |
| ICS 2025 | Globální – kapitálový standard pro IAIG | Výpočet regulatorního kapitálu s jednotným globálním standardem (v provozu od roku 2025) |
Konflikt GDPR versus pojistná retence
Jedno z nejsložitějších dilemat pro vývojáře pojištění: GDPR ukládá správně do zapomnění, ale pojistné předpisy vyžadují uchovávání dat na období od 5 do 30 let (pohledávky s otevřenými rezervami, soudní spory, závazky pojistná matematika). Typické řešení zahrnuje progresivní pseudonymizace: údaje identifikátory jsou odděleny od transakčních dat a odstraněny, je-li to možné, při zachování anonymizované údaje pro regulační povinnosti.
Architektura moderní platformy InsurTech
Moderní pojistné platformy přebírají architekturu cloud-native, API-first, řízený událostmi. Starší monolit je rozdělen do ohraničených zarovnaných mikroslužeb kontext domény.
Typický technologický balíček (2025–2026)
| Vrstvy | Technologie | Funkce |
|---|---|---|
| Frontend | Angular, React, Vue + mikrofrontend | Agentský portál, zákaznický portál, backoffice |
| Brána API | Kong, AWS API Gateway, Apigee | Omezení rychlosti, ověřování, směrování, verzování |
| Mikroslužby | Node.js/NestJS, Java/Spring Boot, Go | Zásady, reklamace, hodnocení, fakturace, CRM |
| Event Bus | Apache Kafka, AWS EventBridge, RabbitMQ | Doménové události, CQRS, event sourcing |
| Databáze | PostgreSQL, MongoDB, DynamoDB | Databáze na službu (databáze na omezený kontext) |
| AI/ML | Python, TensorFlow, SageMaker | Detekce podvodů, optimalizace cen, OCR dokumenty |
| Orchestr | Kubernetes, AWS ECS, Temporal.io | Škálování, ságové vzory, dlouhotrvající pracovní postupy |
| Pozorovatelnost | Datadog, Grafana, OpenTelemetry | Distribuované sledování, metriky, centralizované protokolování |
Klíčové architektonické vzory
Sourcing událostí pro zásady
L'zajišťování zdrojů událostí a zvláště vhodné pro oblast pojištění, protože politika a ve své podstatě sled událostí (vydání, potvrzení, obnovení, nárok). Místo pouhého ukládání aktuálního stavu ukládáte všechny události a obnovujete aktuální stav přes přehrání. To automaticky poskytuje kompletní auditní záznam, klíčový regulační požadavek.
Vzor ságy pro procesy napříč kontextem
Procesy, jako je vydávání zásad, zahrnují více ohraničených kontextů: Upisování schvaluje, Správce zásad, Fakturace vytvoří fakturu, Zajištění vypočítá přiřazení. The ságový vzor (orchestrovaný nebo choreografický) koordinuje tyto distribuované kroky zajištění případné konzistence a kompenzace v případě selhání. Temporal.io e obzvláště populární v InsurTech pro implementaci dlouhotrvajících stavových pracovních postupů vytrvalý.
Multi-Agent AI Systems (Trend 2026)
Místo jediného monolitického asistenta umělé inteligence stojí nejpokročilejší platformy InsurTech provádění multiagentní systémy se specializovanými agenty: jeden agent pro příjem reklamací, jeden pro kontrolu podvodu, jeden pro komunikaci se zákazníkem, jeden pro platby a vymáhání. Tito agenti jsou organizováni pomocí jasných pracovních postupů a spolupracují na automatizaci celého životního cyklu reklamace.
Závěry a další kroky
Pojišťovací doména je jednou z nejbohatších a nejsložitějších, s nimiž se může developer setkat. V tomto článku jsme postavili základy: produkty, aktéři, hodnotový řetězec, datové modely, životní cykly, ratingový engine, aplikovaný DDD a regulační prostředí.
Zde jsou s sebou hlavní:
- Pojistný produkt je příslib: díky tomu jsou datové modely ze své podstaty dočasné a verzované
- Univerzální model neexistuje: Life, P&C, Health a Speciality mají zcela odlišné potřeby
- Stavový stroj a základní vzorec: pro politiky i nároky, životní cyklus a stavový stroj s dobře definovanými přechody
- Neměnnost je regulační požadavek: každá modifikace generuje novou verzi, nikdy nepřepisování
- DDD a přirozený přístup: ohraničený kontext zarovnaný s hodnotovým řetězcem, agregáty, které chrání obchodní invarianty, doménové události pro oddělení
- Shoda řídí architekturu: Solvency II, IFRS 17, GDPR a DORA nejsou „příjemné“, ale primární architektonická omezení
- ACORD a lingua franca: Standardy ACORD (zejména Next-Gen JSON) jsou nezbytné pro interoperabilitu v ekosystému
V další epizodě
V dalším článku ze série InsurTech Engineering se budeme hlouběji zabývat Zásady Administrační systém: jak navrhnout moderní PAS s produktovým konfigurátorem, dočasné verzování, schvalovací modul a integrace s hodnocením. Uvidíme konkrétní vzory pro řízení složitosti pojistných produktů s více krytí doménově řízený přístup.







