Skip to main content
Version: 2.2

ElastiCORE Insurance Domain Sample Model

An entity model design guide for the insurance industry based on ElastiCORE. Referencing the Salesforce Insurance data model, this guide presents models ready for real-world use.

📋 Domain Overview​

Core Business Entities​

  • Insurance Policy: Core information of insurance contracts
  • Insurance Product: Available insurance products for sale
  • Insurance Quote: Quotation and underwriting process
  • Insurance Claim: Insurance claim filing and payment
  • Coverage Type: Insurance coverage scope definitions
  • Policy Participant: Insured persons, beneficiaries, etc.

🏗️ Entity Model Definitions​

1. Insurance Policy​

entity:
InsurancePolicy:
meta: entity @expose(50) @audited @extend(AuditEntity) @table(name="INSURANCE_POLICY")
fields:
policyId: long @id @sequence @search(eq) -- Policy ID
policyNumber: string(50)! @search(like) @unique -- Policy number (user-facing)
policyType: string(30)! @search(eq) -- Insurance type (AUTO, HOME, LIFE, HEALTH)
policyStatus: string(20)! @search(eq) -- Policy status (ACTIVE, EXPIRED, CANCELLED, PENDING)
insuredName: string(100)! @search(like) -- Insured name
policyEffectiveDate: date! @search(between) -- Policy effective date
policyExpiryDate: date! @search(between) -- Policy expiry date
totalPremium: bigdecimal(12.2) @search(between) -- Total premium
currencyCode: string(3) @search(eq) @default('KRW') -- Currency code (KRW, USD)
producerId: long @search(eq) @ref(Producer.id) -- Assigned agent/producer ID
productId: long! @search(eq) @ref(InsuranceProduct.id) -- Insurance product ID
accountId: long! @search(eq) @ref(Account.id) -- Customer account ID
renewalCount: int @search(between) @default(0) -- Renewal count
riskScore: int @search(between) -- Risk score (1-100)
notes: text @search(like) -- Special notes

2. Insurance Product​

entity:
InsuranceProduct:
meta: entity @expose(50) @audited @extend(AuditEntity) @table(name="INSURANCE_PRODUCT")
fields:
productId: long @id @sequence @search(eq) -- Product ID
productCode: string(20)! @search(eq) @unique -- Product code
productName: string(100)! @search(like) -- Product name
productType: string(30)! @search(eq) -- Product type (AUTO, HOME, LIFE, HEALTH, COMMERCIAL)
productCategory: string(50) @search(eq) -- Product category
isActive: boolean @search(eq) @default(true) -- Available for sale
minPremium: bigdecimal(12.2) @search(between) -- Minimum premium
maxPremium: bigdecimal(12.2) @search(between) -- Maximum premium
minCoverage: bigdecimal(15.2) @search(between) -- Minimum coverage limit
maxCoverage: bigdecimal(15.2) @search(between) -- Maximum coverage limit
salesStartDate: date @search(between) -- Sales start date
salesEndDate: date @search(between) -- Sales end date
description: text @search(like) -- Product description
terms: text -- Terms and conditions

3. Insurance Coverage​

entity:
InsuranceCoverage:
meta: entity @expose(50) @table(name="INSURANCE_COVERAGE")
fields:
coverageId: long @id @sequence -- Coverage ID
policyId: long! @search(eq) @ref(InsurancePolicy.id) -- Policy ID
coverageTypeId: long! @search(eq) @ref(CoverageType.id) -- Coverage type ID
coverageAmount: bigdecimal(15.2)! @search(between) -- Coverage limit
deductibleAmount: bigdecimal(12.2) @search(between) @default(0) -- Deductible amount
premiumAmount: bigdecimal(12.2) @search(between) -- Coverage premium
isOptional: boolean @search(eq) @default(false) -- Optional coverage flag
effectiveDate: date! @search(between) -- Coverage start date
expiryDate: date! @search(between) -- Coverage end date

4. Insurance Claim​

entity:
InsuranceClaim:
meta: entity @expose(50) @audited @pageable @extend(AuditEntity) @table(name="INSURANCE_CLAIM")
fields:
claimId: long @id @sequence @search(eq) -- Claim ID
claimNumber: string(50)! @search(like) @unique -- Claim number
policyId: long! @search(eq) @ref(InsurancePolicy.id) -- Policy ID
claimStatus: string(20)! @search(eq) -- Claim status (SUBMITTED, INVESTIGATING, APPROVED, DENIED, PAID)
claimType: string(30)! @search(eq) -- Claim type (ACCIDENT, THEFT, DAMAGE, MEDICAL, DEATH)
incidentDate: date! @search(between) -- Incident date
reportedDate: datetime! @search(between) -- Report date/time
claimedAmount: bigdecimal(15.2)! @search(between) -- Claimed amount
approvedAmount: bigdecimal(15.2) @search(between) -- Approved amount
paidAmount: bigdecimal(15.2) @search(between) -- Paid amount
deductibleApplied: bigdecimal(12.2) @search(between) @default(0) -- Applied deductible
claimantName: string(100)! @search(like) -- Claimant name
claimantPhone: string(20) @search(like) -- Claimant phone number
incidentLocation: string(200) @search(like) -- Incident location
description: text @search(like) -- Incident description
assessorId: long @search(eq) @ref(Assessor.id) -- Claims assessor ID
finalizedDate: datetime @search(between) -- Finalized date/time

5. Coverage Type​

