Domena ubezpieczeniowa dla programistów: produkty, aktorzy i modele danych
Prawdopodobnie jeśli jesteś programistą nowym w świecie ubezpieczeń zetkniesz się z nieprzeniknionym żargonem: gwarantowanie, poparcie, FNOL, subrogacja, bordereaux. Nie martw się: ten przewodnik tłumaczy całą domenę ubezpieczenie koncepcji, modeli danych i wzorców architektonicznych zrozumiałych dla programisty, wdrożyć i przede wszystkim modelować poprawnie w kodzie.
Branża ubezpieczeniowa na całym świecie idzie do przodu 7 bilionów dolarów rocznych składek (dane 2025, Swiss Re Sigma) i jest jednym z najbardziej regulowanych sektorów na świecie. Jednak większość obsługujące go systemy informatyczne sięgają lat 80. i 90.: komputery mainframe COBOL, partie nocne, interfejsy zielonego ekranu. Cyfrowa transformacja branży, tzw Ubezpieczenie, przeprojektowuje to wszystko, a programiści są w centrum zmian.
Artykuł ten inauguruje serię Inżynieria InsurTech z pełnym przeglądem dziedziny: produkty ubezpieczeniowe, uczestnicy łańcucha wartości, podstawowe modele danych, cykl życia polis i roszczeń oraz nowoczesne wzorce architektoniczne budowy platform ubezpieczenia natywne w chmurze.
Czego dowiesz się w tym artykule
- Kategorie produktów ubezpieczeniowych (na życie, majątkowe, zdrowotne, specjalistyczne) i ich różnice techniczne
- Uczestnicy łańcucha wartości: ubezpieczający, ubezpieczyciel, broker, agent, reasekurator, regulator
- Łańcuch wartości ubezpieczeń: dystrybucja, underwriting, zarządzanie polisami, roszczenia, inwestycje
- Podstawowe modele danych: Polisa, Roszczenie, Premium, Ubezpieczenie, Potwierdzenie, Rider
- Pełny cykl życia polisy: wycena, wydanie, zmiana, odnowienie, anulowanie
- Cykl życia roszczenia: FNOL, ocena, rozliczenie, windykacja
- Projekt oparty na domenie zastosowany w ubezpieczeniach: ograniczony kontekst i agregaty
- Architektura silnika ratingowego i kalkulacja składek
- Standardy ACORD i wzorce API dotyczące interoperacyjności
- Krajobraz regulacyjny: Wypłacalność II, MSSF 17, RODO
Branża ubezpieczeniowa: przegląd dewelopera
Przed napisaniem choćby jednej linii kodu konieczne jest zrozumienie jak działa biznes ubezpieczenie. W przeciwieństwie do handlu elektronicznego, gdzie produkt jest namacalny, w ubezpieczeniach „produktem” jest obietnica: wypłata przyszłego odszkodowania w przypadku wystąpienia a niepewne wydarzenie. To sprawia, że domena jest z natury złożona z punktu widzenia modelowania danych.
„Ubezpieczenie to jedyny produkt, który kupujesz z nadzieją, że nigdy z niego nie skorzystasz. To paradoks definiuje całą architekturę systemów, które nim zarządzają.”
Podstawowa zasada: wzajemność ryzyka
Kluczową koncepcją jest wzajemność ryzyka (łączenie ryzyka): świetne grupa osób lub firm wpłaca regularne składki do wspólnego funduszu, z którego są pobierane środków, aby zrekompensować nielicznym poszkodowanym. Rola ubezpieczyciela i zarządzanie tym funduszu w sposób zrównoważony aktuarialnie, zapewniając, że pobierane składki wystarczą na pokrycie oczekiwane roszczenia plus koszty operacyjne i marża zysku.
Kategorie produktów ubezpieczeniowych
Produkty ubezpieczeniowe podzielone są na makrokategorie o bardzo różnych parametrach technicznych. Zrozumienie tych różnic ma kluczowe znaczenie dla prawidłowego modelowania danych.
| Kategoria | Przykłady | Typowy czas trwania | Charakter ryzyka | Złożoność danych |
|---|---|---|---|---|
| Życie (Życie) | Terminowe, mieszane, powiązane z jednostkami, planszowe | 10-40 lat | Śmiertelność, długowieczność | Wysokie (tabele aktuarialne, rezerwy matematyczne) |
| Uszkodzenia (P&C) | Samochód, dom, profesjonalny RC, ogień | 1 rok (odnawialny) | Majątek, odpowiedzialność cywilna | Średnia (częstotliwość szkód, średni koszt) |
| Zdrowie (Zdrowie) | Zwrot kosztów, wypadki, opieka długoterminowa | 1 rok/wieloletnie | Zachorowalność, niepełnosprawność | Wysoki (ICD, DRG, kodowanie sieci opieki zdrowotnej) |
| Specjalności | Morskie, lotnicze, cyber, D&O, E&O | Zmienny | Ryzyko złożone/katastrofalne | Bardzo wysoki (modele CAT, kumulacje) |
Implikacje dla Dewelopera
Nie ma jednego, uniwersalnego modelu danych dla ubezpieczeń. System Life zarządza rezerwy matematyczne i tablice śmiertelności; system P&C zarządza odliczeniami, limitami i wyceny; System opieki zdrowotnej zarządza kodami medycznymi i sieciami dostawców. Wybór architektoniczny pomiędzy A ujednolicony model e specjalistyczne modele dla LOB (Linia biznesowa) to jedna z najważniejszych decyzji przy projektowaniu platformy ubezpieczeniowej.
Aktorzy łańcucha wartości
Ekosystem ubezpieczeniowy obejmuje wielu aktorów pełniących różne role. Każdy z nich staje się jednostka w naszym modelu danych i często oddzielny, ograniczony kontekst w architekturze.
Mapa głównych aktorów
| Aktor | Rola w domenie | Kluczowy podmiot danych | Główne interakcje |
|---|---|---|---|
| Wykonawca (Ubezpieczający) | Kup polisę, opłać składki | Klient, Konto, Metoda Płatności | Limit, wiązanie, płatność premium, złożenie wniosku |
| Ubezpieczony | Osoba/rzecz objęta polisą | Ubezpieczona Strona, Obiekt Ryzyka | Może różnić się od Wykonawcy |
| Ubezpieczyciel (Ubezpieczyciel / Przewoźnik) | Podejmuje ryzyko, płaci roszczenia | Firma, portfel, rezerwa | Gwarantuj, wystawiaj, reguluj roszczenia |
| Agent | Reprezentuje ubezpieczyciela, sprzedaje polisy | Agent, Agencja, Komisja | Rozproszone, przydziały, usługi |
| Pośrednik | Reprezentuje klienta, negocjuje warunki | Broker, BrokerFirm, Placement | Postaw ryzyko, negocjuj warunki |
| Reasekurator | Ubezpiecza ubezpieczyciela (nadwyżka ryzyka) | Traktat, cesja, odzyskanie | Uzyskuje, wycofuje się, rozlicza |
| Ekspert (regulator) | Ocenia roszczenia i ustala odszkodowanie | Ocena, oszacowanie, raport | Sprawdź, Oceń, Poleć |
| Regulator (Regulator) | Nadzoruje rynek, narzuca zasady | Archiwizacja, zgodność, raporty | Zatwierdź produkty, audyt, zakończ |
Relacja krytyczna: wykonawca vs ubezpieczony vs beneficjent
Jedną z najbardziej niedocenianych komplikacji jest rozróżnienie pomiędzy ubezpieczającym, ubezpieczonym i beneficjent. W najprostszym przypadku (indywidualna polisa samochodowa) te trzy liczby się pokrywają. Ale w korporacyjnej polisie ubezpieczeniowej na życie, wykonawca i firma, ubezpieczony są pracownicy i beneficjenci są wyznaczonymi członkami rodziny. Model danych musi wspieraj tę elastyczność za pomocą relacji wiele do wielu między tymi jednostkami.
Łańcuch wartości ubezpieczeń
Łańcuch wartości ubezpieczenia opisuje cały przebieg działalności od pierwszego kontaktu z ubezpieczycielem klienta do czasu rozpatrzenia reklamacji i odnowienia polisy. Każde ogniwo w łańcuchu zazwyczaj odpowiada a ograniczony kontekst w architekturze oprogramowania.
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. Dystrybucja
Dystrybucja obejmuje wszystkie kanały, którymi produkty ubezpieczeniowe docierają do klienta: agenci (jednofirmowe lub wielofirmowe), pośrednik, bancassurance, porównywarki internetowe e kanały bezpośrednie (internet, aplikacja, call center). Dla dewelopera przekłada się to na wielokanałowe interfejsy API wyceny, zintegrowane systemy CRM i silniki konfiguracji produktów.
2. Underwriting (Założenie ryzyka)
Underwriting to proces, w ramach którego ubezpieczyciel ocenia proponowane ryzyko i podejmuje decyzję, czy je zaakceptować, na jakich warunkach i za jaką cenę. Stanowi techniczne serce działalności ubezpieczeniowej i obejmuje:
- Ocena ryzyka: Ocena charakterystyki ryzyka (wiek, stan zdrowia, lokalizacja, historia roszczeń)
- Ocena: Obliczanie składki poprzez silnik ocen (algorytmy aktuarialne + reguły biznesowe)
- Wybór ryzyka: Decyzja o przyjęciu, odrzuceniu lub modyfikacji warunków
- Polecenia: Eskalacja do starszego gwaranta w przypadku ryzyk wykraczających poza parametry automatyczne
3. Zarządzanie polityką (administracja polityką)
Il System zarządzania polityką (PAS) to centralny system zarządzający całością cykl życia polisy: wydanie, zmiany (zatwierdzenie), odnowienia, anulowanie i przywrócenie. Jest to zazwyczaj najbardziej złożony system w ekosystemie IT ubezpieczeń.
4. Zarządzanie roszczeniami
Zarządzanie roszczeniami obejmuje cały proces od zgłoszenia szkody (FNOL – Pierwsze zawiadomienie o Strata) do czasu likwidacji i ewentualnej odzyskania (subrogacji). I ten proces bezpośrednio wpływa na satysfakcję klientów i rentowność ubezpieczyciela.
5. Inwestycje i zarządzanie rezerwami
Ubezpieczyciele inwestują zebrane składki w oczekiwaniu na wypłatę przyszłych roszczeń. Zarządzanie inwestycji (Zarządzanie aktywami i pasywami) i obliczenie rezerwy techniki są to procesy regulowane, które wymagają wyrafinowanych modeli aktuarialnych.
Podstawowe modele danych
Przejdźmy do sedna tego, co programista musi modelować. Poniżej znajdują się agregaty (w sensie DDD) podstawy każdej platformy ubezpieczeniowej.
Główne podmioty i relacje
// ============================================
// 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;
}
Wzorzec kluczowy: niezmienność i wersjonowanie
Zwróć uwagę, jak korzysta każdy interfejs readonly na wszystkich nieruchomościach. W dziedzinie ubezpieczeń,
the identyfikowalność oraz wymóg regulacyjny: każda zmiana w polityce generuje
nowy poparcie co zwiększa version. To nigdy się nie „zmienia”.
polityka; tworzona jest nowa wersja. Ten wzór doskonale komponuje się zpozyskiwanie wydarzeń
oraz z architekturami CQRS.
Cykl życia polisy
Polityka w trakcie swego istnienia przechodzi przez dobrze zdefiniowane stany. Modelujmy ten cykl życia jak jeden maszyna stanu, podstawowy wzorzec w oprogramowaniu ubezpieczeniowym.
// ============================================
// 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,
};
}
Kluczowe fazy cyklu życia
Faza przedwydawnicza
- Szanse: Orientacyjny szacunek oparty na minimalnych danych. Typowy okres ważności: 30 dni
- Aplikacja: Formalna propozycja zawierająca wszystkie dane niezbędne do zawarcia umowy
- Wiązać: Ubezpieczyciel zgadza się zapewnić ochronę (ale polisa nie jest jeszcze wystawiona)
- Wydanie: Wydanie oficjalnego dokumentu politycznego
Faza po wydaniu
- popiera: Zmiana obowiązujących warunków (nowa wersja)
- Odnowić: Odnowienie po wygaśnięciu (może obejmować ponowną ocenę)
- Wstrzymać: Tymczasowe zawieszenie (np. brak płatności)
- Anulować: Anulowanie z obliczeniem składki memoriałowej
- Nastawić: Przywrócenie do pracy po zawieszeniu lub przepadku
Cykl życia roszczeń
Wypadek to zdarzenie, które aktywuje obietnicę ubezpieczenia. Jego cykl życia jest taki sam uporządkowany i doskonale nadaje się do modelowania jako maszyna stanu.
// ============================================
// 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;
}
Fazy wypadku w szczegółach
| Faza | Działalność | Zaangażowani aktorzy | Wygenerowane dane |
|---|---|---|---|
| FNOL | Zgłoś wypadek przez telefon, stronę internetową, aplikację lub e-mail | Ubezpieczony, Call Center | Powiadomienie o roszczeniach, rezerwa wstępna |
| Ocena stanu zdrowia rannych | Klasyfikacja roszczeń, nadanie pierwszeństwa, weryfikacja zasięgu | Osoba zajmująca się likwidacją szkód, system automatyczny | Weryfikacja zasięgu, priorytet, przydział |
| Dochodzenie | Gromadzenie dokumentacji, wycena, weryfikacja okoliczności | Ekspert, badacz, lekarz sądowy | Ocena, zdjęcia, raport eksperta |
| Wyrok | Decyzja: całkowita, częściowa akceptacja lub odrzucenie | Menedżer ds. roszczeń, Komisja ds. roszczeń | Decyzja, korekta Oblicz |
| Osady | Obliczanie odszkodowania i płatności | Osoba zajmująca się obsługą roszczeń, Biuro Płatności | Płatność, Ugoda |
| Powrót do zdrowia | Subrogacja na rzecz odpowiedzialnych stron trzecich, odzysk powypadkowy | Kancelaria prawna, Biuro windykacyjne | Roszczenie subrogacyjne, windykacja |
Architektura silnika oceny
Il silnik ocen oraz składnik obliczający składkę ubezpieczeniową. I jeden z najbardziej krytyczne i wydajne systemy w ekosystemie InsurTech: muszą przetwarzać tysiące ofert na sekundę z aktuarialną precyzją i pełną identyfikowalnością.
Jak działa kalkulacja składki
Obliczanie składki odbywa się według dobrze zdefiniowanego potoku, który przekształca czynniki ryzyka w: ostateczna cena. Zobaczmy uproszczony przykład dla 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 nowoczesnego silnika oceny
Produkowany silnik oceny jest znacznie bardziej złożony niż w tym przykładzie. Kluczowe funkcje obejmują:
- Wersje tabel stawek: Każda tabela taryfowa ma datę wejścia w życie. System musi zastosować właściwą tabelę w oparciu o datę wejścia w życie polisy, a nie datę bieżącą
- Oddzielny silnik reguł: Reguły biznesowe (limity, wykluczenia, rabaty) można konfigurować bez konieczności wdrażania kodu, zazwyczaj za pośrednictwem silnika reguł (opartego na Drools, RETE lub JSON)
- Pełna ścieżka audytu: Każdy etap obliczeń musi być identyfikowalny pod kątem zgodności z przepisami
- Skalowalność pozioma: Silnik oceny musi zarządzać szczytami tysięcy cytatów na sekundę (komparatory, rejestracja otwarta)
- Idempotencja: To samo wejście musi zawsze dawać ten sam wynik (czysta funkcja)
Projektowanie oparte na domenie dla ubezpieczeń
Domain-Driven Design (DDD) to najbardziej odpowiednie podejście architektoniczne w dziedzinie ubezpieczeń jego nieodłączną złożoność i potrzebę dostosowania oprogramowania do języka biznesowego. Zobaczmy, jak zastosować to konkretnie.
Ograniczony kontekst ekosystemu ubezpieczeniowego
Każdy ograniczony kontekst ma swój własny wszechobecny język, jego modele i własne zasady. Termin „polisa” ma różne znaczenia w kontekście ubezpieczeniowym (wniosek do oceny) w porównaniu z Policy Administration (wydana umowa).
// ============================================
// 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
Agregaty i niezmienniki
W DDD, każdy agregat chroni swoje niezmienniki biznesowe. Oto one główne niezmienniki dla dwóch kluczowych agregatów:
Polityka zbiorcza
- Polisa musi mieć co najmniej jedno aktywne ubezpieczenie
- Data ważności musi być późniejsza od daty wejścia w życie
- Składka całkowita musi być sumą składek za ubezpieczenie + dopłat
- Każde potwierdzenie musi zwiększać wersję
- Przejścia między stanami muszą uwzględniać maszynę stanów
- Polisy nie można anulować w przypadku otwartych roszczeń
Agregat roszczeń
- Data wypadku musi mieścić się w okresie objętym polisą
- Rezerwa nie może być ujemna
- Całkowita zapłacona suma nie może przekroczyć limitu ubezpieczenia
- Zamknięty wniosek nie może otrzymać nowych płatności (należy go ponownie otworzyć)
- Decyzja wymaga co najmniej oceny eksperckiej
- Płatność wymaga zatwierdzenia, jeśli przekracza próg uprawnień
Wydarzenia domeny
I zdarzenia domeny są mechanizmem, dzięki któremu ograniczone konteksty komunikują się w określony sposób oddzielony. Każde wydarzenie reprezentuje coś znaczącego, co wydarzyło się w domenie.
// ============================================
// 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 i interoperacyjność
POGOD (Stowarzyszenie na rzecz Badań i Rozwoju Operacji Spółdzielczych) e organizacja wyznaczająca standardy danych dla globalnej branży ubezpieczeniowej. Dla dewelopera ACORD jest odpowiednikiem HL7/FHIR w służbie zdrowia lub SWIFT w finansach.
Standardy danych ACORD: czym są
ACORD zapewnia szczegółowe modele danych, formaty wiadomości (XML i JSON) oraz schematy zaprojektowane specjalnie dla procesów ubezpieczeniowych. Celem jest zapewnienie przepływu efektywne przetwarzanie danych pomiędzy wszystkimi graczami w ekosystemie: ubezpieczycielami, brokerami, agentami, reasekuratorów i organów regulacyjnych.
| Standardowy ACORD | Format | Stosowanie | Sektor |
|---|---|---|---|
| AKORD AL3 | Właściciel (stała długość) | Wymiana danych agent-ubezpieczyciel (USA) | Linie osobiste P&C |
| ACORD XML | Schemat XML | Wycena, wystawienie, reklamacja, fakturowanie | P&C, Życie, Zdrowie |
| ACORD GRLC 2.0 | JSON/XML | Reasekuracja i duże komercyjne (globalne) | Reasekuracja, specjalność |
| ACORD nowej generacji | JSON (najpierw API) | Mikrousługi, REST API, zdarzenia asynchroniczne | Międzysektorowe |
| Formularze ACORD | PDF/XML-a | Standaryzowane formularze (certyfikaty, załączniki) | Warunki i zasady (USA) |
GRLC Generacja 2.0 (kwiecień 2025)
Najważniejsza aktualizacja w ostatnich latach i uruchomienie GRLC Generacja 2.0, cyfrowy standard oparty na JSON, zoptymalizowany pod kątem drobnych transakcji, takich jak mikrousługi i API. Obsługuje kompleksowe i proste przetwarzanie całego cyklu życia polisy w globalnym ekosystemie reasekuracyjnym, umożliwiając nowoczesne integracje bez przechodzenia przez stare Wsadowe formaty XML.
Wzorzec API dla ubezpieczeń
Nowoczesne interfejsy API ubezpieczeń działają według określonych wzorców odzwierciedlających złożoność domeny:
- Cytowanie asynchroniczne: Złożone oferty (komercyjne, specjalistyczne) wymagają przetwarzania asynchronicznego. Interfejs API zwraca a
quoteRequestIdi powiadom o zakończeniu za pomocą webhooka - Wersjonowanie tymczasowe: Każdy zasób (polisa, zasięg) ma wymiar czasowy. Interfejs API obsługuje zapytania dla
asOfDateprzywrócić stan historyczny - Idempotencja: Operacje wiązania i płatności muszą odbywać się za pośrednictwem idempotentu
idempotencyKeyaby uniknąć powielania - Transmisja wydarzeń: Zmiany stanu są powiadamiane za pośrednictwem zdarzeń (webhook lub broker komunikatów) w celu integracji z systemami podrzędnymi
Krajobraz regulacyjny
Branża ubezpieczeniowa jest jedną z najbardziej regulowanych na świecie. Dla programisty oznacza to którymi jest wiele decyzji architektonicznych podyktowane przestrzeganiem, nie tylko od najlepsze praktyki inżynieryjne.
Kluczowe regulacje i wpływ na oprogramowanie
| Regulacja | Zakres | Wpływ na oprogramowanie |
|---|---|---|
| Wypłacalność II | UE – Wymogi kapitałowe i wypłacalności | Modele ryzyka, kalkulacja SCR (kapitałowego wymogu wypłacalności), raportowanie XBRL, ramy jakości danych |
| MSSF 17 | Global - Księgowość umów ubezpieczeniowych | Kalkulacja CSM (Contractual Service Margin), grupowanie kontraktów, modele pomiaru (BBA, VFA, PAA) |
| RODO / Prywatność | UE – Ochrona danych osobowych | Zgoda szczegółowa, prawo do bycia zapomnianym a obowiązkowe przechowywanie (konflikt), pseudonimizacja, DPIA |
| IDD | UE - Dystrybucja ubezpieczeń | Identyfikowalność doradztwa, adekwatność produktu, konflikt interesów, dokumentacja przedkontraktowa |
| DORA | UE – Cyfrowa odporność operacyjna | Zarządzanie ryzykiem ICT, raportowanie incydentów, testy odporności, ryzyko stron trzecich (dostawca chmury) |
| ICS 2025 | Globalny - Standard Kapitałowy dla IAIG | Kalkulacja kapitału regulacyjnego według ujednoliconego, światowego standardu (obowiązuje od 2025 r.) |
RODO a konflikt dotyczący utrzymania ubezpieczenia
Jeden z najbardziej złożonych dylematów dla dewelopera ubezpieczeń: RODO narzuca prawda do zapomnienia, ale przepisy ubezpieczeniowe wymagają przechowywanie danych na okresy od 5 do 30 lat (roszczenia z otwartymi rezerwami, spory prawne, zobowiązania aktuarialne). Typowe rozwiązanie obejmuje postępująca pseudonimizacja: dane identyfikatory są oddzielane od danych transakcyjnych i usuwane w miarę możliwości, z zachowaniem zanonimizowane dane na potrzeby obowiązków regulacyjnych.
Architektura nowoczesnej platformy InsurTech
Nowoczesne platformy ubezpieczeniowe przyjmują architekturę natywny dla chmury, oparty na API, sterowane zdarzeniami. Starszy monolit jest podzielony na mikrousługi z wyrównanymi ograniczeniami kontekst domeny.
Typowy stos technologii (2025–2026)
| Warstwy | Technologie | Funkcjonować |
|---|---|---|
| Frontend | Angular, React, Vue + mikrofrontend | Portal agenta, portal klienta, backoffice |
| Brama API | Kong, brama API AWS, Apigee | Ograniczanie szybkości, uwierzytelnianie, routing, wersjonowanie |
| Mikrousługi | Node.js/NestJS, Java/Spring Boot, idź | Polityka, roszczenia, ocena, fakturowanie, CRM |
| Autobus imprezowy | Apache Kafka, AWS EventBridge, RabbitMQ | Zdarzenia domeny, CQRS, pozyskiwanie zdarzeń |
| Bazy danych | PostgreSQL, MongoDB, DynamoDB | Baza danych na usługę (baza danych na ograniczony kontekst) |
| AI/ML | Python, TensorFlow, SageMaker | Wykrywanie nadużyć, optymalizacja cen, dokumenty OCR |
| Orkiestracja | Kubernetes, AWS ECS, Temporal.io | Skalowanie, wzorce sagi, długotrwałe przepływy pracy |
| Obserwowalność | Datadog, Grafana, OpenTelemetry | Rozproszone śledzenie, metryki, scentralizowane rejestrowanie |
Kluczowe wzorce architektoniczne
Pozyskiwanie zdarzeń dla zasad
L'pozyskiwanie wydarzeń i szczególnie nadaje się do domeny ubezpieczeniowej, ponieważ polityki i z natury rzeczy jest to sekwencja zdarzeń (wydanie, zatwierdzenie, odnowienie, roszczenie). Zamiast po prostu przechowywać bieżący stan, przechowujesz wszystkie zdarzenia i odbudowujesz aktualny stan poprzez powtórna rozgrywka. To automatycznie zapewnia pełną ścieżkę audytu, kluczowy wymóg regulacyjny.
Wzór Saga dla procesów międzykontekstowych
Procesy takie jak wydawanie polisy obejmują wiele ograniczonych kontekstów: zatwierdzanie ubezpieczenia, Administrator polis wystawia fakturę, Dział rozliczeń tworzy fakturę, Dział reasekuracji oblicza cesję. The wzór sagi (zaaranżowany lub choreograficzny) koordynuje te rozproszone kroki zapewnienie ostatecznej spójności i rekompensaty w przypadku niepowodzenia. Temporal.io e szczególnie popularny w InsurTech do wdrażania długotrwałych, stanowych przepływów pracy trwałe.
Wieloagentowe systemy AI (trend 2026)
Zamiast pojedynczego monolitycznego asystenta AI stoją najbardziej zaawansowane platformy InsurTech wdrażanie systemy wieloagentowe z wyspecjalizowanymi agentami: jeden agent ds przyjmowania roszczeń, jeden w celu sprawdzenia oszustwa, jeden w celu komunikacji z klientem, jeden w celu płatności i windykacja. Agenci ci są zorganizowani poprzez przejrzyste przepływy pracy i współpracują, aby zautomatyzować cały cykl życia roszczenia.
Wnioski i dalsze kroki
Dziedzina ubezpieczeniowa jest jedną z najbogatszych i najbardziej skomplikowanych, z jakimi może się zmierzyć deweloper. W tym artykule zbudowaliśmy fundamenty: produkty, aktorzy, łańcuch wartości, modele danych, cykle życia, mechanizm ratingowy, zastosowany DDD i krajobraz regulacyjny.
Oto dania na wynos główny:
- Produkt ubezpieczeniowy to obietnica: sprawia to, że modele danych są z natury tymczasowe i posiadają wersjonowanie
- Nie ma uniwersalnego modelu: Życie, P&C, Zdrowie i Specjalność mają całkowicie różne potrzeby
- Maszyna stanów i podstawowy wzór: zarówno w przypadku polis, jak i roszczeń, cykl życia i maszyna stanów z dobrze zdefiniowanymi przejściami
- Niezmienność jest wymogiem regulacyjnym: każda modyfikacja generuje nową wersję, nigdy nadpisanie
- DDD i naturalne podejście: ograniczony kontekst dostosowany do łańcucha wartości, agregaty chroniące niezmienniki biznesowe, zdarzenia domeny w celu oddzielenia
- Zgodność napędza architekturę: Wypłacalność II, MSSF 17, RODO i DORA nie są „dobrze mieć”, ale stanowią podstawowe ograniczenia architektoniczne
- ACORD i język francuski: Standardy ACORD (zwłaszcza JSON nowej generacji) są niezbędne dla interoperacyjności w ekosystemie
W następnym odcinku
W kolejnym artykule z serii InsurTech Engineering zagłębimy się w temat Polityka System administracyjny: jak zaprojektować nowoczesny PAS z konfiguratorem produktu, wersjonowanie tymczasowe, silnik rekomendacji i integracja z silnikiem oceny. Zobaczymy konkretne wzorce zarządzania złożonością produktów ubezpieczeniowych obejmujących wiele zakresów ubezpieczenia podejście oparte na domenie.