entity:
CoverageType:
meta: entity @expose(50) @table(name="COVERAGE_TYPE")
fields:
coverageTypeId: long @id @sequence @search(eq) -- Coverage type ID
coverageCode: string(20)! @search(eq) @unique -- Coverage code
coverageName: string(100)! @search(like) -- Coverage name
insuranceType: string(30)! @search(eq) -- Insurance type (AUTO, HOME, LIFE, HEALTH)
isBasic: boolean @search(eq) @default(false) -- Basic coverage flag
defaultAmount: bigdecimal(15.2) @search(between) -- Default coverage amount
minAmount: bigdecimal(15.2) @search(between) -- Minimum coverage amount
maxAmount: bigdecimal(15.2) @search(between) -- Maximum coverage amount
description: text @search(like) -- Coverage description

6. Policy Participant​

entity:
PolicyParticipant:
meta: entity @expose(50) @table(name="POLICY_PARTICIPANT")
fields:
participantId: long @id @sequence -- Participant ID
policyId: long! @search(eq) @ref(InsurancePolicy.id) -- Policy ID
participantType: string(20)! @search(eq) -- Participant type (INSURED, BENEFICIARY, OWNER, GUARDIAN)
contactId: long! @search(eq) @ref(Contact.id) -- Contact ID
relationshipType: string(30) @search(eq) -- Relationship (SELF, SPOUSE, CHILD, PARENT, SIBLING, OTHER)
beneficiaryPercentage: bigdecimal(5.2) @search(between) -- Beneficiary allocation (0-100%)
isPrimary: boolean @search(eq) @default(false) -- Primary participant flag
effectiveDate: date! @search(between) -- Participation start date
expiryDate: date @search(between) -- Participation end date

7. Insurance Quote​

entity:
InsuranceQuote:
meta: entity @expose(50) @pageable @extend(AuditEntity) @table(name="INSURANCE_QUOTE")
fields:
quoteId: long @id @sequence @search(eq) -- Quote ID
quoteNumber: string(50)! @search(like) @unique -- Quote number
quoteStatus: string(20)! @search(eq) -- Quote status (DRAFT, SUBMITTED, APPROVED, REJECTED, CONVERTED)
productId: long! @search(eq) @ref(InsuranceProduct.id) -- Insurance product ID
accountId: long! @search(eq) @ref(Account.id) -- Customer account ID
producerId: long @search(eq) @ref(Producer.id) -- Agent/producer ID
quotedPremium: bigdecimal(12.2)! @search(between) -- Quoted premium
totalCoverage: bigdecimal(15.2) @search(between) -- Total coverage amount
validUntil: date! @search(between) -- Quote validity period
riskScore: int @search(between) -- Risk score
underwritingNotes: text @search(like) -- Underwriting notes
convertedPolicyId: long @search(eq) @ref(InsurancePolicy.id) -- Converted policy ID

🔗 Relational Design Patterns​

1:N Relationships​

  • InsurancePolicy (1) ↔ (N) InsuranceCoverage
  • InsurancePolicy (1) ↔ (N) InsuranceClaim
  • InsurancePolicy (1) ↔ (N) PolicyParticipant
  • InsuranceProduct (1) ↔ (N) InsurancePolicy

N:M Relationships (Using Junction Tables)​

  • InsuranceProduct ↔ CoverageType (ProductCoverage junction table)

📊 DTO Design Examples​

PolicySearchDTO​

dto:
PolicySearchDTO:
meta: dto @searchable @template('SEARCH')
fields:
policyNumber: string @search(like) -- Policy number
insuredName: string @search(like) -- Insured name
policyStatus: string @search(eq) -- Policy status
effectiveDateFrom: date @search(gte) @param('policyEffectiveDate') -- Effective date (from)
effectiveDateTo: date @search(lte) @param('policyEffectiveDate') -- Effective date (to)

ClaimSummaryDTO​

dto:
ClaimSummaryDTO:
meta: dto
fields:
claimNumber: string -- Claim number
policyNumber: string -- Policy number
claimStatus: string -- Claim status
claimedAmount: bigdecimal(15.2) -- Claimed amount
approvedAmount: bigdecimal(15.2) -- Approved amount
incidentDate: date -- Incident date

📚 Repository Design Patterns​

Complex Search Queries​

repository:
InsurancePolicy:
methods:
- id: findPoliciesByStatusAndDateRange
params:
status: string
startDate: date
endDate: date
return: List<InsurancePolicy>
nativeQuery: true
query: |
SELECT p.* FROM INSURANCE_POLICY p
WHERE p.policy_status = :status
AND p.policy_effective_date BETWEEN :startDate AND :endDate
ORDER BY p.policy_effective_date DESC

- id: getClaimStatsByPolicy
params:
policyId: long
return: ClaimStatsDTO
nativeQuery: true
query: |
SELECT
COUNT(*) as claim_count,
SUM(claimed_amount) as total_claimed,
SUM(approved_amount) as total_approved
FROM INSURANCE_CLAIM
WHERE policy_id = :policyId

🎯 Best Practice Guidelines​

1. Data Integrity​

  • Apply @nullable(false) to required fields
  • Ensure referential integrity with the @ref annotation on foreign keys
  • Manage status values with a restricted set of enum-style values

2. Search Optimization​

  • Apply appropriate @search annotations to frequently searched fields
  • Use @search(between) for date range searches
  • Use @search(like) for text searches

3. Audit Tracking​

  • Apply @audited annotation to critical entities
  • Include creation and modification timestamp fields

4. Performance Considerations​

  • Use @pageable for large dataset queries
  • Consider @Index annotation for fields that need indexing
  • Handle computed fields in DTOs

5. Business Logic​

  • Use decimal types for monetary fields to ensure precision
  • Manage status changes through workflow-based processes
  • Date validation logic is essential

These models provide a foundation for building a stable system that can effectively handle various business requirements in the insurance industry.