---
id: ArrearsFullyPaidEventV1
name: Arrears Fully Paid Event
version: 0.0.1
summary: Event emitted when all arrears on a policy have been fully paid
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: green
textColor: white
---
## Overview
The `ArrearsFullyPaidEventV1` event is emitted when all arrears on a policy have been fully paid, resulting in the reset of the failed collection counter and the policy returning to good standing. This event indicates that the policy balance has reached zero or positive after a payment.
### When is this event emitted?
This event is triggered when:
- A payment is received that clears all outstanding arrears on a policy
- The policy balance transitions from negative (in arrears) to zero or positive
- The failed collection counter is reset as a result of the payment
### Why is this event important?
This event enables downstream systems to:
- Update the policy status to reflect good standing
- Reset any internal counters tracking failed collections
- Notify policyholders that their account is back in good standing
- Trigger reinstatement of any services that were limited due to arrears
- Update risk assessments and credit scoring systems
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy that is now fully paid |
| `paymentAmount` | The amount of the payment that cleared the arrears |
| `newBalance` | The new policy balance after the payment (zero or positive) |
| `previousFailedCollectionCounter` | The failed collection counter value before it was reset |
| `paymentReference` | External reference for the payment that cleared the arrears |
> **Note: No Avro Schema**
>
> This event has a Java domain class (`ArrearsFullyPaidEvent`) but no corresponding Avro `.avsc` schema file in the `sft-capstone-policy-avro-events` module. It is an internal domain event not published to Kinesis. Schema fields above are derived from the Java domain class.
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ArrearsFullyPaidEventV1",
"description": "Event emitted when all arrears on a policy have been fully paid.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"paymentAmount",
"newBalance",
"previousFailedCollectionCounter"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"paymentAmount": {
"type": "object",
"description": "The amount of the payment that cleared the arrears",
"properties": {
"amount": {
"type": "number",
"description": "The numeric amount"
},
"currency": {
"type": "string",
"description": "The currency code (e.g., ZAR)"
}
},
"required": ["amount", "currency"]
},
"newBalance": {
"type": "object",
"description": "The new policy balance after the payment",
"properties": {
"amount": {
"type": "number",
"description": "The numeric amount"
},
"currency": {
"type": "string",
"description": "The currency code (e.g., ZAR)"
}
},
"required": ["amount", "currency"]
},
"previousFailedCollectionCounter": {
"type": "integer",
"description": "The failed collection counter value before it was reset"
},
"paymentReference": {
"type": "string",
"description": "External reference for the payment that cleared the arrears"
}
}
}
---
id: BundleIssuanceForNewPolicyEventV2
name: Bundle Issuance For New Policy Event
version: 0.0.1
summary: Event emitted when bundle issuance is initiated for a new policy.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Issuance
backgroundColor: purple
textColor: white
---
## Overview
The `BundleIssuanceForNewPolicyEventV2` event is emitted when a bundle issuance is initiated to create a new insurance policy. This event contains comprehensive information needed to establish the policy including products, beneficiaries, coverage terms, and policyholder details.
## When is this event emitted?
This event is published when:
- An InitiateBundleIssuanceForNewPolicy command is processed
- The command passes validation against the bundle configuration
- Coverage amounts are calculated based on configuration rules
## Key Information
The event payload includes:
- **Bundle Identification**: Bundle ID, partner ID, package ID, bundle name
- **Product Details**: Full list of products with beneficiaries and cover amounts
- **Coverage Terms**: Cover term, chrono unit, and cover per term unit
- **Policyholder Details**: Employment information and bank details
- **Compliance**: Terms acceptance and POPIA consent flags
## Downstream Consumers
Systems that typically consume this event include:
- Policy Service for new policy creation
- Unverified Identity Service for customer data capture
- Data product services for reporting
- Partner notification services
## Raw Schema:schema.avsc
{
"type": "record",
"name": "BundleIssuanceForNewPolicyV2",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro",
"doc": "Event emitted when bundle issuance is initiated for a new policy.",
"fields": [
{
"name": "id",
"type": { "type": "string", "logicalType": "uuid" },
"doc": "Event ID"
},
{
"name": "correlationId",
"type": ["null", { "type": "string", "logicalType": "uuid" }],
"doc": "Correlation ID (nullable)",
"default": null
},
{
"name": "noticedDate",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{
"name": "effectedDate",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{ "name": "detailType", "type": "string" },
{ "name": "logicalClockReading", "type": "int" },
{ "name": "bundleId", "type": "string" },
{
"name": "partnerId",
"type": { "type": "string", "logicalType": "uuid" }
},
{
"name": "packageId",
"type": { "type": "string", "logicalType": "uuid" }
},
{ "name": "bundleName", "type": "string" },
{
"name": "products",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "RedeemedProduct",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro.bundleissuance",
"fields": [
{ "name": "productId", "type": "string" },
{ "name": "productInstanceId", "type": "string" },
{ "name": "productLifeId", "type": "string" },
{
"name": "productLifeExternalId",
"type": ["null", { "type": "string" }],
"default": null
},
{ "name": "productLifeRelationshipToMain", "type": "string" },
{
"name": "dateOfBirth",
"type": ["null", { "type": "int", "logicalType": "date" }],
"default": null,
"doc": "Date of birth of the product life (nullable)"
},
{
"name": "gender",
"type": ["null", "string"],
"default": null,
"doc": "Gender of the product life (nullable)"
},
{
"name": "beneficiaries",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "RedeemedBeneficiary",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro.bundleissuance",
"fields": [
{
"name": "beneficiaryId",
"type": { "type": "string", "logicalType": "uuid" },
"doc": "Internal generated beneficiary UUID (string)"
},
{
"name": "percentageAllocation",
"type": ["null", "long"],
"default": null,
"doc": "Allocation percentage (nullable)"
}
]
}
},
"default": []
},
{
"name": "coverAmount",
"type": ["null", "double"],
"default": null,
"doc": "Cover amount allocated to this product."
},
{
"name": "premium",
"type": ["null", "double"],
"default": null,
"doc": "Premium allocated to this product (nullable)."
},
{
"name": "replacementCoverDetails",
"type": [
"null",
{
"type": "record",
"name": "ReplacementCoverDetail",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro.bundleissuance",
"fields": [
{ "name": "isReplacementPolicy", "type": ["null", "boolean"], "default": null },
{ "name": "previousInsurer", "type": ["null", "string"], "default": null },
{
"name": "willCancelExistingPolicy",
"type": ["null", "boolean"],
"default": null
},
{
"name": "datetimeCommittedToCancel",
"type": [
"null",
{ "type": "long", "logicalType": "timestamp-millis" }
],
"default": null
}
]
}
],
"default": null,
"doc": "Replacement cover details for the main life product (nullable)."
}
]
}
},
"default": []
},
{
"name": "policyStartDate",
"type": { "type": "long", "logicalType": "timestamp-millis" },
"doc": "Start date of the policy associated with this issuance (if supplied)."
},
{
"name": "coverTerm",
"type": ["null", "int"],
"default": null,
"doc": "Cover term magnitude paired with coverTermChronoUnit (nullable)."
},
{
"name": "coverTermChronoUnit",
"type": "string",
"doc": "ChronoUnit that qualifies the cover term."
},
{
"name": "coverPerTermUnit",
"type": [
"null",
{
"type": "record",
"name": "AvroMoneyNewPolicy",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro.bundleissuance",
"fields": [
{
"name": "amount",
"type": "long",
"doc": "Amount in smallest currency unit - cents"
},
{
"name": "currency",
"type": "string"
}
]
}
],
"default": null,
"doc": "Cover amount per term unit (nullable)."
},
{
"name": "policyholderEmployment",
"type": [
"null",
{
"type": "record",
"name": "Employment",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro.bundleissuance",
"fields": [
{ "name": "status", "type": ["null", "string"], "default": null },
{ "name": "industry", "type": ["null", "string"], "default": null }
]
}
],
"default": null,
"doc": "Employment details of the policyholder (nullable)."
},
{
"name": "bankDetails",
"type": [
"null",
{
"type": "record",
"name": "BankDetails",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro.bundleissuance",
"fields": [
{
"name": "bankAccountName",
"type": ["null", "string"],
"default": null
},
{ "name": "bankName", "type": ["null", "string"], "default": null },
{
"name": "bankAccountNumber",
"type": ["null", "string"],
"default": null
},
{ "name": "bankBranch", "type": ["null", "string"], "default": null },
{ "name": "accountType", "type": ["null", "string"], "default": null }
]
}
],
"default": null,
"doc": "Bank details for the policyholder (nullable)."
},
{
"name": "termsAndConditionsAccepted",
"type": ["null", "boolean"],
"default": null,
"doc": "Whether the terms and conditions were accepted (nullable)."
},
{
"name": "popiaConsentGiven",
"type": ["null", "boolean"],
"default": null,
"doc": "Whether the POPIA consent was given (nullable)."
}
]
}
---
id: CaptchaFailedEventV1
name: CAPTCHA Failed Event
version: 0.0.1
summary: Logged when a reCAPTCHA validation fails or returns a low score.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Observability
backgroundColor: green
textColor: white
- content: Security
backgroundColor: red
textColor: white
---
## Overview
The `CaptchaFailedEventV1` is a log event emitted when the BFF Web service fails to validate a reCAPTCHA v3 token. This may indicate bot activity, missing tokens, or configuration issues.
## When is this event emitted?
This event is logged when:
- A request requires CAPTCHA but no token is provided
- The reCAPTCHA token is invalid or expired
- Google's siteverify API returns a score below the threshold
- The CAPTCHA service is misconfigured
## Key Information
The event payload includes:
- **Reason**: The specific failure reason
- **Score**: The risk score if available
- **Advisory Mode**: Whether the request was allowed despite failure
## Failure Reasons
| Reason | Description |
|--------|-------------|
| `missing_token` | No x-recaptcha-token header provided |
| `missing_secret` | Server-side secret not configured |
| `low_score` | Score below configured threshold |
| `verification_failed` | Google API rejected the token |
| `action_mismatch` | Token action doesn't match expected |
| `hostname_mismatch` | Token hostname doesn't match expected |
## Advisory Mode
When `recaptchaAdvisory` is enabled (non-production), failed validations are logged but requests are allowed to proceed. This helps identify issues without blocking legitimate traffic during testing.
## Use Cases
This event is used for:
- Detecting bot attack patterns
- Monitoring CAPTCHA configuration issues
- Identifying misconfigured client applications
- Security incident investigation
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://eventcatalog.digisure.com/schemas/BFFWeb/CaptchaFailedEventV1.json",
"x-parser-schema-format": "application/schema+json;version=draft-2020-12",
"title": "CaptchaFailedEventV1",
"description": "Log event emitted when a reCAPTCHA validation fails.",
"type": "object",
"required": [
"level",
"msg",
"env",
"partner_id",
"request_id",
"method",
"path",
"reason"
],
"properties": {
"level": {
"type": "string",
"enum": ["warn", "error"],
"description": "Log level (warn for advisory mode, error for blocking)"
},
"msg": {
"type": "string",
"enum": ["recaptcha_failed", "recaptcha_failed_advisory"],
"description": "Event message identifier"
},
"env": {
"type": "string",
"description": "Environment name (e.g., sbx, stg, prd)"
},
"partner_id": {
"type": "string",
"description": "Partner identifier for multi-tenant context"
},
"request_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for request correlation"
},
"method": {
"type": "string",
"description": "HTTP method of the request"
},
"path": {
"type": "string",
"description": "URL path of the request"
},
"reason": {
"type": "string",
"enum": [
"missing_token",
"missing_secret",
"low_score",
"verification_failed",
"action_mismatch",
"hostname_mismatch",
"unsupported_provider"
],
"description": "Reason for CAPTCHA validation failure"
},
"score": {
"type": ["number", "null"],
"minimum": 0,
"maximum": 1,
"description": "Risk score if available"
},
"advisory": {
"type": "boolean",
"description": "Whether advisory mode allowed the request to proceed"
}
}
}
---
id: CaptchaValidatedEventV1
name: CAPTCHA Validated Event
version: 0.0.1
summary: Logged when a reCAPTCHA token is successfully validated.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Observability
backgroundColor: green
textColor: white
- content: Security
backgroundColor: red
textColor: white
---
## Overview
The `CaptchaValidatedEventV1` is a log event emitted when the BFF Web service successfully validates a reCAPTCHA v3 token. This indicates the request passed bot detection and is allowed to proceed to the backend.
## When is this event emitted?
This event is logged when:
- A request requires CAPTCHA validation (POST, PUT, PATCH, DELETE methods)
- The x-recaptcha-token header contains a valid token
- Google's siteverify API returns a passing score above the threshold
## Key Information
The event payload includes:
- **Provider**: The CAPTCHA provider used (recaptcha_v3)
- **Score**: The risk score returned by Google (0.0 to 1.0)
- **Request Context**: Environment, partner, request ID
## CAPTCHA Score Interpretation
| Score Range | Interpretation |
|-------------|----------------|
| 0.9 - 1.0 | Very likely a good interaction |
| 0.7 - 0.9 | Likely a good interaction |
| 0.5 - 0.7 | Uncertain, may require additional verification |
| 0.0 - 0.5 | Likely bot or suspicious activity |
## Use Cases
This event is used for:
- Monitoring CAPTCHA validation success rates
- Analyzing score distributions
- Tuning threshold configurations
- Security audit trails
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://eventcatalog.digisure.com/schemas/BFFWeb/CaptchaValidatedEventV1.json",
"x-parser-schema-format": "application/schema+json;version=draft-2020-12",
"title": "CaptchaValidatedEventV1",
"description": "Log event emitted when a reCAPTCHA token is successfully validated.",
"type": "object",
"required": [
"level",
"msg",
"env",
"partner_id",
"request_id",
"method",
"path",
"provider"
],
"properties": {
"level": {
"type": "string",
"const": "info",
"description": "Log level for this event"
},
"msg": {
"type": "string",
"const": "recaptcha_validated",
"description": "Event message identifier"
},
"env": {
"type": "string",
"description": "Environment name (e.g., sbx, stg, prd)"
},
"partner_id": {
"type": "string",
"description": "Partner identifier for multi-tenant context"
},
"request_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for request correlation"
},
"method": {
"type": "string",
"description": "HTTP method of the request"
},
"path": {
"type": "string",
"description": "URL path of the request"
},
"provider": {
"type": "string",
"const": "recaptcha_v3",
"description": "CAPTCHA provider used for validation"
},
"score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Risk score from reCAPTCHA (0.0 = bot, 1.0 = human)"
}
}
}
---
id: ClaimRepudiatedEventV1
name: Claim Repudiated Event
version: 0.0.1
summary: Event emitted when a claim is repudiated (denied).
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The `ClaimRepudiatedEventV1` event is emitted by the ClaimsService when a claim is repudiated (denied). This marks a terminal negative outcome for the claim, recording the reason codes, who repudiated it, and when.
## When is this event emitted?
This event is published when:
- A claims assessor repudiates a claim due to policy exclusions or invalid claim conditions
- An automated rule determines the claim should be repudiated
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, noticed and effected timestamps
- **Claim Identification**: Claim ID
- **Repudiation Details**: Reason codes (array), who repudiated, and when
- **Logical Clock**: Event ordering via logical clock reading
## Downstream Consumers
Systems that typically consume this event include:
- Notification services (to inform claimant of repudiation)
- BFF services (for UI updates)
- Reporting and analytics platforms
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ClaimRepudiatedEventV1",
"description": "Event representing the repudiated status of a claim.",
"type": "object",
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "claimId"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related events"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event was noticed"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event took effect"
},
"detailType": {
"type": "string",
"const": "claimRepudiated",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"claimId": {
"type": "string",
"description": "The ID of the claim that was repudiated"
},
"repudiationReasonCodes": {
"type": ["array", "null"],
"items": { "type": "string" },
"description": "List of reason codes for the repudiation"
},
"repudiatedBy": {
"type": ["string", "null"],
"description": "The user who repudiated the claim"
},
"repudiatedAt": {
"type": ["integer", "null"],
"description": "Timestamp (epoch millis) when the claim was repudiated"
}
}
}
---
id: ClaimSubmittedToCrmEventV1
name: Claim Submitted to CRM Event
version: 0.0.1
summary: Event emitted when a claim is submitted to a CRM system for servicing.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Integration
backgroundColor: orange
textColor: white
---
## Overview
The `ClaimSubmittedToCrmEventV1` event is emitted by the ClaimsService when a claim is submitted to the CRM system for servicing. This event contains the CRM submission details including the document pack link and submission metadata.
## When is this event emitted?
This event is published when:
- The SubmitClaimToCrmCommand is successfully executed
- The claim documents have been packaged and submitted to the CRM
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, noticed and effected timestamps
- **Claim Identification**: Claim ID
- **CRM Submission**: Document pack link, submission timestamp, who submitted
## Downstream Consumers
Systems that typically consume this event include:
- CRM integration systems
- Notification services
- Audit and compliance systems
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ClaimSubmittedToCrmEventV1",
"description": "Event representing when a claim was submitted to a CRM.",
"type": "object",
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "claimId", "crmSubmission"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related events"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event was noticed"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event took effect"
},
"detailType": {
"type": "string",
"const": "claimSubmittedToCrm",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"claimId": {
"type": "string",
"description": "The ID of the claim"
},
"crmSubmission": {
"type": "object",
"description": "CRM submission details",
"required": ["documentPackLink", "submittedAt", "submittedBy"],
"properties": {
"documentPackLink": {
"type": "string",
"description": "Link for the document pack"
},
"submittedAt": {
"type": "integer",
"description": "Timestamp (epoch millis) of submission"
},
"submittedBy": {
"type": "string",
"description": "Who submitted the claim to the CRM"
}
}
}
}
}
---
id: ClaimUpdatedEventV1
name: Claim Updated Event
version: 0.0.1
summary: Event emitted when a claim is updated (main life, covered life, or banking details change).
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The `ClaimUpdatedEventV1` event is emitted by the ClaimsService when a claim's state is modified. This is a general-purpose update event that covers multiple scenarios, differentiated by the `detailType` field.
## When is this event emitted?
This event is published when:
- A claim is updated for a main life deceased scenario (`claimUpdatedMainLife`)
- A claim is updated for a covered life deceased scenario (`claimUpdatedCoveredLife`)
- Banking details are updated on a claim (`claimUpdatedBankDetails`)
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, noticed and effected timestamps
- **Claim Identification**: Claim ID
- **Detail Type**: Discriminator indicating which type of update occurred (claimUpdatedMainLife, claimUpdatedCoveredLife, claimUpdatedBankDetails)
- **Logical Clock**: Event ordering via logical clock reading
## Downstream Consumers
Systems that typically consume this event include:
- BFF services (for real-time UI updates)
- Reporting and analytics platforms
- CRM integration services
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ClaimUpdatedEventV1",
"description": "Event representing the update of a claim.",
"type": "object",
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "claimId"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related events"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event was noticed"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event took effect"
},
"detailType": {
"type": "string",
"enum": ["claimUpdatedMainLife", "claimUpdatedCoveredLife", "claimUpdatedBankDetails"],
"description": "Type of the update event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"claimId": {
"type": "string",
"description": "The ID of the claim that was updated"
}
}
}
---
id: CollectionCreationFailedEventV4
name: Collection Creation Failed Event
version: 0.0.1
summary: Event emitted when a collection creation request fails in the collections gateway.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: green
textColor: white
- content: Failure
backgroundColor: red
textColor: white
---
## Overview
The `CollectionCreationFailedEventV4` event indicates a collection request could not be
created. It includes failure details used by policy services to handle collection
setup failures.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CollectionCreationFailedEventV4",
"title": "CollectionCreationFailedEventV4",
"description": "Event emitted when a collection creation request fails (derived from collections CG Avro schema).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.multi.pay.collections.cg.events.collectioncreationevent.v4.avro",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"orderReferenceId",
"merchantId",
"collectionId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation identifier linking to the originating command"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"orderReferenceId": {
"type": "string",
"description": "Order reference identifier associated with the collection"
},
"merchantId": {
"type": "string",
"description": "Merchant to which this collection pertains"
},
"collectionId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the collection"
},
"errorCode": {
"type": "string",
"description": "Error code associated with the failure"
},
"errorMessage": {
"type": "string",
"description": "Error message associated with the failure"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
}
}
}
---
id: CollectionCreationSucceededEventV4
name: Collection Creation Succeeded Event
version: 0.0.1
summary: Event emitted when a collection is created successfully by the collections gateway.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: green
textColor: white
- content: Success
backgroundColor: teal
textColor: white
---
## Overview
The `CollectionCreationSucceededEventV4` event indicates that a collection request was
accepted and a collection record was created successfully. Policy services use this
signal to confirm schedule creation and proceed with collection tracking.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CollectionCreationSucceededEventV4",
"title": "CollectionCreationSucceededEventV4",
"description": "Event emitted when a collection is created successfully (derived from collections CG Avro schema).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.multi.pay.collections.cg.events.collectioncreationevent.v4.avro",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"orderReferenceId",
"merchantId",
"collectionId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation identifier linking to the originating command"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"orderReferenceId": {
"type": "string",
"description": "Order reference identifier associated with the collection"
},
"merchantId": {
"type": "string",
"description": "Merchant to which this collection pertains"
},
"collectionId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the collection"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
}
}
}
---
id: CollectionFailedEventV5
name: Collection Failed Event
version: 0.0.1
summary: Event emitted when a premium collection fails.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Collection
backgroundColor: green
textColor: white
- content: Failure
backgroundColor: red
textColor: white
---
## Overview
The `CollectionFailedEventV5` event indicates a collection transaction failed. Policy
services use this event to update collection status and handle retry or lapse logic.
## Raw Schema:schema.avsc
{
"sft-metadata": {
"version": 1,
"owner-application": "sft-multi-pay-collections-cg",
"aws-glue-schema-registry-name-pattern": "${StackName}-event-stream-registry",
"aws-glue-schema-registry-read-only-role-arn-pattern": "arn:aws:iam::${AwsAccountId}:role/${StackName}-glue-schema-role",
"default-env-variables": {
"sbx": {
"StackName": "sft-multi-pay-collections-cg",
"AwsAccountId": "381491845955"
},
"dev": {
"StackName": "sft-multi-pay-collections-cg",
"AwsAccountId": "017820704877"
},
"ppe": {
"StackName": "sft-multi-pay-collections-cg",
"AwsAccountId": "017820704723"
},
"prd": {
"StackName": "sft-multi-pay-collections-cg",
"AwsAccountId": "017820704959"
}
}
},
"namespace": "sft.multi.pay.collections.cg.events.collectionfailedevent.v5.avro",
"type": "record",
"name": "CollectionFailedEventV5",
"fields": [
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "detailType",
"type": "string"
},
{
"name": "noticedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "effectedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "submissionDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "logicalClockReading",
"type": [
"null",
"int"
],
"default": null
},
{
"name": "correlationId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "The correlation identifier for tracing"
},
{
"name": "merchantId",
"type": "string",
"doc": "The merchant to which this transaction pertains"
},
{
"name": "orderReferenceId",
"type": "string",
"doc": "The order reference identifier associated with the collection, this can be a policy code, contract number, etc."
},
{
"name": "collectionId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "The unique identifier for the collection"
},
{
"name": "transactionDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "transactionAmount",
"type": {
"type": "record",
"name": "AvroMoney",
"fields": [
{
"name": "amount",
"type": "long",
"doc": "Amount in smallest currency unit - cents"
},
{
"name": "currency",
"type": "string"
}
]
}
},
{
"name": "transactionExternalReason",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "metadata",
"type": [
"null",
{
"type": "record",
"name": "AvroMetadata",
"fields": [
{
"name": "externalId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "originCode",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "submittedAt",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
],
"default": null
},
{
"name": "nextActionAt",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
],
"default": null
},
{
"name": "group",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "subgroup",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "entityId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "entityName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "categoryId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "categoryName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "itemId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "itemName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "value",
"type": [
"null",
"AvroMoney"
],
"default": null
},
{
"name": "items",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroItemDetails",
"fields": [
{
"name": "itemId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "itemName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "itemAmount",
"type": [
"null",
"AvroMoney"
],
"default": null
}
]
}
}
],
"default": null
},
{
"name": "additionalData",
"type": [
"null",
{
"type": "map",
"values": "string"
}
],
"default": null
}
]
}
],
"default": null
}
]
}
---
id: CollectionSucceededEventV5
name: Collection Succeeded Event
version: 0.0.1
summary: Event emitted when a premium collection succeeds.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Collection
backgroundColor: green
textColor: white
- content: Success
backgroundColor: teal
textColor: white
---
## Overview
The `CollectionSucceededEventV5` event indicates a collection transaction completed
successfully. Policy services use this event to update financial state and billing
status.
## Raw Schema:schema.avsc
{
"sft-metadata": {
"version": 1,
"owner-application": "sft-multi-pay-collections-cg",
"aws-glue-schema-registry-name-pattern": "${StackName}-event-stream-registry",
"aws-glue-schema-registry-read-only-role-arn-pattern": "arn:aws:iam::${AwsAccountId}:role/${StackName}-glue-schema-role",
"default-env-variables": {
"sbx": {
"StackName": "sft-multi-pay-collections-cg",
"AwsAccountId": "381491845955"
},
"dev": {
"StackName": "sft-multi-pay-collections-cg",
"AwsAccountId": "017820704877"
},
"ppe": {
"StackName": "sft-multi-pay-collections-cg",
"AwsAccountId": "017820704723"
},
"prd": {
"StackName": "sft-multi-pay-collections-cg",
"AwsAccountId": "017820704959"
}
}
},
"namespace": "sft.multi.pay.collections.cg.events.collectionsucceededevent.v5.avro",
"type": "record",
"name": "CollectionSucceededEventV5",
"fields": [
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "detailType",
"type": "string"
},
{
"name": "noticedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "effectedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "submissionDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "logicalClockReading",
"type": [
"null",
"int"
],
"default": null
},
{
"name": "correlationId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "merchantId",
"type": "string",
"doc": "The merchant to which this transaction pertains"
},
{
"name": "orderReferenceId",
"type": "string",
"doc": "The order reference identifier associated with the collection, this can be a policy code, contract number, etc."
},
{
"name": "collectionId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "The unique identifier for the collection"
},
{
"name": "transactionDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "transactionAmount",
"type": {
"type": "record",
"name": "AvroMoney",
"fields": [
{
"name": "amount",
"type": "long",
"doc": "Amount in smallest currency unit - cents"
},
{
"name": "currency",
"type": "string"
}
]
}
},
{
"name": "transactionExternalReason",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "metadata",
"type": [
"null",
{
"type": "record",
"name": "AvroMetadata",
"fields": [
{
"name": "externalId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "originCode",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "submittedAt",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
],
"default": null
},
{
"name": "nextActionAt",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
],
"default": null
},
{
"name": "group",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "subgroup",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "entityId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "entityName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "categoryId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "categoryName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "itemId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "itemName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "value",
"type": [
"null",
"AvroMoney"
],
"default": null
},
{
"name": "items",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroItemDetails",
"fields": [
{
"name": "itemId",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "itemName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "itemAmount",
"type": [
"null",
"AvroMoney"
],
"default": null
}
]
}
}
],
"default": null
},
{
"name": "additionalData",
"type": [
"null",
{
"type": "map",
"values": "string"
}
],
"default": null
}
]
}
],
"default": null
}
]
}
---
id: CorsPreflightHandledEventV1
name: CORS Preflight Handled Event
version: 0.0.1
summary: Logged when a CORS preflight (OPTIONS) request is handled.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Observability
backgroundColor: green
textColor: white
- content: CORS
backgroundColor: blue
textColor: white
---
## Overview
The `CorsPreflightHandledEventV1` is a log event emitted when the BFF Web service handles a CORS preflight request. Browsers send these OPTIONS requests before making cross-origin requests to verify the server allows the intended request.
## When is this event emitted?
This event is logged when:
- An OPTIONS request is received from a browser
- The request includes Access-Control-Request-Method header
- The service responds with CORS headers allowing or denying the request
## Key Information
The event payload includes:
- **Origin**: The requesting origin attempting cross-origin access
- **Allowed Status**: Whether the origin is in the allowed list
- **Dev Passthrough**: Whether development mode allowed an unlisted origin
## Use Cases
This event is used for:
- Monitoring CORS configuration effectiveness
- Identifying misconfigured client applications
- Debugging cross-origin access issues
- Security auditing of origin access patterns
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://eventcatalog.digisure.com/schemas/BFFWeb/CorsPreflightHandledEventV1.json",
"x-parser-schema-format": "application/schema+json;version=draft-2020-12",
"title": "CorsPreflightHandledEventV1",
"description": "Log event emitted when a CORS preflight request is handled.",
"type": "object",
"required": [
"level",
"msg",
"env",
"partner_id",
"request_id",
"method",
"path",
"origin",
"allowed"
],
"properties": {
"level": {
"type": "string",
"const": "info",
"description": "Log level for this event"
},
"msg": {
"type": "string",
"const": "cors_preflight",
"description": "Event message identifier"
},
"env": {
"type": "string",
"description": "Environment name (e.g., sbx, stg, prd)"
},
"partner_id": {
"type": "string",
"description": "Partner identifier for multi-tenant context"
},
"request_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for request correlation"
},
"method": {
"type": "string",
"const": "OPTIONS",
"description": "HTTP method (always OPTIONS for preflight)"
},
"path": {
"type": "string",
"description": "URL path of the request"
},
"origin": {
"type": "string",
"description": "Origin header from the preflight request"
},
"allowed": {
"type": "boolean",
"description": "Whether the origin is in the allowed origins list"
},
"dev_passthru": {
"type": "boolean",
"description": "Whether dev extension passthrough mode is enabled"
}
}
}
---
id: CrmOutcomeCapturedEventV1
name: CRM Outcome Captured Event
version: 0.0.1
summary: Event emitted when CRM servicing outcomes are captured for a claim.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Integration
backgroundColor: orange
textColor: white
---
## Overview
The `CrmOutcomeCapturedEventV1` event is emitted by the ClaimsService when the CRM servicing outcomes are captured for a claim. This includes verification results from various checks performed by the CRM system.
## When is this event emitted?
This event is published when:
- The CaptureCrmOutcomeCommand is successfully executed
- CRM servicing results are recorded against a claim
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, noticed and effected timestamps
- **Claim Identification**: Claim ID
- **CRM Outcome**: Case number, document verification status, VOPD outcomes (deceased and claimant), PDD outcome, Xtend outcome, employment verification, extended outcome, capture metadata
## Downstream Consumers
Systems that typically consume this event include:
- Payout decision services
- Repudiation evaluation services
- Audit and compliance systems
- Reporting and analytics platforms
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CrmOutcomeCapturedEventV1",
"description": "Event representing when CRM servicing outcomes were captured for a claim.",
"type": "object",
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "claimId", "crmOutcome"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related events"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event was noticed"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event took effect"
},
"detailType": {
"type": "string",
"const": "crmOutcomeCaptured",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"claimId": {
"type": "string",
"description": "The ID of the claim"
},
"crmOutcome": {
"type": "object",
"description": "CRM servicing outcome details",
"required": ["crmCaseNumber"],
"properties": {
"crmCaseNumber": {
"type": "string",
"description": "CRM case number"
},
"documentsVerified": {
"type": ["boolean", "null"],
"description": "Whether documents were verified"
},
"deceasedVopdOutcome": {
"type": ["string", "null"],
"description": "Deceased VOPD verification outcome"
},
"claimantVopdOutcome": {
"type": ["string", "null"],
"description": "Claimant VOPD verification outcome"
},
"pddOutcome": {
"type": ["string", "null"],
"description": "PDD verification outcome"
},
"xtendOutcome": {
"type": ["string", "null"],
"description": "Xtend verification outcome"
},
"deceasedEmploymentVerified": {
"type": ["boolean", "null"],
"description": "Whether deceased employment was verified"
},
"extendedOutcome": {
"type": ["string", "null"],
"description": "Extended verification outcome"
},
"capturedAt": {
"type": ["integer", "null"],
"description": "Timestamp (epoch millis) when outcome was captured"
},
"capturedBy": {
"type": ["string", "null"],
"description": "Who captured the outcome"
}
}
}
}
}
---
id: DeathDetailsCapturedEventV1
name: Death Details Captured Event
version: 0.0.1
summary: Event emitted when death details are captured for a claim.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The `DeathDetailsCapturedEventV1` event is emitted by the ClaimsService when the death details (date and cause of death) are captured for a claim. This is a key step in the claims process before payout calculation.
## When is this event emitted?
This event is published when:
- The CaptureDeathDetailsCommand is successfully executed
- Death certificate information is recorded against a claim
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, noticed and effected timestamps
- **Claim Identification**: Claim ID
- **Death Details**: Date of death and cause of death
## Downstream Consumers
Systems that typically consume this event include:
- Payout calculation services
- CRM integration systems
- Reporting and analytics platforms
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "DeathDetailsCapturedEventV1",
"description": "Event for when death details of a claim were captured.",
"type": "object",
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "claimId", "deathDetails"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related events"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event was noticed"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event took effect"
},
"detailType": {
"type": "string",
"const": "claimDeathDetailsCaptured",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"claimId": {
"type": "string",
"description": "The ID of the claim"
},
"deathDetails": {
"type": "object",
"description": "Death details captured for the claim",
"required": ["dateOfDeath", "causeOfDeath"],
"properties": {
"dateOfDeath": {
"type": "integer",
"description": "Timestamp (epoch millis) of the date of death"
},
"causeOfDeath": {
"type": "string",
"description": "The cause of death"
}
}
}
}
}
---
id: DocumentExtractionCompletedEventV1
name: Document Extraction Completed Event
version: 0.0.1
summary: |
Published when document extraction completes successfully.
Contains extracted data, confidence scores, and processing metadata.
---
## Overview
The **Document Extraction Completed Event** is published when a document extraction command finishes successfully. It contains the extracted structured data, confidence metrics, and contextual information for downstream processing.
## Event Structure
```json
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"commandId": "550e8400-e29b-41d4-a716-446655440000",
"createdDate": "2025-03-11T10:35:22Z",
"createdBy": "DocumentExtractionCGService",
"originationType": "POLICY",
"originationId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"documentType": "DEATH_CERTIFICATE",
"fileType": "PDF",
"provider": "AWS_TEXTRACT",
"correlationId": "a1b2c3d4-e5f6-47a8-9b1c-2d3e4f5a6b7c",
"extractedFields": {
"full_name": "John Doe",
"date_of_birth": "1950-05-15",
"date_of_death": "2025-03-10",
"id_number": "1950051500123"
},
"confidenceScores": {
"full_name": 0.95,
"date_of_birth": 0.87,
"date_of_death": 0.92,
"id_number": 0.89
},
"rawText": "...",
"processingDuration": 317,
"metadata": {
"pageCount": 2,
"detectedLanguage": "en"
}
}
```
## Event Details
### Standard Fields
- **id**: Unique event identifier
- **commandId**: Reference to the original ExtractDocumentCommand
- **createdDate**: Event publication timestamp
- **createdBy**: Service identifier
- **correlationId**: Trace ID for request tracking
### Extraction Metadata
- **originationType**: Business context (POLICY, QUOTE, CLAIMS)
- **originationId**: ID of the related business entity
- **documentType**: Classified document type (DEATH_CERTIFICATE, BIRTH_CERTIFICATE, etc.)
- **fileType**: Original file format (PDF, JPEG, PNG, etc.)
- **provider**: Extraction provider used (AWS_TEXTRACT, BI_FORM, etc.)
### Extraction Results
- **extractedFields**: Key-value pairs of extracted data
- **confidenceScores**: Confidence level (0.0-1.0) for each field
- **rawText**: Full OCR text output from provider
- **bounding_boxes**: Position information (optional)
### Processing Metrics
- **processingDuration**: Elapsed milliseconds from command start to completion
- **metadata**: Additional processing context
- pageCount: Number of pages analyzed
- detectedLanguage: Language detected in document
- modelVersion: Extraction model/version used
## Downstream Consumers
### Policy Service
Receives extracted policy document data:
- Policyholder information
- Policy details
- Premium information
### Quote Service
Receives extracted supporting documents:
- Income verification documents
- Identification documents
- Medical records
### Claims Service
Receives claim evidence extraction:
- Medical reports
- Receipts
- Supporting documentation
## Integration Patterns
### Event Publishing
```
DocumentExtractionCGService -> EventBridge -> Kinesis Stream (future)
```
Current flow publishes via EventBridge rules to downstream subscribers.
### Event Consumption
Downstream services subscribe via:
1. **EventBridge Rules**: Filter by originationType and documentType
2. **SQS Queues**: Receive routed events from EventBridge
3. **Lambda Handlers**: Process extracted data and update domain models
## Field Mapping
### Death Certificate Extraction
| Extracted Field | Domain Field | Notes |
|-----------------|--------------|-------|
| full_name | Deceased Name | |
| date_of_birth | DOB | |
| date_of_death | Death Date | Primary extraction target |
| id_number | ID/Passport | |
### Birth Certificate Extraction
| Extracted Field | Domain Field | Notes |
|-----------------|--------------|-------|
| full_name | Child Name | |
| date_of_birth | DOB | Primary extraction target |
| mother_name | Mother Name | |
| father_name | Father Name | |
### BI Form Extraction
| Extracted Field | Domain Field | Notes |
|-----------------|--------------|-------|
| gross_income | Annual Income | Key field |
| employment_status | Employment | |
| tax_reference_number | TRN | |
| monthly_rent | Rental Cost | |
## Confidence Handling
Extracted fields include confidence scores (0.0-1.0):
- **0.90-1.0**: High confidence - use directly
- **0.75-0.89**: Medium confidence - may require review
- **< 0.75**: Low confidence - recommend manual verification
Downstream services implement confidence thresholds:
```json
{
"confidenceThreshold": 0.85,
"action": "if_below_threshold = manual_review"
}
```
## Failure Scenarios
If extraction fails, `DocumentExtractionFailedEventV1` is published instead.
## Event Retention
- **Event Store**: 30 days in Kinesis
- **Archive**: 1 year in S3 (compliance)
- **Audit Log**: Indefinite (locked storage)
## Idempotency
Events are idempotent using commandId:
- Duplicate events with same commandId contain identical extraction results
- Downstream services deduplicate using commandId
---
id: DocumentExtractionFailedEventV1
name: Document Extraction Failed Event
version: 0.0.1
summary: |
Published when document extraction fails after all retry attempts.
Contains error details and recommendations for resolution.
---
## Overview
The **Document Extraction Failed Event** is published when a document extraction command fails to complete successfully after exhausting configured retry attempts. It signals failure and provides diagnostic information for debugging and manual intervention.
## Event Structure
```json
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"commandId": "550e8400-e29b-41d4-a716-446655440000",
"createdDate": "2025-03-11T10:50:15Z",
"createdBy": "DocumentExtractionCGService",
"originationType": "POLICY",
"originationId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"documentType": "DEATH_CERTIFICATE",
"fileType": "PDF",
"provider": "AWS_TEXTRACT",
"correlationId": "a1b2c3d4-e5f6-47a8-9b1c-2d3e4f5a6b7c",
"errorCode": "EXTRACTION_TIMEOUT",
"errorMessage": "Document extraction exceeded configured timeout threshold",
"errorDetails": {
"retrievalTimestamp": "2025-03-11T10:45:00Z",
"timeoutDuration": 300,
"lastRetryAttempt": 5,
"maxRetryAttempts": 5
},
"suggestedAction": "MANUAL_REVIEW",
"dlqLocation": "arn:aws:sqs:us-east-1:123456789:sft-capstone-document-extraction-prd-dlq",
"metadata": {
"fileSize": 2097152,
"pageCount": 15
}
}
```
## Event Details
### Standard Fields
- **id**: Unique event identifier
- **commandId**: Reference to the original ExtractDocumentCommand
- **createdDate**: Event publication timestamp
- **createdBy**: Service identifier
- **correlationId**: Trace ID for request tracking
### Failure Information
- **errorCode**: Machine-readable error classification
- **errorMessage**: Human-readable error description
- **errorDetails**: Structured error context with retry information
- **suggestedAction**: Recommended next action (MANUAL_REVIEW, RETRY_LATER, CONTACT_SUPPORT)
### DLQ Location
- **dlqLocation**: ARN of Dead-Letter Queue containing the failed command
- Enables manual retrieval and reprocessing of failed messages
## Error Codes
| Code | Category | Cause | Action |
|------|----------|-------|--------|
| INVALID_DOCUMENT | Validation | Document not processable | MANUAL_REVIEW |
| EXTRACTION_TIMEOUT | Timeout | Processing exceeded threshold | RETRY_LATER |
| EXTRACTION_FAILED | Provider Error | Provider returned error | CONTACT_SUPPORT |
| INVALID_FILE_TYPE | Validation | Unsupported file type | MANUAL_REVIEW |
| CORRUPTED_FILE | Integrity | File cannot be read | CONTACT_SUPPORT |
| PROVIDER_ERROR | Provider | External service error | RETRY_LATER |
| RATE_LIMITED | Throttle | Provider rate limit hit | RETRY_LATER |
| MEMORY_ERROR | System | Processing memory limit | CONTACT_SUPPORT |
| NETWORK_ERROR | Connectivity | Network failure | RETRY_LATER |
| UNKNOWN_ERROR | Other | Unexpected error | CONTACT_SUPPORT |
## Suggested Actions
### MANUAL_REVIEW
Trigger manual document review workflow:
- Human review of document quality
- Potential alternative extraction method
- Manual data entry if needed
- Document quarantine for analysis
### RETRY_LATER
Automatic retry with exponential backoff:
- Initial delay: 1 minute
- Max delay: 1 hour
- Max attempts: Configurable (default: 3)
### CONTACT_SUPPORT
Escalate to operations team:
- Create support ticket
- Notify relevant stakeholders
- Block workflow pending resolution
## Downstream Consumers
### Policy Service
Receives extraction failure notifications:
- Mark document processing as pending
- Trigger manual review workflows
- Block policy creation if required
### Quote Service
Receives extraction failure for supporting documents:
- Notify applicant of document issues
- Request document resubmission
- Suggest alternative document types
### Claims Service
Receives extraction failure for claim evidence:
- Alert claims processor
- Create manual evidence review task
- Track failure metrics
## Retry Mechanism
### Automatic Retries (within Service)
```
Attempt 1 -> Fail -> Wait 1s
Attempt 2 -> Fail -> Wait 2s
Attempt 3 -> Fail -> Wait 4s
Attempt 4 -> Fail -> Wait 8s
Attempt 5 -> Fail -> Move to DLQ, Publish Event
```
### Manual Reprocessing
Failed command moved to DLQ can be:
1. Investigated by operations team
2. Fixed (e.g., document replaced)
3. Resubmitted to command queue
## Error Investigation
### Debugging Information
Included in event for diagnostics:
- **File Metadata**: Size, page count, format
- **Processing Timeline**: Start time, attempt timestamps
- **Provider Logs**: Error responses from extraction provider
- **System Context**: Memory usage, timeout values
### Log Correlation
Use correlationId to find related logs:
```
Dashboard -> Filter by correlationId
-> View command flow
-> See all extraction attempts
-> Review provider responses
```
## Monitoring and Alerting
### Metrics
- Total extraction failures per hour
- Failure rate by document type
- Failure rate by error code
- Recovery rate (manual reprocessing success)
### Alerts
- Alert if failure rate > 5%
- Alert if specific error code spike detected
- Alert if DLQ depth exceeds threshold
## Handling Strategies
### By Document Type
**Death Certificate Failures**
- Usually corruption or image quality
- Recommend rescanning
- May require manual review
**BI Form Failures**
- Often layout variations
- Try alternate form template
- Fall back to manual extraction
**General Document**
- Try alternative provider
- Check file format conversion
- Manual data entry
### By Error Code
**Timeout Errors**
- Usually large files
- Split document into parts
- Increase timeout threshold
**Validation Errors**
- User action required
- Document replacement
- Format conversion needed
**Provider Errors**
- Retry with backoff
- Contact provider support
- Use fallback provider
## Event Retention
- **Event Store**: 30 days in Kinesis
- **Archive**: 1 year in S3
- **DLQ Messages**: 14 days (configurable)
- **Audit Logs**: Indefinite
## Idempotency
Events are idempotent using commandId:
- Duplicate failures with same commandId indicate same issue
- Downstream services prevent duplicate error handling
---
id: FileDeletedEvent
name: File Deleted Event
version: 0.0.1
summary: Event emitted when a file associated with a quote is deleted.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: File
backgroundColor: green
textColor: white
---
## Overview
The `FileDeletedEvent` is emitted when a file (such as a document or image) that was previously associated with a quote is deleted. This event is consumed by services that need to clean up or track file deletions.
## When is this event emitted?
This event is published when:
- A customer removes an uploaded document
- An outdated document is replaced
- A document is deleted as part of data cleanup
## Key Information
The event payload includes:
- **File Identification**: File ID and event ID
- **Origination**: The type and ID of the entity the file was associated with
- **Timestamps**: When the event was noticed and effected
## Downstream Consumers
Systems that typically consume this event include:
- Document management systems
- Storage cleanup services
- Compliance and audit systems
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "FileDeletedEvent",
"type": "object",
"title": "FileDeletedEvent",
"description": "Event emitted when a file associated with a quote is deleted.",
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking"
},
"eventType": {
"type": "string",
"description": "The type of event"
},
"noticedDate": {
"type": "string",
"format": "date-time",
"description": "When the event was noticed"
},
"effectedDate": {
"type": "string",
"format": "date-time",
"description": "When the event took effect"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for ordering"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the deleted file"
},
"origination": {
"type": "string",
"description": "The type of entity the file was associated with"
},
"originationId": {
"type": "string",
"format": "uuid",
"description": "The ID of the entity the file was associated with"
}
},
"required": ["eventId", "correlationId", "noticedDate", "effectedDate", "fileId", "origination", "originationId"]
}
---
id: FileDeletedEventV1
name: File Deleted Event
version: 0.0.1
summary: Event emitted when a file is deleted from the system.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `FileDeletedEventV1` event is emitted by the FileUploadService when a file is successfully deleted from the system. This event marks the end of the file lifecycle and notifies downstream systems that the file is no longer available.
## When is this event emitted?
This event is published when:
- A delete file command is successfully processed
- The file record is marked as deleted in the system
- Associated storage resources may be cleaned up
## Key Information
The event payload includes:
- **Event Identification**: Event ID, correlation ID, timestamps
- **File Details**: File ID of the deleted file
- **Origination**: Source context (CLAIMS, POLICY, QUOTE) and origination ID
- **Event Ordering**: Logical clock reading for event ordering
## Downstream Consumers
Systems that typically consume this event include:
- Policy service (to update document references)
- Claims service (to update claim evidence records)
- Document indexing services (to remove from search indexes)
- Audit and compliance systems
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "FileDeletedEventV1",
"title": "FileDeletedEventV1",
"description": "Event emitted when a file is deleted. Wire format: Avro (namespace: sft.pas.fileupload.events.filedeleted.avro)",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.fileupload.events.filedeleted.avro",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"fileId",
"origination",
"originationId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking the event across systems"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch, Avro logicalType: timestamp-millis)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch, Avro logicalType: timestamp-millis)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the deleted file"
},
"origination": {
"type": "string",
"enum": ["CLAIMS", "POLICY", "QUOTE"],
"description": "Source or origin of the file (Avro enum: AvroOrigination)"
},
"originationId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the origination entity"
}
}
}
---
id: FileOriginationSetEventV1
name: File Origination Set Event
version: 0.0.1
summary: Event emitted when a file has its origination context set or updated.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `FileOriginationSetEventV1` event is emitted by the FileUploadService when a file's origination context is set or updated. This event enables files to be associated with their business context (Claims, Policy, or Quote) after upload.
## When is this event emitted?
This event is published when:
- A file's origination is set for the first time
- A file's origination context is updated (e.g., a quote document becomes a policy document)
- The SetFileOrigination command is successfully processed
## Key Information
The event payload includes:
- **Event Identification**: Event ID, correlation ID, timestamps
- **File Details**: File ID, file name, and document type
- **Origination**: New source context (CLAIMS, POLICY, QUOTE) and origination ID
- **Event Ordering**: Logical clock reading for event ordering
## Use Cases
- Files uploaded before their business context is known
- Quote documents converted to policy documents
- Reassigning documents between business contexts
## Downstream Consumers
Systems that typically consume this event include:
- Policy service (to link documents to policies)
- Claims service (to link documents to claims)
- Quote service (to link documents to quotes)
- Document routing and classification services
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "FileOriginationSetEventV1",
"title": "FileOriginationSetEventV1",
"description": "Event emitted when a file has its origination set. Wire format: Avro (namespace: sft.pas.fileupload.events.fileoriginationset.avro)",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.fileupload.events.fileoriginationset.avro",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"fileId",
"origination",
"originationId",
"fileName",
"documentType"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking the event across systems"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch, Avro logicalType: timestamp-millis)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch, Avro logicalType: timestamp-millis)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the file"
},
"origination": {
"type": "string",
"enum": ["CLAIMS", "POLICY", "QUOTE"],
"description": "New source or origin context for the file (Avro enum: AvroOrigination)"
},
"originationId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the origination entity"
},
"fileName": {
"type": "string",
"description": "Name of the file"
},
"documentType": {
"type": "string",
"description": "Type of document"
}
}
}
---
id: FileUploadedEvent
name: File Uploaded Event
version: 0.0.1
summary: Event emitted when a file is uploaded and associated with a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: File
backgroundColor: green
textColor: white
---
## Overview
The `FileUploadedEvent` is emitted when a file (such as a document or image) is uploaded and associated with a quote. This event is consumed by services that need to process or store uploaded files.
## When is this event emitted?
This event is published when:
- A customer uploads an identity document
- A supporting document is attached to a quote
- A signed document is uploaded
## Key Information
The event payload includes:
- **File Identification**: File ID and event ID
- **Origination**: The type and ID of the entity the file is associated with
- **File Details**: File name and document type
- **Timestamps**: When the event was noticed and effected
## Downstream Consumers
Systems that typically consume this event include:
- Document management systems
- Verification services
- Compliance and audit systems
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "FileUploadedEvent",
"type": "object",
"title": "FileUploadedEvent",
"description": "Event emitted when a file is uploaded and associated with a quote.",
"properties": {
"eventId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking"
},
"eventType": {
"type": "string",
"description": "The type of event"
},
"noticedDate": {
"type": "string",
"format": "date-time",
"description": "When the event was noticed"
},
"effectedDate": {
"type": "string",
"format": "date-time",
"description": "When the event took effect"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for ordering"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the uploaded file"
},
"origination": {
"type": "string",
"description": "The type of entity the file is associated with"
},
"originationId": {
"type": "string",
"format": "uuid",
"description": "The ID of the entity the file is associated with"
},
"fileName": {
"type": "string",
"description": "The name of the uploaded file"
},
"documentType": {
"type": "string",
"description": "The type of document uploaded"
}
},
"required": ["eventId", "correlationId", "noticedDate", "effectedDate", "fileId", "origination", "originationId"]
}
---
id: FileUploadedEventV1
name: File Uploaded Event
version: 0.0.1
summary: Event emitted when a file is successfully uploaded to the system.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `FileUploadedEventV1` event is emitted by the FileUploadService when a file is successfully uploaded and stored in the system. This event marks the completion of the file upload process and contains information about the uploaded file and its origination context.
## When is this event emitted?
This event is published when:
- A file is uploaded via the direct upload (base64) endpoint
- A file upload is completed via a pre-signed URL (S3 triggers this)
- The file has been validated and stored successfully
## Key Information
The event payload includes:
- **Event Identification**: Event ID, correlation ID, timestamps
- **File Details**: File ID for referencing the uploaded file
- **Origination**: Source context (CLAIMS, POLICY, QUOTE) and origination ID
- **File Metadata**: File name and document type
- **Event Ordering**: Logical clock reading for event ordering
## Downstream Consumers
Systems that typically consume this event include:
- Policy service (for policy document tracking)
- Claims service (for claim evidence processing)
- Quote service (for quote document management)
- Document management and indexing services
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "FileUploadedEventV1",
"title": "FileUploadedEventV1",
"description": "Event emitted when a file is uploaded. Wire format: Avro (namespace: sft.pas.fileupload.events.fileuploaded.avro)",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.fileupload.events.fileuploaded.avro",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"fileId",
"origination",
"originationId",
"fileName",
"documentType"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking the event across systems"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch, Avro logicalType: timestamp-millis)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch, Avro logicalType: timestamp-millis)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the uploaded file"
},
"origination": {
"type": "string",
"enum": ["CLAIMS", "POLICY", "QUOTE"],
"description": "Source or origin of the file upload (Avro enum: AvroOrigination)"
},
"originationId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the origination entity"
},
"fileName": {
"type": "string",
"description": "Name of the uploaded file"
},
"documentType": {
"type": "string",
"description": "Type of document uploaded"
}
}
}
---
id: InventoryItemRedeemedExistingPolicyEventV2
name: Inventory Item Redeemed Existing Policy Event
version: 0.0.1
summary: Event emitted when an inventory item is linked to an existing policy.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Redemption
backgroundColor: green
textColor: white
---
## Overview
The `InventoryItemRedeemedExistingPolicyEventV2` event is emitted when an inventory item is successfully linked to an existing insurance policy. This allows partners to extend coverage on policies that are already active.
## When is this event emitted?
This event is published when:
- A customer redeems an active, non-expired inventory item for an existing policy
- The item is validated against the bundle configuration
- The item is marked as redeemed with the policy code reference
## Key Information
The event payload includes:
- **Item Identification**: Bundle ID, serial number, partner ID, package ID
- **Policy Reference**: The policy code being extended
- **Coverage Information**: Cover term and cover amount per term unit
- **Timestamps**: Original redemption time and update time
## Downstream Consumers
Systems that typically consume this event include:
- Policy Service for coverage extension
- Data product services for reporting
- Partner integration services
## Raw Schema:schema.avsc
{
"type": "record",
"name": "InventoryItemRedeemedExistingPolicyV2",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro",
"doc": "Event emitted when an inventory item is linked to an existing policy.",
"fields": [
{
"name": "id",
"type": { "type": "string", "logicalType": "uuid" },
"doc": "Event ID"
},
{
"name": "correlationId",
"type": ["null", { "type": "string", "logicalType": "uuid" }],
"doc": "Correlation ID (nullable)",
"default": null
},
{
"name": "noticedDate",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{
"name": "effectedDate",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{ "name": "detailType", "type": "string" },
{ "name": "logicalClockReading", "type": "int" },
{ "name": "bundleId", "type": "string" },
{
"name": "partnerId",
"type": { "type": "string", "logicalType": "uuid" }
},
{
"name": "packageId",
"type": { "type": "string", "logicalType": "uuid" }
},
{ "name": "serialNumber", "type": "string" },
{ "name": "policyCode", "type": "string" },
{
"name": "redeemedAt",
"type": ["null", { "type": "long", "logicalType": "timestamp-millis" }],
"default": null,
"doc": "Original redemption timestamp (nullable)."
},
{
"name": "coverTerm",
"type": ["null", "int"],
"default": null,
"doc": "Cover term in months (nullable)."
},
{
"name": "coverPerTermUnit",
"type": [
"null",
{
"type": "record",
"name": "AvroMoneyExistingPolicy",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro",
"fields": [
{
"name": "amount",
"type": "long",
"doc": "Amount in smallest currency unit - cents"
},
{
"name": "currency",
"type": "string"
}
]
}
],
"default": null,
"doc": "Cover amount per term unit (nullable)."
},
{
"name": "updatedAt",
"type": { "type": "long", "logicalType": "timestamp-millis" },
"doc": "Timestamp when the existing policy linkage occurred."
}
]
}
---
id: InventoryItemRedeemedNewPolicyEventV2
name: Inventory Item Redeemed New Policy Event
version: 0.0.1
summary: Event emitted when an inventory item is redeemed to create a new insurance policy.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Redemption
backgroundColor: green
textColor: white
---
## Overview
The `InventoryItemRedeemedNewPolicyEventV2` event is emitted when an inventory item is successfully redeemed to create a new insurance policy. This event contains comprehensive information about the redemption including products, beneficiaries, and coverage details.
## When is this event emitted?
This event is published when:
- A customer redeems an active, non-expired inventory item
- The redemption is validated against the bundle configuration rules
- The item is marked as redeemed in the inventory
## Key Information
The event payload includes:
- **Item Identification**: Bundle ID, serial number, partner ID, package ID
- **Product Details**: List of redeemed products with life IDs and beneficiaries
- **Coverage Information**: Cover term, cover amount per term unit, policy start date
- **Event Metadata**: Correlation ID, timestamps, and logical clock reading
## Downstream Consumers
Systems that typically consume this event include:
- Policy Service for new policy creation
- Data product services for reporting
- Partner integration services
- Customer communication services
## Raw Schema:schema.avsc
{
"type": "record",
"name": "InventoryItemRedeemedNewPolicyV2",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro",
"doc": "Event emitted when a single inventory item is redeemed.",
"fields": [
{
"name": "id",
"type": { "type": "string", "logicalType": "uuid" },
"doc": "Event ID"
},
{
"name": "correlationId",
"type": ["null", { "type": "string", "logicalType": "uuid" }],
"doc": "Correlation ID (nullable)",
"default": null
},
{
"name": "noticedDate",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{
"name": "effectedDate",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{ "name": "detailType", "type": "string" },
{ "name": "logicalClockReading", "type": "int" },
{ "name": "bundleId", "type": "string" },
{
"name": "partnerId",
"type": { "type": "string", "logicalType": "uuid" }
},
{
"name": "packageId",
"type": { "type": "string", "logicalType": "uuid" }
},
{ "name": "serialNumber", "type": "string" },
{
"name": "products",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "RedeemedProduct",
"fields": [
{ "name": "productId", "type": "string" },
{ "name": "productInstanceId", "type": "string" },
{ "name": "productLifeId", "type": "string" },
{ "name": "productLifeExternalId", "type": ["null", {"type": "string"}], "default": null },
{ "name": "productLifeRelationshipToMain", "type": "string" },
{
"name": "dateOfBirth",
"type": ["null", { "type": "int", "logicalType": "date" }],
"default": null,
"doc": "Date of birth of the product life (nullable)"
},
{
"name": "gender",
"type": ["null", "string"],
"default": null,
"doc": "Gender of the product life (nullable)"
},
{
"name": "beneficiaries",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "RedeemedBeneficiary",
"fields": [
{ "name": "beneficiaryId", "type": { "type": "string", "logicalType": "uuid" }, "doc": "Internal generated beneficiary UUID (string)" },
{ "name": "percentageAllocation", "type": ["null", "long"], "default": null, "doc": "Allocation percentage (nullable)" }
]
}
},
"default": []
},
{
"name": "coverAmount",
"type": ["null", "double"],
"default": null,
"doc": "Cover amount allocated to this product."
}
]
}
},
"default": []
},
{
"name": "redeemedAt",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{
"name": "policyStartDate",
"type": { "type": "long", "logicalType": "timestamp-millis" },
"doc": "Start date of the policy associated with this redemption (if supplied)."
},
{
"name": "coverTerm",
"type": ["null", "int"],
"default": null,
"doc": "Cover term magnitude paired with coverTermChronoUnit (nullable)."
},
{
"name": "coverTermChronoUnit",
"type": "string",
"doc": "ChronoUnit that qualifies the cover term."
},
{
"name": "coverPerTermUnit",
"type": [
"null",
{
"type": "record",
"name": "AvroMoneyNewPolicy",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro",
"fields": [
{
"name": "amount",
"type": "long",
"doc": "Amount in smallest currency unit - cents"
},
{
"name": "currency",
"type": "string"
}
]
}
],
"default": null,
"doc": "Cover amount per term unit (nullable)."
}
]
}
---
id: LastFailedCollectionReceivedBeforeCancellationEventV1
name: Last Failed Collection Received Before Cancellation Event
version: 0.0.1
summary: Event emitted when a policy receives its final failed collection before cancellation
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: red
textColor: white
---
## Overview
The `LastFailedCollectionReceivedBeforeCancellationEventV1` event is emitted when a policy receives its final failed collection attempt before it will be cancelled. This event serves as a critical warning that the policy is one more failed collection away from automatic cancellation.
### When is this event emitted?
This event is triggered when:
- A collection attempt fails and the policy reaches its maximum allowed failed collections minus one
- The next failed collection will result in automatic policy cancellation
- The policy is in a critical state requiring immediate attention
### Why is this event important?
This event enables downstream systems to:
- Send urgent notifications to policyholders warning of imminent cancellation
- Trigger escalation workflows for retention efforts
- Update policy status to reflect the critical state
- Initiate proactive outreach from customer service teams
- Log the event for compliance and audit trail purposes
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy that received the last failed collection before cancellation |
> **Note: Java-Only Internal Event (No Avro Schema)**
>
> This event exists as a Java domain class (`LastFailedCollectionReceivedBeforeCancellationEvent`) but has no corresponding Avro `.avsc` schema file in the `sft-capstone-policy-avro-events` module. It is an internal domain event used within the Policy service boundary and is not published to Kinesis. Only `policyId` is carried as event payload alongside the standard base event fields.
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "LastFailedCollectionReceivedBeforeCancellationEventV1",
"description": "Event emitted when a policy receives its final failed collection before cancellation.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
}
}
}
---
id: NoPolicyCollectionReceivedWithinGracePeriodEventV1
name: No Policy Collection Received Within Grace Period
version: 0.0.1
summary: Event emitted when no premium collection has been received within the grace period
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: green
textColor: white
---
## Overview
The `NoPolicyCollectionReceivedWithinGracePeriodEventV1` event is emitted when a policy's premium payment has not been received within the allowed grace period. This event signals a critical point in the collection workflow where the policy may be at risk of lapsing due to non-payment.
This event is part of the collection workflow's monitoring and escalation process, enabling downstream systems to take appropriate action when payment is overdue.
### Collection Workflow Context
The premium collection workflow includes a grace period mechanism to handle failed or missed collections:
1. **Premium Due Date** - The date when the premium payment is expected
2. **Grace Period** - A defined period after the due date during which payment can still be made
3. **Grace Period Expiry** - When the grace period ends without payment, this event is emitted
4. **Policy Status Impact** - Downstream processes may update policy status (e.g., lapse the policy)
This event represents the expiry of the grace period without successful collection. It provides:
- The original premium due date
- The grace period end date
- The amount that was due
### Key Fields
- **premiumDueDate** - The date when the premium was originally due
- **gracePeriodEndDate** - The date when the grace period expired
- **amountDue** - The premium amount that was not collected
- **policyId** - The affected policy identifier
### Typical Downstream Actions
When this event is received, systems may:
- Update the policy status to "lapsed" or "suspended"
- Trigger notifications to the policyholder
- Initiate reinstatement workflows if the policyholder makes a subsequent payment
- Update reporting and analytics systems
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "NoPolicyCollectionReceivedWithinGracePeriodEventV1",
"type": "object",
"description": "Event emitted when no premium collection has been received within the grace period for a policy.",
"definitions": {
"Money": {
"type": "object",
"properties": {
"amount": {
"type": "integer",
"description": "Amount in minor units (e.g. cents)"
},
"currency": {
"type": "string",
"description": "ISO 4217 currency code"
}
},
"required": ["amount", "currency"]
}
},
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Event ID (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "When the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "When the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Event detail type string"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Policy ID (UUID as string)"
},
"premiumDueDate": {
"type": "integer",
"description": "Premium due date (milliseconds since epoch, start of day)"
},
"gracePeriodEndDate": {
"type": "integer",
"description": "Grace period end date (milliseconds since epoch, start of day)"
},
"amountDue": {
"$ref": "#/definitions/Money",
"description": "Amount due for the premium"
}
},
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"premiumDueDate",
"gracePeriodEndDate",
"amountDue"
]
}
---
id: NotificationDispatchedEventV1
name: Notification Dispatched Event
version: 0.0.1
summary: "DEPRECATED: Superseded by NotificationDispatchedEventV2."
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
- content: Deprecated
backgroundColor: red
textColor: white
---
> **Deprecated**: This event has been superseded by `NotificationDispatchedEventV2`. New consumers should use V2.
## Overview
The `NotificationDispatchedEventV1` event is emitted by the NotificationService when a notification has been dispatched to the delivery provider (email via SES or SMS). This event marks the transition of a notification from triggered/scheduled state to dispatched state.
## When is this event emitted?
This event is published when:
- An immediate notification is triggered and sent to the Glue gateway
- A scheduled notification reaches its dispatch time and is sent
- A notification is re-dispatched after a previous failure
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Origin Identification**: Origin ID (policy ID or claim ID) and source type
- **Notification Details**: Notification type, medium (EMAIL/SMS), and status
- **Provider Tracking**: Notification provider correlation ID for delivery tracking
- **Recipient**: Configured recipient type (POLICY_HOLDER or CLAIMANT)
## Downstream Consumers
Systems that typically consume this event include:
- Notification data product (for analytics and auditing)
- Notification state aggregates (to update dispatched notifications list)
- Operational dashboards (for real-time monitoring)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationDispatchedEventV1",
"x-schema-format": "JSON Schema",
"x-avro-schema-version": "NotificationDispatchedEventV2",
"title": "NotificationDispatchedEventV1",
"description": "Event emitted when a notification is dispatched to the delivery provider. Note: Production uses Avro schema NotificationDispatchedEventV2.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"originId",
"notificationSource",
"notificationType",
"notificationMethod",
"notificationStatus"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"notificationProviderCorrelationId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Correlation ID from the notification provider for delivery tracking"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"originId": {
"type": "string",
"format": "uuid",
"description": "The origin identifier - policy ID or claim ID (UUID as string)"
},
"notificationSource": {
"type": "string",
"enum": ["POLICY_FUNERAL", "POLICY_RISK", "QUOTE", "CLAIMS"],
"description": "The source domain that triggered the notification"
},
"notificationType": {
"type": "string",
"description": "The type of notification being dispatched",
"enum": [
"POLICY_CONFIRMATION_WELCOME",
"POLICY_CANCELLED",
"POLICY_EXPIRED",
"POLICY_EXPIRING_SOON",
"POLICY_EXPIRING_TOMORROW",
"POLICY_SEND_SCHEDULE",
"PREMIUM_COLLECTED",
"POLICY_REINSTATEMENT",
"POLICY_PAYMENT_REMINDER",
"CLAIM_REJECTED",
"CLAIM_APPROVED_POLICY_ACTIVE",
"CLAIM_PAYOUT_COMPLETE",
"WAITING_PERIOD_COMPLETE"
]
},
"notificationMethod": {
"type": "string",
"enum": ["EMAIL", "SMS"],
"description": "The delivery channel for the notification"
},
"notificationStatus": {
"type": "string",
"enum": ["DISPATCHED", "SCHEDULED", "PROVIDER_SEND_SUCCESS", "PROVIDER_SEND_FAILED"],
"description": "The current status of the notification"
},
"recipient": {
"type": ["string", "null"],
"enum": ["POLICY_HOLDER", "CLAIMANT", null],
"description": "The configured recipient for this notification"
}
}
}
---
id: NotificationDispatchedEventV2
name: Notification Dispatched Event
version: 0.0.1
summary: Event emitted when a notification is dispatched to the delivery provider.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
- content: V2
backgroundColor: green
textColor: white
---
## Overview
The `NotificationDispatchedEventV2` event is emitted by the NotificationService when a notification has been dispatched to the delivery provider (email via SES or SMS). This event marks the transition of a notification from triggered/scheduled state to dispatched state.
## What Changed from V1
- `correlationId` is now nullable (union with null)
- `noticedDate` and `effectedDate` are nullable timestamp fields
- `detailType` field added with default value `notificationDispatched`
- `recipient` field type changed to nullable string
## When is this event emitted?
This event is published when:
- An immediate notification is triggered and sent to the Glue gateway
- A scheduled notification reaches its dispatch time and is sent
- A notification is re-dispatched after a previous failure
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Origin Identification**: Origin ID (policy ID or claim ID)
- **Notification Details**: Notification type, medium (EMAIL/SMS), and status
- **Provider Tracking**: Notification provider correlation ID for delivery tracking
- **Recipient**: Configured recipient type (POLICY_HOLDER or CLAIMANT)
## Downstream Consumers
Systems that typically consume this event include:
- Notification data product (for analytics and auditing)
- Notification state aggregates (to update dispatched notifications list)
- Operational dashboards (for real-time monitoring)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationDispatchedEventV2",
"x-schema-format": "JSON Schema",
"x-avro-schema-version": "NotificationDispatchedEventV2",
"title": "NotificationDispatchedEventV2",
"description": "Event emitted when a notification is dispatched to the provider gateway.",
"type": "object",
"required": [
"id",
"originId",
"notificationSource",
"notificationType",
"notificationMethod",
"notificationStatus"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"originId": {
"type": "string",
"format": "uuid",
"description": "The origin entity ID (policy ID or claim ID)"
},
"detailType": {
"type": ["string", "null"],
"default": "notificationDispatched",
"description": "Event detail type identifier"
},
"noticedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"notificationSource": {
"type": "string",
"description": "The source of the notification (e.g. POLICY_FUNERAL, CLAIMS)"
},
"notificationType": {
"type": "string",
"description": "The type of notification (e.g. POLICY_CONFIRMATION_WELCOME)"
},
"notificationMethod": {
"type": "string",
"description": "The delivery channel (EMAIL or SMS)"
},
"notificationStatus": {
"type": "string",
"description": "Current status of the notification (e.g. DISPATCHED)"
},
"notificationProviderCorrelationId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Correlation ID from the notification provider for delivery tracking"
},
"recipient": {
"type": ["string", "null"],
"description": "Recipient type (POLICY_HOLDER or CLAIMANT)"
}
}
}
---
id: NotificationScheduleCancelledEventV1
name: Notification Schedule Cancelled Event
version: 0.0.1
summary: "DEPRECATED: Superseded by NotificationScheduledProcessCancelledEventV2."
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
- content: Deprecated
backgroundColor: red
textColor: white
---
> **Deprecated**: This event has been superseded by `NotificationScheduledProcessCancelledEventV2`. New consumers should use V2.
## Overview
The `NotificationScheduleCancelledEventV1` event is emitted by the NotificationService when a previously scheduled notification is cancelled before dispatch. This typically occurs when the conditions that triggered the scheduled notification are no longer valid.
## When is this event emitted?
This event is published when:
- A policy is cancelled before a scheduled notification is dispatched
- A scheduled expiry reminder is cancelled because the policy was renewed
- A payment reminder is cancelled because payment was received
- A beneficiary reminder is cancelled because beneficiaries were added
- Schedule cancellation rules are triggered by subsequent policy events
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Origin Identification**: Origin ID (policy ID) and source type
- **Schedule Reference**: The schedule process ID being cancelled
- **Notification Configuration**: The notification config that was to be sent
## Cancellation Rules
Scheduled notifications are cancelled based on configured rules:
- Policy status changes (cancelled, lapsed, expired)
- Condition satisfaction (beneficiaries added, payment received)
- Manual cancellation requests
- Conflicting notification triggers
## Downstream Consumers
Systems that typically consume this event include:
- Notification scheduler (to remove from queue)
- Notification data product (for audit trail)
- Notification state aggregates (to update scheduled notifications list)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationScheduleCancelledEventV1",
"x-schema-format": "JSON Schema",
"x-avro-schema-version": "NotificationScheduledProcessCancelledEventV2",
"title": "NotificationScheduleCancelledEventV1",
"description": "Event emitted when a scheduled notification is cancelled before dispatch. Note: Production uses Avro schema NotificationScheduledProcessCancelledEventV2.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"originId",
"scheduleProcessId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"originId": {
"type": "string",
"format": "uuid",
"description": "The origin identifier - policy ID (UUID as string)"
},
"notificationSource": {
"type": ["string", "null"],
"enum": ["POLICY_FUNERAL", "POLICY_RISK", "QUOTE", "CLAIMS", null],
"description": "The source domain of the cancelled notification"
},
"scheduleProcessId": {
"type": "string",
"description": "The unique identifier of the scheduled notification process being cancelled"
},
"notificationConfig": {
"$ref": "#/$defs/NotificationConfig",
"description": "The notification configuration that was to be sent"
},
"packageId": {
"type": ["string", "null"],
"format": "uuid",
"description": "The package identifier for the notification"
},
"partnerId": {
"type": ["string", "null"],
"format": "uuid",
"description": "The partner identifier for the notification"
}
},
"$defs": {
"NotificationConfig": {
"type": ["object", "null"],
"properties": {
"notificationType": {
"type": "string",
"description": "The type of notification that was scheduled"
},
"notificationTiming": {
"type": ["string", "null"],
"enum": ["IMMEDIATE", "SCHEDULED", null],
"description": "Whether the notification was immediate or scheduled"
},
"notificationFrequency": {
"type": ["string", "null"],
"enum": ["ONCE", "RECURRING", null],
"description": "Whether the notification was one-time or recurring"
}
}
}
}
}
---
id: NotificationScheduledEventV1
name: Notification Scheduled Event
version: 0.0.1
summary: "DEPRECATED: Superseded by NotificationScheduledEventV2."
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
- content: Deprecated
backgroundColor: red
textColor: white
---
> **Deprecated**: This event has been superseded by `NotificationScheduledEventV2`. New consumers should use V2.
## Overview
The `NotificationScheduledEventV1` event is emitted by the NotificationService when a notification is scheduled for delivery at a future time. This event captures the intent to send a notification at a calculated dispatch time based on policy state and notification configuration.
## When is this event emitted?
This event is published when:
- A policy event triggers a notification configured with scheduled timing
- A notification is scheduled based on policy dates (e.g., expiry reminders)
- A recurring notification schedule is created
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Origin Identification**: Origin ID (policy ID) and source type
- **Notification Details**: Notification type being scheduled
- **Schedule Information**: Target dispatch time and schedule process ID
- **Recipient**: Configured recipient type (POLICY_HOLDER)
## Schedule Process ID
The schedule process ID is a unique identifier for the scheduled notification process. It is used to:
- Track the scheduled notification through its lifecycle
- Cancel the notification if conditions change
- Link scheduled and dispatched events together
## Downstream Consumers
Systems that typically consume this event include:
- Notification scheduler (to queue the notification for future dispatch)
- Notification data product (for tracking scheduled notifications)
- Notification state aggregates (to update scheduled notifications list)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationScheduledEventV1",
"x-schema-format": "JSON Schema",
"x-avro-schema-version": "NotificationScheduledEventV2",
"title": "NotificationScheduledEventV1",
"description": "Event emitted when a notification is scheduled for future delivery. Note: Production uses Avro schema NotificationScheduledEventV2.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"originId",
"notificationSource",
"notificationType",
"scheduledFor",
"scheduleProcessId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"originId": {
"type": "string",
"format": "uuid",
"description": "The origin identifier - policy ID or claim ID (UUID as string)"
},
"notificationSource": {
"type": "string",
"enum": ["POLICY_FUNERAL", "POLICY_RISK", "QUOTE", "CLAIMS"],
"description": "The source domain that triggered the notification"
},
"notificationType": {
"type": "string",
"description": "The type of notification being scheduled",
"enum": [
"POLICY_EXPIRING_SOON",
"POLICY_EXPIRING_IN_ONE_WEEK",
"POLICY_EXPIRING_IN_TWO_WEEKS",
"POLICY_EXPIRING_TOMORROW",
"POLICY_PAYMENT_REMINDER",
"WAITING_PERIOD_COMPLETE",
"POLICY_NO_BENEFICIARIES_ADDED",
"POLICY_OUTSTANDING_BENEFICIARY_INFO"
]
},
"scheduledFor": {
"type": "integer",
"description": "Timestamp when the notification is scheduled for dispatch (milliseconds since epoch)"
},
"scheduleProcessId": {
"type": "string",
"description": "Unique identifier for the scheduled notification process"
},
"recipient": {
"type": ["string", "null"],
"enum": ["POLICY_HOLDER", "CLAIMANT", null],
"description": "The configured recipient for this notification"
}
}
}
---
id: NotificationScheduledEventV2
name: Notification Scheduled Event
version: 0.0.1
summary: Event emitted when a notification is scheduled for future delivery.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
- content: V2
backgroundColor: green
textColor: white
---
## Overview
The `NotificationScheduledEventV2` event is emitted by the NotificationService when a notification is scheduled for delivery at a future time. This event captures the intent to send a notification at a calculated dispatch time based on policy state and notification configuration.
## What Changed from V1
- `correlationId` is now nullable
- `noticedDate` and `effectedDate` are nullable timestamp fields
- `detailType` field added with default value `notificationScheduled`
- `recipient` field is now a required non-null string
## When is this event emitted?
This event is published when:
- A policy event triggers a notification configured with scheduled timing
- A notification is scheduled based on policy dates (e.g., expiry reminders)
- A recurring notification schedule is created
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Origin Identification**: Origin ID (policy ID)
- **Notification Details**: Notification type being scheduled
- **Schedule Information**: Target dispatch time (`scheduledFor`) and schedule process ID
- **Recipient**: Configured recipient type (POLICY_HOLDER)
## Schedule Process ID
The schedule process ID is a unique identifier for the scheduled notification process. It is used to:
- Track the scheduled notification through its lifecycle
- Cancel the notification if conditions change (via NotificationScheduledProcessCancelledEventV2)
- Link scheduled and dispatched events together
## Downstream Consumers
Systems that typically consume this event include:
- Notification scheduler (to queue the notification for future dispatch)
- Notification data product (for tracking scheduled notifications)
- Notification state aggregates (to update scheduled notifications list)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationScheduledEventV2",
"x-schema-format": "JSON Schema",
"x-avro-schema-version": "NotificationScheduledEventV2",
"title": "NotificationScheduledEventV2",
"description": "Event emitted when a notification is scheduled for future delivery.",
"type": "object",
"required": [
"id",
"originId",
"notificationSource",
"notificationType",
"scheduledFor",
"scheduleProcessId",
"recipient"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"originId": {
"type": "string",
"format": "uuid",
"description": "The origin entity ID (policy ID)"
},
"detailType": {
"type": ["string", "null"],
"default": "notificationScheduled",
"description": "Event detail type identifier"
},
"noticedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"notificationSource": {
"type": "string",
"description": "The source of the notification (e.g. POLICY_FUNERAL)"
},
"notificationType": {
"type": "string",
"description": "The type of notification being scheduled (e.g. POLICY_EXPIRING_SOON)"
},
"scheduledFor": {
"type": "integer",
"description": "Timestamp when the notification is scheduled to be dispatched (milliseconds since epoch)"
},
"scheduleProcessId": {
"type": "string",
"description": "Unique identifier for the scheduled notification process, used to track and cancel"
},
"recipient": {
"type": "string",
"description": "Recipient type (POLICY_HOLDER)"
}
}
}
---
id: NotificationScheduledProcessCancelledEventV2
name: Notification Scheduled Process Cancelled Event
version: 0.0.1
summary: Event emitted when a previously scheduled notification process is cancelled and will not be executed.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
- content: V2
backgroundColor: green
textColor: white
---
## Overview
The `NotificationScheduledProcessCancelledEventV2` event is emitted by the NotificationService when a previously scheduled notification is cancelled before dispatch. This is the V2 replacement for `NotificationScheduleCancelledEventV1`, renamed to more accurately reflect that it is the scheduled *process* that is cancelled (not just the schedule entry).
## What Changed from V1 (NotificationScheduleCancelledEventV1)
- Renamed from `NotificationScheduleCancelledEventV1` to `NotificationScheduledProcessCancelledEventV2`
- `correlationId` is now nullable
- `noticedDate` and `effectedDate` are nullable timestamp fields
- `detailType` field added with default value `notificationScheduledProcessCancelled`
- `notificationSource` and `notificationType` fields added for richer context
## When is this event emitted?
This event is published when:
- A policy is cancelled before a scheduled notification is dispatched
- A scheduled expiry reminder is cancelled because the policy was renewed
- A payment reminder is cancelled because payment was received
- A beneficiary reminder is cancelled because beneficiaries were added
- Schedule cancellation rules are triggered by subsequent policy events
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Origin Identification**: Origin ID (policy ID)
- **Schedule Reference**: The `scheduleProcessId` of the process being cancelled
- **Notification Context**: Source and type of the notification that was cancelled
## Cancellation Rules
Scheduled notifications are cancelled based on configured rules:
- Policy status changes (cancelled, lapsed, expired)
- Condition satisfaction (beneficiaries added, payment received)
- Conflicting notification triggers
- Manual cancellation requests
## Downstream Consumers
Systems that typically consume this event include:
- Notification scheduler (to remove from queue)
- Notification data product (for audit trail)
- Notification state aggregates (to update scheduled notifications list)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationScheduledProcessCancelledEventV2",
"x-schema-format": "JSON Schema",
"x-avro-schema-version": "NotificationScheduledProcessCancelledEventV2",
"title": "NotificationScheduledProcessCancelledEventV2",
"description": "Event emitted when a previously scheduled notification process has been cancelled and will not be executed.",
"type": "object",
"required": [
"id",
"originId",
"notificationSource",
"notificationType",
"scheduleProcessId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"originId": {
"type": "string",
"format": "uuid",
"description": "The origin entity ID (policy ID)"
},
"detailType": {
"type": ["string", "null"],
"default": "notificationScheduledProcessCancelled",
"description": "Event detail type identifier"
},
"noticedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"notificationSource": {
"type": "string",
"description": "The source of the notification (e.g. POLICY_FUNERAL)"
},
"notificationType": {
"type": "string",
"description": "The type of notification that was cancelled (e.g. POLICY_EXPIRING_SOON)"
},
"scheduleProcessId": {
"type": "string",
"description": "The schedule process ID of the cancelled notification process"
}
}
}
---
id: NotificationSendFailedEventV2
name: Notification Send Failed Event
version: 0.0.1
summary: Event emitted when a notification send request fails.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
- content: V2
backgroundColor: green
textColor: white
---
## Overview
The `NotificationSendFailedEventV2` event is emitted by the NotificationService (via the Glue gateway callback) when a notification delivery attempt has failed. This event includes details about the failure reason and whether it is a terminal failure (no further retry).
## When is this event emitted?
This event is published when:
- The Glue gateway reports a failed delivery attempt for an email or SMS
- A notification send exceeds maximum retry attempts
- An unrecoverable delivery error is encountered
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Gateway Correlation**: `gcid` — the Glue gateway correlation ID
- **Sender Identity**: The sender identity configured for the notification
- **Destination**: The recipient email address or phone number
- **Medium**: Delivery channel (EMAIL, SMS, or other supported channels)
- **Message**: The message content that failed to send
- **Failure Details**: `failedReason` (optional description) and `terminalFailure` flag
## Failure Semantics
| Field | Type | Description |
|-------|------|-------------|
| `failedReason` | string (nullable) | Human-readable description of why the send failed |
| `terminalFailure` | boolean | `true` if no further retry will be attempted; `false` if the system may retry |
## Message Structure
The `message` object contains:
### Body
| Field | Type | Values | Description |
|-------|------|--------|-------------|
| `format` | enum | `TEXT`, `HTML` | The body content format |
| `source` | enum | `INLINE`, `S3_PRE_SIGNED`, `S3_OBJECT` | Where the body content is sourced from |
| `value` | string | — | The body content or reference URL |
### Attachments
Each attachment in the `attachments` array contains:
| Field | Type | Values | Description |
|-------|------|--------|-------------|
| `format` | enum | `PDF`, `XLSX` | Attachment file format |
| `source` | enum | `S3_PRE_SIGNED`, `S3_OBJECT` | Where the attachment is sourced from |
| `value` | string | — | The attachment content or reference URL |
## Supported Channels (Medium)
`EMAIL`, `SMS`, `FACEBOOK`, `TWITTER`, `WHATSAPP`, `INSTAGRAM`, `LINKEDIN`, `TELEGRAM`
## Downstream Consumers
Systems that typically consume this event include:
- Notification data product (to record PROVIDER_SEND_FAILED status)
- Notification state aggregates (to update failed notification state)
- Alerting systems (for operational monitoring of delivery failures)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationSendFailedEventV2",
"x-schema-format": "JSON Schema",
"x-avro-schema-version": "NotificationSendFailedEventV2",
"title": "NotificationSendFailedEventV2",
"description": "Event emitted when a notification send request fails.",
"type": "object",
"required": [
"id",
"gcid",
"senderIdentity",
"destination",
"medium",
"message",
"terminalFailure"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"detailType": {
"type": ["string", "null"],
"default": "notificationSendFailed",
"description": "Event detail type identifier"
},
"noticedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"gcid": {
"type": "string",
"format": "uuid",
"description": "Glue gateway correlation ID for delivery tracking"
},
"senderIdentity": {
"type": "string",
"description": "The sender identity configured for the notification (e.g. email address or sender ID)"
},
"destination": {
"type": "string",
"description": "The recipient email address or phone number"
},
"medium": {
"type": "string",
"enum": ["EMAIL", "SMS", "FACEBOOK", "TWITTER", "WHATSAPP", "INSTAGRAM", "LINKEDIN", "TELEGRAM"],
"description": "The delivery channel used"
},
"message": {
"type": "object",
"description": "The message content that failed to send",
"required": ["body"],
"properties": {
"subject": {
"type": ["string", "null"],
"description": "Email subject line (null for SMS)"
},
"body": {
"type": "object",
"description": "The message body",
"required": ["format", "source", "value"],
"properties": {
"format": {
"type": "string",
"enum": ["TEXT", "HTML"],
"description": "The body content format"
},
"source": {
"type": "string",
"enum": ["INLINE", "S3_PRE_SIGNED", "S3_OBJECT"],
"description": "Where the body content is sourced from"
},
"value": {
"type": "string",
"description": "The body content or reference URL"
}
}
},
"attachments": {
"type": "array",
"default": [],
"description": "List of attachments",
"items": {
"type": "object",
"required": ["format", "source", "value"],
"properties": {
"format": {
"type": "string",
"enum": ["PDF", "XLSX"],
"description": "Attachment file format"
},
"source": {
"type": "string",
"enum": ["S3_PRE_SIGNED", "S3_OBJECT"],
"description": "Where the attachment is sourced from"
},
"value": {
"type": "string",
"description": "The attachment content or reference URL"
}
}
}
}
}
},
"failedReason": {
"type": ["string", "null"],
"description": "Human-readable description of why the send failed"
},
"terminalFailure": {
"type": "boolean",
"default": false,
"description": "true if no further retry will be attempted; false if the system may retry"
}
}
}
---
id: NotificationSentSucceededEventV2
name: Notification Sent Succeeded Event
version: 0.0.1
summary: Event emitted when a notification send request has completed successfully.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
- content: V2
backgroundColor: green
textColor: white
---
## Overview
The `NotificationSentSucceededEventV2` event is emitted by the NotificationService (via the Glue gateway callback) when a notification has been successfully delivered to the recipient. This event confirms end-to-end delivery success.
## When is this event emitted?
This event is published when:
- The Glue gateway confirms successful delivery of an email via AWS SES
- The Glue gateway confirms successful delivery of an SMS
- A previously queued notification send has been acknowledged as delivered
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Gateway Correlation**: `gcid` — the Glue gateway correlation ID
- **Sender Identity**: The sender identity configured for the notification
- **Destination**: The recipient email address or phone number
- **Medium**: Delivery channel (EMAIL, SMS, or other supported channels)
- **Message**: Full message content including subject, body (with format and source), and attachments
## Message Structure
The `message` object contains:
### Body
| Field | Type | Values | Description |
|-------|------|--------|-------------|
| `format` | enum | `TEXT`, `HTML` | The body content format |
| `source` | enum | `INLINE`, `S3_PRE_SIGNED`, `S3_OBJECT` | Where the body content is sourced from |
| `value` | string | — | The body content or reference URL |
### Attachments
Each attachment in the `attachments` array contains:
| Field | Type | Values | Description |
|-------|------|--------|-------------|
| `format` | enum | `PDF`, `XLSX` | Attachment file format |
| `source` | enum | `S3_PRE_SIGNED`, `S3_OBJECT` | Where the attachment is sourced from |
| `value` | string | — | The attachment content or reference URL |
## Supported Channels (Medium)
`EMAIL`, `SMS`, `FACEBOOK`, `TWITTER`, `WHATSAPP`, `INSTAGRAM`, `LINKEDIN`, `TELEGRAM`
## Downstream Consumers
Systems that typically consume this event include:
- Notification data product (for delivery confirmation analytics)
- Notification state aggregates (to mark notification as PROVIDER_SEND_SUCCESS)
- Operational dashboards (for SLA and delivery tracking)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationSentSucceededEventV2",
"x-schema-format": "JSON Schema",
"x-avro-schema-version": "NotificationSentSucceededEventV2",
"title": "NotificationSentSucceededEventV2",
"description": "Event emitted when a notification send request has completed successfully.",
"type": "object",
"required": [
"id",
"gcid",
"senderIdentity",
"destination",
"medium",
"message"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"detailType": {
"type": ["string", "null"],
"default": "notificationSentSucceeded",
"description": "Event detail type identifier"
},
"noticedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": ["integer", "null"],
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"gcid": {
"type": "string",
"format": "uuid",
"description": "Glue gateway correlation ID for delivery tracking"
},
"senderIdentity": {
"type": "string",
"description": "The sender identity configured for the notification (e.g. email address or sender ID)"
},
"destination": {
"type": "string",
"description": "The recipient email address or phone number"
},
"medium": {
"type": "string",
"enum": ["EMAIL", "SMS", "FACEBOOK", "TWITTER", "WHATSAPP", "INSTAGRAM", "LINKEDIN", "TELEGRAM"],
"description": "The delivery channel used"
},
"message": {
"type": "object",
"description": "The message content",
"required": ["body"],
"properties": {
"subject": {
"type": ["string", "null"],
"description": "Email subject line (null for SMS)"
},
"body": {
"type": "object",
"description": "The message body",
"required": ["format", "source", "value"],
"properties": {
"format": {
"type": "string",
"enum": ["TEXT", "HTML"],
"description": "The body content format"
},
"source": {
"type": "string",
"enum": ["INLINE", "S3_PRE_SIGNED", "S3_OBJECT"],
"description": "Where the body content is sourced from"
},
"value": {
"type": "string",
"description": "The body content or reference URL"
}
}
},
"attachments": {
"type": "array",
"default": [],
"description": "List of attachments",
"items": {
"type": "object",
"required": ["format", "source", "value"],
"properties": {
"format": {
"type": "string",
"enum": ["PDF", "XLSX"],
"description": "Attachment file format"
},
"source": {
"type": "string",
"enum": ["S3_PRE_SIGNED", "S3_OBJECT"],
"description": "Where the attachment is sourced from"
},
"value": {
"type": "string",
"description": "The attachment content or reference URL"
}
}
}
}
}
}
}
}
---
id: NotificationTriggeredEventV1
name: Notification Triggered Event
version: 0.0.1
summary: Event emitted when notification trigger rules are satisfied and a notification is ready for dispatch.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Notification
backgroundColor: orange
textColor: white
---
## Overview
The `NotificationTriggeredEventV1` event is emitted by the NotificationService when a notification's trigger rules are satisfied and the notification is ready for dispatch. This event is an internal domain event that initiates the notification dispatch process.
## When is this event emitted?
This event is published when:
- A policy event triggers an immediate notification and all trigger rules pass
- A scheduled notification reaches its dispatch time and conditions are still valid
- Trigger rules for a notification configuration are satisfied
## Immediate vs Scheduled Triggers
### Immediate Notifications
For immediate notifications, this event is emitted right after the triggering policy/claims event when:
- All trigger rules are satisfied
- The notification config specifies IMMEDIATE timing
### Scheduled Notifications
For scheduled notifications, this event is emitted when:
- The scheduled dispatch time is reached
- The conditions are re-evaluated and still valid
- The notification has not been cancelled
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps
- **Origin Identification**: Policy ID, partner ID, package ID
- **Notification Configuration**: Full notification config including template and timing
- **Sender Identity**: Configured sender for email/SMS
- **State Snapshot**: Policy or claims state at trigger time for template rendering
- **Dispatch Time**: When the notification should be sent (for scheduled)
## Downstream Consumers
This event triggers:
- Notification enrichment with recipient contact details
- Template rendering with policy/claims context
- Dispatch command creation for Glue gateway
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "NotificationTriggeredEventV1",
"x-schema-format": "JSON Schema",
"x-note": "Internal domain event - no Avro schema published",
"title": "NotificationTriggeredEventV1",
"description": "Event emitted when notification trigger rules are satisfied and a notification is ready for dispatch. This is an internal domain event.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"policyId",
"notificationConfig"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier linking related events (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering within the aggregate"
},
"detailType": {
"type": ["string", "null"],
"description": "Detail type for the event (e.g., FuneralPolicyImmediateNotificationTriggered)"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The policy identifier (UUID as string)"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "The partner identifier (UUID as string)"
},
"packageId": {
"type": "string",
"format": "uuid",
"description": "The package identifier (UUID as string)"
},
"notificationConfig": {
"$ref": "#/$defs/NotificationConfig",
"description": "The notification configuration for this trigger"
},
"senderIdentity": {
"$ref": "#/$defs/SenderIdentity",
"description": "The configured sender identity for the notification"
},
"policyState": {
"$ref": "#/$defs/PolicyState",
"description": "Snapshot of policy state at trigger time for template rendering"
},
"dispatchTime": {
"type": ["integer", "null"],
"description": "Target dispatch time for scheduled notifications (milliseconds since epoch)"
}
},
"$defs": {
"NotificationConfig": {
"type": "object",
"required": ["notificationType"],
"properties": {
"notificationType": {
"type": "string",
"description": "The type of notification to send"
},
"notificationTiming": {
"type": ["string", "null"],
"enum": ["IMMEDIATE", "SCHEDULED", null],
"description": "Whether notification is immediate or scheduled"
},
"notificationFrequency": {
"type": ["string", "null"],
"enum": ["ONCE", "RECURRING", null],
"description": "Whether notification is one-time or recurring"
},
"notificationMediums": {
"type": ["array", "null"],
"items": {
"$ref": "#/$defs/NotificationMediumConfig"
},
"description": "Configured delivery channels for the notification"
},
"recipients": {
"type": ["array", "null"],
"items": {
"type": "string",
"enum": ["POLICY_HOLDER", "CLAIMANT"]
},
"description": "Configured recipients for the notification"
}
}
},
"NotificationMediumConfig": {
"type": "object",
"properties": {
"medium": {
"type": "string",
"enum": ["EMAIL", "SMS"],
"description": "The delivery channel"
},
"templateId": {
"type": ["string", "null"],
"description": "Template identifier for this medium"
}
}
},
"SenderIdentity": {
"type": ["object", "null"],
"properties": {
"emailFrom": {
"type": ["string", "null"],
"description": "Email sender address"
},
"emailFromName": {
"type": ["string", "null"],
"description": "Email sender display name"
},
"smsFrom": {
"type": ["string", "null"],
"description": "SMS sender ID"
}
}
},
"PolicyState": {
"type": ["object", "null"],
"description": "Snapshot of policy state for template context",
"properties": {
"policyCode": {
"type": ["string", "null"],
"description": "Human-readable policy code"
},
"policyStatus": {
"type": ["string", "null"],
"enum": ["ACTIVE", "LAPSED", "CANCELLED", "EXPIRED", null],
"description": "Current policy status"
},
"policyStartDate": {
"type": ["integer", "null"],
"description": "Policy start date (milliseconds since epoch)"
},
"policyExpiryDate": {
"type": ["integer", "null"],
"description": "Policy expiry date (milliseconds since epoch)"
},
"policyHolder": {
"$ref": "#/$defs/PolicyHolder",
"description": "Policy holder details"
}
}
},
"PolicyHolder": {
"type": ["object", "null"],
"properties": {
"firstName": {
"type": ["string", "null"],
"description": "Policy holder first name"
},
"surname": {
"type": ["string", "null"],
"description": "Policy holder surname"
},
"email": {
"type": ["string", "null"],
"format": "email",
"description": "Policy holder email address"
},
"mobileNumber": {
"type": ["string", "null"],
"description": "Policy holder mobile number"
}
}
}
}
}
---
id: OrmsDecisionFoundEventV1
name: ORMS Decision Found Event
version: 0.0.1
summary: Event emitted when an ORMS analyst decision is found during polling.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: ORMS
backgroundColor: purple
textColor: white
- content: Decision
backgroundColor: green
textColor: white
---
## Overview
The `OrmsDecisionFoundEventV1` event is emitted by the Verification Service when an ORMS analyst has made a decision on a previously pending case. This event signals that the manual review process is complete and contains the analyst's final decision.
## When is this event emitted?
This event is published when:
- Decision polling finds that an analyst has made a decision
- The ORMS case status changes from pending to resolved
- A compliance analyst approves or rejects a flagged party
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps
- **Original Command**: Reference to the original command that triggered screening
- **Screening Reference**: ORMS screening event ID that was resolved
- **Decision Details**: Analyst decision, description, decision ID, and who made it
- **Resolution Metrics**: Check attempts and time to resolution
- **Risk Assessment**: Final risk indicator and resolved watchlists
- **Party Reference**: The CIS party ID that was screened
## Analyst Decisions
| Decision | Description | Downstream Event |
|----------|-------------|------------------|
| `APPROVED` | Party cleared after review | VerificationSucceededEventV1 |
| `REJECTED` | Party confirmed on watchlist | VerificationHardFailEventV1 |
## What Happens Next
After this event is emitted:
1. Based on the analyst decision:
- `APPROVED` -> `VerificationSucceededEventV1` is emitted
- `REJECTED` -> `VerificationHardFailEventV1` is emitted
2. The verification workflow completes
3. Downstream services can proceed based on final outcome
## Downstream Consumers
Systems that typically consume this event include:
- ORMS Reactor (to emit final verification event)
- Compliance Monitoring (to log analyst decisions)
- Audit Systems (to maintain decision history)
- SLA Monitoring (to track resolution times)
- Policy Service (to receive final verification result)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "OrmsDecisionFoundEventV1",
"title": "OrmsDecisionFoundEventV1",
"description": "Event emitted when an ORMS analyst decision is found during polling. This is a JSON Schema representation of the Avro schema used in production (namespace: sft.pas.verification.cg.events.ormsdecisionfounde.avro).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.verification.cg.events.ormsdecisionfounde.avro",
"x-avro-registry": "sft-capstone-verification-cg-event-stream-registry",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"verificationType",
"requestExternalToken",
"internalId",
"requestTo",
"partyId",
"originalCommandId",
"screeningEventId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation ID to link this event to the originating command"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event (e.g., ORMS_DECISION_FOUND_EVENT)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"x-avro-type": "enum",
"x-avro-enum-name": "AvroVerificationType",
"description": "Type of verification that was resolved"
},
"requestExternalToken": {
"type": "string",
"description": "The id of the external request made to the provider"
},
"internalId": {
"type": "string",
"description": "The id of the command received by the command gateway"
},
"requestTo": {
"type": "string",
"description": "The provider to whom the request was made (ORMS)"
},
"partyId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The CIS identifier for party who was being verified"
},
"originalCommandId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The original command that triggered the screening"
},
"screeningEventId": {
"type": "integer",
"description": "The ORMS screening event ID that was resolved"
},
"decisionId": {
"type": ["null", "integer"],
"x-avro-type": "union",
"description": "The analyst's decision ID from ORMS"
},
"analystDecision": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The analyst's final decision (e.g., APPROVED, REJECTED)"
},
"decisionDescription": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Description of the decision"
},
"decisionUser": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The analyst who made the decision"
},
"decisionCreated": {
"type": ["null", "integer"],
"x-avro-type": "union",
"x-avro-logical-type": "timestamp-millis",
"description": "When the decision was made (milliseconds since epoch)"
},
"relationshipRiskIndicator": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Final risk indicator"
},
"resolvedWatchlists": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Watchlists involved in the case"
},
"checkAttempts": {
"type": ["null", "integer"],
"x-avro-type": "union",
"description": "Number of attempts before resolution"
},
"resolutionTimeMinutes": {
"type": ["null", "integer"],
"x-avro-type": "union",
"description": "Time to resolution in minutes"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"x-avro-type": "map",
"default": {},
"description": "Additional data specific to the verification request"
}
}
}
---
id: OrmsDecisionPendingEventV1
name: ORMS Decision Pending Event
version: 0.0.1
summary: Event emitted when an ORMS verification case requires manual analyst review.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: ORMS
backgroundColor: purple
textColor: white
- content: Pending
backgroundColor: yellow
textColor: black
---
## Overview
The `OrmsDecisionPendingEventV1` event is emitted by the Verification Service when an ORMS sanctions screening returns a STOP status, indicating that the case requires manual analyst review due to potential watchlist matches.
## When is this event emitted?
This event is published when:
- ORMS screening finds potential matches against watchlists
- The case is flagged for due diligence review
- A human analyst needs to verify the match before proceeding
- The screening status indicates "Under Review" or similar
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps
- **Screening Details**: ORMS screening event ID, status, and description
- **Risk Information**: Flagged watchlists and risk indicator
- **Party Reference**: The CIS party ID being screened
## Screening Status Values
| Status | Description |
|--------|-------------|
| `STOP` | Potential match found, review required |
| `UNDER_REVIEW` | Case assigned to analyst |
| `DUE_DILIGENCE_IN_PROGRESS` | Active investigation ongoing |
## What Happens Next
When this event is emitted:
1. The verification remains in a pending state
2. Decision polling is initiated to check for analyst decisions
3. Once an analyst makes a decision, `OrmsDecisionFoundEventV1` is emitted
4. Finally, a `VerificationSucceededEventV1` or `VerificationHardFailEventV1` is emitted
## Downstream Consumers
Systems that typically consume this event include:
- ORMS Decision Poller (to start polling for analyst decisions)
- Policy Service (to mark verification as pending manual review)
- Operations Dashboard (to track pending reviews)
- Compliance Monitoring (to track SLA on review times)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "OrmsDecisionPendingEventV1",
"title": "OrmsDecisionPendingEventV1",
"description": "Event emitted when an ORMS verification case requires manual analyst review. This is a JSON Schema representation of the Avro schema used in production (namespace: sft.pas.verification.cg.events.ormsdecisionpendingevent.avro).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.verification.cg.events.ormsdecisionpendingevent.avro",
"x-avro-registry": "sft-capstone-verification-cg-event-stream-registry",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"verificationType",
"requestExternalToken",
"internalId",
"requestTo",
"partyId",
"screeningEventId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation ID to link this event to the originating command"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event (e.g., ORMS_DECISION_PENDING_EVENT)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"x-avro-type": "enum",
"x-avro-enum-name": "AvroVerificationType",
"description": "Type of verification that requires decision"
},
"requestExternalToken": {
"type": "string",
"description": "The id of the external request made to the provider"
},
"internalId": {
"type": "string",
"description": "The id of the command received by the command gateway"
},
"requestTo": {
"type": "string",
"description": "The provider to whom the request was made (ORMS)"
},
"partyId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The CIS identifier for party who was being verified"
},
"screeningEventId": {
"type": "integer",
"description": "The ORMS screening event ID requiring decision"
},
"screeningStatus": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The status from ORMS screening (e.g., STOP, UNDER_REVIEW)"
},
"screeningDescription": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Description of the screening result"
},
"flaggedWatchlists": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Watchlists that flagged this case"
},
"riskIndicator": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Risk indicator from the screening (e.g., HIGH, MEDIUM, LOW)"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"x-avro-type": "map",
"default": {},
"description": "Additional data specific to the verification request"
}
}
}
---
id: OrmsScreeningCompletedEventV1
name: ORMS Screening Completed Event
version: 0.0.1
summary: Event emitted when ORMS sanctions screening is completed, regardless of outcome.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: ORMS
backgroundColor: purple
textColor: white
- content: Screening
backgroundColor: blue
textColor: white
---
## Overview
The `OrmsScreeningCompletedEventV1` event is emitted by the Verification Service when an ORMS sanctions screening request completes. This event captures the immediate result from ORMS before any analyst review.
## When is this event emitted?
This event is published when:
- ORMS returns an immediate GO decision (no matches found)
- ORMS returns a STOP decision (potential match found)
- ORMS screening completes with any status
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps
- **ORMS Response**: Screening event ID, status, code, and success flag
- **Risk Assessment**: Flagged watchlists and risk indicator
- **Party Reference**: The CIS party ID that was screened
## ORMS Status Codes
| Code | Status | Description |
|------|--------|-------------|
| `GO` | No alert | Party cleared with no watchlist matches |
| `STOP` | Due Diligence in Progress | Potential match requires review |
## Risk Indicators
| Indicator | Description |
|-----------|-------------|
| `HIGH` | High-risk match requiring immediate attention |
| `MEDIUM` | Medium-risk match requiring standard review |
| `LOW` | Low-risk or false positive likely |
## Downstream Flow
```
OrmsScreeningCompletedEventV1
|
+---> If GO: Emit VerificationSucceededEventV1
|
+---> If STOP: Emit OrmsDecisionPendingEventV1
-> Start decision polling
```
## Downstream Consumers
Systems that typically consume this event include:
- ORMS Reactor (to determine next steps)
- Compliance Monitoring (to track screening results)
- Risk Management Systems
- Audit and Reporting platforms
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "OrmsScreeningCompletedEventV1",
"title": "OrmsScreeningCompletedEventV1",
"description": "Event emitted when ORMS screening is completed, regardless of outcome. This is a JSON Schema representation of the Avro schema used in production (namespace: sft.pas.verification.cg.events.ormsscreeningcompletedevent.avro).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.verification.cg.events.ormsscreeningcompletedevent.avro",
"x-avro-registry": "sft-capstone-verification-cg-event-stream-registry",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"verificationType",
"requestExternalToken",
"internalId",
"requestTo",
"partyId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation ID to link this event to the originating command"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event (e.g., ORMS_SCREENING_COMPLETED_EVENT)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"x-avro-type": "enum",
"x-avro-enum-name": "AvroVerificationType",
"description": "Type of verification that was screened"
},
"requestExternalToken": {
"type": "string",
"description": "The id of the external request made to the provider"
},
"internalId": {
"type": "string",
"description": "The id of the command received by the command gateway"
},
"requestTo": {
"type": "string",
"description": "The provider to whom the request was made (ORMS)"
},
"partyId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The CIS identifier for party who was being verified"
},
"ormsScreeningEventId": {
"type": ["null", "integer"],
"x-avro-type": "union",
"description": "The ORMS screening event ID"
},
"ormsStatus": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The ORMS response status (e.g., No alert, Due Diligence in Progress)"
},
"ormsCode": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The ORMS response code (GO, STOP, etc.)"
},
"ormsSuccess": {
"type": ["null", "boolean"],
"x-avro-type": "union",
"description": "Whether the ORMS call was successful"
},
"flaggedWatchlists": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Watchlists that flagged this party (if any)"
},
"riskIndicator": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Risk indicator from screening (e.g., HIGH, MEDIUM, LOW)"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"x-avro-type": "map",
"default": {},
"description": "Additional data specific to the verification request"
}
}
}
---
id: PayoutInitiatedEventV1
name: Payout Initiated Event
version: 0.0.1
summary: Event emitted when a claim payout is initiated.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Financial
backgroundColor: green
textColor: white
---
## Overview
The `PayoutInitiatedEventV1` event is emitted by the ClaimsService when a payout is initiated for an approved claim. This event contains the financial details of the payout including amount, currency, and payment references.
## When is this event emitted?
This event is published when:
- A claim has been approved and the payout process is initiated
- The PayClaimCommand is successfully executed
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, noticed and effected timestamps
- **Claim Identification**: Claim ID
- **Payout Details**: Payout ID, payment reference, payment instruction ID, amount, currency
- **Actor**: Who initiated the payout
## Downstream Consumers
Systems that typically consume this event include:
- Payment processing systems
- Notification services (to inform claimant of payout)
- Financial reconciliation systems
- Reporting and analytics platforms
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PayoutInitiatedEventV1",
"description": "Event representing initiation of a claim payout.",
"type": "object",
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "claimId", "payoutId", "paymentReference", "paymentInstructionId", "amount", "currency", "initiatedBy"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related events"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event was noticed"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp (epoch millis) when the event took effect"
},
"detailType": {
"type": "string",
"const": "payoutInitiated",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"claimId": {
"type": "string",
"description": "The ID of the claim"
},
"payoutId": {
"type": "string",
"format": "uuid",
"description": "The payout identifier"
},
"paymentReference": {
"type": "string",
"description": "External payment reference"
},
"paymentInstructionId": {
"type": "string",
"description": "Reference to the payout payment instruction (no PII)"
},
"amount": {
"type": "string",
"description": "Payout amount as a string"
},
"currency": {
"type": "string",
"description": "Payout currency code"
},
"initiatedBy": {
"type": "string",
"description": "Actor who initiated the payout"
}
}
}
---
id: PDFEncryptedEventV1
name: PDF Encrypted Event
version: 0.0.1
summary: Event emitted when a PDF document has been successfully encrypted with password protection.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Security
backgroundColor: red
textColor: white
- content: Not Yet Implemented
backgroundColor: red
textColor: white
---
## Overview
The `PDFEncryptedEventV1` event is designed to be emitted by the PDF Generator Service when a PDF document has been successfully encrypted with password protection and uploaded to S3. This event provides the location and access information for the encrypted document.
> **⚠️ Implementation Status:** This event is currently **not being published** by the PDF Generator Service handlers. The event is documented here to define the contract, but no Kinesis publishing code exists in the current V1 implementation.
## When is this event emitted?
This event is published when:
- An encryption request is successfully processed
- The source PDF has been retrieved and encrypted
- The encrypted PDF has been uploaded to S3
- A pre-signed URL has been created for document access
## Key Information
The event payload includes:
- **Storage Location**: S3 bucket and key where the encrypted document is stored
- **Access URL**: Pre-signed URL for downloading the encrypted document (valid for 7 days)
- **Resource URI**: S3 URI format for internal service references
## Important Notes
- The password used for encryption is NOT included in the event for security reasons
- The recipient must be provided with the password through a separate secure channel
- The encrypted document requires the password to be opened and viewed
## Downstream Consumers
Systems that typically consume this event include:
- Policy Service (to update document references with encrypted version)
- Notification Service (to send secure document links with password delivery)
- Audit and Compliance Systems
## Response Structure
The event contains the same information returned in the API response:
```json
{
"bucket": "capstone-documents",
"key": "policies/POL-123/schedule-encrypted.pdf",
"link": "https://bucket.s3.amazonaws.com/key?signature=...",
"resourceUri": "s3://capstone-documents/policies/POL-123/schedule-encrypted.pdf"
}
```
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PDFEncryptedEventV1",
"title": "PDFEncryptedEventV1",
"x-schema-format": "json-schema",
"description": "Event emitted when a PDF document has been successfully encrypted with password protection. Based on Python lambda response format.",
"type": "object",
"required": ["bucket", "key", "link", "resourceUri"],
"properties": {
"bucket": {
"type": "string",
"description": "The S3 bucket where the encrypted PDF is stored"
},
"key": {
"type": "string",
"description": "The S3 object key (path) of the encrypted PDF"
},
"link": {
"type": "string",
"format": "uri",
"description": "Pre-signed URL for downloading the encrypted document (expires in 7 days)"
},
"resourceUri": {
"type": "string",
"description": "S3 URI in format s3://bucket/key for internal references"
}
}
}
---
id: PDFGeneratedEventV1
name: PDF Generated Event
version: 0.0.1
summary: Event emitted when a PDF document has been successfully generated and stored in S3.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Document
backgroundColor: purple
textColor: white
- content: Not Yet Implemented
backgroundColor: red
textColor: white
---
## Overview
The `PDFGeneratedEventV1` event is designed to be emitted by the PDF Generator Service when a PDF document has been successfully created from HTML content and uploaded to S3. This event provides the location and access information for the generated document.
> **⚠️ Implementation Status:** This event is currently **not being published** by the PDF Generator Service handlers. The event is documented here to define the contract, but no Kinesis publishing code exists in the current V1 implementation.
## When is this event emitted?
This event is published when:
- A PDF generation request is successfully processed
- The generated PDF has been uploaded to S3
- A pre-signed URL has been created for document access
## Key Information
The event payload includes:
- **Storage Location**: S3 bucket and key where the document is stored
- **Access URL**: Pre-signed URL for downloading the document (valid for 7 days)
- **Resource URI**: S3 URI format for internal service references
## Downstream Consumers
Systems that typically consume this event include:
- Policy Service (to store document references on policies)
- Notification Service (to include download links in communications)
- Document Management Systems
## Response Structure
The event contains the same information returned in the API response:
```json
{
"bucket": "capstone-documents",
"key": "policies/POL-123/schedule.pdf",
"link": "https://bucket.s3.amazonaws.com/key?signature=...",
"resourceUri": "s3://capstone-documents/policies/POL-123/schedule.pdf"
}
```
## Signed URL Expiration
The pre-signed URL included in the event expires after 7 days (604800 seconds). If access is needed after expiration, a new signed URL must be generated using the bucket and key information.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PDFGeneratedEventV1",
"title": "PDFGeneratedEventV1",
"x-schema-format": "json-schema",
"description": "Event emitted when a PDF document has been successfully generated and stored in S3. Based on DocumentGenerationResponseSchema from source TypeScript code.",
"type": "object",
"required": ["bucket", "key", "link", "resourceUri"],
"properties": {
"bucket": {
"type": "string",
"description": "The S3 bucket where the generated PDF is stored"
},
"key": {
"type": "string",
"description": "The S3 object key (path) of the generated PDF"
},
"link": {
"type": "string",
"format": "uri",
"description": "Pre-signed URL for downloading the document (expires in 7 days)"
},
"resourceUri": {
"type": "string",
"description": "S3 URI in format s3://bucket/key for internal references"
}
}
}
---
id: PolicyAdHocCollectionRequestedEventV1
name: Policy Ad-Hoc Collection Requested
version: 0.0.1
summary: Event emitted when an ad-hoc premium collection is requested for a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: green
textColor: white
---
## Overview
The `PolicyAdHocCollectionRequestedEventV1` event is emitted when an ad-hoc (out-of-schedule) premium collection is requested for a funeral policy. Unlike regular scheduled collections, ad-hoc collections are triggered manually or by specific business processes that require immediate payment processing.
This event is part of the collection workflow and enables flexibility in premium collection beyond the standard billing cycle.
### Collection Workflow Context
The premium collection workflow typically operates on a scheduled basis, but ad-hoc collections provide flexibility for:
1. **Catch-up Payments** - When a policyholder wants to pay missed premiums
2. **Advance Payments** - When a policyholder wishes to pay premiums ahead of schedule
3. **Special Circumstances** - Business processes that require immediate collection outside the normal cycle
When an ad-hoc collection is requested:
1. This event is emitted with the collection details
2. The collection provider processes the payment request
3. Success or failure events are published based on the outcome
### Key Fields
- **collectionAmount** - The specific amount to be collected in this ad-hoc request
- **policyPremium** - The total premium amount for reference
- **collectionProviderName** - The provider that will process this collection
- **products** - Detailed breakdown of products, tranches, and beneficiaries associated with the policy
- **collectionFrequency** - The normal collection frequency for context
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyAdHocCollectionRequestedEventV1",
"type": "object",
"description": "Event emitted when an ad-hoc premium collection is requested for a funeral policy.",
"definitions": {
"Money": {
"type": "object",
"properties": {
"amount": {
"type": "string",
"description": "The monetary amount as a string"
},
"currency": {
"type": "string",
"description": "The currency code (e.g., USD, EUR, ZAR)"
}
},
"required": ["amount", "currency"]
},
"TemporalInterval": {
"type": "object",
"properties": {
"unit": {
"type": "string",
"enum": ["DAYS", "WEEKS", "MONTHS", "YEARS"],
"description": "The temporal unit"
},
"amount": {
"type": "integer",
"description": "The amount of the temporal unit"
}
},
"required": ["unit", "amount"]
},
"TemporalFrequency": {
"type": "object",
"properties": {
"recurrence": {
"type": "string",
"enum": ["ONCE", "RECURRING"],
"description": "Whether the frequency is once-off or recurring"
},
"interval": {
"oneOf": [
{ "$ref": "#/definitions/TemporalInterval" },
{ "type": "null" }
],
"description": "The temporal interval (null for ONCE recurrence)"
}
},
"required": ["recurrence"]
},
"BeneficiaryEventInfo": {
"type": "object",
"properties": {
"beneficiaryId": {
"type": "string",
"description": "Beneficiary ID"
},
"percentageAllocated": {
"type": "number",
"description": "Percentage allocated to the beneficiary"
}
},
"required": ["beneficiaryId", "percentageAllocated"]
},
"TrancheEventInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Tranche ID"
},
"startDate": {
"type": "integer",
"description": "Tranche start date (milliseconds since epoch)"
},
"endDate": {
"type": "integer",
"description": "Tranche end date (milliseconds since epoch)"
},
"premium": {
"$ref": "#/definitions/Money",
"description": "Tranche premium"
},
"coverAmount": {
"$ref": "#/definitions/Money",
"description": "Tranche cover amount"
},
"waitingPeriods": {
"type": "object",
"additionalProperties": {
"$ref": "#/definitions/TemporalInterval"
},
"description": "Waiting periods as key-value pairs"
}
},
"required": ["id", "startDate", "endDate", "premium", "coverAmount", "waitingPeriods"]
},
"ProductEventInfo": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Product ID"
},
"productInstanceId": {
"type": "string",
"description": "Product instance ID"
},
"productLifeId": {
"type": "string",
"description": "Product life ID"
},
"riskRatings": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Risk ratings as key-value pairs"
},
"name": {
"type": "string",
"description": "Product name"
},
"premium": {
"$ref": "#/definitions/Money",
"description": "Product premium"
},
"tranches": {
"type": "array",
"items": {
"$ref": "#/definitions/TrancheEventInfo"
},
"description": "Product tranches"
},
"beneficiaries": {
"type": "array",
"items": {
"$ref": "#/definitions/BeneficiaryEventInfo"
},
"description": "Product beneficiaries"
}
},
"required": ["id", "productInstanceId", "productLifeId", "riskRatings", "name", "premium", "tranches", "beneficiaries"]
}
},
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event detail"
},
"noticedDate": {
"type": "integer",
"description": "Date when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Date when the event was effected (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for the event"
},
"policyCode": {
"type": ["string", "null"],
"description": "The code of the policy"
},
"policyHolderId": {
"type": ["string", "null"],
"description": "The ID of the policyholder"
},
"partnerId": {
"type": ["string", "null"],
"description": "The ID of the partner associated with the policy"
},
"partnerName": {
"type": ["string", "null"],
"description": "The name of the partner associated with the policy"
},
"packageId": {
"type": ["string", "null"],
"description": "The ID of the package associated with the policy"
},
"packageName": {
"type": ["string", "null"],
"description": "The name of the package associated with the policy"
},
"productCategoryId": {
"type": ["string", "null"],
"description": "The ID of the product category associated with the policy"
},
"productCategoryName": {
"type": ["string", "null"],
"description": "The name of the product category associated with the policy"
},
"division": {
"type": ["string", "null"],
"description": "The division associated with the policy"
},
"subdivision": {
"type": ["string", "null"],
"description": "The subdivision associated with the policy"
},
"collectionId": {
"type": ["string", "null"],
"format": "uuid",
"description": "The collection ID associated with the policy"
},
"collectionDaySelected": {
"type": ["integer", "null"],
"description": "The day selected for collections"
},
"collectionFrequency": {
"oneOf": [
{ "$ref": "#/definitions/TemporalFrequency" },
{ "type": "null" }
],
"description": "The frequency of collections for the policy"
},
"collectionAmount": {
"oneOf": [
{ "$ref": "#/definitions/Money" },
{ "type": "null" }
],
"description": "The amount to be collected in this ad-hoc collection"
},
"policyPremium": {
"oneOf": [
{ "$ref": "#/definitions/Money" },
{ "type": "null" }
],
"description": "The total premium amount for the policy"
},
"nextCollectionDate": {
"type": ["integer", "null"],
"description": "The next scheduled collection date for the policy (milliseconds since epoch)"
},
"collectionProviderName": {
"type": ["string", "null"],
"description": "The name of the collection provider to be used"
},
"products": {
"oneOf": [
{
"type": "array",
"items": {
"$ref": "#/definitions/ProductEventInfo"
}
},
{ "type": "null" }
],
"description": "A list of products associated with the policy at the time of event creation"
},
"countryCode": {
"type": ["string", "null"],
"description": "Country code for collection command creation"
}
},
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading"
]
}
---
id: PolicyBeneficiaryAddedEventV1
name: Policy Beneficiary Added Event
version: 0.0.1
summary: Event emitted when a beneficiary is added to a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Beneficiary
backgroundColor: orange
textColor: white
---
## Overview
The `PolicyBeneficiaryAddedEventV1` event is emitted when a new beneficiary is added to a policy. This event captures all relevant details about the beneficiary addition, including the policy and product instance the beneficiary is associated with, the percentage allocation assigned to the beneficiary, and who performed the addition.
This event is essential for tracking beneficiary changes on policies and maintaining an accurate audit trail of all beneficiary-related modifications within the Policy Administration System.
### Key Fields
- **policyId**: The unique identifier of the policy to which the beneficiary was added
- **beneficiaryId**: The unique identifier of the newly added beneficiary
- **productInstanceId**: The specific product instance within the policy that the beneficiary is linked to
- **percentageAllocated**: The benefit percentage assigned to this beneficiary
- **updatedBy**: The service or person who performed the beneficiary addition
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyBeneficiaryAddedEventV1",
"description": "Event emitted when a beneficiary is added to a policy",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading",
"policyId",
"beneficiaryId",
"productInstanceId",
"percentageAllocated",
"updatedBy"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"beneficiaryId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the beneficiary (UUID as string)"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"percentageAllocated": {
"type": "number",
"description": "Percentage allocated to the beneficiary (serialized Percentage object)"
},
"updatedBy": {
"type": "string",
"description": "The service/person who added the beneficiary."
}
}
}
---
id: PolicyBeneficiaryRemovedEventV1
name: Policy Beneficiary Removed Event
version: 0.0.1
summary: Event emitted when a beneficiary is removed from a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Beneficiary
backgroundColor: orange
textColor: white
---
## Overview
The `PolicyBeneficiaryRemovedEventV1` event is emitted when a beneficiary is removed from a policy. This event captures the details of the removal action, including which beneficiary was removed, from which policy and product instance, the reason for removal (if provided), and who performed the removal.
This event is critical for maintaining compliance and audit trails when beneficiaries are removed from policies, whether due to policyholder requests, regulatory requirements, or other business reasons.
### Key Fields
- **policyId**: The unique identifier of the policy from which the beneficiary was removed
- **beneficiaryId**: The unique identifier of the removed beneficiary
- **productInstanceId**: The specific product instance within the policy that the beneficiary was linked to
- **removalReason**: An optional field capturing the reason for the beneficiary removal
- **removedBy**: The service or person who performed the beneficiary removal
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyBeneficiaryRemovedEventV1",
"description": "Event emitted when a beneficiary is removed on a policy",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading",
"policyId",
"productInstanceId",
"beneficiaryId",
"removedBy"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"beneficiaryId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the beneficiary (UUID as string)"
},
"removalReason": {
"type": ["string", "null"],
"description": "Reason for a beneficiary getting removed"
},
"removedBy": {
"type": "string",
"description": "The service/person who removed the beneficiary detail"
}
}
}
---
id: PolicyBeneficiaryUpdatedEventV1
name: Policy Beneficiary Updated Event
version: 0.0.1
summary: Event emitted when a beneficiary is updated on a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Beneficiary
backgroundColor: orange
textColor: white
---
## Overview
The `PolicyBeneficiaryUpdatedEventV1` event is emitted when an existing beneficiary's details are modified on a policy. This event captures what changes were made to the beneficiary, including the updated percentage allocation and a list of which specific fields were modified.
This event enables downstream systems to react to beneficiary changes and maintain accurate records of all modifications made to beneficiary information over time.
### Key Fields
- **policyId**: The unique identifier of the policy containing the updated beneficiary
- **beneficiaryId**: The unique identifier of the beneficiary that was updated
- **productInstanceId**: The specific product instance within the policy that the beneficiary is linked to
- **percentageAllocated**: The updated benefit percentage assigned to this beneficiary
- **updatedBy**: The service or person who performed the beneficiary update
- **updatedFields**: An array of field names that were modified in this update, enabling consumers to understand exactly what changed
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyBeneficiaryUpdatedEventV1",
"description": "Event emitted when a beneficiary is updated on a policy",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading",
"policyId",
"beneficiaryId",
"productInstanceId",
"percentageAllocated",
"updatedBy",
"updatedFields"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"beneficiaryId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the beneficiary (UUID as string)"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"percentageAllocated": {
"type": "number",
"description": "Percentage allocated to the beneficiary (serialized Percentage object)"
},
"updatedBy": {
"type": "string",
"description": "The service/person who updated the beneficiary detail"
},
"updatedFields": {
"type": "array",
"items": {
"type": "string"
},
"description": "An array of string values representing the fields updated for a beneficiary"
}
}
}
---
id: PolicyBillingDateUpdatedEventV1
name: Policy Billing Date Updated Event
version: 0.0.1
summary: Event emitted when a policy billing date is updated
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Update
backgroundColor: blue
textColor: white
---
## Overview
The `PolicyBillingDateUpdatedEventV1` event is emitted when the billing date for a policy is changed. This event captures the transition from the previous billing date to a new billing date, along with when the change becomes effective.
### When is this event emitted?
This event is triggered when:
- A policyholder requests a change to their billing date
- Administrative adjustments are made to align billing cycles
- Billing date is modified due to payment schedule optimization
### Why is this event important?
This event enables downstream systems to:
- Update billing and collection schedules
- Adjust premium collection timing
- Synchronize financial systems with new billing cycles
- Notify relevant parties of billing schedule changes
- Maintain accurate records for audit and compliance
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy being updated |
| `previousBillingDate` | The original billing date before the change |
| `newBillingDate` | The updated billing date |
| `effectiveFrom` | When the new billing date becomes effective |
| `updatedBy` | The user or system that initiated the update |
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyBillingDateUpdatedEventV1",
"description": "Event emitted when a policy billing date is updated.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"previousBillingDate",
"newBillingDate",
"effectiveFrom"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"previousBillingDate": {
"type": "integer",
"description": "The date at which billing was previously sent (milliseconds since epoch)"
},
"newBillingDate": {
"type": "integer",
"description": "The new billing date to update to (milliseconds since epoch)"
},
"effectiveFrom": {
"type": "integer",
"description": "The date at which the new billing date will take effect (milliseconds since epoch)"
},
"updatedBy": {
"type": ["null", "string"],
"description": "Who updated the policy"
}
}
}
---
id: PolicyCancelledEventV1
name: Policy Cancelled Event
version: 0.0.1
summary: Event emitted when an insurance policy is cancelled.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The `PolicyCancelledEventV1` event is emitted by the PolicyService when an insurance policy is cancelled. This event signifies a terminal state in the policy lifecycle and contains details about the cancellation including the reason, any applicable refunds, and the financial state at the time of cancellation.
## When is this event emitted?
This event is published when:
- A policyholder requests cancellation of their policy
- An administrator cancels a policy on behalf of the policyholder
- A policy is cancelled due to non-payment after exhausting grace periods
- A policy is cancelled due to fraud or misrepresentation
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Policy Identification**: Policy ID and policy status at cancellation
- **Cancellation Details**: Cancellation date, reason, who requested it, and who approved it
- **Financial Information**: Refund amount and financial details at the time of cancellation
- **Policyholder**: Policy holder identifier
## Downstream Consumers
Systems that typically consume this event include:
- Billing systems (to stop collections and process refunds)
- Customer communication services (to send cancellation confirmations)
- Reporting and analytics platforms
- Partner systems (to update policy status)
- Claims systems (to close any open claims)
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyCancelledEventV1",
"title": "PolicyCancelledEventV1",
"description": "Event emitted when a policy is cancelled.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"cancellationDate",
"refundAmount",
"cancellationReason"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"requestedBy": {
"type": [
"null",
"string"
],
"description": "Who requested the cancellation."
},
"approvedBy": {
"type": [
"null",
"string"
],
"description": "Who approved the cancellation."
},
"cancellationDate": {
"type": "integer",
"description": "Timestamp when the cancellation took effect (milliseconds since epoch)"
},
"refundAmount": {
"$ref": "#/$defs/Money",
"description": "The refund amount."
},
"cancellationReason": {
"type": "string",
"description": "The reason for the cancellation of the policy."
},
"policyFinancialDetail": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/PolicyFinancialDetail"
}
],
"description": "Financial details captured when the policy was cancelled."
},
"policyHolderId": {
"type": [
"null",
"string"
],
"format": "uuid",
"description": "Unique identifier for the policy holder (UUID as string)"
},
"policyStatus": {
"type": [
"null",
"string"
],
"description": "Status of the policy at cancellation time"
}
},
"$defs": {
"Money": {
"type": "object",
"required": [
"amount",
"currency"
],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string"
}
}
},
"TemporalInterval": {
"type": "object",
"required": [
"unit",
"value"
],
"properties": {
"unit": {
"type": "string",
"enum": [
"NANOS",
"MICROS",
"MILLIS",
"SECONDS",
"MINUTES",
"HOURS",
"HALF_DAYS",
"DAYS",
"WEEKS",
"MONTHS",
"YEARS",
"DECADES",
"CENTURIES",
"MILLENNIA",
"ERAS",
"FOREVER"
],
"description": "The temporal unit for the interval"
},
"value": {
"type": "integer",
"description": "The value for the temporal interval"
}
}
},
"TemporalFrequency": {
"type": "object",
"required": [
"recurrence",
"interval"
],
"properties": {
"recurrence": {
"type": "string",
"enum": [
"RECURRING",
"ONCE"
],
"description": "Indicates how the interval recurs"
},
"interval": {
"$ref": "#/$defs/TemporalInterval",
"description": "Interval for the frequency"
}
}
},
"BankDetails": {
"type": "object",
"required": [
"bankAccountName",
"bankName",
"bankAccountNumber"
],
"properties": {
"bankAccountName": {
"type": "string",
"description": "Name on the bank account"
},
"bankName": {
"type": "string",
"description": "Name of the bank"
},
"bankAccountNumber": {
"type": "string",
"description": "Bank account number"
},
"bankBranch": {
"type": [
"null",
"string"
],
"description": "Bank branch information"
},
"accountType": {
"type": [
"null",
"string"
],
"description": "Type of bank account"
}
}
},
"CollectionSchedule": {
"type": "object",
"required": [
"scheduleId",
"createdAt",
"isActive"
],
"properties": {
"scheduleId": {
"type": "string",
"format": "uuid",
"description": "Identifier of the collection schedule"
},
"createdAt": {
"type": "integer",
"description": "Timestamp when the schedule entry was created (milliseconds since epoch)"
},
"isActive": {
"type": "boolean",
"description": "Indicates if the schedule is active"
},
"scheduleActivatedAt": {
"type": [
"null",
"integer"
],
"description": "Timestamp when the schedule became active (milliseconds since epoch)"
}
}
},
"PolicyFinancialDetail": {
"type": "object",
"required": [
"policyBalance"
],
"properties": {
"policyBalance": {
"$ref": "#/$defs/Money",
"description": "Current balance of the policy"
},
"nextCollectionDate": {
"type": [
"null",
"integer"
],
"description": "Next collection date for the policy (milliseconds since epoch)"
},
"bankDetails": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/BankDetails"
}
],
"description": "Bank details for collection"
},
"collectionFrequency": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/TemporalFrequency"
}
],
"description": "Frequency of collection"
},
"collectionDaySelected": {
"type": [
"null",
"integer"
],
"description": "Day of the month selected for collection"
},
"collectionMethod": {
"type": [
"null",
"string"
],
"description": "Method of collection (e.g., DIRECT_DEBIT, PARTNER_COLLECTION)"
},
"collectionProviderName": {
"type": [
"null",
"string"
],
"description": "Name of the collection provider"
},
"collectionId": {
"type": [
"null",
"string"
],
"format": "uuid",
"description": "Unique identifier for the collection"
},
"sourceOfFunds": {
"type": [
"null",
"string"
],
"description": "Source of funds for the policy"
},
"collectionSchedules": {
"type": [
"null",
"array"
],
"description": "Collection schedules associated to the policy",
"items": {
"$ref": "#/$defs/CollectionSchedule"
}
},
"globalCounters": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/GlobalCounters"
}
],
"description": "Global counters tracking collection attempts and client actions"
}
}
},
"GlobalCounters": {
"type": "object",
"properties": {
"collectionMonthsTotal": {
"type": [
"null",
"integer"
],
"description": "Total number of collection months"
},
"collectionAttemptedMonthsTotal": {
"type": [
"null",
"integer"
],
"description": "Total number of months where collection was attempted"
},
"runningBalanceFail": {
"type": [
"null",
"integer"
],
"description": "Count of failed running balance attempts"
},
"runningBalanceSuccess": {
"type": [
"null",
"integer"
],
"description": "Count of successful running balance attempts"
},
"runningBalanceSkip": {
"type": [
"null",
"integer"
],
"description": "Count of skipped running balance attempts"
},
"runningBalanceOther": {
"type": [
"null",
"integer"
],
"description": "Count of other running balance outcomes"
},
"noOfClientCancellations": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated cancellations"
},
"noOfClientReinstatements": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated reinstatements"
},
"noOfClientPauses": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated pauses"
}
}
}
}
}
---
id: PolicyCollectionAnalysisEventV1
name: Policy Collection Analysis
version: 0.0.1
summary: Event emitted when the premium collection command is run for analysis purposes
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: green
textColor: white
---
## Overview
The `PolicyCollectionAnalysisEventV1` event is emitted when the premium collection command is executed. This event provides detailed analysis data about a collection transaction, including comprehensive information about the policy, products, and collection configuration.
This event is part of the collection workflow and serves as a rich data source for analytics, reporting, and downstream processing of collection-related information.
### Collection Workflow Context
The premium collection workflow involves several stages:
1. **Collection Scheduling** - The system schedules premium collections based on the policy's billing date and collection frequency
2. **Collection Command Execution** - When a collection command runs, this analysis event is emitted
3. **Collection Processing** - The collection provider processes the payment request
4. **Outcome Recording** - Success or failure events are published based on the result
This event is emitted during step 2, providing a comprehensive snapshot of the collection context at the time the command is executed. It includes:
- Policy and policyholder details
- Partner and package information
- Product breakdown with individual premiums
- Collection frequency and scheduling details
- Transaction amount and type
### Key Fields
- **transactionAmount** / **policyPremium** - The monetary values involved in the collection
- **productData** - Array containing details about each product and its premium contribution
- **collectionFrequency** - The recurring schedule for collections (e.g., monthly, weekly)
- **transactionExternalReason** - External reason code for the transaction
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyCollectionAnalysisEventV1",
"type": "object",
"description": "Event emitted when the premium collection command is run.",
"definitions": {
"Money": {
"type": "object",
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "ISO 4217 currency code"
}
},
"required": ["amount", "currency"]
},
"TemporalInterval": {
"type": "object",
"properties": {
"unit": {
"type": "string",
"enum": ["NANOS", "MICROS", "MILLIS", "SECONDS", "MINUTES", "HOURS", "HALF_DAYS", "DAYS", "WEEKS", "MONTHS", "YEARS", "DECADES", "CENTURIES", "MILLENNIA", "ERAS", "FOREVER"],
"description": "The temporal unit for the interval"
},
"value": {
"type": "integer",
"description": "The value for the temporal interval"
}
},
"required": ["unit", "value"]
},
"TemporalFrequency": {
"type": "object",
"properties": {
"recurrence": {
"type": "string",
"enum": ["RECURRING", "ONCE"],
"description": "Indicates how the interval recurs"
},
"interval": {
"$ref": "#/definitions/TemporalInterval",
"description": "Interval for the frequency"
}
},
"required": ["recurrence", "interval"]
},
"ProductData": {
"type": "object",
"properties": {
"productId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"productName": {
"type": ["string", "null"],
"description": "Name of the product"
},
"productPremium": {
"$ref": "#/definitions/Money",
"description": "Premium amount for the product"
}
},
"required": ["productId", "productPremium"]
}
},
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": ["string", "null"],
"description": "Type of the event"
},
"logicalClockReading": {
"type": ["integer", "null"],
"description": "Logical clock reading for event ordering"
},
"policyCode": {
"type": "string",
"description": "Unique policy code"
},
"correlationId": {
"type": ["string", "null"],
"format": "uuid",
"description": "The correlationId (UUID as string)"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the partner (UUID as string)"
},
"partnerName": {
"type": ["string", "null"],
"description": "Name of the partner"
},
"productCategoryId": {
"type": "string",
"format": "uuid",
"description": "Identifier for the product category (UUID as string)"
},
"productCategoryName": {
"type": ["string", "null"],
"description": "Name for the product category"
},
"packageId": {
"type": "string",
"format": "uuid",
"description": "Identifier for the package (UUID as string)"
},
"packageName": {
"type": "string",
"description": "Name of the package"
},
"policyHolderId": {
"type": "string",
"format": "uuid",
"description": "Identifier for the policy holder (UUID as string)"
},
"divisionName": {
"type": ["string", "null"],
"description": "Division name"
},
"subDivisionName": {
"type": ["string", "null"],
"description": "Subdivision name"
},
"transactionDate": {
"type": ["integer", "null"],
"description": "Date/time of the transaction (milliseconds since epoch)"
},
"nextCollectionDate": {
"type": ["integer", "null"],
"description": "Next collection date/time (milliseconds since epoch)"
},
"transactionAmount": {
"$ref": "#/definitions/Money",
"description": "Transaction amount"
},
"transactionType": {
"type": "string",
"description": "Type of transaction"
},
"policyPremium": {
"$ref": "#/definitions/Money",
"description": "Premium amount for the policy"
},
"transactionExternalReason": {
"type": "string",
"description": "External reason for the transaction"
},
"originCountry": {
"type": "string",
"description": "Origin country code"
},
"productData": {
"type": "array",
"items": {
"$ref": "#/definitions/ProductData"
},
"description": "List of product data"
},
"collectionId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Unique identifier for the collection"
},
"collectionDay": {
"type": ["integer", "null"],
"description": "Selected collection day of month"
},
"collectionFrequency": {
"$ref": "#/definitions/TemporalFrequency",
"description": "Frequency of the collection"
},
"provider": {
"type": ["string", "null"],
"description": "Collection provider"
}
},
"required": [
"id",
"noticedDate",
"effectedDate",
"policyCode",
"policyId",
"partnerId",
"productCategoryId",
"packageId",
"packageName",
"policyHolderId",
"transactionAmount",
"transactionType",
"policyPremium",
"transactionExternalReason",
"originCountry",
"productData",
"collectionFrequency"
]
}
---
id: PolicyCollectionDetailsUpdatedEventV1
name: Policy Collection Details Updated Event
version: 0.0.1
summary: Event emitted when collection details on a policy are updated
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Update
backgroundColor: blue
textColor: white
---
## Overview
The `PolicyCollectionDetailsUpdatedEventV1` event is emitted when payment collection details associated with a policy are modified. This includes changes to banking information used for premium collection.
### When is this event emitted?
This event is triggered when:
- A policyholder updates their bank account details
- The collection method is changed (e.g., switching banks)
- Bank account holder information is modified
- Branch code or account type is updated
### Why is this event important?
This event enables downstream systems to:
- Update payment collection systems with new banking details
- Ensure premium collections are directed to the correct account
- Maintain compliance with financial regulations
- Trigger verification workflows for new banking details
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy being updated |
| `collectionMethod` | The method used to collect premiums |
| `bankName` | Name of the bank for premium collection |
| `accountNumber` | Obfuscated bank account number for security |
| `accountType` | Type of bank account (e.g., savings, checking) |
| `branchCode` | Bank branch code for routing |
| `accountHolderName` | Obfuscated name of the account holder |
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyCollectionDetailsUpdatedEventV1",
"description": "Event emitted when collection details are updated.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"collectionMethod",
"bankName",
"accountNumber",
"branchCode",
"accountHolderName"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"collectionMethod": {
"type": "string",
"description": "Collection method"
},
"bankName": {
"type": "string",
"description": "Bank name"
},
"accountNumber": {
"type": "string",
"description": "Obfuscated bank account number"
},
"accountType": {
"type": ["null", "string"],
"description": "Type of bank account"
},
"branchCode": {
"type": "string",
"description": "Bank branch code"
},
"accountHolderName": {
"type": "string",
"description": "Obfuscated account holder name"
}
}
}
---
id: PolicyCoveredLifeDeceasedEventV1
name: Policy Covered Life Deceased Event
version: 0.0.1
summary: Event emitted when a covered life on a funeral policy is marked as deceased
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Other
backgroundColor: gray
textColor: white
---
## Overview
The `PolicyCoveredLifeDeceasedEventV1` event is emitted when a covered life on a funeral policy is marked as deceased. This event captures the critical information needed to process claims and adjust policy premiums following the death of an insured person.
### When is this event emitted?
This event is triggered when:
- A covered life (insured person) on the policy is reported and confirmed as deceased
- The policy administration system processes the death notification and updates the policy accordingly
### Why is this event important?
This event enables downstream systems to:
- Initiate claims processing workflows for the deceased covered life
- Update premium calculations to reflect the removal of the deceased person from coverage
- Trigger notifications to beneficiaries and relevant parties
- Maintain accurate policy records and audit trails
- Update billing systems with the new premium amount
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy affected by the death |
| `policyCode` | The policy code associated with the policy |
| `policyHolderId` | The unique identifier of the policy holder |
| `deceasedCoveredLifeId` | The unique identifier of the covered life that was declared deceased |
| `lapseType` | The type of lapse affecting the policy |
| `billingRef` | The billing reference for the policy |
| `policyPremiumBefore` | The policy premium amount before the covered life was marked as deceased |
| `policyPremiumAfter` | The policy premium amount after the covered life was marked as deceased |
| `countryCode` | The country code for the policy |
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyCoveredLifeDeceasedEventV1",
"description": "Event emitted when a covered life on a funeral policy is marked as deceased.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"policyCode",
"policyHolderId",
"deceasedCoveredLifeId",
"lapseType",
"billingRef",
"policyPremiumBefore",
"policyPremiumAfter",
"countryCode"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"policyCode": {
"type": "string",
"description": "Policy code associated with the policy"
},
"policyHolderId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy holder"
},
"deceasedCoveredLifeId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the covered life that was declared deceased"
},
"lapseType": {
"type": "string",
"description": "Type of lapse affecting the policy"
},
"billingRef": {
"type": "string",
"description": "Billing reference for the policy"
},
"policyPremiumBefore": {
"type": "object",
"description": "The policy premium before the covered life was marked as deceased",
"required": ["amount", "currency"],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "Currency code"
}
}
},
"policyPremiumAfter": {
"type": "object",
"description": "The policy premium after the covered life was marked as deceased",
"required": ["amount", "currency"],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "Currency code"
}
}
},
"countryCode": {
"type": "string",
"description": "Country code for the policy."
}
}
}
---
id: PolicyCoverEscalationAppliedEventV1
name: Policy Cover Escalation Applied
version: 0.0.1
summary: Event emitted when a cover escalation is applied to a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Cover
backgroundColor: teal
textColor: white
- content: Escalation
backgroundColor: purple
textColor: white
---
import Footer from '@catalog/components/footer.astro'
## Overview
The `PolicyCoverEscalationAppliedEventV1` event is emitted when a cover escalation is applied to a policy. Cover escalation is a mechanism that automatically increases the coverage amount on a policy at defined intervals, helping policyholders maintain adequate protection against inflation and rising costs.
## Understanding Cover Escalation
Cover escalation ensures that the policy's coverage keeps pace with economic changes:
- **Percentage-based increase**: The cover amount increases by a defined percentage (e.g., 5% annually)
- **Interval-driven**: Escalations occur at regular intervals (typically annually)
- **Automatic application**: Once configured, escalations are applied automatically without policyholder intervention
### Key Differences from Premium Escalation
While cover escalation increases the benefit amount, premium escalation increases the premium paid. These can be applied independently or together:
| Escalation Type | What Changes | Impact |
|----------------|--------------|--------|
| Cover Escalation | Benefit/coverage amount | Higher payout on claims |
| Premium Escalation | Premium payments | Higher monthly/annual cost |
## Event Fields
The event captures:
- **Previous and new cover amounts**: Track the change in coverage
- **Escalation details**: Percentage and interval of the escalation
- **Escalation reason and type**: Context for why the escalation occurred
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "PolicyCoverEscalationAppliedEventV1",
"description": "Event emitted when a cover escalation is applied to a policy",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"escalation": {
"type": "object",
"description": "The escalation details",
"properties": {
"percentage": {
"type": "number",
"description": "The escalation percentage"
},
"interval": {
"type": "object",
"description": "Interval for the frequency",
"properties": {
"unit": {
"type": "string",
"enum": ["NANOS", "MICROS", "MILLIS", "SECONDS", "MINUTES", "HOURS", "HALF_DAYS", "DAYS", "WEEKS", "MONTHS", "YEARS", "DECADES", "CENTURIES", "MILLENNIA", "ERAS", "FOREVER"],
"description": "The temporal unit for the interval"
},
"value": {
"type": "integer",
"description": "The value for the temporal interval"
}
},
"required": ["unit", "value"]
}
},
"required": ["percentage", "interval"]
},
"previousCover": {
"type": "object",
"description": "The previous cover amount",
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "Currency code"
}
},
"required": ["amount", "currency"]
},
"newCover": {
"type": "object",
"description": "The new cover amount",
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "Currency code"
}
},
"required": ["amount", "currency"]
},
"escalationReason": {
"type": "string",
"description": "The reason for escalation"
},
"escalationType": {
"type": "string",
"description": "The escalation type"
}
},
"required": ["id", "correlationId", "detailType", "noticedDate", "effectedDate", "logicalClockReading", "policyId", "escalation", "previousCover", "newCover", "escalationReason", "escalationType"]
}
---
id: PolicyCoverStackedEventV1
name: Policy Cover Stacked
version: 0.0.1
summary: Event emitted when a policy has its cover stacked
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Cover
backgroundColor: teal
textColor: white
- content: Stacking
backgroundColor: blue
textColor: white
---
import Footer from '@catalog/components/footer.astro'
## Overview
The `PolicyCoverStackedEventV1` event is emitted when a policy has its cover stacked. Cover stacking is a mechanism where additional coverage amounts are added on top of existing coverage in distinct tranches, allowing for incremental coverage building over time.
## Understanding Cover Stacking
Cover stacking provides a way to build up coverage incrementally:
- **Tranche-based coverage**: Each stack represents a separate tranche of coverage with its own end date
- **Cumulative benefit**: Total coverage is the sum of all active tranches
- **Independent expiration**: Each tranche can have its own maturity/expiration timeline
### Cover Stacking vs Cover Staggering
| Concept | Cover Stacking | Cover Staggering |
|---------|---------------|------------------|
| Structure | Additive coverage amounts | Time-distributed coverage periods |
| Purpose | Build cumulative coverage | Phase coverage over time |
| Premium impact | Increases with each stack | Distributed across terms |
| Use case | Growing protection needs | Term-based product structures |
## Event Fields
The event captures:
- **Tranche information**: Unique tranche ID and end date
- **Product instance**: Links to the specific product being stacked
- **Stack cover amount**: The additional coverage amount being added
- **Premium**: The premium associated with this coverage tranche
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "PolicyCoverStackedEventV1",
"description": "Event emitted when a policy has its cover stacked",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"trancheId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the tranche (UUID as string)"
},
"trancheEndDate": {
"type": "integer",
"description": "The end date of the tranche (milliseconds since epoch)"
},
"stackCoverAmount": {
"type": "object",
"description": "Stacked cover amount",
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "Currency code"
}
},
"required": ["amount", "currency"]
},
"premium": {
"type": "object",
"description": "Premium amount",
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "Currency code"
}
},
"required": ["amount", "currency"]
}
},
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "policyId", "productInstanceId", "trancheId", "trancheEndDate", "stackCoverAmount", "premium"]
}
---
id: PolicyCoverStaggeredEventV1
name: Policy Cover Staggered
version: 0.0.1
summary: Event emitted when a policy has its cover staggered
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Cover
backgroundColor: teal
textColor: white
- content: Staggering
backgroundColor: indigo
textColor: white
---
import Footer from '@catalog/components/footer.astro'
## Overview
The `PolicyCoverStaggeredEventV1` event is emitted when a policy has its cover staggered. Cover staggering is a mechanism that distributes coverage across different time periods or terms, allowing for phased coverage structures within a single policy.
## Understanding Cover Staggering
Cover staggering organizes coverage into distinct time-based segments:
- **Term-based structure**: Coverage is divided into tranches with specific terms (e.g., 5-year, 10-year, 15-year)
- **Phased maturity**: Different portions of coverage mature at different times
- **Flexible planning**: Enables sophisticated coverage strategies aligned with life events or financial plans
### Common Use Cases
1. **Education planning**: Coverage tranches aligned with children's education milestones
2. **Debt coverage**: Staggered coverage matching decreasing mortgage balances
3. **Retirement planning**: Coverage phases that adjust as retirement approaches
### Cover Staggering vs Cover Stacking
| Aspect | Cover Staggering | Cover Stacking |
|--------|-----------------|----------------|
| Focus | Time distribution | Coverage accumulation |
| Structure | Sequential or overlapping terms | Additive coverage layers |
| Outcome | Coverage that evolves over time | Growing total coverage |
## Event Fields
The event captures:
- **Tranche information**: Unique tranche ID and end date
- **Product instance**: Links to the specific product being staggered
- **Term details**: The temporal interval defining this stagger period
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "PolicyCoverStaggeredEventV1",
"description": "Event emitted when a policy has its cover staggered",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"trancheId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the tranche (UUID as string)"
},
"trancheEndDate": {
"type": "integer",
"description": "The end date of the tranche (milliseconds since epoch)"
},
"term": {
"type": "object",
"description": "The term associated with the coverage",
"properties": {
"unit": {
"type": "string",
"enum": ["NANOS", "MICROS", "MILLIS", "SECONDS", "MINUTES", "HOURS", "HALF_DAYS", "DAYS", "WEEKS", "MONTHS", "YEARS", "DECADES", "CENTURIES", "MILLENNIA", "ERAS", "FOREVER"],
"description": "The temporal unit for the interval"
},
"value": {
"type": "integer",
"description": "The value for the temporal interval"
}
},
"required": ["unit", "value"]
}
},
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "policyId", "productInstanceId", "trancheId", "trancheEndDate", "term"]
}
---
id: PolicyCreatedEventV1
name: Policy Created Event
version: 0.0.1
summary: Event emitted when a new insurance policy is created in the system.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The `PolicyCreatedEventV1` event is emitted by the PolicyService when a new insurance policy is successfully created in the system. This event marks the beginning of the policy lifecycle and contains comprehensive information about the newly created policy.
## When is this event emitted?
This event is published when:
- A customer successfully completes the policy purchase process
- A quote is converted into an active policy
- A new policy is created through administrative channels
## Key Information
The event payload includes:
- **Policy Identification**: Policy ID, policy code, and status
- **Policyholder Details**: Policy holder ID and associated quote ID
- **Partner Information**: Partner ID, name, package details
- **Product Details**: Full product information including premiums, tranches, and beneficiaries
- **Financial Configuration**: Premium amounts, escalation settings, and collection details
- **Categorization**: Division, subdivision, product category, and country code
## Downstream Consumers
Systems that typically consume this event include:
- Billing and collections systems
- Customer communication services
- Reporting and analytics platforms
- Partner integration services
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyCreatedEventV1",
"title": "PolicyCreatedEventV1",
"description": "Event emitted when a policy is created.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"policyCode",
"policyStatus",
"policyStartDate",
"policyHolderId",
"partnerId",
"partnerName",
"packageId",
"packageName",
"productCategoryId",
"productCategoryName",
"division",
"subdivision",
"countryCode"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"policyCode": {
"type": "string",
"description": "Unique identifier for the policy"
},
"policyStatus": {
"type": "string",
"description": "Status of the policy (e.g., PENDING_FIRST_PAYMENT, ACTIVE)"
},
"policyStartDate": {
"type": "integer",
"description": "Start date of the policy (milliseconds since epoch)"
},
"policyHolderId": {
"type": "string",
"description": "Unique identifier for the policy holder"
},
"quoteId": {
"type": [
"null",
"string"
],
"format": "uuid",
"description": "Unique identifier for the quote (UUID as string)"
},
"partnerId": {
"type": "string",
"description": "Unique identifier for the partner"
},
"partnerName": {
"type": "string",
"description": "Name of the partner"
},
"packageId": {
"type": "string",
"description": "Unique identifier for the package"
},
"packageName": {
"type": "string",
"description": "Name of the package"
},
"productBundleName": {
"type": [
"null",
"string"
],
"description": "Name of the product bundle"
},
"productBundleId": {
"type": [
"null",
"string"
],
"description": "Unique identifier for the product bundle"
},
"productCategoryId": {
"type": "string",
"description": "Unique identifier for the product category"
},
"productCategoryName": {
"type": "string",
"description": "Name of the product category"
},
"division": {
"type": "string",
"description": "Division information for categorization"
},
"subdivision": {
"type": "string",
"description": "Subdivision information for categorization"
},
"products": {
"type": [
"null",
"array"
],
"description": "List of products associated with this event",
"items": {
"$ref": "#/$defs/ProductEventInfo"
}
},
"metaData": {
"type": [
"null",
"object"
],
"description": "Additional metadata as key-value pairs",
"additionalProperties": {
"type": "string"
}
},
"countryCode": {
"type": "string",
"description": "Country code for the policy."
},
"policyPremium": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/Money"
}
],
"description": "The premium amount for the policy"
},
"escalationConfiguration": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/EscalationConfiguration"
}
],
"description": "Configuration for escalation handling."
},
"policyFinancialDetail": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/PolicyFinancialDetail"
}
],
"description": "Financial details related to this policy."
},
"billingDay": {
"type": [
"null",
"integer"
],
"minimum": 1,
"maximum": 31,
"description": "Day of month for premium billing (1-31). Null for legacy events."
}
},
"$defs": {
"Money": {
"type": "object",
"required": [
"amount",
"currency"
],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string"
}
}
},
"TemporalInterval": {
"type": "object",
"required": [
"unit",
"value"
],
"properties": {
"unit": {
"type": "string",
"enum": [
"NANOS",
"MICROS",
"MILLIS",
"SECONDS",
"MINUTES",
"HOURS",
"HALF_DAYS",
"DAYS",
"WEEKS",
"MONTHS",
"YEARS",
"DECADES",
"CENTURIES",
"MILLENNIA",
"ERAS",
"FOREVER"
],
"description": "The temporal unit for the interval"
},
"value": {
"type": "integer",
"description": "The value for the temporal interval"
}
}
},
"TemporalFrequency": {
"type": "object",
"required": [
"recurrence",
"interval"
],
"properties": {
"recurrence": {
"type": "string",
"enum": [
"RECURRING",
"ONCE"
],
"description": "Indicates how the interval recurs"
},
"interval": {
"$ref": "#/$defs/TemporalInterval",
"description": "Interval for the frequency"
}
}
},
"ProductEventInfo": {
"type": "object",
"required": [
"id",
"productInstanceId",
"premium"
],
"properties": {
"id": {
"type": "string",
"description": "Identifier for the product"
},
"productInstanceId": {
"type": "string",
"description": "Unique identifier for the product"
},
"productLifeId": {
"type": [
"null",
"string"
],
"description": "Unique identifier for the product life"
},
"productLifeType": {
"type": [
"null",
"string"
],
"description": "The product life type"
},
"relationshipToMain": {
"type": [
"null",
"string"
],
"description": "The relationship to main"
},
"riskRatings": {
"type": [
"null",
"object"
],
"description": "Risk ratings as key-value pairs",
"additionalProperties": {
"type": "string"
}
},
"name": {
"type": [
"null",
"string"
],
"description": "Name of the product"
},
"premium": {
"$ref": "#/$defs/Money",
"description": "Premium amount (serialized Money object)"
},
"tranches": {
"type": [
"null",
"array"
],
"description": "List of tranches for this product",
"items": {
"$ref": "#/$defs/TrancheEventInfo"
}
},
"beneficiaries": {
"type": [
"null",
"array"
],
"description": "List of beneficiaries for this product",
"items": {
"$ref": "#/$defs/BeneficiaryEventInfo"
}
}
}
},
"TrancheEventInfo": {
"type": "object",
"required": [
"id",
"startDate",
"premium",
"coverAmount"
],
"properties": {
"id": {
"type": "string",
"description": "Identifier for the tranche"
},
"startDate": {
"type": "integer",
"description": "Start date of the tranche (milliseconds since epoch)"
},
"endDate": {
"type": [
"null",
"integer"
],
"description": "End date of the tranche (milliseconds since epoch)"
},
"premium": {
"$ref": "#/$defs/Money",
"description": "Premium amount for this tranche (serialized Money object)"
},
"coverAmount": {
"$ref": "#/$defs/Money",
"description": "Cover amount for this tranche (serialized Money object)"
},
"waitingPeriods": {
"type": [
"null",
"object"
],
"description": "Waiting periods as key-value pairs",
"additionalProperties": {
"$ref": "#/$defs/TemporalInterval"
}
},
"isReplacementPolicy": {
"type": [
"boolean",
"null"
],
"description": "Indicates if this tranche is linked to a replacement policy",
"default": false
}
}
},
"BeneficiaryEventInfo": {
"type": "object",
"required": [
"beneficiaryId",
"percentageAllocated"
],
"properties": {
"beneficiaryId": {
"type": "string",
"description": "Unique identifier for the beneficiary"
},
"percentageAllocated": {
"type": "number",
"description": "Percentage allocated to the beneficiary (serialized Percentage object)"
}
}
},
"EscalationConfiguration": {
"type": "object",
"properties": {
"premiumEscalationInterval": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/TemporalInterval"
}
],
"description": "Interval between premium escalations (nullable)"
},
"premiumEscalationPercentage": {
"type": [
"null",
"number"
],
"description": "Percentage for premium escalation (nullable)"
},
"coverEscalationInterval": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/TemporalInterval"
}
],
"description": "Interval between cover escalations (nullable)"
},
"coverEscalationPercentage": {
"type": [
"null",
"number"
],
"description": "Percentage for cover escalation (nullable)"
}
}
},
"BankDetails": {
"type": "object",
"required": [
"bankAccountName",
"bankName",
"bankAccountNumber"
],
"properties": {
"bankAccountName": {
"type": "string",
"description": "Name on the bank account"
},
"bankName": {
"type": "string",
"description": "Name of the bank"
},
"bankAccountNumber": {
"type": "string",
"description": "Bank account number"
},
"bankBranch": {
"type": [
"null",
"string"
],
"description": "Bank branch information"
},
"accountType": {
"type": [
"null",
"string"
],
"description": "Type of bank account"
}
}
},
"CollectionSchedule": {
"type": "object",
"required": [
"scheduleId",
"createdAt",
"isActive"
],
"properties": {
"scheduleId": {
"type": "string",
"format": "uuid",
"description": "Identifier of the schedule"
},
"createdAt": {
"type": "integer",
"description": "Instant when the schedule entry was created (milliseconds since epoch)"
},
"isActive": {
"type": "boolean",
"description": "Indicates if the schedule is active"
},
"scheduleActivatedAt": {
"type": [
"null",
"integer"
],
"description": "Timestamp when the schedule became active (milliseconds since epoch)"
}
}
},
"PolicyFinancialDetail": {
"type": "object",
"required": [
"policyBalance",
"collectionMethod"
],
"properties": {
"policyBalance": {
"$ref": "#/$defs/Money",
"description": "Current balance of the policy"
},
"nextCollectionDate": {
"type": [
"null",
"integer"
],
"description": "Next collection date for the policy (milliseconds since epoch)"
},
"bankDetails": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/BankDetails"
}
],
"description": "Bank details for collection"
},
"collectionFrequency": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/TemporalFrequency"
}
],
"description": "Frequency of collection"
},
"collectionDaySelected": {
"type": [
"null",
"integer"
],
"description": "Day of the month selected for collection"
},
"collectionMethod": {
"type": "string",
"description": "Method of collection (e.g., DEBIT_ORDER, CASH)"
},
"collectionProviderName": {
"type": [
"null",
"string"
],
"description": "Name of the collection provider"
},
"collectionId": {
"type": [
"null",
"string"
],
"format": "uuid",
"description": "Unique identifier for the collection"
},
"sourceOfFunds": {
"type": [
"null",
"string"
],
"description": "Source of funds for the policy"
},
"collectionSchedules": {
"type": [
"null",
"array"
],
"description": "Collection schedules stored against the policy",
"items": {
"$ref": "#/$defs/CollectionSchedule"
}
},
"globalCounters": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/GlobalCounters"
}
],
"description": "Global counters tracking collection attempts and client actions"
}
}
},
"GlobalCounters": {
"type": "object",
"properties": {
"collectionMonthsTotal": {
"type": [
"null",
"integer"
],
"description": "Total number of collection months"
},
"collectionAttemptedMonthsTotal": {
"type": [
"null",
"integer"
],
"description": "Total number of months where collection was attempted"
},
"runningBalanceFail": {
"type": [
"null",
"integer"
],
"description": "Count of failed running balance attempts"
},
"runningBalanceSuccess": {
"type": [
"null",
"integer"
],
"description": "Count of successful running balance attempts"
},
"runningBalanceSkip": {
"type": [
"null",
"integer"
],
"description": "Count of skipped running balance attempts"
},
"runningBalanceOther": {
"type": [
"null",
"integer"
],
"description": "Count of other running balance outcomes"
},
"noOfClientCancellations": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated cancellations"
},
"noOfClientReinstatements": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated reinstatements"
},
"noOfClientPauses": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated pauses"
}
}
}
}
}
---
id: PolicyExpiredEventV1
name: Policy Expired Event
version: 0.0.1
summary: Event emitted when a policy has reached its expiry date.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The `PolicyExpiredEventV1` event is emitted by the PolicyService when an insurance policy has reached its natural expiration date. This event represents the end of the policy term as originally defined, distinct from cancellation or lapse scenarios.
## When is this event emitted?
This event is published when:
- A policy reaches its pre-defined end date
- A term-limited policy completes its coverage period
- A policy expires without renewal
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Policy Identification**: Policy ID and policy holder ID
- **Expiry Details**: Expiry date when the policy term ended
- **Status Information**: Policy status and sub-status at the time of expiry
## Downstream Consumers
Systems that typically consume this event include:
- Customer communication services (to send expiry notifications and renewal offers)
- Billing systems (to finalize billing and close accounts)
- Claims systems (to update coverage end dates)
- Reporting and analytics platforms
- Renewal processing systems
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyExpiredEventV1",
"title": "PolicyExpiredEventV1",
"description": "Event emitted when a policy has expired.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"policySubStatus",
"expiryDate",
"policyHolderId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"policySubStatus": {
"type": "string",
"description": "Sub status of the policy at the time of the event"
},
"expiryDate": {
"type": "integer",
"description": "Timestamp when the expiry took effect (milliseconds since epoch)"
},
"policyHolderId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy holder"
},
"policyStatus": {
"type": ["null", "string"],
"description": "Status of the policy at expiry time"
}
}
}
---
id: PolicyHolderAddedToQuoteEventV2
name: Policy Holder Added To Quote Event
version: 0.0.1
summary: Event emitted when policyholder details are captured on a quote.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Policyholder
backgroundColor: orange
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `PolicyHolderAddedToQuoteEventV2` event is emitted by the QuoteService when policyholder details have been captured on a quote. This typically triggers the generation of a resume link for the customer.
## When is this event emitted?
This event is published when:
- A customer completes the policyholder details capture step
- Policyholder information is updated on a quote
- A sales agent captures policyholder details on behalf of a customer
## Key Information
The event payload includes:
- **Quote Identification**: Quote ID and correlation ID
- **Policyholder Reference**: Policy holder ID and external ID
- **Resume Link Configuration**: Configuration for generating resume links
## Downstream Consumers
Systems that typically consume this event include:
- **Quote Reactor**: Generates resume links for customers to continue their quote
- **Notification Service**: Sends quote resume links to customers via SMS/Email
- **Analytics**: Tracks quote progression through capture stages
## Raw Schema:schema.avsc
{
"sft-metadata": {
"version": 1,
"owner-application": "sft-capstone-quote",
"aws-glue-schema-registry-name-pattern": "${StackName}-event-stream-registry",
"aws-glue-schema-registry-read-only-role-arn-pattern": "arn:aws:iam::${AwsAccountId}:role/${StackName}-glue-schema-role",
"default-env-variables": {
"sbx": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "127214170779",
"EnvironmentShortname": "sbx"
},
"dev": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "699475923539",
"EnvironmentShortname": "dev"
},
"ppe": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "147997160730",
"EnvironmentShortname": "ppe"
},
"prd": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "202533528935",
"EnvironmentShortname": "prd"
}
}
},
"type": "record",
"name": "PolicyHolderAddedToQuoteEventV2",
"namespace": "sft.pas.quote.events.policyholderaddedtoquoteevent.avro",
"doc": "Event emitted when a policy holder is added to a quote.",
"fields": [
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the event (UUID as string)"
},
{
"name": "correlationId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Correlation ID for tracking the event across systems"
},
{
"name": "noticedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event was noticed"
},
{
"name": "effectedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event took effect"
},
{
"name": "detailType",
"type": "string",
"doc": "Type of the event."
},
{
"name": "logicalClockReading",
"type": "int",
"doc": "Logical clock reading for event ordering"
},
{
"name": "quoteId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the quote"
},
{
"name": "policyHolderId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "ID of the policy holder"
},
{
"name": "policyHolderExternalId",
"type": [
"null",
"string"
],
"doc": "External ID for the policy holder"
},
{
"name": "resumeQuoteConfiguration",
"type": [
"null",
{
"type": "record",
"name": "AvroResumeQuoteConfiguration",
"fields": [
{
"name": "resumeLinkStructure",
"type": "string",
"doc": "Template of the resume link structure"
},
{
"name": "shortenLink",
"type": "boolean",
"doc": "Whether the link should be shortened"
},
{
"name": "linkExpiry",
"type": [
"null",
{
"type": "record",
"name": "AvroTemporalInterval",
"fields": [
{
"name": "unit",
"type": {
"type": "enum",
"name": "AvroChronoUnit",
"symbols": [
"NANOS",
"MICROS",
"MILLIS",
"SECONDS",
"MINUTES",
"HOURS",
"HALF_DAYS",
"DAYS",
"WEEKS",
"MONTHS",
"YEARS",
"DECADES",
"CENTURIES",
"MILLENNIA",
"ERAS",
"FOREVER"
]
}
},
{
"name": "value",
"type": "int"
}
]
}
],
"doc": "Optional expiry interval for the link"
}
]
}
],
"doc": "Resume quote configuration present at time policy holder was added"
}
]
}
---
id: PolicyLapsedEventV1
name: Policy Lapsed Event
version: 0.0.1
summary: Event emitted when a policy has lapsed due to non-payment.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The `PolicyLapsedEventV1` event is emitted by the PolicyService when an insurance policy has lapsed. A policy lapse occurs when premium payments have not been received within the allowed grace period, resulting in a suspension of coverage. Unlike cancellation, a lapsed policy may potentially be reinstated.
## When is this event emitted?
This event is published when:
- A policy has missed premium payments beyond the allowed grace period
- The billing system has exhausted all collection retry attempts
- The policy transitions from an active or pending state to a lapsed state
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Policy Identification**: Policy ID, policy code, and policy holder ID
- **Lapse Details**: Lapse type indicating the specific reason for the lapse
- **Billing Information**: Billing reference and policy premium amount
- **Financial State**: Policy financial details at the time of lapse including balance and collection information
- **Location**: Country code for the policy
## Downstream Consumers
Systems that typically consume this event include:
- Customer communication services (to send lapse notifications and reinstatement options)
- Billing systems (to pause collection attempts)
- Claims systems (to suspend coverage)
- Reporting and analytics platforms
- Partner integration services
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyLapsedEventV1",
"title": "PolicyLapsedEventV1",
"description": "Event emitted when a policy has lapsed.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"policyCode",
"policyHolderId",
"lapseType",
"billingRef",
"policyPremium",
"countryCode"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"policyCode": {
"type": "string",
"description": "Policy code associated with the policy"
},
"policyHolderId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy holder"
},
"lapseType": {
"type": "string",
"description": "Type of lapse affecting the policy"
},
"billingRef": {
"type": "string",
"description": "Billing reference for the policy"
},
"policyPremium": {
"$ref": "#/$defs/Money",
"description": "The premium amount for the policy"
},
"countryCode": {
"type": "string",
"description": "Country code for the policy."
},
"policyFinancialDetail": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/PolicyFinancialDetail"
}
],
"description": "Financial details captured when the policy lapsed."
}
},
"$defs": {
"Money": {
"type": "object",
"required": [
"amount",
"currency"
],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string"
}
}
},
"TemporalInterval": {
"type": "object",
"required": [
"unit",
"value"
],
"properties": {
"unit": {
"type": "string",
"enum": [
"NANOS",
"MICROS",
"MILLIS",
"SECONDS",
"MINUTES",
"HOURS",
"HALF_DAYS",
"DAYS",
"WEEKS",
"MONTHS",
"YEARS",
"DECADES",
"CENTURIES",
"MILLENNIA",
"ERAS",
"FOREVER"
],
"description": "The temporal unit for the interval"
},
"value": {
"type": "integer",
"description": "The value for the temporal interval"
}
}
},
"TemporalFrequency": {
"type": "object",
"required": [
"recurrence",
"interval"
],
"properties": {
"recurrence": {
"type": "string",
"enum": [
"RECURRING",
"ONCE"
],
"description": "Indicates how the interval recurs"
},
"interval": {
"$ref": "#/$defs/TemporalInterval",
"description": "Interval for the frequency"
}
}
},
"BankDetails": {
"type": "object",
"required": [
"bankAccountName",
"bankName",
"bankAccountNumber"
],
"properties": {
"bankAccountName": {
"type": "string",
"description": "Name on the bank account"
},
"bankName": {
"type": "string",
"description": "Name of the bank"
},
"bankAccountNumber": {
"type": "string",
"description": "Bank account number"
},
"bankBranch": {
"type": [
"null",
"string"
],
"description": "Bank branch information"
},
"accountType": {
"type": [
"null",
"string"
],
"description": "Type of bank account"
}
}
},
"CollectionSchedule": {
"type": "object",
"required": [
"scheduleId",
"createdAt",
"isActive"
],
"properties": {
"scheduleId": {
"type": "string",
"format": "uuid",
"description": "Identifier of the collection schedule"
},
"createdAt": {
"type": "integer",
"description": "Timestamp when the schedule entry was registered (milliseconds since epoch)"
},
"isActive": {
"type": "boolean",
"description": "Indicates if the schedule is active"
},
"scheduleActivatedAt": {
"type": [
"null",
"integer"
],
"description": "Timestamp when the schedule was activated (milliseconds since epoch)"
}
}
},
"PolicyFinancialDetail": {
"type": "object",
"required": [
"policyBalance"
],
"properties": {
"policyBalance": {
"$ref": "#/$defs/Money",
"description": "Current balance of the policy"
},
"nextCollectionDate": {
"type": [
"null",
"integer"
],
"description": "Next collection date for the policy (milliseconds since epoch)"
},
"bankDetails": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/BankDetails"
}
],
"description": "Bank details for collection"
},
"collectionFrequency": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/TemporalFrequency"
}
],
"description": "Frequency of collection"
},
"collectionDaySelected": {
"type": [
"null",
"integer"
],
"description": "Day of the month selected for collection"
},
"collectionMethod": {
"type": [
"null",
"string"
],
"description": "Method of collection (e.g., DIRECT_DEBIT, PARTNER_COLLECTION)"
},
"collectionProviderName": {
"type": [
"null",
"string"
],
"description": "Name of the collection provider"
},
"collectionId": {
"type": [
"null",
"string"
],
"format": "uuid",
"description": "Unique identifier for the collection"
},
"sourceOfFunds": {
"type": [
"null",
"string"
],
"description": "Source of funds for the policy"
},
"collectionSchedules": {
"type": [
"null",
"array"
],
"description": "Collection schedules retained against the policy",
"items": {
"$ref": "#/$defs/CollectionSchedule"
}
},
"globalCounters": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/GlobalCounters"
}
],
"description": "Global counters tracking collection attempts and client actions"
}
}
},
"GlobalCounters": {
"type": "object",
"properties": {
"collectionMonthsTotal": {
"type": [
"null",
"integer"
],
"description": "Total number of collection months"
},
"collectionAttemptedMonthsTotal": {
"type": [
"null",
"integer"
],
"description": "Total number of months where collection was attempted"
},
"runningBalanceFail": {
"type": [
"null",
"integer"
],
"description": "Count of failed running balance attempts"
},
"runningBalanceSuccess": {
"type": [
"null",
"integer"
],
"description": "Count of successful running balance attempts"
},
"runningBalanceSkip": {
"type": [
"null",
"integer"
],
"description": "Count of skipped running balance attempts"
},
"runningBalanceOther": {
"type": [
"null",
"integer"
],
"description": "Count of other running balance outcomes"
},
"noOfClientCancellations": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated cancellations"
},
"noOfClientReinstatements": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated reinstatements"
},
"noOfClientPauses": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated pauses"
}
}
}
}
}
---
id: PolicyPersonalDetailsUpdatedEventV1
name: Policy Personal Details Updated Event
version: 0.0.1
summary: Event emitted when personal details on a policy are updated
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Update
backgroundColor: blue
textColor: white
---
## Overview
The `PolicyPersonalDetailsUpdatedEventV1` event is emitted when personal details associated with a policy are modified. This event captures changes to personal information for a specific life (insured person) on a product within the policy.
### When is this event emitted?
This event is triggered when:
- A policyholder updates their personal information (e.g., name, contact details, address)
- Personal details of an insured life on the policy are modified
- Administrative corrections are made to personal information
### Why is this event important?
This event enables downstream systems to:
- Keep personal records synchronized across the insurance platform
- Trigger compliance workflows when sensitive personal data changes
- Update communication preferences and contact information
- Maintain audit trails for personal data modifications
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy being updated |
| `productLifeId` | Identifies the specific life (person) on the product whose details changed |
| `productInstanceId` | The product instance associated with the update |
| `updatedFields` | Array listing which specific fields were modified |
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyPersonalDetailsUpdatedEventV1",
"description": "Event emitted when personal details on a policy are updated",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading",
"policyId",
"productLifeId",
"productInstanceId",
"updatedFields"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"productLifeId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier of a life on a the product (UUID as string)"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"updatedFields": {
"type": "array",
"items": {
"type": "string"
},
"description": "An array of string values representing the fields updated for a beneficiary"
}
}
}
---
id: PolicyPremiumCollectedEventV1
name: Policy Premium Collected
version: 0.0.1
summary: Event emitted when a policy premium is collected
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: green
textColor: white
---
## Overview
The `PolicyPremiumCollectedEventV1` event is emitted when a policy premium has been successfully collected from a policyholder. This event is a key component of the premium collection workflow and signals that payment has been received for a policy.
This event is part of the collection workflow that manages the recurring premium payment lifecycle for insurance policies. When a collection is processed and payment is confirmed, this event is published to notify downstream systems of the successful collection.
### Collection Workflow Context
The premium collection workflow involves several stages:
1. **Collection Scheduling** - The system schedules premium collections based on the policy's billing date and collection frequency
2. **Collection Processing** - The collection provider processes the payment request
3. **Collection Confirmation** - Upon successful collection, this event is emitted
4. **Grace Period Monitoring** - If collection fails, the system monitors for payment within the grace period
This event indicates that step 3 has completed successfully. It includes information about whether a full or partial premium was collected, along with the count of consecutive successful collections which may be relevant for policy benefits or status.
### Key Fields
- **collectionSubStatus** - Indicates whether the full premium or a partial premium was collected
- **collectionConsecutiveSuccesses** - Tracks the number of consecutive successful collections
- **collectionStatusReason** - Provides context about the collection outcome
- **collectionEffectiveDate** - The date the collection took effect
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyPremiumCollectedEventV1",
"type": "object",
"description": "Event emitted when a policy premium is collected.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"collectionEffectiveDate": {
"type": "integer",
"description": "Timestamp when the collection took effect (milliseconds since epoch)"
},
"collectionStatusReason": {
"type": "string",
"description": "The collection status reason"
},
"collectionConsecutiveSuccesses": {
"type": "integer",
"description": "The number of collection consecutive successes"
},
"collectionSubStatus": {
"type": "string",
"enum": ["PARTIAL_PREMIUM_COLLECTED", "FULL_PREMIUM_COLLECTED"],
"description": "The collection sub status"
}
},
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"collectionEffectiveDate",
"collectionStatusReason",
"collectionConsecutiveSuccesses",
"collectionSubStatus"
]
}
---
id: PolicyPremiumEscalationAppliedEventV1
name: Policy Premium Escalation Applied
version: 0.0.1
summary: Event emitted when a premium escalation is applied to a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Premium
backgroundColor: orange
textColor: white
- content: Escalation
backgroundColor: purple
textColor: white
---
import Footer from '@catalog/components/footer.astro'
## Overview
The `PolicyPremiumEscalationAppliedEventV1` event is emitted when a premium escalation is applied to a policy. Premium escalation adjusts the premium amount at defined intervals, typically to account for inflation and ensure the policy remains financially sustainable for the insurer while continuing to provide value to the policyholder.
## Understanding Premium Escalation
Premium escalation is a scheduled increase in the policy's premium payments:
- **Percentage-based increase**: The premium increases by a defined percentage (e.g., 5% annually)
- **Interval-driven**: Escalations occur at regular intervals, commonly annually on the policy anniversary
- **Linked to cover**: Premium escalation often accompanies cover escalation to maintain the balance between cost and benefit
### Premium vs Cover Escalation
| Aspect | Premium Escalation | Cover Escalation |
|--------|-------------------|------------------|
| What changes | Amount paid by policyholder | Benefit amount on claims |
| Typical rate | 3-10% annually | 3-10% annually |
| Purpose | Maintains policy profitability | Maintains coverage adequacy |
## Event Fields
The event captures:
- **Previous and new premium amounts**: Track the change in premium
- **Escalation details**: Percentage and interval of the escalation
- **Escalation reason and type**: Context for why the escalation occurred
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "PolicyPremiumEscalationAppliedEventV1",
"description": "Event emitted when a premium escalation is applied to a policy",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"escalation": {
"type": "object",
"description": "The escalation details",
"properties": {
"percentage": {
"type": "number",
"description": "The escalation percentage"
},
"interval": {
"type": "object",
"description": "Interval for the frequency",
"properties": {
"unit": {
"type": "string",
"enum": ["NANOS", "MICROS", "MILLIS", "SECONDS", "MINUTES", "HOURS", "HALF_DAYS", "DAYS", "WEEKS", "MONTHS", "YEARS", "DECADES", "CENTURIES", "MILLENNIA", "ERAS", "FOREVER"],
"description": "The temporal unit for the interval"
},
"value": {
"type": "integer",
"description": "The value for the temporal interval"
}
},
"required": ["unit", "value"]
}
},
"required": ["percentage", "interval"]
},
"previousPremium": {
"type": "object",
"description": "The previous premium amount",
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "Currency code"
}
},
"required": ["amount", "currency"]
},
"newPremium": {
"type": "object",
"description": "The new premium amount",
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit - cents"
},
"currency": {
"type": "string",
"description": "Currency code"
}
},
"required": ["amount", "currency"]
},
"escalationReason": {
"type": "string",
"description": "The reason for escalation"
},
"escalationType": {
"type": "string",
"description": "The escalation type"
}
},
"required": ["id", "correlationId", "detailType", "noticedDate", "effectedDate", "logicalClockReading", "policyId", "escalation", "previousPremium", "newPremium", "escalationReason", "escalationType"]
}
---
id: PolicyProductExpiredEventV1
name: Policy Product Expired
version: 0.0.1
summary: Event emitted when a product within a policy has expired
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Cover
backgroundColor: teal
textColor: white
- content: Lifecycle
backgroundColor: gray
textColor: white
---
import Footer from '@catalog/components/footer.astro'
## Overview
The `PolicyProductExpiredEventV1` event is emitted when a product within a policy reaches its expiration date. This typically occurs when a term-based product or a stacked/staggered coverage tranche reaches its maturity date.
## Understanding Product Expiration
Product expiration is a natural lifecycle event for term-based insurance products:
- **Term completion**: The product has reached the end of its coverage term
- **Tranche maturity**: A specific coverage tranche within a stacked or staggered structure has matured
- **Scheduled expiration**: The product was designed to expire at a predetermined date
### Relationship to Cover Stacking and Staggering
Product expiration is closely related to stacking and staggering concepts:
| Context | Expiration Meaning |
|---------|-------------------|
| Stacked cover | A single coverage layer/tranche has reached its end date |
| Staggered cover | A time-phased coverage segment has completed its term |
| Simple term product | The entire product coverage period has ended |
### Downstream Impacts
When a product expires:
1. **Coverage reduction**: Total policy coverage may decrease
2. **Premium adjustment**: Policy premium may be recalculated
3. **Notification triggers**: Policyholder may be notified of the change
4. **Renewal consideration**: Opportunity for policy review or renewal
## Event Fields
The event captures:
- **Policy and product identifiers**: Links to the specific policy and expired product
- **End date**: The date when the product coverage ended
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "PolicyProductExpiredEventV1",
"description": "Event emitted when a product has expired",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"endDate": {
"type": "integer",
"description": "The date the product ended (milliseconds since epoch)"
}
},
"required": ["id", "correlationId", "noticedDate", "effectedDate", "detailType", "logicalClockReading", "policyId", "productInstanceId", "endDate"]
}
---
id: PolicyReinstatedEventV1
name: Policy Reinstated Event
version: 0.0.1
summary: Event emitted when a previously lapsed policy has been reinstated.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The `PolicyReinstatedEventV1` event is emitted by the PolicyService when a previously lapsed insurance policy has been reinstated. Reinstatement restores the policy to active status after a period of lapse, typically following receipt of outstanding premium payments.
## When is this event emitted?
This event is published when:
- Outstanding premium payments are received for a lapsed policy
- A policyholder successfully completes the reinstatement process
- An administrator reinstates a policy through manual intervention
- Arrears are cleared and the policy meets reinstatement criteria
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Policy Identification**: Policy ID identifying the reinstated policy
- **Reinstatement Details**: Reinstatement date when coverage was restored
## Downstream Consumers
Systems that typically consume this event include:
- Billing systems (to resume normal collection schedules)
- Customer communication services (to confirm reinstatement)
- Claims systems (to restore coverage eligibility)
- Reporting and analytics platforms
- Partner integration services
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyReinstatedEventV1",
"title": "PolicyReinstatedEventV1",
"description": "Event emitted when a policy has been reinstated.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"reinstatementDate"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"reinstatementDate": {
"type": "integer",
"description": "Timestamp when the policy was reinstated (milliseconds since epoch)"
}
}
}
---
id: PolicyReplacementCoverDetailsUpdatedEventV1
name: Policy Replacement Cover Details Updated Event
version: 0.0.1
summary: Event emitted when replacement cover details on a policy are updated
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Update
backgroundColor: blue
textColor: white
---
## Overview
The `PolicyReplacementCoverDetailsUpdatedEventV1` event is emitted when replacement cover details are modified on a policy. Replacement cover refers to insurance coverage that replaces an existing policy from another insurer.
### When is this event emitted?
This event is triggered when:
- Replacement cover information is added or updated on a policy
- Details about the original insurer are modified
- The replacement cover amount or premium is adjusted
- The reason for replacement is updated or corrected
### Why is this event important?
This event enables downstream systems to:
- Track policies that replace coverage from other insurers
- Ensure regulatory compliance for replacement business
- Maintain accurate records for anti-churning regulations
- Support commission calculations that may differ for replacement business
- Generate required disclosures and notifications
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy being updated |
| `originalPolicyNumber` | The policy number from the previous insurer |
| `originalInsurer` | Name of the insurer being replaced |
| `replacementCoverAmount` | The amount of cover being replaced |
| `replacementPremium` | The premium amount from the replaced policy |
| `replacementReason` | The stated reason for replacing the original coverage |
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyReplacementCoverDetailsUpdatedEventV1",
"description": "Event emitted when replacement cover details on a policy are updated",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading",
"policyId",
"originalInsurer"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"originalPolicyNumber": {
"type": ["null", "string"],
"description": "Representation of a user friendly unique identifier on a policy"
},
"originalInsurer": {
"type": "string",
"description": "The original insurer that previously covered the client"
},
"replacementCoverAmount": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/Money" }
],
"description": "Replacement cover amount"
},
"replacementPremium": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/Money" }
],
"description": "Premium amount replaced"
},
"replacementReason": {
"type": ["null", "string"],
"description": "Reason for the replacement cover"
}
},
"$defs": {
"Money": {
"type": "object",
"required": ["amount", "currency"],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit (cents)"
},
"currency": {
"type": "string",
"description": "Currency code"
}
}
}
}
}
---
id: PolicyScheduleGeneratedEventV1
name: Policy Schedule Generated Event
version: 0.0.1
summary: Event emitted when a policy schedule document is created
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Other
backgroundColor: gray
textColor: white
---
## Overview
The `PolicyScheduleGeneratedEventV1` event is emitted when a policy schedule document is successfully generated. A policy schedule is a formal document that outlines the key details of the insurance policy, including coverage terms, premium amounts, beneficiaries, and other important policy information.
### When is this event emitted?
This event is triggered when:
- A new policy is created and its schedule document is generated
- An existing policy is updated and a new schedule reflecting the changes is produced
- A policyholder or administrator requests a policy schedule document
- The system generates a refreshed schedule with updated download links
### Why is this event important?
This event enables downstream systems to:
- Notify policyholders that their policy schedule is available for download
- Track document generation for compliance and audit purposes
- Trigger automated delivery of policy schedules via email or other channels
- Maintain a history of policy schedule versions
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy for which the schedule was generated |
| `resourceUri` | The resource URI where the generated schedule document is stored |
| `downloadLink` | A link that can be used to download the generated policy schedule |
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyScheduleGeneratedEventV1",
"description": "Event emitted when a policy schedule is created.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"resourceUri"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"resourceUri": {
"type": "string",
"description": "The resource uri for the generated schedule."
},
"downloadLink": {
"type": "string",
"description": "Download link for the generated policy schedule.",
"default": ""
}
}
}
---
id: PolicyScheduleLinkRefreshedEventV1
name: Policy Schedule Link Refreshed Event
version: 0.0.1
summary: Event emitted when a policy schedule download link is refreshed
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Other
backgroundColor: gray
textColor: white
---
## Overview
The `PolicyScheduleLinkRefreshedEventV1` event is emitted when a policy schedule download link is refreshed or regenerated. Download links for policy schedule documents typically have an expiration time for security purposes, and this event indicates that a new link has been generated.
### When is this event emitted?
This event is triggered when:
- A policyholder requests a new download link for their policy schedule
- An existing download link has expired and needs to be refreshed
- An administrator regenerates the schedule download link
- The system automatically refreshes links as part of scheduled maintenance
### Why is this event important?
This event enables downstream systems to:
- Notify policyholders that a new download link is available
- Track link refresh activity for security and audit purposes
- Update any cached or stored links with the new URL
- Monitor link refresh patterns for potential security concerns
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy for which the schedule link was refreshed |
| `resourceUri` | The resource URI where the policy schedule document is stored |
| `downloadLink` | The new download link for the policy schedule |
> **Note: Missing Avro Schema**
>
> A Java domain class (`PolicyScheduleLinkRefreshedEvent`) exists for this event, but no corresponding Avro `.avsc` schema file has been created in the `sft-capstone-policy-avro-events` module. This means the event is not currently published to Kinesis via AWS Glue Schema Registry. An Avro schema should be created if this event needs to be consumed by external services.
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyScheduleLinkRefreshedEventV1",
"description": "Event emitted when a policy schedule download link is refreshed.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"resourceUri": {
"type": "string",
"description": "The resource URI where the policy schedule document is stored."
},
"downloadLink": {
"type": "string",
"description": "The new download link for the policy schedule."
}
}
}
---
id: PolicyUpdatedFromQuoteEventV1
name: Policy Updated From Quote Event
version: 0.0.1
summary: Event emitted when a policy is updated from a quote
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Update
backgroundColor: blue
textColor: white
---
## Overview
The `PolicyUpdatedFromQuoteEventV1` event is emitted when an existing policy is modified based on a new or revised quote. This is a comprehensive event that captures all aspects of the policy update including cover amounts, premiums, products, and financial details.
### When is this event emitted?
This event is triggered when:
- A policyholder accepts a revised quote to modify their existing policy
- Coverage amounts are adjusted based on a new quotation
- Premium changes are applied from an accepted quote
- Products are added, removed, or modified through the quote process
### Why is this event important?
This event enables downstream systems to:
- Synchronize policy details across the insurance platform
- Update billing systems with new premium amounts
- Adjust coverage records in claims processing systems
- Trigger underwriting reviews if necessary
- Notify partners and distribution channels of policy changes
- Update financial projections and reporting
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy being updated |
| `quoteId` | The quote that triggered this policy update |
| `updatedCoverAmount` | The new total cover amount after the update |
| `updatedPremium` | The new premium amount after the update |
| `changedFields` | List of specific fields that were modified |
| `products` | Updated list of products on the policy |
| `policyFinancialDetail` | Comprehensive financial information including collection details |
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyUpdatedFromQuoteEventV1",
"description": "Event emitted when a policy is updated from a quote.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"quoteId",
"updatedCoverAmount",
"updatedPremium",
"policyCode",
"policyHolderId",
"partnerId",
"packageId",
"productCategoryId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the quote used to update the policy"
},
"updatedCoverAmount": {
"$ref": "#/$defs/Money",
"description": "The updated cover amount"
},
"updatedPremium": {
"$ref": "#/$defs/Money",
"description": "The updated premium amount"
},
"updatedBy": {
"type": [
"null",
"string"
],
"description": "Who updated the policy"
},
"changedFields": {
"type": [
"null",
"array"
],
"items": {
"type": "string"
},
"description": "List of fields that were changed"
},
"policyCode": {
"type": "string",
"description": "Policy code identifier"
},
"policyHolderId": {
"type": "string",
"description": "Unique identifier for the policy holder"
},
"partnerId": {
"type": "string",
"description": "Partner identifier"
},
"partnerName": {
"type": [
"null",
"string"
],
"description": "Partner name"
},
"packageId": {
"type": "string",
"description": "Package identifier"
},
"packageName": {
"type": [
"null",
"string"
],
"description": "Package name"
},
"productCategoryId": {
"type": "string",
"description": "Product category identifier"
},
"productCategoryName": {
"type": [
"null",
"string"
],
"description": "Product category name"
},
"division": {
"type": [
"null",
"string"
],
"description": "Division"
},
"subdivision": {
"type": [
"null",
"string"
],
"description": "Subdivision"
},
"products": {
"type": [
"null",
"array"
],
"items": {
"$ref": "#/$defs/ProductInfo"
},
"description": "List of products on the policy"
},
"policyFinancialDetail": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/FinancialDetail"
}
],
"description": "Financial details of the policy"
},
"countryCode": {
"type": [
"null",
"string"
],
"description": "Country code"
}
},
"$defs": {
"Money": {
"type": "object",
"required": [
"amount",
"currency"
],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in smallest currency unit (cents)"
},
"currency": {
"type": "string",
"description": "Currency code"
}
}
},
"ProductInfo": {
"type": "object",
"required": [
"id",
"productInstanceId",
"premium"
],
"properties": {
"id": {
"type": "string",
"description": "Product identifier"
},
"productInstanceId": {
"type": "string",
"description": "Product instance identifier"
},
"name": {
"type": [
"null",
"string"
],
"description": "Product name"
},
"premium": {
"$ref": "#/$defs/Money",
"description": "Premium for this product"
}
}
},
"FinancialDetail": {
"type": "object",
"properties": {
"policyBalance": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/Money"
}
],
"description": "Current policy balance"
},
"nextCollectionDate": {
"type": [
"null",
"integer"
],
"description": "Next collection date (milliseconds since epoch)"
},
"bankDetails": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/BankDetails"
}
],
"description": "Bank account details"
},
"collectionFrequency": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/TemporalFrequency"
}
],
"description": "How often collections occur"
},
"collectionDaySelected": {
"type": [
"null",
"integer"
],
"description": "Selected day for collection"
},
"collectionMethod": {
"type": [
"null",
"string"
],
"description": "Method of collection"
},
"collectionProviderName": {
"type": [
"null",
"string"
],
"description": "Collection provider name"
},
"collectionId": {
"type": [
"null",
"string"
],
"format": "uuid",
"description": "Collection identifier"
},
"sourceOfFunds": {
"type": [
"null",
"string"
],
"description": "Source of funds"
},
"collectionSchedules": {
"type": [
"null",
"array"
],
"items": {
"$ref": "#/$defs/CollectionSchedule"
},
"description": "Collection schedules"
},
"globalCounters": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/GlobalCounters"
}
],
"description": "Global counters tracking collection attempts and client actions"
}
}
},
"BankDetails": {
"type": "object",
"properties": {
"bankAccountName": {
"type": [
"null",
"string"
],
"description": "Bank account name"
},
"bankName": {
"type": [
"null",
"string"
],
"description": "Bank name"
},
"bankAccountNumber": {
"type": [
"null",
"string"
],
"description": "Bank account number"
},
"bankBranch": {
"type": [
"null",
"string"
],
"description": "Bank branch"
},
"accountType": {
"type": [
"null",
"string"
],
"description": "Account type"
}
}
},
"TemporalFrequency": {
"type": "object",
"required": [
"recurrence"
],
"properties": {
"recurrence": {
"type": "string",
"enum": [
"RECURRING",
"ONCE"
],
"description": "Recurrence type"
},
"interval": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/$defs/TemporalInterval"
}
],
"description": "Interval details"
}
}
},
"TemporalInterval": {
"type": "object",
"required": [
"unit",
"value"
],
"properties": {
"unit": {
"type": "string",
"enum": [
"NANOS",
"MICROS",
"MILLIS",
"SECONDS",
"MINUTES",
"HOURS",
"HALF_DAYS",
"DAYS",
"WEEKS",
"MONTHS",
"YEARS",
"DECADES",
"CENTURIES",
"MILLENNIA",
"ERAS",
"FOREVER"
],
"description": "Time unit"
},
"value": {
"type": "integer",
"description": "Interval value"
}
}
},
"CollectionSchedule": {
"type": "object",
"required": [
"scheduleId",
"createdAt",
"isActive"
],
"properties": {
"scheduleId": {
"type": "string",
"format": "uuid",
"description": "Schedule identifier"
},
"createdAt": {
"type": "integer",
"description": "Creation timestamp (milliseconds since epoch)"
},
"isActive": {
"type": "boolean",
"description": "Whether the schedule is active"
},
"scheduleActivatedAt": {
"type": [
"null",
"integer"
],
"description": "Activation timestamp (milliseconds since epoch)"
}
}
},
"GlobalCounters": {
"type": "object",
"properties": {
"collectionMonthsTotal": {
"type": [
"null",
"integer"
],
"description": "Total number of collection months"
},
"collectionAttemptedMonthsTotal": {
"type": [
"null",
"integer"
],
"description": "Total number of months where collection was attempted"
},
"runningBalanceFail": {
"type": [
"null",
"integer"
],
"description": "Count of failed running balance attempts"
},
"runningBalanceSuccess": {
"type": [
"null",
"integer"
],
"description": "Count of successful running balance attempts"
},
"runningBalanceSkip": {
"type": [
"null",
"integer"
],
"description": "Count of skipped running balance attempts"
},
"runningBalanceOther": {
"type": [
"null",
"integer"
],
"description": "Count of other running balance outcomes"
},
"noOfClientCancellations": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated cancellations"
},
"noOfClientReinstatements": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated reinstatements"
},
"noOfClientPauses": {
"type": [
"null",
"integer"
],
"description": "Number of client-initiated pauses"
}
}
}
}
}
---
id: PolicyUpdatedFromQuoteFailedEventV1
name: Policy Updated From Quote Failed Event
version: 0.0.1
summary: Event emitted when a policy update from quote fails due to a stale policy version
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Update
backgroundColor: red
textColor: white
---
## Overview
The `PolicyUpdatedFromQuoteFailedEventV1` event is emitted when an attempt to update a policy from a quote fails because the policy version received in the request does not match the expected version. This is a concurrency control mechanism that prevents stale quote data from overwriting more recent policy changes.
### When is this event emitted?
This event is triggered when:
- A request to update a policy from a quote is received with an outdated policy version
- The `receivedVersion` on the request does not match the `expectedVersion` stored on the policy
- A concurrent modification has occurred between when the quote was created and when the update was attempted
### Why is this event important?
This event enables downstream systems to:
- Notify the quote service that the policy update was rejected so it can retry with the latest version
- Alert operators or support staff of version conflicts that may indicate concurrent editing
- Log audit trail entries for failed update attempts
- Trigger compensating actions in the quote workflow to re-fetch and re-apply changes
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The unique identifier of the policy for which the update failed |
| `quoteId` | The identifier of the quote that triggered the failed update attempt |
| `expectedVersion` | The policy version that was expected by the system |
| `receivedVersion` | The policy version that was received in the request (may be null if not provided) |
| `reason` | Human-readable description of why the update failed |
| `timestamp` | The timestamp when the failure was recorded |
## Schemas
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PolicyUpdatedFromQuoteFailedEventV1",
"description": "Event emitted when a quote is rejected due to stale policy version.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"quoteId",
"expectedVersion",
"reason",
"timestamp"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the quote that triggered the failed update (UUID as string)"
},
"expectedVersion": {
"type": "integer",
"description": "The policy version that was expected by the system"
},
"receivedVersion": {
"type": ["null", "integer"],
"description": "The policy version that was received in the request (null if not provided)"
},
"reason": {
"type": "string",
"description": "Human-readable description of why the update failed"
},
"timestamp": {
"type": "integer",
"description": "Timestamp when the failure was recorded (milliseconds since epoch)"
}
}
}
---
id: PolicyVerificationCompletedEventV1
name: Policy Verification Completed
version: 0.0.1
summary: Event emitted when the verification process is completed for a policy.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Verification
backgroundColor: indigo
textColor: white
---
## Overview
The `PolicyVerificationCompletedEventV1` event is emitted when the entire verification process for a policy has been completed. This is a terminal event in the verification workflow that signals all requested verifications have finished processing.
### Verification Workflow
This event marks the end of the verification lifecycle. It is emitted after all individual verification results (succeeded, soft fail, or hard fail) have been processed and the policy verification state has been finalized.
### Event Context
The event contains comprehensive policy context including:
- Partner and product information
- Policy holder details
- Premium and fee information
- Collection configuration
### Downstream Processing
When this event is received, downstream systems can:
1. Update policy status based on verification outcomes
2. Trigger onboarding completion workflows
3. Initiate collection setup if verifications passed
4. Generate compliance reports
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The policy that completed verification |
| `correlationId` | Links to the original verification request |
| `policyStatus` | Current status of the policy after verification |
| `policyPremium` | The policy premium amount |
| `CollectionMethod` | Payment collection method configured |
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyVerificationCompletedEventV1",
"title": "PolicyVerificationCompletedEventV1",
"description": "Event emitted when the verification process is completed.",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"partnerId",
"partnerName",
"productCategoryId",
"productCategoryName",
"packageId",
"packageName",
"policyHolderId",
"originCountry",
"policyCode",
"productData",
"policyPremium",
"CollectionMethod"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the partner (UUID as string)"
},
"partnerName": {
"type": "string",
"description": "Name of the partner"
},
"productCategoryId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product category (UUID as string)"
},
"productCategoryName": {
"type": "string",
"description": "Name of the product category"
},
"packageId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the package (UUID as string)"
},
"packageName": {
"type": "string",
"description": "Name of the package"
},
"policyHolderId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy holder (UUID as string)"
},
"policyStatus": {
"type": ["string", "null"],
"description": "Status of the policy at expiry time"
},
"nextCollectionDate": {
"type": ["integer", "null"],
"description": "Timestamp for the next collection date (milliseconds since epoch)"
},
"originCountry": {
"type": "string",
"description": "Country code of the origin country"
},
"policyCode": {
"type": "object",
"description": "Represents the policy code",
"required": ["value"],
"properties": {
"value": {
"type": "string",
"description": "The product code value"
}
}
},
"productData": {
"type": "array",
"description": "List of product data",
"items": {
"type": "object",
"required": ["productId", "productName", "productPremium"],
"properties": {
"productId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the product (UUID as string)"
},
"productName": {
"type": "string",
"description": "Name of the product"
},
"productPremium": {
"type": "object",
"description": "Premium amount for the product",
"required": ["amount", "currency"],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in minor currency units"
},
"currency": {
"type": "string",
"description": "Currency code"
}
}
}
}
}
},
"collectionId": {
"type": ["string", "null"],
"format": "uuid",
"description": "Unique identifier for the collection"
},
"collectionDay": {
"type": ["integer", "null"],
"description": "Day of the collection"
},
"collectionFrequency": {
"oneOf": [
{ "type": "null" },
{
"type": "object",
"description": "Frequency of collection",
"required": ["recurrence", "interval"],
"properties": {
"recurrence": {
"type": "string",
"enum": ["RECURRING", "ONCE"],
"description": "Indicates how the interval recurs"
},
"interval": {
"type": "object",
"required": ["unit", "value"],
"properties": {
"unit": {
"type": "string",
"enum": [
"NANOS", "MICROS", "MILLIS", "SECONDS", "MINUTES", "HOURS",
"HALF_DAYS", "DAYS", "WEEKS", "MONTHS", "YEARS", "DECADES",
"CENTURIES", "MILLENNIA", "ERAS", "FOREVER"
],
"description": "The temporal unit for the interval"
},
"value": {
"type": "integer",
"description": "The value for the temporal interval"
}
}
}
}
}
]
},
"provider": {
"oneOf": [
{ "type": "null" },
{
"type": "object",
"description": "Provider information",
"properties": {
"providerId": {
"type": ["string", "null"],
"description": "Unique identifier for the provider"
}
}
}
]
},
"policyPremium": {
"type": "object",
"description": "Policy premium amount",
"required": ["amount", "currency"],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in minor currency units"
},
"currency": {
"type": "string",
"description": "Currency code"
}
}
},
"administrationFee": {
"oneOf": [
{ "type": "null" },
{
"type": "object",
"description": "Administration fee amount",
"required": ["amount", "currency"],
"properties": {
"amount": {
"type": "integer",
"description": "Amount in minor currency units"
},
"currency": {
"type": "string",
"description": "Currency code"
}
}
}
]
},
"CollectionMethod": {
"type": "string",
"enum": [
"DIRECT_DEBIT",
"EFT",
"CREDIT_CARD",
"SASSA_GRANT",
"KAZANG",
"PAYSHAP",
"PARTNER_COLLECTION"
],
"description": "Method of the collection"
}
}
}
---
id: PolicyVerificationHardFailEventV1
name: Policy Verification Hard Fail
version: 0.0.1
summary: Event emitted when a policy handles a hard fail verification result.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Verification
backgroundColor: indigo
textColor: white
---
## Overview
The `PolicyVerificationHardFailEventV1` event is emitted when a verification check results in a hard failure. A hard fail indicates a critical verification failure that may prevent the policy from proceeding or require immediate action.
### Verification Workflow
This event is part of the verification result phase. A hard fail represents a serious issue that typically:
- Blocks policy issuance or activation
- Requires escalation or manual intervention
- May indicate fraud, compliance issues, or data integrity problems
- Blocks multiple or all related policy actions
### Soft Fail vs Hard Fail
| Aspect | Soft Fail | Hard Fail |
|--------|-----------|-----------|
| Policy Status | Can proceed | May be blocked |
| Blocked Actions | Specific actions only | All related actions |
| Remediation | Often possible | May require escalation |
| Severity | Warning level | Critical level |
### Common Hard Fail Scenarios
Hard failures may occur in cases such as:
- **Sanctions Match** - Party appears on a sanctions or PEP list
- **Identity Fraud** - Personal details do not match authoritative sources
- **Invalid Bank Account** - Bank account is closed, invalid, or flagged
- **Deceased Indicator** - Identity records indicate the person is deceased
### Failure Information
The event provides detailed failure context:
- **failureCode** - A machine-readable code identifying the failure type
- **failureReason** - A human-readable explanation of why verification failed
- **failureDetails** - Additional context about the failure
- **blockedActions** - List of policy actions that are blocked
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The policy associated with the verification |
| `partyId` | The party whose verification hard failed |
| `correlationId` | Links to the original verification request |
| `verificationType` | The type of verification that failed |
| `blockedActions` | Actions blocked due to this failure |
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyVerificationHardFailEventV1",
"title": "PolicyVerificationHardFailEventV1",
"description": "Event emitted when a policy handles a hard fail verification",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading",
"policyId",
"partyId",
"verificationType"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"partyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the party who was verified (UUID as string)"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"description": "Type of verification"
},
"failureReason": {
"type": ["string", "null"],
"description": "Reason for the failure"
},
"failureCode": {
"type": ["string", "null"],
"description": "Code for the failure"
},
"failureDetails": {
"type": ["string", "null"],
"description": "The details of the failure"
},
"blockedActions": {
"oneOf": [
{ "type": "null" },
{
"type": "array",
"items": {
"type": "string"
},
"description": "The actions blocked because of the failure"
}
]
}
}
}
---
id: PolicyVerificationRequestedEventV1
name: Policy Verification Requested
version: 0.0.1
summary: Event emitted when a verification process is requested for a policy.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Verification
backgroundColor: indigo
textColor: white
---
## Overview
The `PolicyVerificationRequestedEventV1` event is emitted when a verification process is initiated for a policy. This event triggers the verification workflow by specifying which verifications need to be performed for a given party.
### Verification Workflow
This event marks the beginning of the verification lifecycle. When a policy requires verification of customer details, bank information, or sanctions screening, this event is published to initiate those checks.
### Verification Types
The event supports the following verification types:
- **VERIFICATION_OF_PERSONAL_DETAILS** - Validates the customer's personal information against authoritative sources
- **VERIFICATION_OF_BANK_DETAILS** - Confirms bank account ownership and validity
- **SANCTIONS_SCREENING** - Checks the party against sanctions and PEP (Politically Exposed Persons) lists
### Verification Requirements
Each requested verification can be marked as:
- **REQUIRED** - The verification must pass for the policy to proceed
- **OPTIONAL** - The verification is performed but failure does not block the policy
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The policy for which verification is requested |
| `partyId` | The CIS identifier of the party being verified |
| `correlationId` | Links all related verification events together |
| `requestedVerifications` | Array of verification configurations with type, requirement, and order |
| `metadata` | Additional context as key-value pairs |
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyVerificationRequestedEventV1",
"title": "PolicyVerificationRequestedEventV1",
"description": "Event emitted when a verification process is requested.",
"type": "object",
"required": [
"id",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"policyId",
"partnerId",
"requestedAt",
"correlationId",
"partyId",
"requestedVerifications",
"metadata"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"partnerId": {
"type": "string",
"description": "Unique identifier for the partner"
},
"requestedAt": {
"type": "integer",
"description": "Timestamp when the verification was requested (milliseconds since epoch)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for tracking related events"
},
"partyId": {
"type": "string",
"format": "uuid",
"description": "The CIS identifier for the party to be verified"
},
"requestedVerifications": {
"type": "array",
"description": "List of verification configurations requested",
"items": {
"type": "object",
"required": ["verificationType", "verificationRequirementType"],
"properties": {
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"description": "Type of verification to be performed"
},
"verificationRequirementType": {
"type": "string",
"enum": ["REQUIRED", "OPTIONAL"],
"description": "Whether this verification is required or optional"
},
"order": {
"type": "integer",
"default": 0,
"description": "Order in which this verification should be performed"
}
}
}
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"description": "Additional metadata as key-value pairs"
}
}
}
---
id: PolicyVerificationSoftFailEventV1
name: Policy Verification Soft Fail
version: 0.0.1
summary: Event emitted when a policy handles a soft fail verification result.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Verification
backgroundColor: indigo
textColor: white
---
## Overview
The `PolicyVerificationSoftFailEventV1` event is emitted when a verification check results in a soft failure. A soft fail indicates that the verification did not pass but does not prevent the policy from proceeding. Instead, certain actions may be blocked or flagged for review.
### Verification Workflow
This event is part of the verification result phase. A soft fail differs from a hard fail in that:
- The policy can still be issued or remain active
- Specific actions may be blocked (documented in `blockedActions`)
- Manual review or remediation may be required
- The customer may be asked to provide additional documentation
### Soft Fail vs Hard Fail
| Aspect | Soft Fail | Hard Fail |
|--------|-----------|-----------|
| Policy Status | Can proceed | May be blocked |
| Blocked Actions | Specific actions only | All related actions |
| Remediation | Often possible | May require escalation |
| Severity | Warning level | Critical level |
### Failure Information
The event provides detailed failure context:
- **failureCode** - A machine-readable code identifying the failure type
- **failureReason** - A human-readable explanation of why verification failed
- **failureDetails** - Additional context about the failure
- **blockedActions** - List of specific policy actions that are blocked
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The policy associated with the verification |
| `partyId` | The party whose verification soft failed |
| `correlationId` | Links to the original verification request |
| `verificationType` | The type of verification that failed |
| `blockedActions` | Actions blocked due to this failure |
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyVerificationSoftFailEventV1",
"title": "PolicyVerificationSoftFailEventV1",
"description": "Event emitted when a policy handles a soft fail verification",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading",
"policyId",
"partyId",
"verificationType"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"partyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the party who was verified (UUID as string)"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"description": "Type of verification"
},
"failureReason": {
"type": ["string", "null"],
"description": "Reason for the failure"
},
"failureCode": {
"type": ["string", "null"],
"description": "Code for the failure"
},
"failureDetails": {
"type": ["string", "null"],
"description": "The details of the failure"
},
"blockedActions": {
"oneOf": [
{ "type": "null" },
{
"type": "array",
"items": {
"type": "string"
},
"description": "The actions blocked because of the failure"
}
]
}
}
}
---
id: PolicyVerificationSucceededEventV1
name: Policy Verification Succeeded
version: 0.0.1
summary: Event emitted when a policy handles a successful verification result.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Verification
backgroundColor: indigo
textColor: white
---
## Overview
The `PolicyVerificationSucceededEventV1` event is emitted when a specific verification check passes successfully for a policy. This event indicates that the verified party's information has been validated without issues.
### Verification Workflow
This event is part of the verification result phase. After a verification is requested via `PolicyVerificationRequestedEventV1`, the verification service processes the check and returns results. A successful verification triggers this event.
### Verification Types
The event includes which verification type succeeded:
- **VERIFICATION_OF_PERSONAL_DETAILS** - Customer's personal information validated successfully
- **VERIFICATION_OF_BANK_DETAILS** - Bank account confirmed as valid and owned by the customer
- **SANCTIONS_SCREENING** - Party cleared against sanctions and PEP lists
### Outcome
When this event is emitted:
1. The specific verification is marked as passed
2. If all required verifications succeed, the policy can proceed normally
3. No actions are blocked due to this verification
### Key Fields
| Field | Description |
|-------|-------------|
| `policyId` | The policy associated with the verification |
| `partyId` | The party whose verification succeeded |
| `correlationId` | Links to the original verification request |
| `verificationType` | The type of verification that succeeded |
## Schemas
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "PolicyVerificationSucceededEventV1",
"title": "PolicyVerificationSucceededEventV1",
"description": "Event emitted when a policy handles a successful verification",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"logicalClockReading",
"policyId",
"partyId",
"verificationType"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for the event (UUID as string)"
},
"detailType": {
"type": "string",
"description": "Type of the event."
},
"noticedDate": {
"type": "integer",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the policy (UUID as string)"
},
"partyId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the party who was verified (UUID as string)"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"description": "Type of verification"
}
}
}
---
id: ProductBundleInventoryItemsCreatedEventV2
name: Product Bundle Inventory Items Created Event
version: 0.0.1
summary: Event emitted after inventory items are generated and persisted for a product bundle.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Inventory
backgroundColor: teal
textColor: white
---
## Overview
The `ProductBundleInventoryItemsCreatedEventV2` event is emitted when a batch of inventory items is successfully generated for a product bundle. This event contains the details of the created items including their serial numbers and expiration date.
## When is this event emitted?
This event is published when:
- A partner requests generation of new inventory items for a bundle configuration
- The serial numbers are successfully generated with valid check digits
- The items are persisted to the inventory repository
## Key Information
The event payload includes:
- **Bundle Identification**: Bundle ID, partner code, and package code
- **Item Details**: Count of items created and list of serial numbers
- **Expiration**: When the inventory items expire
- **Event Metadata**: Correlation ID, timestamps, and logical clock reading
## Downstream Consumers
Systems that typically consume this event include:
- Data product services for reporting
- Partner notification systems
- Inventory tracking dashboards
## Raw Schema:schema.avsc
{
"type": "record",
"name": "ProductBundleInventoryItemsCreatedV2",
"namespace": "sft.capstone.productbundle.events.productbundleinventory.avro",
"doc": "Event emitted after inventory items are generated and persisted.",
"fields": [
{
"name": "id",
"type": { "type": "string", "logicalType": "uuid" },
"doc": "Event ID"
},
{
"name": "correlationId",
"type": ["null", { "type": "string", "logicalType": "uuid" }],
"doc": "Correlation ID (nullable)",
"default": null
},
{
"name": "noticedDate",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{
"name": "effectedDate",
"type": { "type": "long", "logicalType": "timestamp-millis" }
},
{ "name": "detailType", "type": "string" },
{ "name": "logicalClockReading", "type": "int" },
{ "name": "bundleId", "type": "string" },
{ "name": "partnerCode", "type": "string" },
{ "name": "packageCode", "type": "string" },
{ "name": "bundleName", "type": "string" },
{ "name": "count", "type": "int" },
{
"name": "serialNumbers",
"type": { "type": "array", "items": "string" },
"default": []
},
{
"name": "expiresAt",
"type": { "type": "long", "logicalType": "timestamp-millis" }
}
]
}
---
id: ProxyRequestSentEventV1
name: Proxy Request Sent Event
version: 0.0.1
summary: Logged when a request is being proxied to the upstream backend API.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Observability
backgroundColor: green
textColor: white
---
## Overview
The `ProxyRequestSentEventV1` is a log event emitted when the BFF Web service is about to forward a request to the upstream backend BFF API. This event captures the proxy configuration and authentication status.
## When is this event emitted?
This event is logged when:
- CORS validation has passed
- CAPTCHA validation has passed (if required)
- The request is about to be sent to the backend
## Key Information
The event payload includes:
- **URL**: The original request URL path and query
- **Upstream**: The full upstream URL being called
- **Authentication**: Whether authorization headers are present
## Use Cases
This event is used for:
- Tracking request routing patterns
- Debugging proxy configuration issues
- Monitoring backend API traffic
- Performance analysis correlation
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://eventcatalog.digisure.com/schemas/BFFWeb/ProxyRequestSentEventV1.json",
"x-parser-schema-format": "application/schema+json;version=draft-2020-12",
"title": "ProxyRequestSentEventV1",
"description": "Log event emitted when a request is being proxied to the upstream backend.",
"type": "object",
"required": [
"level",
"msg",
"env",
"partner_id",
"request_id",
"method",
"path",
"url",
"upstream"
],
"properties": {
"level": {
"type": "string",
"const": "info",
"description": "Log level for this event"
},
"msg": {
"type": "string",
"const": "proxy_request",
"description": "Event message identifier"
},
"env": {
"type": "string",
"description": "Environment name (e.g., sbx, stg, prd)"
},
"partner_id": {
"type": "string",
"description": "Partner identifier for multi-tenant context"
},
"request_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for request correlation"
},
"method": {
"type": "string",
"description": "HTTP method of the request"
},
"path": {
"type": "string",
"description": "URL path of the request"
},
"url": {
"type": "string",
"description": "Original request URL path and query string"
},
"upstream": {
"type": "string",
"format": "uri",
"description": "Full upstream URL the request is being sent to"
},
"has_auth": {
"type": "boolean",
"description": "Whether the request includes authorization or x-api-key headers"
}
}
}
---
id: ProxyResponseReceivedEventV1
name: Proxy Response Received Event
version: 0.0.1
summary: Logged when a response is received from the upstream backend API.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Observability
backgroundColor: green
textColor: white
---
## Overview
The `ProxyResponseReceivedEventV1` is a log event emitted when the BFF Web service receives a response from the upstream backend BFF API. This event captures the response status and timing information.
## When is this event emitted?
This event is logged when:
- The upstream backend returns a response (any status code)
- Before the response is wrapped with CORS and security headers
- Includes successful and error responses from upstream
## Key Information
The event payload includes:
- **Status**: HTTP status code of the proxied response
- **Upstream Status**: Original status from the backend
- **Upstream URL**: The backend URL that was called
- **Latency**: Time taken for the complete proxy operation
## Use Cases
This event is used for:
- Backend API response monitoring
- Latency tracking and performance analysis
- Error rate monitoring by status code
- SLA compliance measurement
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://eventcatalog.digisure.com/schemas/BFFWeb/ProxyResponseReceivedEventV1.json",
"x-parser-schema-format": "application/schema+json;version=draft-2020-12",
"title": "ProxyResponseReceivedEventV1",
"description": "Log event emitted when a response is received from the upstream backend.",
"type": "object",
"required": [
"level",
"msg",
"env",
"partner_id",
"request_id",
"method",
"path",
"status",
"upstream_status",
"upstream",
"latency_ms"
],
"properties": {
"level": {
"type": "string",
"const": "info",
"description": "Log level for this event"
},
"msg": {
"type": "string",
"const": "proxy_response",
"description": "Event message identifier"
},
"env": {
"type": "string",
"description": "Environment name (e.g., sbx, stg, prd)"
},
"partner_id": {
"type": "string",
"description": "Partner identifier for multi-tenant context"
},
"request_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for request correlation"
},
"method": {
"type": "string",
"description": "HTTP method of the request"
},
"path": {
"type": "string",
"description": "URL path of the request"
},
"status": {
"type": "integer",
"minimum": 100,
"maximum": 599,
"description": "HTTP status code of the proxied response"
},
"upstream_status": {
"type": "integer",
"minimum": 100,
"maximum": 599,
"description": "Original HTTP status code from the upstream backend"
},
"upstream": {
"type": "string",
"format": "uri",
"description": "Full upstream URL that was called"
},
"latency_ms": {
"type": "integer",
"minimum": 0,
"description": "Total latency in milliseconds from request received to response sent"
}
}
}
---
id: ProxyUpstreamErrorEventV1
name: Proxy Upstream Error Event
version: 0.0.1
summary: Logged when the upstream backend API is unavailable or returns a network error.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Observability
backgroundColor: green
textColor: white
- content: Error
backgroundColor: red
textColor: white
---
## Overview
The `ProxyUpstreamErrorEventV1` is a log event emitted when the BFF Web service fails to reach the upstream backend API. This indicates a network-level error rather than an application error response.
## When is this event emitted?
This event is logged when:
- The upstream backend is unreachable (DNS failure, connection timeout)
- The connection is reset or terminated unexpectedly
- TLS/SSL handshake fails
- Any network error prevents the request from completing
## Key Information
The event payload includes:
- **Error**: Description of the network error
- **Upstream**: The backend URL that could not be reached
- **Latency**: Time elapsed before the error occurred
## Response to Client
When this error occurs, the BFF Web returns:
- HTTP Status: 502 Bad Gateway
- Body: `{"error": "upstream_unavailable"}`
## Use Cases
This event is used for:
- Backend availability monitoring
- Network incident detection
- Automatic alerting for service outages
- Root cause analysis during incidents
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://eventcatalog.digisure.com/schemas/BFFWeb/ProxyUpstreamErrorEventV1.json",
"x-parser-schema-format": "application/schema+json;version=draft-2020-12",
"title": "ProxyUpstreamErrorEventV1",
"description": "Log event emitted when the upstream backend API is unavailable.",
"type": "object",
"required": [
"level",
"msg",
"env",
"partner_id",
"request_id",
"method",
"path",
"error",
"upstream",
"latency_ms"
],
"properties": {
"level": {
"type": "string",
"const": "error",
"description": "Log level for this event"
},
"msg": {
"type": "string",
"const": "proxy_upstream_error",
"description": "Event message identifier"
},
"env": {
"type": "string",
"description": "Environment name (e.g., sbx, stg, prd)"
},
"partner_id": {
"type": "string",
"description": "Partner identifier for multi-tenant context"
},
"request_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for request correlation"
},
"method": {
"type": "string",
"description": "HTTP method of the request"
},
"path": {
"type": "string",
"description": "URL path of the request"
},
"error": {
"type": "string",
"description": "Error message describing the network failure"
},
"upstream": {
"type": "string",
"format": "uri",
"description": "Full upstream URL that could not be reached"
},
"latency_ms": {
"type": "integer",
"minimum": 0,
"description": "Time elapsed before the error occurred in milliseconds"
}
}
}
---
id: QuoteConvertedEventV2
name: Quote Converted Event
version: 0.0.1
summary: Event emitted when a finalised quote has been successfully converted to a policy.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `QuoteConvertedEventV2` event is emitted by the QuoteService when a quote has been successfully converted to a policy. This event marks the completion of the quote lifecycle and the transition to policy management.
## When is this event emitted?
This event is published when:
- The Policy Service confirms successful policy creation from a QuoteFinalisedEvent
- A quote status is changed to CONVERTED
- For requotes, the existing policy has been updated
## Key Information
The event payload includes:
- **Quote Identification**: Quote ID and correlation ID
- **Policy Reference**: Existing policy ID and code (for requotes)
- **File References**: List of file IDs associated with the quote
## Downstream Consumers
Systems that typically consume this event include:
- Analytics and reporting platforms
- Customer journey completion tracking
- Partner integration services for conversion notifications
## Raw Schema:schema.avsc
{
"sft-metadata": {
"version": 1,
"owner-application": "sft-capstone-quote",
"aws-glue-schema-registry-name-pattern": "${StackName}-event-stream-registry",
"aws-glue-schema-registry-read-only-role-arn-pattern": "arn:aws:iam::${AwsAccountId}:role/${StackName}-glue-schema-role",
"default-env-variables": {
"sbx": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "127214170779",
"EnvironmentShortname": "sbx"
},
"dev": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "699475923539",
"EnvironmentShortname": "dev"
},
"ppe": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "147997160730",
"EnvironmentShortname": "ppe"
},
"prd": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "202533528935",
"EnvironmentShortname": "prd"
}
}
},
"type": "record",
"name": "QuoteConvertedEventV2",
"namespace": "sft.pas.quote.events.quoteconvertedevent.avro",
"doc": "Event emitted when a quote is converted.",
"fields": [
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the event (UUID as string)"
},
{
"name": "correlationId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Correlation ID for tracking the event across systems"
},
{
"name": "noticedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event was noticed"
},
{
"name": "effectedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event took effect"
},
{
"name": "detailType",
"type": "string",
"doc": "Type of the event."
},
{
"name": "logicalClockReading",
"type": "int",
"doc": "Logical clock reading for event ordering"
},
{
"name": "quoteId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the quote"
},
{
"name": "existingPolicyId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
],
"doc": "Existing policy ID"
},
{
"name": "existingPolicyCode",
"type": [
"null",
"string"
],
"doc": "Existing policy code"
},
{
"name": "fileIds",
"type": [
"null",
{
"type": "array",
"items": {
"type": "string",
"logicalType": "uuid"
}
}
],
"doc": "List of fileIds on the quote."
}
]
}
---
id: QuoteCreatedEventV2
name: Quote Created Event
version: 0.0.1
summary: Event emitted when a new insurance quote is created in the system.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `QuoteCreatedEventV2` event is emitted by the QuoteService when a new insurance quote is successfully created in the system. This event marks the beginning of the quote lifecycle.
## When is this event emitted?
This event is published when:
- A customer initiates a new quote through a partner channel
- A sales agent creates a quote on behalf of a customer
- A requote is initiated for an existing policy
## Key Information
The event payload includes:
- **Quote Identification**: Quote ID and correlation ID
- **Partner Information**: Partner ID and package ID
- **Product Category**: The product category being quoted
- **Timestamps**: When the event was noticed and effected
## Downstream Consumers
Systems that typically consume this event include:
- Analytics and reporting platforms
- Customer journey tracking systems
- Partner integration services
## Raw Schema:schema.avsc
{
"sft-metadata": {
"version": 1,
"owner-application": "sft-capstone-quote",
"aws-glue-schema-registry-name-pattern": "${StackName}-event-stream-registry",
"aws-glue-schema-registry-read-only-role-arn-pattern": "arn:aws:iam::${AwsAccountId}:role/${StackName}-glue-schema-role",
"default-env-variables": {
"sbx": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "127214170779",
"EnvironmentShortname": "sbx"
},
"dev": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "699475923539",
"EnvironmentShortname": "dev"
},
"ppe": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "147997160730",
"EnvironmentShortname": "ppe"
},
"prd": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "202533528935",
"EnvironmentShortname": "prd"
}
}
},
"type": "record",
"name": "QuoteCreatedEventV2",
"namespace": "sft.pas.quote.events.quotecreatedevent.avro",
"doc": "Event emitted when a quote is created.",
"fields": [
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the event (UUID as string)"
},
{
"name": "correlationId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Correlation ID for tracking the event across systems"
},
{
"name": "noticedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event was noticed"
},
{
"name": "effectedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event took effect"
},
{
"name": "detailType",
"type": "string",
"doc": "Type of the event."
},
{
"name": "logicalClockReading",
"type": "int",
"doc": "Logical clock reading for event ordering"
},
{
"name": "quoteId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the quote"
},
{
"name": "partnerId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "ID of the partner"
},
{
"name": "packageId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "ID of the partner package"
},
{
"name": "productCategoryId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Product Category ID"
}
]
}
---
id: QuoteExpiredEventV2
name: Quote Expired Event
version: 0.0.1
summary: Event emitted when a quote has expired due to inactivity or time limit.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `QuoteExpiredEventV2` event is emitted by the QuoteService when a quote has expired. Quotes expire when they are not finalised within a configured time period.
## When is this event emitted?
This event is published when:
- A scheduled expiration job processes quotes past their expiry date
- A quote has exceeded its maximum allowed age
- Manual expiration is triggered by an administrator
## Key Information
The event payload includes:
- **Quote Identification**: Quote ID and correlation ID
- **Timestamps**: When the event was noticed and effected
## Downstream Consumers
Systems that typically consume this event include:
- Analytics platforms tracking quote conversion rates
- Customer journey tracking for abandoned quotes
- Partner reporting systems
## Raw Schema:schema.avsc
{
"sft-metadata": {
"version": 1,
"owner-application": "sft-capstone-quote",
"aws-glue-schema-registry-name-pattern": "${StackName}-event-stream-registry",
"aws-glue-schema-registry-read-only-role-arn-pattern": "arn:aws:iam::${AwsAccountId}:role/${StackName}-glue-schema-role",
"default-env-variables": {
"sbx": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "127214170779",
"EnvironmentShortname": "sbx"
},
"dev": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "699475923539",
"EnvironmentShortname": "dev"
},
"ppe": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "147997160730",
"EnvironmentShortname": "ppe"
},
"prd": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "202533528935",
"EnvironmentShortname": "prd"
}
}
},
"type": "record",
"name": "QuoteExpiredEventV2",
"namespace": "sft.pas.quote.events.quoteexpiredevent.avro",
"doc": "Event emitted when a quote is expired.",
"fields": [
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "correlationId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Correlation ID for tracking the event across systems"
},
{
"name": "noticedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "effectedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "detailType",
"type": "string"
},
{
"name": "logicalClockReading",
"type": "int"
},
{
"name": "quoteId",
"type": {
"type": "string",
"logicalType": "uuid"
}
}
]
}
---
id: QuoteFinalisedEventV2
name: Quote Finalised Event
version: 0.0.1
summary: Event emitted when a quote is finalised and ready for policy conversion.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Lifecycle
backgroundColor: purple
textColor: white
- content: Critical
backgroundColor: red
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `QuoteFinalisedEventV2` event is emitted by the QuoteService when a quote has been fully configured and is ready for conversion to a policy. This is the most comprehensive event in the quote domain, containing all information needed to create a policy.
## When is this event emitted?
This event is published when:
- All required quote information has been captured
- Terms and conditions have been accepted
- Required verifications have been completed
- The quote meets all validation rules for finalisation
## Key Information
The event payload includes:
- **Quote Identification**: Quote ID, existing policy ID (for requotes)
- **Sales Information**: Sales agent ID, broker ID and percentage, sales channel ID
- **Partner Information**: Partner ID, name, code, package ID and name
- **Policyholder Details**: Policy holder ID, external ID, employment information
- **Product Details**: Complete product array with tranches, beneficiaries, and pricing
- **Financial Details**: Collection method, bank details, billing configuration
- **Quote Deltas**: Products added, removed, increased, or decreased (for requotes)
- **Verification Details**: Verification configurations and history
- **Terms and Conditions**: T&C acceptance details and download links
## Downstream Consumers
Systems that typically consume this event include:
- **Policy Service**: Creates a new policy from the quote data
- **Collections Service**: Sets up premium collection schedules
- **Document Generation**: Creates policy schedules and welcome packs
- **Partner Integration**: Notifies partners of successful quote completion
## Raw Schema:schema.avsc
{
"sft-metadata": {
"version": 1,
"owner-application": "sft-capstone-quote",
"aws-glue-schema-registry-name-pattern": "${StackName}-event-stream-registry",
"aws-glue-schema-registry-read-only-role-arn-pattern": "arn:aws:iam::${AwsAccountId}:role/${StackName}-glue-schema-role",
"default-env-variables": {
"sbx": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "127214170779",
"EnvironmentShortname": "sbx"
},
"dev": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "699475923539",
"EnvironmentShortname": "dev"
},
"ppe": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "147997160730",
"EnvironmentShortname": "ppe"
},
"prd": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "202533528935",
"EnvironmentShortname": "prd"
}
}
},
"type": "record",
"name": "QuoteFinalisedEventV2",
"namespace": "sft.pas.quote.events.quotefinalisedevent.avro",
"doc": "Event emitted when a quote is finalised.",
"fields": [
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the event (UUID as string)"
},
{
"name": "correlationId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Correlation ID for tracking the event across systems"
},
{
"name": "noticedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event was noticed"
},
{
"name": "effectedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event took effect"
},
{
"name": "detailType",
"type": "string",
"doc": "Type of the event."
},
{
"name": "logicalClockReading",
"type": "int",
"doc": "Logical clock reading for event ordering"
},
{
"name": "quoteId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the quote"
},
{
"name": "existingPolicyId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
],
"doc": "Existing policy ID if this is an update"
},
{
"name": "existingPolicyCode",
"type": [
"null",
"string"
],
"doc": "Existing policy code if this is an update"
},
{
"name": "salesAgentId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
],
"doc": "ID of the sales agent"
},
{
"name": "brokerId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
],
"doc": "ID of the broker"
},
{
"name": "brokerPercentage",
"type": "int",
"doc": "Percentage for the broker"
},
{
"name": "salesChannelId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
],
"doc": "ID of the sales channel"
},
{
"name": "partnerId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
],
"doc": "ID of the partner"
},
{
"name": "partnerName",
"type": "string",
"doc": "Name of the partner"
},
{
"name": "partnerCode",
"type": "int",
"doc": "Code of the partner"
},
{
"name": "productCategory",
"type": {
"type": "record",
"name": "AvroProductCategory",
"fields": [
{
"name": "categoryName",
"type": "string"
},
{
"name": "categoryCode",
"type": "int"
},
{
"name": "productCategoryId",
"type": {
"type": "string",
"logicalType": "uuid"
}
}
]
},
"doc": "Product category"
},
{
"name": "packageId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "ID of the partner package"
},
{
"name": "packageName",
"type": "string",
"doc": "Name of the partner package"
},
{
"name": "countryCode",
"type": "string",
"doc": "Country code for the quote"
},
{
"name": "policyHolderId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "ID of the policy holder"
},
{
"name": "policyHolderExternalId",
"type": [
"null",
"string"
],
"doc": "External ID for the policy holder"
},
{
"name": "employment",
"type": [
"null",
{
"type": "record",
"name": "AvroEmployment",
"fields": [
{
"name": "status",
"type": [
"null",
{
"type": "enum",
"name": "AvroEmploymentStatus",
"symbols": [
"EMPLOYED",
"UNEMPLOYED",
"SELF_EMPLOYED",
"RETIRED",
"STUDENT",
"OTHER"
]
}
],
"default": null,
"doc": "Employment status"
},
{
"name": "industry",
"type": [
"null",
{
"type": "enum",
"name": "AvroIndustry",
"symbols": [
"AGRICULTURE_FORESTRY_AND_FISHING",
"ADULT_ENTERTAINMENT",
"ARTS_ENTERTAINMENT_AND_RECREATION",
"BROADCASTING_AND_ENTERTAINMENT",
"CHEMICAL_ENGINEERING_MANUFACTURING",
"CONSTRUCTION_AND_CIVIL_ENGINEERING",
"ELECTRICITY_SOLAR_WATER_GAS_AND_WASTE_SERVICES",
"EXTRACTIVE_SERVICES_MINING_AND_QUARRYING",
"ENTREPRENEURSHIP",
"ESTATE_LIVING_AND_FAMILY_TRUSTS",
"FINANCIAL_AND_INSURANCE",
"LEGAL_PRACTITIONER",
"PROFESSIONAL_SPORT",
"REAL_ESTATE_AND_PROPERTY_SERVICES",
"SHELL_BANKING",
"VIRTUAL_CURRENCIES",
"EDUCATION",
"GOVERNMENT_SERVICES_ARMS_AND_STATE_OWNED_ENTERPRISES",
"HEALTHCARE_AND_MEDICAL",
"PFMA_SCHEDULE_1_CONSTITUTIONAL_INSTITUTIONS",
"PFMA_SCHEDULE_2_MAJOR_PUBLIC_ENTITIES",
"PFMA_SCHEDULE_3A_NATIONAL_PUBLIC_ENTITIES",
"ADMINISTRATIVE_AND_SUPPORT_SERVICES",
"COMMUNITY_AND_SOCIAL_ACTIVITIES",
"GAMBLING",
"INFORMATION_TECHNOLOGY_COMMUNICATION_AND_TELECOMS",
"MANUFACTURING",
"MOTOR_WHOLESALE_RETAIL_TRADE_AND_REPAIR",
"NON_PROFIT_ORGANISATION_REGULATED_CHARITY",
"NON_GOVERNMENT_ORGANISATION_NGO",
"TRANSPORT_STORAGE_COURIER_AND_FREIGHT",
"TRAVEL_TOURISM_ACCOMMODATION_AND_FOOD_SERVICES",
"OTHER"
]
}
],
"default": null,
"doc": "Employment industry"
}
]
}
],
"default": null,
"doc": "Employment details of the policy holder"
},
{
"name": "popiaConsentGiven",
"type": [
"null",
"boolean"
],
"default": null,
"doc": "POPIA consent flag for the policy holder"
},
{
"name": "quoteFinancialDetail",
"type": [
"null",
{
"type": "record",
"name": "AvroQuoteFinancialDetail",
"fields": [
{
"name": "isThirdPartyPayer",
"type": "boolean",
"doc": "Is a third party payer involved"
},
{
"name": "thirdPartyPayerInfo",
"type": [
"null",
"string"
],
"doc": "Third party payer information"
},
{
"name": "thirdPartyPaymentReference",
"type": [
"null",
"string"
],
"doc": "Third party payment reference"
},
{
"name": "bankAccountName",
"type": "string",
"doc": "Bank account name"
},
{
"name": "bankName",
"type": "string",
"doc": "Bank name"
},
{
"name": "bankAccountNumber",
"type": "string",
"doc": "Bank account number"
},
{
"name": "bankBranch",
"type": "string",
"doc": "Bank branch"
},
{
"name": "bankAccountType",
"type": [
"null",
"string"
],
"doc": "Bank account type"
},
{
"name": "collectionFrequency",
"type": [
"null",
{
"type": "record",
"name": "AvroTemporalFrequency",
"fields": [
{
"name": "recurrence",
"type": {
"type": "enum",
"name": "AvroRecurrence",
"symbols": [
"RECURRING",
"ONCE"
]
}
},
{
"name": "interval",
"type": {
"type": "record",
"name": "AvroTemporalInterval",
"fields": [
{
"name": "unit",
"type": {
"type": "enum",
"name": "AvroChronoUnit",
"symbols": [
"NANOS",
"MICROS",
"MILLIS",
"SECONDS",
"MINUTES",
"HOURS",
"HALF_DAYS",
"DAYS",
"WEEKS",
"MONTHS",
"YEARS",
"DECADES",
"CENTURIES",
"MILLENNIA",
"ERAS",
"FOREVER"
]
},
"doc": "The temporal unit for the interval"
},
{
"name": "value",
"type": "int",
"doc": "The value for the temporal interval"
}
]
}
}
]
}
],
"doc": "Collection frequency"
},
{
"name": "collectionDaySelected",
"type": "int",
"doc": "Collection day selected"
},
{
"name": "collectionMethod",
"type": {
"type": "enum",
"name": "AvroCollectionMethod",
"symbols": [
"DIRECT_DEBIT",
"EFT",
"CREDIT_CARD",
"SASSA_GRANT",
"KAZANG",
"PAYSHAP",
"PARTNER_COLLECTION"
]
},
"doc": "Collection method"
},
{
"name": "collectionProvider",
"type": [
"null",
"string"
],
"doc": "Collection provider"
},
{
"name": "billingId",
"type": [
"null",
"string"
],
"doc": "Billing ID"
},
{
"name": "clientAuthorise",
"type": "boolean",
"doc": "Client authorisation status"
},
{
"name": "sourceOfFunds",
"type": [
"null",
"string"
],
"doc": "Source of funds"
}
]
}
],
"doc": "Financial details of the quote"
},
{
"name": "coverStart",
"type": "string"
},
{
"name": "totalPremium",
"type": {
"type": "record",
"name": "AvroMoney",
"fields": [
{
"name": "amount",
"type": "long"
},
{
"name": "currency",
"type": "string"
}
]
},
"doc": "Premium amount for the product"
},
{
"name": "policyAdministrationFee",
"type": "AvroMoney",
"doc": "The administration fee for the policy"
},
{
"name": "quoteProducts",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "AvroProduct",
"fields": [
{
"name": "productId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "productInstanceId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "productCategory",
"type": "AvroProductCategory"
},
{
"name": "productName",
"type": "string"
},
{
"name": "productLife",
"type": [
"null",
{
"type": "record",
"name": "AvroQuoteProductLife",
"fields": [
{
"name": "productLifeId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "productLifeType",
"type": {
"type": "enum",
"name": "AvroProductLifeType",
"symbols": [
"MAIN",
"COVERED_LIFE",
"BENEFICIARY"
]
}
},
{
"name": "relationshipToMain",
"type": {
"type": "enum",
"name": "AvroProductLifeRelationshipToMain",
"symbols": [
"SPOUSE",
"CHILD",
"PARENT",
"AUNT",
"BROTHER",
"BROTHER_IN_LAW",
"DAUGHTER_IN_LAW",
"FIRST_COUSIN",
"FIRST_COUSIN_CHILD",
"GRANDCHILD",
"GRANDPARENT",
"GRANDPARENT_IN_LAW",
"GREAT_GRANDCHILD",
"GREAT_GRANDPARENT",
"GREAT_GRANDPARENT_IN_LAW",
"NEPHEW",
"NIECE",
"PARENT_IN_LAW",
"SISTER",
"SISTER_IN_LAW",
"SON_IN_LAW",
"UNCLE",
"MAIN"
]
}
},
{
"name": "productLifeRisk",
"type": {
"type": "record",
"name": "AvroProductLifeRisk",
"fields": [
{
"name": "age",
"type": [
"null",
"int"
]
},
{
"name": "gender",
"type": [
"null",
"string"
]
},
{
"name": "income",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "incomeType",
"type": [
"null",
"string"
]
},
{
"name": "maritalStatus",
"type": [
"null",
"string"
]
},
{
"name": "smokerStatus",
"type": [
"null",
"string"
]
},
{
"name": "education",
"type": [
"null",
"string"
]
},
{
"name": "hivStatus",
"type": [
"null",
"string"
]
},
{
"name": "motorcycle",
"type": [
"null",
"string"
]
},
{
"name": "occupation",
"type": [
"null",
"int"
]
},
{
"name": "medicalQandaLink",
"type": [
"null",
"string"
]
},
{
"name": "scorecardOutcome",
"type": [
"null",
"string"
]
},
{
"name": "weight",
"type": [
"null",
"int"
]
},
{
"name": "height",
"type": [
"null",
"double"
]
},
{
"name": "bmi",
"type": [
"null",
"double"
]
}
]
}
},
{
"name": "productLifeExternalId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
]
}
]
}
]
},
{
"name": "futureCover",
"type": "AvroMoney"
},
{
"name": "currentCover",
"type": "AvroMoney"
},
{
"name": "currentPremium",
"type": "AvroMoney"
},
{
"name": "futurePremium",
"type": "AvroMoney"
},
{
"name": "deltaCover",
"type": "AvroMoney"
},
{
"name": "deltaPremium",
"type": "AvroMoney"
},
{
"name": "effectiveCover",
"type": "AvroMoney"
},
{
"name": "effectivePremium",
"type": "AvroMoney"
},
{
"name": "premiumChangeReason",
"type": [
"null",
{
"type": "enum",
"name": "AvroProductPremiumChangeReason",
"symbols": [
"NO_CHANGE",
"COVER_INCREASE",
"COVER_DECREASE",
"ADD_PRODUCT",
"REMOVE_PRODUCT",
"RISK_COVER_CHANGE"
]
}
]
},
{
"name": "quoteBeneficiaries",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroQuoteBeneficiary",
"fields": [
{
"name": "beneficiaryId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "percentageAllocation",
"type": "int"
},
{
"name": "lastActiveDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "isActive",
"type": "boolean"
}
]
}
}
]
},
{
"name": "replacementCoverDetails",
"type": [
"null",
{
"type": "record",
"name": "AvroReplacementCoverDetail",
"fields": [
{
"name": "isReplacementPolicy",
"type": "boolean"
},
{
"name": "previousInsurer",
"type": ["null", "string"],
"default": null
},
{
"name": "willCancelExistingPolicy",
"type": ["null", "boolean"],
"default": null
},
{
"name": "datetimeCommittedToCancel",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
],
"default": null
}
]
}
],
"default": null
},
{
"name": "createdDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "productRules",
"type": [
"null",
{
"type": "record",
"name": "AvroProductRules",
"fields": [
{
"name": "minAge",
"type": "int"
},
{
"name": "maxAge",
"type": "int"
},
{
"name": "minCoverAmount",
"type": "AvroMoney"
},
{
"name": "maxCoverAmount",
"type": "AvroMoney"
},
{
"name": "relationshipToMainTypes",
"type": [
"null",
{
"type": "array",
"items": "AvroProductLifeRelationshipToMain"
}
]
}
]
}
]
},
{
"name": "productConfiguration",
"type": {
"type": "record",
"name": "AvroProductConfiguration",
"fields": [
{
"name": "version",
"type": "int"
},
{
"name": "isBaseOffering",
"type": "boolean"
},
{
"name": "isComplimentary",
"type": "boolean"
},
{
"name": "complimentaryTerm",
"type": [
"null",
"AvroTemporalInterval"
]
},
{
"name": "coverType",
"type": "string"
},
{
"name": "hasDisplayInputs",
"type": "boolean"
},
{
"name": "hasBeneficiaries",
"type": "boolean"
},
{
"name": "maxBeneficiaries",
"type": "int"
},
{
"name": "fixedCalculatedNonePrice",
"type": "string"
},
{
"name": "waitingPeriods",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroWaitingPeriod",
"fields": [
{
"name": "type",
"type": {
"type": "enum",
"name": "AvroWaitingPeriodType",
"symbols": [
"NATURAL_DEATH",
"SUICIDE",
"STILL_BIRTH"
]
},
"doc": "Represents the waiting period type"
},
{
"name": "interval",
"type": "AvroTemporalInterval",
"doc": "Interval for the waiting period"
}
]
}
}
]
},
{
"name": "fixedCost",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "productMetaData",
"type": [
"null",
"string"
]
},
{
"name": "isAutoAddedProduct",
"type": [
"null",
"boolean"
]
},
{
"name": "allowedProductTerms",
"type": [
"null",
{
"type": "array",
"items": "AvroTemporalInterval"
}
]
},
{
"name": "pricingCalculation",
"type": [
"null",
{
"type": "record",
"name": "AvroPricingCalculation",
"fields": [
{
"name": "premiumToCover",
"type": {
"type": "record",
"name": "AvroCalculationConfig",
"fields": [
{
"name": "factorQueryIds",
"type": {
"type": "array",
"items": {
"type": "string",
"logicalType": "uuid"
}
}
},
{
"name": "calculatorIds",
"type": {
"type": "array",
"items": {
"type": "string",
"logicalType": "uuid"
}
}
}
]
}
},
{
"name": "coverToPremium",
"type": "AvroCalculationConfig"
}
]
}
]
}
]
}
},
{
"name": "isActive",
"type": "boolean"
},
{
"name": "pricingConfigVersion",
"type": "int"
},
{
"name": "optionalBenefits",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroOptionalBenefit",
"fields": [
{
"name": "benefitId",
"type": "string"
},
{
"name": "benefitType",
"type": {
"type": "enum",
"name": "AvroOptionalBenefitType",
"symbols": [
"TOP_UP",
"ACCIDENTAL_DEATH"
]
}
},
{
"name": "coverModifier",
"type": {
"type": "record",
"name": "AvroModifier",
"fields": [
{
"name": "modifierType",
"type": {
"type": "enum",
"name": "AvroModifierType",
"symbols": [
"FIXED",
"PERCENTAGE"
]
}
},
{
"name": "value",
"type": "float"
}
]
}
},
{
"name": "premiumModifier",
"type": "AvroModifier"
},
{
"name": "isActive",
"type": "boolean"
},
{
"name": "createdDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "startDate",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
]
},
{
"name": "endDate",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
]
}
]
}
}
]
},
{
"name": "productTerm",
"type": [
"null",
"AvroTemporalInterval"
]
}
]
}
}
},
{
"name": "quoteDeltas",
"type": [
"null",
{
"type": "record",
"name": "AvroQuoteDeltas",
"fields": [
{
"name": "productsAdded",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroProductAdditionDelta",
"fields": [
{
"name": "productId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "productInstanceId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "productConfiguration",
"type": [
"null",
"AvroProductConfiguration"
]
},
{
"name": "productName",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "productCategory",
"type": [
"null",
"AvroProductCategory"
],
"default": null
},
{
"name": "productMetaData",
"type": [
"null",
"string"
],
"default": null
},
{
"name": "productLife",
"type": [
"null",
"AvroQuoteProductLife"
]
},
{
"name": "beneficiaries",
"type": [
"null",
{
"type": "array",
"items": "AvroQuoteBeneficiary"
}
]
},
{
"name": "totalCover",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "totalPremium",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "pricingConfigVersion",
"type": [
"null",
"int"
]
},
{
"name": "productConfigVersion",
"type": [
"null",
"int"
]
},
{
"name": "effectiveDate",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
]
},
{
"name": "productTerm",
"type": [
"null",
"AvroTemporalInterval"
]
},
{
"name": "tranches",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroQuoteTranche",
"fields": [
{
"name": "trancheCoverAmount",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "tranchePremium",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "trancheCoverStartDate",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
]
},
{
"name": "trancheCreatedDate",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
]
},
{
"name": "coolOffPeriod",
"type": [
"null",
"AvroTemporalInterval"
]
},
{
"name": "pricingConfigVersion",
"type": [
"null",
"int"
]
},
{
"name": "productConfigVersion",
"type": [
"null",
"int"
]
}
]
}
}
]
}
]
}
}
]
},
{
"name": "productsRemoved",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroProductRemovalDelta",
"fields": [
{
"name": "productInstanceId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "removalDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
}
},
{
"name": "removalReason",
"type": [
"null",
"string"
]
},
{
"name": "allowReinstatement",
"type": [
"null",
"boolean"
]
},
{
"name": "refundAmount",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "removalSubStatus",
"type": [
"null",
"string"
]
}
]
}
}
]
},
{
"name": "productsIncreasedInCover",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroProductIncreaseDelta",
"fields": [
{
"name": "productInstanceId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "newTranche",
"type": [
"null",
"AvroQuoteTranche"
]
},
{
"name": "coverIncrease",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "premiumIncrease",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "pricingConfigVersion",
"type": [
"null",
"int"
]
},
{
"name": "productConfigVersion",
"type": [
"null",
"int"
]
},
{
"name": "effectiveDate",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
]
},
{
"name": "calculatorInputsKeys",
"type": [
"null",
{
"type": "array",
"items": "string"
}
]
}
]
}
}
]
},
{
"name": "productsDecreasedInCover",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroProductDecreaseDelta",
"fields": [
{
"name": "productInstanceId",
"type": {
"type": "string",
"logicalType": "uuid"
}
},
{
"name": "totalCoverReduction",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "totalPremiumReduction",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "coolOffStatus",
"type": [
"null",
"string"
]
},
{
"name": "effectiveDate",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
]
},
{
"name": "reductions",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroTrancheReduction",
"fields": [
{
"name": "trancheId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
]
},
{
"name": "reductionCoverAmount",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "reductionPremiumAmount",
"type": [
"null",
"AvroMoney"
]
},
{
"name": "reductionTimestamp",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-millis"
}
]
},
{
"name": "coolingOffPeriodSeconds",
"type": [
"null",
"long"
]
}
]
}
}
]
}
]
}
}
]
}
]
}
],
"default": null,
"doc": "Aggregate of deltas that occurred on the quote during finalisation."
},
{
"name": "termsAndConditionsDetail",
"type": {
"type": "record",
"name": "AvroTermsAndConditionsDetail",
"fields": [
{
"name": "isTermsAccepted",
"type": "boolean",
"doc": "Whether the terms and conditions have been accepted"
},
{
"name": "termsVersionNo",
"type": "int",
"doc": "Version number of the terms and conditions"
},
{
"name": "clientToken",
"type": [
"null",
"string"
],
"doc": "Unique identifier for the client"
},
{
"name": "documentId",
"type": [
"null",
"string"
],
"doc": "Unique identifier for the terms and conditions document"
},
{
"name": "partnerTermsAndConditionsDownloadLink",
"type": [
"null",
"string"
],
"default": null,
"doc": "Download link for the partner terms and conditions document"
}
]
},
"doc": "Terms and conditions detail"
},
{
"name": "termsAndConditionsDownloadLink",
"type": "string",
"doc": "The terms and conditions download link."
},
{
"name": "verificationConfigurations",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroVerificationConfiguration",
"fields": [
{
"name": "verificationType",
"type": {
"type": "enum",
"name": "AvroVerificationType",
"symbols": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
]
},
"doc": "Type of verification."
},
{
"name": "verificationRequirementType",
"type": {
"type": "enum",
"name": "AvroVerificationRequirementType",
"symbols": [
"REQUIRED",
"OPTIONAL"
]
},
"doc": "Requirement type for verification."
},
{
"name": "order",
"type": [
"null",
"int"
],
"default": null,
"doc": "Order of the verification step."
}
]
}
}
],
"doc": "List of verification configurations for the quote."
},
{
"name": "verificationHistories",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroVerificationHistory",
"fields": [
{
"name": "verificationDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Date and time of the verification."
},
{
"name": "verificationType",
"type": "AvroVerificationType",
"doc": "Type of verification."
},
{
"name": "verificationRequestBy",
"type": "string",
"doc": "Who requested the verification."
},
{
"name": "verificationRequestTo",
"type": "string",
"doc": "Who the verification was requested to."
},
{
"name": "verificationRequestExternalToken",
"type": "string",
"doc": "External token for the verification request."
},
{
"name": "verificationRequestOutcome",
"type": {
"type": "enum",
"name": "AvroVerificationRequestOutcome",
"symbols": [
"SUCCEEDED",
"HARD_FAIL",
"SOFT_FAIL",
"SYSTEM_OUTAGE"
]
},
"doc": "Outcome of the verification request."
},
{
"name": "verificationOn",
"type": {
"type": "enum",
"name": "AvroVerificationOn",
"symbols": [
"MAIN_LIFE",
"COVERED_LIFE",
"BENEFICIARY",
"APPROVED",
"FINALISED"
]
},
"doc": "Entity or stage on which verification was performed."
},
{
"name": "verificationInternalId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Internal UUID for the verification."
},
{
"name": "verificationStage",
"type": {
"type": "enum",
"name": "AvroVerificationStage",
"symbols": [
"QUOTE",
"POLICY_ACTIVE",
"POLICY_ALTERATION",
"CLAIM"
]
},
"doc": "Stage of the verification."
},
{
"name": "createdBy",
"type": "string",
"doc": "Who created the verification record."
}
]
}
}
],
"doc": "List of verification history records for the quote."
},
{
"name": "currencyConfiguration",
"type": {
"type": "record",
"name": "AvroCurrencyConfiguration",
"fields": [
{
"name": "defaultCurrency",
"type": "string",
"doc": "Default currency code for the partner."
},
{
"name": "currencyRoundingRules",
"type": {
"type": "record",
"name": "AvroCurrencyRoundingRules",
"fields": [
{
"name": "roundingMode",
"type": {
"type": "enum",
"name": "AvroRoundingMode",
"symbols": [
"UP",
"DOWN",
"CEILING",
"FLOOR",
"HALF_UP",
"HALF_DOWN",
"HALF_EVEN",
"UNNECESSARY"
]
},
"doc": "Rounding mode."
},
{
"name": "decimalPlaces",
"type": "int",
"doc": "Number of decimal places to round to."
}
]
},
"doc": "Rules for rounding currency amounts."
}
]
},
"doc": "Currency configuration for the partner."
},
{
"name": "partnerRules",
"type": {
"type": "record",
"name": "AvroPartnerRules",
"fields": [
{
"name": "quotesMustHaveSalesAgentId",
"type": "boolean",
"doc": "Whether quotes must have a sales agent ID."
},
{
"name": "bankDetailsRequired",
"type": "boolean",
"doc": "Whether bank details are required."
},
{
"name": "digiSureCollection",
"type": "boolean",
"doc": "Whether DigiSure collection is enabled."
},
{
"name": "validCollectionMethods",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "AvroPartnerPackageCollectionMethod",
"fields": [
{
"name": "collectionMethodName",
"type": "string",
"doc": "Name of the collection method."
},
{
"name": "collectionProviderName",
"type": [
"null",
"string"
],
"doc": "Name of the collection provider."
},
{
"name": "configuration",
"type": {
"type": "record",
"name": "AvroCollectionMethodConfiguration",
"fields": [
{
"name": "collectionDateBuffers",
"type": {
"type": "map",
"values": {
"type": "record",
"name": "AvroCollectionDateBuffer",
"fields": [
{
"name": "bufferInDays",
"type": "int"
},
{
"name": "cutoffDate",
"type": {
"type": "int",
"logicalType": "date"
}
},
{
"name": "cutoffTime",
"type": {
"type": "int",
"logicalType": "time-millis"
}
}
]
}
}
}
]
}
}
]
}
},
"doc": "Valid collection methods for the partner."
},
{
"name": "reinstatementConfiguration",
"type": [
"null",
{
"type": "record",
"name": "AvroReinstatementConfiguration",
"fields": [
{
"name": "reinstatementWindow",
"type": [
"null",
"AvroTemporalInterval"
],
"doc": "The period within which a policy can be reinstated as a TemporalInterval"
},
{
"name": "maxNumberOfReinstatementsAllowed",
"type": [
"null",
"int"
],
"doc": "The maximum number of times a policy can be reinstated as an Integer"
}
]
}
],
"doc": "Configuration for policy reinstatement rules"
},
{
"name": "maxSpousesAllowed",
"type": [
"null",
"int"
],
"default": null,
"doc": "The maximum number of spouses allowed on a policy"
},
{
"name": "maxParentsAllowed",
"type": [
"null",
"int"
],
"default": null,
"doc": "The maximum number of parents allowed on a policy"
}
]
},
"doc": "Rules for the partner."
},
{
"name": "policyFinancialConfiguration",
"type": [
"null",
{
"type": "record",
"name": "AvroPolicyFinancialConfiguration",
"fields": [
{
"name": "coolOffPeriod",
"type": [
"null",
"AvroTemporalInterval"
],
"doc": "The cooling off period as a TemporalInterval"
},
{
"name": "escalationConfiguration",
"type": [
"null",
{
"type": "record",
"name": "AvroEscalationConfiguration",
"fields": [
{
"name": "premiumEscalation",
"type": [
"null",
{
"type": "record",
"name": "AvroEscalation",
"fields": [
{
"name": "percentage",
"type": [
"null",
"double"
],
"doc": "The percentage by which the value will be escalated"
},
{
"name": "interval",
"type": [
"null",
"AvroTemporalInterval"
],
"doc": "The frequency of the escalation"
}
]
}
],
"doc": "The configuration for premium escalations"
},
{
"name": "coverEscalation",
"type": [
"null",
"AvroEscalation"
],
"doc": "The configuration for cover escalations"
}
]
}
],
"doc": "Configuration for premium and cover escalations"
}
]
}
],
"doc": "Configuration for financial policies including escalations"
},
{
"name": "auditDetail",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "AvroAuditDetail",
"fields": [
{
"name": "user",
"type": "string",
"doc": "User who made the change."
},
{
"name": "updatedAt",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp of the change."
},
{
"name": "changeReason",
"type": "string",
"doc": "Reason for the change."
},
{
"name": "changeCommand",
"type": "string",
"doc": "Command that caused the change."
}
]
}
}
],
"doc": "List of audit details for the quote."
}
]
}
---
id: RequestReceivedEventV1
name: Request Received Event
version: 0.0.1
summary: Logged when a new HTTP request is received by the BFF Web service.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Observability
backgroundColor: green
textColor: white
---
## Overview
The `RequestReceivedEventV1` is a log event emitted when the BFF Web service receives an incoming HTTP request. This event captures the initial request metadata for observability and debugging purposes.
## When is this event emitted?
This event is logged at the start of every request lifecycle:
- When any HTTP request arrives at the Cloudflare Worker
- Before any processing (CORS, CAPTCHA, proxying) begins
- Includes both successful and eventually-failed requests
## Key Information
The event payload includes:
- **Request Metadata**: Request ID, HTTP method, URL path
- **Origin Information**: Origin header, host
- **Environment Context**: Partner ID, environment name
- **Tracing**: Traceparent header for distributed tracing
## Use Cases
This event is used for:
- Request volume monitoring and analytics
- Distributed tracing correlation
- Debugging request flow issues
- Security auditing of incoming traffic
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://eventcatalog.digisure.com/schemas/BFFWeb/RequestReceivedEventV1.json",
"x-parser-schema-format": "application/schema+json;version=draft-2020-12",
"title": "RequestReceivedEventV1",
"description": "Log event emitted when an HTTP request is received by the BFF Web service.",
"type": "object",
"required": [
"level",
"msg",
"env",
"partner_id",
"request_id",
"method",
"path"
],
"properties": {
"level": {
"type": "string",
"const": "info",
"description": "Log level for this event"
},
"msg": {
"type": "string",
"const": "request_received",
"description": "Event message identifier"
},
"env": {
"type": "string",
"description": "Environment name (e.g., sbx, stg, prd)"
},
"partner_id": {
"type": "string",
"description": "Partner identifier for multi-tenant context"
},
"request_id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for request correlation"
},
"method": {
"type": "string",
"enum": ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD"],
"description": "HTTP method of the request"
},
"path": {
"type": "string",
"description": "URL path of the request"
},
"origin": {
"type": ["string", "null"],
"description": "Origin header from the request"
},
"host": {
"type": "string",
"description": "Host header from the request"
},
"traceparent": {
"type": ["string", "null"],
"description": "W3C Trace Context traceparent header for distributed tracing"
}
}
}
---
id: ResumeLinkAddedToQuoteEventV2
name: Resume Link Added To Quote Event
version: 0.0.1
summary: Event emitted when a resume link is generated and added to a quote.
owners:
- digisure-engineering
schemaPath: schema.avsc
badges:
- content: Resume
backgroundColor: teal
textColor: white
- content: Avro
backgroundColor: orange
textColor: black
---
## Overview
The `ResumeLinkAddedToQuoteEventV2` event is emitted by the QuoteService when a resume link has been generated and stored on a quote. This allows customers to return and continue their quote at a later time.
## When is this event emitted?
This event is published when:
- The Quote Reactor generates a resume link after policyholder details are captured
- A shortened URL is created and associated with the quote
- An existing resume link is refreshed
## Key Information
The event payload includes:
- **Quote Identification**: Quote ID and correlation ID
- **Resume Link**: The generated URL for resuming the quote
## Downstream Consumers
Systems that typically consume this event include:
- **Notification Service**: Sends the resume link to the customer via SMS or email
- **Analytics**: Tracks resume link generation and usage
## Raw Schema:schema.avsc
{
"sft-metadata": {
"version": 1,
"owner-application": "sft-capstone-quote",
"aws-glue-schema-registry-name-pattern": "${StackName}-event-stream-registry",
"aws-glue-schema-registry-read-only-role-arn-pattern": "arn:aws:iam::${AwsAccountId}:role/${StackName}-glue-schema-role",
"default-env-variables": {
"sbx": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "127214170779",
"EnvironmentShortname": "sbx"
},
"dev": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "699475923539",
"EnvironmentShortname": "dev"
},
"ppe": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "147997160730",
"EnvironmentShortname": "ppe"
},
"prd": {
"StackName": "sft-capstone-quote",
"AwsAccountId": "202533528935",
"EnvironmentShortname": "prd"
}
}
},
"type": "record",
"name": "ResumeLinkAddedToQuoteEventV2",
"namespace": "sft.pas.quote.events.resumelinkaddedtoquoteevent.avro",
"doc": "Event emitted when a resume link is added to a quote.",
"fields": [
{
"name": "id",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the event (UUID as string)"
},
{
"name": "correlationId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Correlation ID for tracking the event across systems"
},
{
"name": "noticedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event was noticed"
},
{
"name": "effectedDate",
"type": {
"type": "long",
"logicalType": "timestamp-millis"
},
"doc": "Timestamp when the event took effect"
},
{
"name": "detailType",
"type": "string",
"doc": "Type of the event."
},
{
"name": "logicalClockReading",
"type": "int",
"doc": "Logical clock reading for event ordering"
},
{
"name": "quoteId",
"type": {
"type": "string",
"logicalType": "uuid"
},
"doc": "Unique identifier for the quote"
},
{
"name": "resumeQuoteLink",
"type": "string",
"doc": "The resume link added to the quote"
}
]
}
---
id: ScheduleCreationSucceededEventV2
name: Schedule Creation Succeeded Event
version: 0.0.1
summary: Event emitted when a collection schedule is created successfully.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Collection
backgroundColor: green
textColor: white
- content: Success
backgroundColor: teal
textColor: white
---
## Overview
The `ScheduleCreationSucceededEventV2` event indicates a collection schedule was
created successfully. Policy services use this to store the schedule identifier and
next collection date.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "ScheduleCreationSucceededEventV2",
"title": "ScheduleCreationSucceededEventV2",
"description": "Event emitted when a collection schedule is created successfully (derived from collections CG Avro schema).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.multi.pay.collections.cg.events.schedulecreationevent.v2.avro",
"type": "object",
"required": [
"id",
"correlationId",
"detailType",
"noticedDate",
"effectedDate",
"contractId",
"merchantId",
"scheduleId",
"nextCollectionDate"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation identifier linking to the originating command"
},
"detailType": {
"type": "string",
"description": "Type of the event"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"contractId": {
"type": "string",
"description": "Contract identifier associated with the schedule"
},
"merchantId": {
"type": "string",
"description": "Merchant to which this schedule pertains"
},
"scheduleId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the schedule"
},
"nextCollectionDate": {
"type": "integer",
"x-avro-logical-type": "date",
"description": "Next scheduled collection date (days since epoch)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
}
}
}
---
id: VerificationHardFailEventV1
name: Verification Hard Fail Event
version: 0.0.1
summary: Event emitted when a verification fails permanently and cannot be retried.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Hard Fail
backgroundColor: red
textColor: white
---
## Overview
The `VerificationHardFailEventV1` event is emitted by the Verification Service when a party verification fails permanently. Hard failures indicate definitive verification failures that cannot be resolved by retrying.
## When is this event emitted?
This event is published when:
- Personal details verification (VOPD) finds the identity number does not exist
- Personal details verification confirms the person is deceased
- Bank account verification finds the account does not exist or is closed
- Sanctions screening confirms a match against a watchlist
- ORMS analyst rejects a flagged case after manual review
- Identity information does not match official records
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Verification Details**: Verification type, internal ID, and external request token
- **Provider Information**: The provider that performed the verification
- **Failure Details**: Failure reason, code, and additional details explaining the failure
- **Party Reference**: The CIS party ID that was verified
## Failure Reasons
| Reason | Description |
|--------|-------------|
| `ID_NOT_FOUND` | The identity number does not exist in official records |
| `PERSON_DECEASED` | The person associated with the ID is marked as deceased |
| `NAME_MISMATCH` | The provided name does not match official records |
| `ACCOUNT_NOT_FOUND` | The bank account does not exist |
| `ACCOUNT_CLOSED` | The bank account has been closed |
| `SANCTIONS_MATCH` | Party matches a sanctions or watchlist entry |
| `ANALYST_REJECTED` | ORMS analyst rejected the case |
## Downstream Consumers
Systems that typically consume this event include:
- Policy Service (to mark verification as failed)
- Customer Onboarding (to halt or reject application)
- Compliance Systems (to log failed verification and reason)
- Fraud Detection Systems (for pattern analysis)
- Customer Communication (to notify of verification issues)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "VerificationHardFailEventV1",
"title": "VerificationHardFailEventV1",
"description": "Event emitted when a verification is completed with a hard fail. This is a JSON Schema representation of the Avro schema used in production (namespace: sft.pas.verification.cg.events.verificationhardfailevent.avro).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.verification.cg.events.verificationhardfailevent.avro",
"x-avro-registry": "sft-capstone-verification-cg-event-stream-registry",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"verificationType",
"requestExternalToken",
"internalId",
"requestTo",
"partyId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation ID to link this event to the originating command"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event (e.g., VERIFICATION_HARD_FAIL_EVENT)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"x-avro-type": "enum",
"x-avro-enum-name": "AvroVerificationType",
"description": "Type of verification that failed"
},
"requestExternalToken": {
"type": "string",
"description": "The id of the external request made to the provider"
},
"internalId": {
"type": "string",
"description": "The id of the command received by the command gateway"
},
"requestTo": {
"type": "string",
"description": "The provider to whom the request was made"
},
"failureReason": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The reason for the failure"
},
"failureCode": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The failure code received (if any)"
},
"failureDetails": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Extra failure details (if any)"
},
"partyId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The CIS identifier for party who was being verified"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"x-avro-type": "map",
"default": {},
"description": "Additional data specific to the verification request"
}
}
}
---
id: VerificationSoftFailEventV1
name: Verification Soft Fail Event
version: 0.0.1
summary: Event emitted when a verification fails with a retryable error.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Soft Fail
backgroundColor: orange
textColor: black
---
## Overview
The `VerificationSoftFailEventV1` event is emitted by the Verification Service when a party verification fails due to a temporary or resolvable issue. Soft failures indicate problems that may be resolved by retrying or correcting input data.
## When is this event emitted?
This event is published when:
- External provider service is temporarily unavailable
- Request timeout occurs when calling the provider
- Provider returns an unexpected or malformed response
- Rate limiting is applied by the external provider
- Data quality issues that can be corrected (e.g., formatting)
- Network connectivity issues during the verification call
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Verification Details**: Verification type, internal ID, and external request token
- **Provider Information**: The provider to whom the request was made
- **Failure Details**: Failure reason, code, and additional details
- **Party Reference**: The CIS party ID that was being verified
## Difference from Hard Fail
| Soft Fail | Hard Fail |
|-----------|-----------|
| Temporary issues | Permanent failures |
| Can be retried | Should not retry |
| May succeed later | Will always fail |
| Infrastructure problems | Data validation failures |
## Failure Reasons
| Reason | Description |
|--------|-------------|
| `PROVIDER_TIMEOUT` | Request to provider timed out |
| `PROVIDER_UNAVAILABLE` | Provider service is down |
| `INVALID_RESPONSE` | Provider returned unexpected response |
| `RATE_LIMITED` | Too many requests to provider |
| `NETWORK_ERROR` | Network connectivity issue |
| `DATA_FORMAT_ERROR` | Input data format issue |
## Downstream Consumers
Systems that typically consume this event include:
- Retry Mechanism (to schedule verification retry)
- Policy Service (to update verification status as pending)
- Monitoring Systems (to track provider health)
- Operations Dashboard (to alert on systematic failures)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "VerificationSoftFailEventV1",
"title": "VerificationSoftFailEventV1",
"description": "Event emitted when a verification is completed with a soft fail. This is a JSON Schema representation of the Avro schema used in production (namespace: sft.pas.verification.cg.events.verificationsoftfailevent.avro).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.verification.cg.events.verificationsoftfailevent.avro",
"x-avro-registry": "sft-capstone-verification-cg-event-stream-registry",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"verificationType",
"requestExternalToken",
"internalId",
"requestTo",
"partyId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation ID to link this event to the originating command"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event (e.g., VERIFICATION_SOFT_FAIL_EVENT)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"x-avro-type": "enum",
"x-avro-enum-name": "AvroVerificationType",
"description": "Type of verification that soft-failed"
},
"requestExternalToken": {
"type": "string",
"description": "The id of the external request made to the provider"
},
"internalId": {
"type": "string",
"description": "The id of the command received by the command gateway"
},
"requestTo": {
"type": "string",
"description": "The provider to whom the request was made"
},
"failureReason": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The reason for the failure"
},
"failureCode": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "The failure code received (if any)"
},
"failureDetails": {
"type": ["null", "string"],
"x-avro-type": "union",
"description": "Extra failure details (if any)"
},
"partyId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The CIS identifier for party who was being verified"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"x-avro-type": "map",
"default": {},
"description": "Additional data specific to the verification request"
}
}
}
---
id: VerificationSucceededEventV1
name: Verification Succeeded Event
version: 0.0.1
summary: Event emitted when a verification is completed successfully.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Success
backgroundColor: green
textColor: white
---
## Overview
The `VerificationSucceededEventV1` event is emitted by the Verification Service when a party verification completes successfully. This indicates that the external provider confirmed the party's information is valid.
## When is this event emitted?
This event is published when:
- Personal details verification (VOPD) confirms identity is valid and person is not deceased
- Bank account verification confirms the account exists and matches the party
- Sanctions screening returns a clear result with no watchlist matches
- ORMS analyst approves a flagged case after manual review
## Key Information
The event payload includes:
- **Event Metadata**: Event ID, correlation ID, timestamps for noticed and effected dates
- **Verification Details**: Verification type, internal ID, and external request token
- **Provider Information**: The provider that performed the verification
- **Party Reference**: The CIS party ID that was verified
- **Request Metadata**: Original metadata from the verification request
## Downstream Consumers
Systems that typically consume this event include:
- Policy Service (to update verification status on policies)
- Customer Onboarding (to proceed with application)
- Compliance Systems (to log successful verification)
- Reporting and Analytics platforms
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "VerificationSucceededEventV1",
"title": "VerificationSucceededEventV1",
"description": "Event emitted when a verification is completed successfully. This is a JSON Schema representation of the Avro schema used in production (namespace: sft.pas.verification.cg.events.verificationsucceededevent.avro).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.verification.cg.events.verificationsucceededevent.avro",
"x-avro-registry": "sft-capstone-verification-cg-event-stream-registry",
"type": "object",
"required": [
"id",
"correlationId",
"noticedDate",
"effectedDate",
"detailType",
"logicalClockReading",
"requestExternalToken",
"internalId",
"requestTo",
"verificationType",
"partyId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the event (UUID as string)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Correlation ID to link this event to the originating command"
},
"noticedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event was noticed (milliseconds since epoch)"
},
"effectedDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the event took effect (milliseconds since epoch)"
},
"detailType": {
"type": "string",
"description": "Type of the event (e.g., VERIFICATION_SUCCEEDED_EVENT)"
},
"logicalClockReading": {
"type": "integer",
"description": "Logical clock reading for event ordering"
},
"requestExternalToken": {
"type": "string",
"description": "The id of the external request made to the provider"
},
"internalId": {
"type": "string",
"description": "The id of the command received by the command gateway"
},
"requestTo": {
"type": "string",
"description": "The provider to whom the request was made"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"x-avro-type": "enum",
"x-avro-enum-name": "AvroVerificationType",
"description": "Type of verification that succeeded"
},
"partyId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The CIS identifier for party who was being verified"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"x-avro-type": "map",
"default": {},
"description": "Additional data specific to the verification request"
}
}
}
---
id: AcceptQuote
name: Accept Quote
version: 0.0.1
summary: Command to accept a quote, moving it to the accepted state.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Accept Quote command marks a quote as accepted by the customer, indicating they wish to proceed with the insurance purchase.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to accept |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AcceptQuote",
"type": "object",
"title": "AcceptQuote",
"description": "Command to accept a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote to accept"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId"]
}
---
id: AddBeneficiary
name: Add Beneficiary
version: 0.0.1
summary: Command to add a beneficiary to a product on a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Add Beneficiary command adds a beneficiary to a specific product on a quote. Beneficiaries are individuals who will receive benefits from the insurance policy.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to add the beneficiary to |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `productInstanceId` | UUID | Yes | The product instance to add the beneficiary to |
| `name` | String | Yes | Beneficiary's first name |
| `surname` | String | Yes | Beneficiary's surname |
| `dateOfBirth` | Date | Yes | Beneficiary's date of birth |
| `gender` | String | Yes | Beneficiary's gender |
| `identification` | Object | Yes | Beneficiary's identification details |
| `percentageAllocation` | Number | Yes | Percentage of benefit allocated to this beneficiary |
| `mobileNumber` | String | No | Beneficiary's mobile number |
| `emailAddress` | String | No | Beneficiary's email address |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AddBeneficiary",
"type": "object",
"title": "AddBeneficiary",
"description": "Command to add a beneficiary to a product on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the product instance"
},
"name": {
"type": "string",
"description": "The beneficiary's first name"
},
"surname": {
"type": "string",
"description": "The beneficiary's surname"
},
"dateOfBirth": {
"type": "string",
"format": "date",
"description": "The beneficiary's date of birth"
},
"gender": {
"type": "string",
"enum": ["MALE", "FEMALE"],
"description": "The beneficiary's gender"
},
"identification": {
"type": "object",
"description": "The beneficiary's identification details",
"properties": {
"type": {
"type": "string",
"description": "The type of identification"
},
"number": {
"type": "string",
"description": "The identification number"
}
}
},
"percentageAllocation": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "The percentage of benefit allocated to this beneficiary"
},
"mobileNumber": {
"type": "string",
"description": "The beneficiary's mobile number"
},
"emailAddress": {
"type": "string",
"format": "email",
"description": "The beneficiary's email address"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "productInstanceId", "name", "surname", "dateOfBirth", "gender", "identification", "percentageAllocation"]
}
---
id: AddBeneficiaryToPolicy
name: Add Beneficiary To Policy
version: 0.0.1
summary: Add a beneficiary to an existing policy
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Adds a new beneficiary to an existing active policy. The beneficiary will be entitled to receive the policy benefits upon the occurrence of a covered event.
## HTTP Endpoint
```
POST /v1/policy/beneficiary
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: AddBeneficiaryToQuote
name: Add Beneficiary To Quote
version: 0.0.1
summary: Add a beneficiary to a quote
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Adds a beneficiary to an in-progress quote. Beneficiaries added at the quote stage will be carried forward to the policy upon acceptance.
## HTTP Endpoint
```
POST /v1/quote/beneficiary
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: AddMainProductAndPolicyholderMacro
name: Add Main Product And Policyholder Macro
version: 0.0.1
summary: Macro command that adds the main product and captures policyholder details in a single atomic operation.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Macro
backgroundColor: red
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Add Main Product And Policyholder Macro command is a composite (macro) command that adds the main insurance product to a quote and captures the policyholder's personal details in a single atomic operation. This ensures the main product and policyholder data are always captured together consistently.
## Purpose
This macro command combines:
- Adding the main product to the quote (AddProductToQuoteCommand)
- Capturing policyholder details (CapturePolicyHolderDetailsCommand)
By executing these together as a macro, the system prevents partial state where a product exists without associated policyholder information.
## Macro Command Pattern
This command extends `QuoteMacroCommand` and contains a `commands` list of `QuoteCommand` sub-commands. The `quoteId` at the macro level identifies which quote is being operated on.
## Request
### Key Fields
- **quoteId**: The quote to add the product and policyholder to
- **commands**: List of sub-commands (AddProductToQuoteCommand, CapturePolicyHolderDetailsCommand) executed as part of this macro
- **id**: The macro command identifier
- **createdDate**: The command creation timestamp
- **createdBy**: The user or system issuing the macro command
## Response
Upon successful execution, the main product and policyholder details are added to the quote aggregate.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AddMainProductAndPolicyholderMacro",
"type": "object",
"title": "AddMainProductAndPolicyholderMacro",
"description": "Macro command that adds the main product and captures policyholder details in a single atomic operation.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The macro command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"commands": {
"type": "array",
"items": {
"type": "object"
},
"description": "List of sub-commands (AddProductToQuoteCommand, CapturePolicyHolderDetailsCommand) executed as part of this macro"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"commands"
]
}
---
id: AddOptionalBenefit
name: Add Optional Benefit
version: 0.0.1
summary: Command to add an optional benefit to a product on a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Add Optional Benefit command adds an optional benefit or rider to a specific product on a quote. Optional benefits provide additional coverage beyond the base product.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to add the benefit to |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `benefitId` | UUID | Yes | The benefit to add |
| `partnerId` | UUID | Yes | The partner identifier |
| `packageId` | UUID | Yes | The package identifier |
| `productId` | UUID | Yes | The product the benefit is for |
| `productInstanceId` | UUID | Yes | The product instance on the quote |
| `startDate` | ISO 8601 | No | When the benefit starts |
| `endDate` | ISO 8601 | No | When the benefit ends |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AddOptionalBenefit",
"type": "object",
"title": "AddOptionalBenefit",
"description": "Command to add an optional benefit to a product on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"benefitId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the benefit to add"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "The partner identifier"
},
"packageId": {
"type": "string",
"format": "uuid",
"description": "The package identifier"
},
"productId": {
"type": "string",
"format": "uuid",
"description": "The product the benefit is for"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The product instance on the quote"
},
"startDate": {
"type": "string",
"format": "date-time",
"description": "When the benefit starts"
},
"endDate": {
"type": "string",
"format": "date-time",
"description": "When the benefit ends"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "benefitId", "partnerId", "packageId", "productId", "productInstanceId"]
}
---
id: AddOptionalBenefitToAllProducts
name: Add Optional Benefit To All Products
version: 0.0.1
summary: Command to add an optional benefit to all products on a quote simultaneously.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Add Optional Benefit To All Products command adds an optional benefit to every product currently on a quote in a single operation. This is used when a benefit applies across all products (e.g., a global rider or supplementary benefit) rather than to a specific product instance.
## Purpose
This command:
- Applies an optional benefit to all products on the quote
- Supports start and end date boundaries for the benefit period
- Provides the partner and package context for benefit validation
## Difference from AddOptionalBenefit
Unlike `AddOptionalBenefit` which targets a specific product instance, this command applies the benefit to all product instances on the quote simultaneously.
## Request
### Key Fields
- **quoteId**: The quote on which the benefit is being added
- **benefitId**: The identifier of the optional benefit to add
- **partnerId**: The partner that owns the benefit configuration
- **packageId**: The partner package context
- **startDate**: The date from which the benefit takes effect
- **endDate**: The date on which the benefit expires
- **correlationId**: Correlation identifier for tracking related operations
## Response
Upon successful execution, the optional benefit is added to all product instances on the quote.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AddOptionalBenefitToAllProducts",
"type": "object",
"title": "AddOptionalBenefitToAllProducts",
"description": "Command to add an optional benefit to all products on a quote simultaneously.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"benefitId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the optional benefit to add"
},
"partnerId": {
"type": "string",
"description": "The identifier of the partner"
},
"packageId": {
"type": "string",
"description": "The identifier of the partner package"
},
"startDate": {
"type": "string",
"format": "date-time",
"description": "The date from which the benefit takes effect"
},
"endDate": {
"type": "string",
"format": "date-time",
"description": "The date on which the benefit expires"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"benefitId",
"partnerId",
"packageId",
"startDate",
"endDate"
]
}
---
id: AddProductToQuote
name: Add Product To Quote
version: 0.0.1
summary: Command to add an insurance product to a quote with pricing calculation.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Add Product To Quote command adds an insurance product to an existing quote. This triggers pricing calculation based on the product configuration and risk factors.
## Purpose
This command:
- Adds a product from the partner package to the quote
- Captures product life information (main life, spouse, child, etc.)
- Triggers premium calculation via the pricing engine
- Creates tranches for the product coverage
## Request
### Key Fields
- **quoteId**: The quote to add the product to
- **partnerId**: The partner that owns the package configuration
- **packageId**: The partner package containing the product
- **productId**: The product definition from the partner package
- **productInstanceId**: The specific product instance on the quote
- **productCategoryId**: The product category identifier
- **quoteProductLife**: Information about the person being covered
- **futureCover**: Desired cover amount (if applicable)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AddProductToQuote",
"type": "object",
"title": "AddProductToQuote",
"description": "Command to add a product to a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"partnerId": {
"type": "string",
"description": "The identifier of the partner"
},
"packageId": {
"type": "string",
"description": "The identifier of the partner package"
},
"productId": {
"type": "string",
"description": "The identifier of the product to add"
},
"productInstanceId": {
"type": "string",
"description": "The identifier of the product instance"
},
"productCategoryId": {
"type": "string",
"description": "The identifier of the product category"
},
"quoteProductLife": {
"type": "object",
"description": "Information about the covered life"
},
"futureCover": {
"type": "object",
"description": "The desired cover amount"
},
"futurePremium": {
"type": "object",
"description": "The calculated or provided premium amount"
},
"replacementCoverDetail": {
"type": "object",
"description": "Replacement cover detail, if applicable"
},
"pricingConfigVersion": {
"type": "integer",
"description": "Pricing configuration version used for calculations"
},
"productTerm": {
"type": "object",
"description": "The temporal interval for the product term"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"partnerId",
"packageId",
"productId",
"productInstanceId",
"productCategoryId",
"quoteProductLife"
]
}
---
id: AddResumeLinkToQuote
name: Add Resume Link To Quote
version: 0.0.1
summary: Command to add a resume link to a quote for later continuation.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Add Resume Link To Quote command adds a URL that allows customers to resume their quote process at a later time. This is useful when customers need to gather additional information or want to complete the quote later.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to add the resume link to |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `resumeQuoteLink` | String | Yes | The URL link to resume the quote |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AddResumeLinkToQuote",
"type": "object",
"title": "AddResumeLinkToQuote",
"description": "Command to add a resume link to a quote for later continuation.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"resumeQuoteLink": {
"type": "string",
"format": "uri",
"description": "The URL link to resume the quote"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "resumeQuoteLink"]
}
---
id: AddVerificationToPolicy
name: Add Verification to Policy
version: 0.0.1
summary: Command to add a verification record to a funeral policy, tracking verification outcomes for personal details, bank details, or sanctions screening.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Verification
backgroundColor: indigo
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The AddVerificationToPolicy command is used to record verification results against a policy. This is a critical compliance and risk management function that tracks the outcome of various verification checks performed during the policy lifecycle.
### Verification Workflow
The verification process involves several key steps:
1. **Verification Request**: A verification request is initiated, specifying the type of verification and the target entity (main life, covered life, or beneficiary).
2. **External Processing**: The verification is processed by an external service or system, generating an external token for tracking.
3. **Outcome Recording**: This command captures the verification outcome and associates it with the policy.
4. **Compliance Tracking**: The verification record becomes part of the policy's compliance history.
### Verification Types
- **VERIFICATION_OF_PERSONAL_DETAILS**: Identity verification of personal information
- **VERIFICATION_OF_BANK_DETAILS**: Bank account verification for premium collection
- **SANCTIONS_SCREENING**: Regulatory sanctions list screening
### Verification Outcomes
- **SUCCEEDED**: Verification passed successfully
- **HARD_FAIL**: Verification failed definitively, may block policy progression
- **SOFT_FAIL**: Verification failed but may allow manual override
- **SYSTEM_OUTAGE**: Verification could not be completed due to system issues
### Verification Stages
Verifications can occur at different stages of the policy lifecycle:
- **QUOTE**: During the quotation phase
- **POLICY_ACTIVE**: On an active policy
- **POLICY_ALTERATION**: During policy changes or amendments
- **CLAIM**: During claims processing
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"createdDate": "2024-07-15T10:30:00Z",
"createdBy": "verification-service",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"partnerId": "456e7891-c23d-45f6-b78a-123456789abc",
"verificationDate": "2024-07-15T10:28:00Z",
"verificationType": "VERIFICATION_OF_PERSONAL_DETAILS",
"verificationRequestBy": "onboarding-service",
"verificationRequestTo": "id-verification-provider",
"verificationRequestExternalToken": "ext-token-abc123",
"verificationRequestOutcome": "SUCCEEDED",
"verificationOn": "MAIN_LIFE",
"verificationInternalId": "def45678-90ab-cdef-1234-567890abcdef",
"verificationStage": "POLICY_ACTIVE"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "AddVerificationToPolicyCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The timestamp when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user or system that created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy to which verification is being added."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking related operations across services."
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the partner associated with the policy."
},
"verificationDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the verification was performed."
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"description": "The type of verification being performed."
},
"verificationRequestBy": {
"type": "string",
"description": "The entity or user who requested the verification."
},
"verificationRequestTo": {
"type": "string",
"description": "The target entity or service to which the verification request was sent."
},
"verificationRequestExternalToken": {
"type": "string",
"description": "An external token associated with the verification request for tracking purposes."
},
"verificationRequestOutcome": {
"type": "string",
"enum": [
"SUCCEEDED",
"HARD_FAIL",
"SOFT_FAIL",
"SYSTEM_OUTAGE"
],
"description": "The outcome of the verification request."
},
"verificationOn": {
"type": "string",
"enum": [
"MAIN_LIFE",
"COVERED_LIFE",
"BENEFICIARY",
"APPROVED",
"FINALISED"
],
"description": "The entity on which the verification is performed."
},
"verificationInternalId": {
"type": "string",
"format": "uuid",
"description": "The internal identifier for the verification record."
},
"verificationStage": {
"type": "string",
"enum": [
"QUOTE",
"POLICY_ACTIVE",
"POLICY_ALTERATION",
"CLAIM"
],
"description": "The stage of the policy lifecycle at which verification occurs."
}
},
"required": [
"id",
"createdDate",
"createdBy",
"policyId",
"correlationId",
"partnerId",
"verificationDate",
"verificationType",
"verificationRequestOutcome",
"verificationOn",
"verificationInternalId",
"verificationStage"
],
"additionalProperties": false
}
---
id: AddVerificationToQuote
name: Add Verification To Quote
version: 0.0.1
summary: Command to add a verification record to a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Add Verification To Quote command records verification results on a quote. This includes identity verification, bank verification, and other compliance checks performed during the quote process.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to add verification to |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `partnerId` | UUID | Yes | The partner performing the verification |
| `verificationDate` | ISO 8601 | Yes | When the verification was performed |
| `verificationType` | String | Yes | Type of verification |
| `verificationRequestBy` | String | Yes | Who requested the verification |
| `verificationRequestTo` | String | Yes | Who the verification was sent to |
| `verificationRequestExternalToken` | String | No | External token for the verification |
| `verificationRequestOutcome` | String | Yes | Outcome of the verification |
| `verificationOn` | String | Yes | What entity was verified |
| `verificationInternalId` | UUID | No | Internal verification identifier |
| `verificationStage` | String | Yes | Stage of the verification process |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AddVerificationToQuote",
"type": "object",
"title": "AddVerificationToQuote",
"description": "Command to add a verification record to a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "The partner performing the verification"
},
"verificationDate": {
"type": "string",
"format": "date-time",
"description": "When the verification was performed"
},
"verificationType": {
"type": "string",
"description": "Type of verification"
},
"verificationRequestBy": {
"type": "string",
"description": "Who requested the verification"
},
"verificationRequestTo": {
"type": "string",
"description": "Who the verification was sent to"
},
"verificationRequestExternalToken": {
"type": "string",
"description": "External token for the verification"
},
"verificationRequestOutcome": {
"type": "string",
"description": "Outcome of the verification"
},
"verificationOn": {
"type": "string",
"description": "What entity was verified"
},
"verificationInternalId": {
"type": "string",
"format": "uuid",
"description": "Internal verification identifier"
},
"verificationStage": {
"type": "string",
"description": "Stage of the verification process"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "partnerId", "verificationDate", "verificationType", "verificationRequestBy", "verificationRequestTo", "verificationRequestOutcome", "verificationOn", "verificationStage"]
}
---
id: ApplyCoverEscalation
name: Apply Cover Escalation
version: 0.0.1
summary: Command to apply cover escalation to a funeral policy, increasing the cover amount based on escalation rules.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Cover
backgroundColor: teal
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The ApplyCoverEscalation command triggers the annual or periodic escalation of cover amounts on a funeral policy. Cover escalation is a mechanism that increases the insured benefit amount over time, typically to keep pace with inflation or cost-of-living adjustments.
### Key Concepts
- **Cover Escalation**: An automatic or triggered increase in the policy's cover amount, ensuring the death benefit maintains its real value over time.
- **Policy Lifecycle**: This command is typically executed during policy anniversary periods or as defined by the product rules.
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"createdDate": "2024-03-15T10:30:00Z",
"createdBy": "system-scheduler",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ApplyCoverEscalationCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy to apply cover escalation."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId"],
"additionalProperties": false
}
---
id: ApplyPremiumEscalation
name: Apply Premium Escalation
version: 0.0.1
summary: Command to apply premium escalation to a funeral policy, adjusting premium amounts based on escalation rules.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Cover
backgroundColor: teal
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The ApplyPremiumEscalation command triggers the annual or periodic escalation of premium amounts on a funeral policy. Premium escalation adjusts the monthly or periodic payment amounts, typically in conjunction with cover escalation to maintain the policy's value proposition.
### Key Concepts
- **Premium Escalation**: An increase in the policy's premium amount, often linked to cover escalation or based on predefined escalation percentages.
- **Escalation Relationship**: Premium escalation is commonly paired with cover escalation - when cover increases, premiums typically increase proportionally.
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"createdDate": "2024-03-15T10:30:00Z",
"createdBy": "system-scheduler",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ApplyPremiumEscalationCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy to apply premium escalation."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId"],
"additionalProperties": false
}
---
id: ArchiveFile
name: Archive File
version: 0.0.1
summary: Command to archive a file for long-term storage
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Archive File command is used to move a file to archived status for long-term storage. Archived files are typically moved to a more cost-effective storage tier.
## Purpose
This command allows file archival by providing:
- The file identifier to archive
- Audit information (who archived and when)
- Correlation ID for tracking
## Request
The command requires the file identifier and standard command metadata.
### Key Fields
- **fileId**: Unique identifier of the file to archive
- **createdBy**: User or system initiating the archival
- **createdDate**: Timestamp of the archival request
- **correlationId**: Correlation ID for tracking
## Response
Upon successful execution, the command:
1. Sets the file's `isArchived` flag to true
2. Records the `archivedAt` timestamp
3. May trigger storage tier migration
## Constraints
- File must exist in the system
- File must not already be archived
- Archive timestamp must not be in the future
## Scheduled Archival
Files can be scheduled for automatic archival by setting the `archiveAt` field during upload. A scheduler process will archive files when their scheduled time arrives.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "ArchiveFileCommand",
"title": "ArchiveFileCommand",
"description": "Command to archive a file for long-term storage. Wire format: JSON (REST API)",
"x-schema-format": "json",
"type": "object",
"required": [
"id",
"createdDate",
"createdBy",
"fileId",
"correlationId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the command"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the command was created"
},
"createdBy": {
"type": "string",
"description": "User or system that created the command"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier of the file to archive"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking"
}
}
}
---
id: AssessorResponse
name: Assessor Response
version: 0.0.1
summary: Submit an assessor's response to a claim (ASCP-specific workflow)
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: ASCP
backgroundColor: teal
textColor: white
---
## Overview
Submits an assessor's response to a claim as part of the ASCP (Agent Sales and Claims Portal) specific claims assessment workflow. The response includes the assessor's decision and supporting notes.
## HTTP Endpoint
```
POST /api/v1/claims/{claimId}/assessor-response
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: CalculateClaimPayout
name: Calculate Claim Payout
version: 0.0.1
summary: Calculate the payout amount for a claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Triggers a calculation of the payout amount for an existing claim. This command evaluates policy benefits, applicable covers, and claim details to determine the final payout figure.
## HTTP Endpoint
```
POST /v1/claims/calculate-claim-payout
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: CalculateClaimPayoutCommand
name: Calculate Claim Payout
version: 0.0.1
summary: Command to calculate the payout amount for an approved claim.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Financial
backgroundColor: green
textColor: white
---
## Overview
The Calculate Claim Payout command calculates the payout amount for a claim based on the policy terms, cover amounts, and applicable deductions. This command enriches the claim with policy data to determine the correct payout.
## Key Fields
- **claimId**: The claim to calculate payout for
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim with the calculated payout amount. Uses the `CalculateClaimPayoutCommandEnrichmentService` to fetch policy details for the calculation.
---
id: CancelPolicy
name: Cancel Policy
version: 0.0.1
summary: Command to cancel an active funeral policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Cancel Policy command is used to cancel an active funeral policy. This command handles various cancellation scenarios including client-requested cancellations, non-payment cancellations, cooling-off period cancellations, and administrative cancellations.
## Purpose
When a policy needs to be cancelled, this command:
- Terminates the policy effective from the cancellation date
- Updates the policy status to cancelled with the appropriate sub-status
- Stops all future collection activities
- Initiates refund processing if applicable
- Triggers downstream events for reporting and reconciliation
## Request
The command requires the policy identifier, cancellation date, and the cancellation sub-status to process the cancellation.
### Key Fields
- **policyId**: The identifier of the policy to be cancelled
- **cancellationDate**: The effective date of the cancellation
- **cancellationSubStatus**: The category of cancellation (e.g., CLIENT_REQUESTED, NON_PAYMENT, COOLING_OFF)
- **cancellationReason**: A detailed description explaining why the policy is being cancelled
- **requesteeOrigin**: Where the cancellation request originated from
- **clientBankingDetails**: Banking details for processing any refunds (if applicable)
## Response
Upon successful execution, the command cancels the policy and emits relevant domain events for downstream systems including collections, reporting, and customer communications.
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "CancelPolicy",
"type": "object",
"title": "CancelPolicy",
"description": "Command to cancel an active funeral policy. This command handles policy cancellation scenarios including client-requested cancellations, non-payment cancellations, and administrative cancellations.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy to cancel"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracking related operations"
},
"cancellationDate": {
"type": "string",
"format": "date-time",
"description": "The date on which the policy cancellation takes effect"
},
"cancellationSubStatus": {
"type": "string",
"description": "The sub-status indicating the specific cancellation reason category (e.g., CLIENT_REQUESTED, NON_PAYMENT, FRAUD)",
"enum": [
"CLIENT_REQUESTED",
"NON_PAYMENT",
"FRAUD",
"DECEASED",
"DUPLICATE_POLICY",
"ADMINISTRATIVE",
"COOLING_OFF"
]
},
"cancellationReason": {
"type": "string",
"description": "A detailed description of the reason for cancellation"
},
"requesteeOrigin": {
"type": "string",
"description": "The origin of the cancellation request indicating whether initiated by the system, client service portal, self-service portal, etc.",
"enum": [
"SYSTEM",
"CLIENT_SERVICE_PORTAL",
"SELF_SERVICE_PORTAL",
"API",
"BATCH_PROCESS"
]
},
"clientBankingDetails": {
"type": "object",
"description": "The client banking details for processing any refunds",
"properties": {
"bankName": {
"type": "string",
"description": "The name of the bank"
},
"accountNumber": {
"type": "string",
"description": "The bank account number"
},
"branchCode": {
"type": "string",
"description": "The bank branch code"
},
"accountType": {
"type": "string",
"description": "The type of bank account"
}
}
}
},
"required": ["id", "policyId", "cancellationDate", "cancellationSubStatus"]
}
---
id: CancelQuote
name: Cancel Quote
version: 0.0.1
summary: Command to cancel an active quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Cancel Quote command marks a quote as cancelled, ending its lifecycle before finalisation.
> **Note — No Lambda Handler:** `CancelQuoteCommand` exists in the Quote domain but currently has **no Lambda handler** implementation. This means the command cannot be triggered via an HTTP endpoint. The domain logic is implemented but the infrastructure entry point is missing. See the infrastructure layer for the gap.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to cancel |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CancelQuote",
"type": "object",
"title": "CancelQuote",
"description": "Command to cancel a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote to cancel"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId"]
}
---
id: CaptureClaimant
name: Capture Claimant
version: 0.0.1
summary: Capture claimant details on a claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Captures the personal and contact details of the claimant (the person submitting the claim) on an existing claim record. This information is used for communication and payout purposes.
## HTTP Endpoint
```
POST /v1/claims/claimant
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: CaptureClaimantBankingDetailsCommand
name: Capture Claimant Banking Details
version: 0.0.1
summary: Command to capture the claimant's banking details for payout.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Financial
backgroundColor: green
textColor: white
---
## Overview
The Capture Claimant Banking Details command records the claimant's banking information required for processing the claim payout.
## Key Fields
- **claimId**: The claim to capture banking details for
- **bankingDetails**: Bank name, account number, account type, branch code
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim with banking details and emits a `ClaimUpdatedEventV1` with detail type `claimantBankingDetailsCaptured`.
---
id: CaptureClaimantCommand
name: Capture Claimant
version: 0.0.1
summary: Command to capture the claimant's personal details on a claim.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Capture Claimant command records the personal details of the person making the claim. This includes identity information, contact details, and relationship to the deceased.
## Key Fields
- **claimId**: The claim to capture claimant details for
- **claimantDetails**: Personal details of the claimant (name, ID number, contact info, relationship)
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim with claimant details and emits a `ClaimUpdatedEventV1` with detail type `claimantCaptured`.
---
id: CaptureCollectionDetails
name: Capture Collection Details
version: 0.0.1
summary: Command to capture premium collection details for a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Capture Collection Details command records the banking and payment collection information for a quote. This includes bank account details, collection frequency, and payment method.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to capture collection details for |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `isThirdPartyPayer` | Boolean | No | Whether a third party is paying |
| `thirdPartyPayerInfo` | String | No | Third party payer information |
| `thirdPartyPaymentReference` | String | No | Third party payment reference |
| `bankAccountName` | String | No | Name on the bank account |
| `bankName` | String | No | Name of the bank |
| `bankAccountNumber` | String | No | Bank account number |
| `bankBranch` | String | No | Bank branch code |
| `bankAccountType` | String | No | Type of bank account |
| `collectionFrequency` | String | No | How often premiums are collected |
| `collectionDaySelected` | Integer | No | Day of month for collection |
| `collectionMethod` | String | No | Method of collection |
| `collectionProvider` | String | No | Collection service provider |
| `billingId` | String | No | Billing identifier |
| `sourceOfFunds` | String | No | Source of funds for payments |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CaptureCollectionDetails",
"type": "object",
"title": "CaptureCollectionDetails",
"description": "Command to capture premium collection details for a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"isThirdPartyPayer": {
"type": "boolean",
"description": "Whether a third party is paying"
},
"thirdPartyPayerInfo": {
"type": "string",
"description": "Third party payer information"
},
"thirdPartyPaymentReference": {
"type": "string",
"description": "Third party payment reference"
},
"bankAccountName": {
"type": "string",
"description": "Name on the bank account"
},
"bankName": {
"type": "string",
"description": "Name of the bank"
},
"bankAccountNumber": {
"type": "string",
"description": "Bank account number"
},
"bankBranch": {
"type": "string",
"description": "Bank branch code"
},
"bankAccountType": {
"type": "string",
"description": "Type of bank account"
},
"collectionFrequency": {
"type": "string",
"enum": ["MONTHLY", "QUARTERLY", "ANNUALLY"],
"description": "How often premiums are collected"
},
"collectionDaySelected": {
"type": "integer",
"minimum": 1,
"maximum": 31,
"description": "Day of month for collection"
},
"collectionMethod": {
"type": "string",
"description": "Method of collection"
},
"collectionProvider": {
"type": "string",
"description": "Collection service provider"
},
"billingId": {
"type": "string",
"description": "Billing identifier"
},
"sourceOfFunds": {
"type": "string",
"description": "Source of funds for payments"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId"]
}
---
id: CaptureCrmOutcomeCommand
name: Capture CRM Outcome
version: 0.0.1
summary: Command to capture CRM servicing outcomes for a claim.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Integration
backgroundColor: orange
textColor: white
---
## Overview
The Capture CRM Outcome command records the servicing outcomes from the CRM system for a claim. This includes various verification results and the CRM case number.
## Key Fields
- **claimId**: The claim to capture CRM outcome for
- **crmCaseNumber**: The CRM case reference number
- **documentsVerified**: Whether documents were verified
- **deceasedVopdOutcome**: Deceased VOPD verification outcome
- **claimantVopdOutcome**: Claimant VOPD verification outcome
- **pddOutcome**: PDD verification outcome
- **xtendOutcome**: Xtend verification outcome
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim with CRM outcomes and emits a `CrmOutcomeCapturedEventV1` with detail type `crmOutcomeCaptured`.
---
id: CaptureDeathDetails
name: Capture Death Details
version: 0.0.1
summary: Capture additional death details on a claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Captures additional death-related details on an existing claim, such as the cause of death, date of death, and supporting documentation references. This information is required for claim assessment and validation.
## HTTP Endpoint
```
PUT /v1/claims/capture-death-details
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: CaptureDeathDetailsCommand
name: Capture Death Details
version: 0.0.1
summary: Command to capture death details (date and cause of death) for a claim.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Capture Death Details command records the date and cause of death for the deceased person on the claim. This is a prerequisite for payout calculation.
## Key Fields
- **claimId**: The claim to capture death details for
- **dateOfDeath**: The date of death
- **causeOfDeath**: The cause of death
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim with death details and emits a `DeathDetailsCapturedEventV1` with detail type `claimDeathDetailsCaptured`.
---
id: CaptureDeceasedCommand
name: Capture Deceased
version: 0.0.1
summary: Command to capture the deceased person's details on a claim.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Capture Deceased command records the details of the deceased person on the claim, including their identity information and relationship to the policy.
## Key Fields
- **claimId**: The claim to capture deceased details for
- **deceasedDetails**: Details of the deceased person (name, ID number, relationship to policy)
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim with deceased details and emits a `ClaimUpdatedEventV1` with detail type `deceasedCaptured`.
---
id: CapturePolicyholder
name: Capture Policyholder
version: 0.0.1
summary: Capture policyholder details on a quote
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Captures the personal details of the policyholder on a quote. This includes identity information, contact details, and address.
## HTTP Endpoint
```
POST /api/v1/quote/capture-policyholder
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: CapturePolicyHolderDetails
name: Capture Policy Holder Details
version: 0.0.1
summary: Command to capture the policy holder's personal details on a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Capture Policy Holder Details command records the personal information of the policy holder associated with a quote. This includes contact information, identification details, and demographic data.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to capture policy holder details for |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `policyHolder` | Object | Yes | The policy holder details |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CapturePolicyHolderDetails",
"type": "object",
"title": "CapturePolicyHolderDetails",
"description": "Command to capture the policy holder's personal details on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"policyHolder": {
"type": "object",
"description": "The policy holder details",
"properties": {
"firstName": {
"type": "string",
"description": "Policy holder's first name"
},
"surname": {
"type": "string",
"description": "Policy holder's surname"
},
"dateOfBirth": {
"type": "string",
"format": "date",
"description": "Policy holder's date of birth"
},
"gender": {
"type": "string",
"description": "Policy holder's gender"
},
"identification": {
"type": "object",
"description": "Policy holder's identification"
},
"contactDetails": {
"type": "object",
"description": "Policy holder's contact details"
},
"address": {
"type": "object",
"description": "Policy holder's address"
}
}
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "policyHolder"]
}
---
id: CaptureReplacementCoverDetails
name: Capture Replacement Cover Details
version: 0.0.1
summary: Command to capture replacement cover details for a specific product instance on a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Capture Replacement Cover Details command records replacement cover information for a specific product instance on a quote. Replacement cover is used when a new policy replaces an existing one, capturing details about the policy being replaced for regulatory and underwriting purposes.
## Purpose
This command captures:
- The product instance to which the replacement cover applies
- The replacement cover details (prior policy information, lapse dates, etc.)
## Request
### Key Fields
- **quoteId**: The quote containing the product instance
- **productInstanceId**: The specific product instance receiving replacement cover details
- **replacementCoverDetail**: The replacement cover details object containing prior policy information
- **correlationId**: Correlation identifier for tracking related operations
## Response
Upon successful execution, the replacement cover details are recorded against the specified product instance on the quote.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CaptureReplacementCoverDetails",
"type": "object",
"title": "CaptureReplacementCoverDetails",
"description": "Command to capture replacement cover details for a specific product instance on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"productInstanceId": {
"type": "string",
"description": "The identifier of the product instance receiving replacement cover details"
},
"replacementCoverDetail": {
"type": "object",
"description": "The replacement cover details including prior policy information"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"productInstanceId",
"replacementCoverDetail"
]
}
---
id: CaptureSalesAgent
name: Capture Sales Agent
version: 0.0.1
summary: Command to associate a sales agent with a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Capture Sales Agent command associates a sales agent with a quote. This is used to track which agent facilitated the quote for commission and reporting purposes.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to associate with the sales agent |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `salesAgentId` | UUID | Yes | The identifier of the sales agent |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CaptureSalesAgent",
"type": "object",
"title": "CaptureSalesAgent",
"description": "Command to associate a sales agent with a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"salesAgentId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the sales agent"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "salesAgentId"]
}
---
id: ChangeQuoteStatusToConverted
name: Change Quote Status To Converted
version: 0.0.1
summary: Command to transition a quote to the converted status after a policy has been created from it.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Change Quote Status To Converted command transitions a quote to the `CONVERTED` status after a policy has been successfully created from it. This command links the quote to its resulting policy by capturing the policy code and policy identifier.
## Purpose
This command:
- Marks the quote as converted (a policy has been issued)
- Records the resulting policy code and policy identifier on the quote
- Triggers the QuoteConvertedEventV2 event for downstream consumers
## Lifecycle Position
This command is typically issued by the Policy service after successfully creating a policy from a finalised quote. It is part of the quote lifecycle transition: `FINALISED → CONVERTED`.
## Request
### Key Fields
- **quoteId**: The quote being converted
- **policyCode**: The human-readable code of the created policy
- **policyId**: The system identifier of the created policy
- **correlationId**: Correlation identifier for tracking related operations
## Response
Upon successful execution, the quote status is updated to CONVERTED and the QuoteConvertedEventV2 event is published.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "ChangeQuoteStatusToConverted",
"type": "object",
"title": "ChangeQuoteStatusToConverted",
"description": "Command to transition a quote to the converted status after a policy has been created from it.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote being converted"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"policyCode": {
"type": "string",
"description": "The human-readable code of the created policy"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The system identifier of the created policy"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"policyCode",
"policyId"
]
}
---
id: CheckPaymentBeforeGracePeriod
name: Check Payment Before Grace Period
version: 0.0.1
summary: Command to verify whether a premium payment was received before the grace period ended.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Collection
backgroundColor: green
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The CheckPaymentBeforeGracePeriod command is a scheduled check that verifies whether a premium payment was received before the grace period ended. This is a critical component of the collection workflow that determines the policy's status after the grace period expires.
### Collection Workflow
1. **Premium Due**: A premium becomes due on the premium due date.
2. **Collection Attempt**: The system attempts to collect the premium through the scheduled collection process.
3. **Grace Period**: If collection fails, the policy enters a grace period during which the policyholder can make payment.
4. **Scheduled Check**: This command is scheduled to run at or after the grace period end date.
5. **Status Determination**: The command checks if payment was received and publishes appropriate events:
- If payment received: Policy continues normally.
- If no payment: A `NoPolicyCollectionReceivedWithinGracePeriod` event is published, which may trigger lapse procedures.
### Key Concepts
- **Grace Period**: A period after the premium due date during which the policy remains active despite non-payment.
- **Premium Due Date**: The original date when the premium payment was expected.
- **Grace Period End Date**: The deadline after which the policy may lapse if no payment is received.
- **Payment Verification**: The process of checking whether a collection was successfully received for the premium period.
### Business Rules
- The command is typically scheduled at the time a collection fails or when premium becomes due.
- The grace period duration is defined by the product rules.
- If no payment is detected by the grace period end date, the policy may be subject to lapse or suspension.
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"createdDate": "2024-03-15T10:30:00Z",
"createdBy": "system-scheduler",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"premiumDueDate": "2024-03-01T00:00:00Z",
"gracePeriodEndDate": "2024-03-15T23:59:59Z"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CheckPaymentBeforeGracePeriodCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy to check payment status."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
},
"premiumDueDate": {
"type": "string",
"format": "date-time",
"description": "The due date for the premium payment being checked."
},
"gracePeriodEndDate": {
"type": "string",
"format": "date-time",
"description": "The end date of the grace period for the premium payment."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId", "premiumDueDate", "gracePeriodEndDate"],
"additionalProperties": false
}
---
id: CheckPendingOrmsDecision
name: Check Pending ORMS Decision
version: 0.0.1
summary: Command to poll ORMS for analyst decisions on flagged screening cases
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Polling
backgroundColor: orange
textColor: white
---
## Overview
The `CheckPendingOrmsDecision` command polls ORMS for analyst decisions on previously flagged sanctions screening cases. This command is used in scheduled polling workflows to retrieve decisions on cases that are pending analyst review.
## Purpose
When a party's sanctions screening requires analyst review (pending decision), this command:
- Polls ORMS service for updated decision status
- Retrieves analyst decisions on flagged cases
- Triggers resolution of pending verification workflows
- Results in final verification outcome events being published
## Request
The command requires the screening reference identifier to poll for updated decision status.
### Key Fields
- **id**: Unique identifier for this command (UUID)
- **correlationId**: Correlation ID for tracing related operations
- **screeningReference**: Reference identifier for the screening case in ORMS
- **verificationRequestId**: The original verification request that triggered the screening
### Decision Types Expected
| Decision | Description | Result Event |
|----------|-------------|--------------|
| `GO` | Screening cleared, no issues found | `VerificationSucceededEventV1` |
| `STOP` | Sanctions match found, case rejected | `VerificationHardFailEventV1` |
| `PENDING` | Still under analyst review, will re-poll | Continue polling |
## Response
The command is processed asynchronously. Outcomes are communicated through domain events:
| Outcome | Event |
|---------|-------|
| Decision resolved - GO | `VerificationSucceededEventV1` |
| Decision resolved - STOP | `VerificationHardFailEventV1` |
| Still pending | `OrmsDecisionPendingEventV1` (scheduled re-polling) |
| Decision found | `OrmsDecisionFoundEventV1` |
## Usage Example
```json
{
"id": "660f9500-f39c-52e5-b827-556766551111",
"createdDate": 1706889600000,
"createdBy": "verification-scheduler",
"correlationId": "8d0f7780-8536-478f-b919-f9e16d2ba8f8",
"screeningReference": "orms-case-12345",
"verificationRequestId": "550e8400-e29b-41d4-a716-446655440000"
}
```
## Scheduling
This command is typically invoked by a scheduler that:
- Tracks pending ORMS decisions
- Polls at regular intervals (e.g., every 30 seconds, 1 minute, or as configured)
- Stops polling once a decision is received
- Implements exponential backoff for resilience
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CheckPendingOrmsDecisionCommandV1",
"title": "CheckPendingOrmsDecisionCommandV1",
"description": "Command to poll ORMS for analyst decisions on flagged screening cases. This is a JSON Schema representation of the Avro schema used in production (namespace: sft.pas.verification.cg.commands.checkpendingormsdecisioncommand.avro).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.verification.cg.commands.checkpendingormsdecisioncommand.avro",
"x-avro-registry": "sft-capstone-verification-cg-commands-registry",
"type": "object",
"required": [
"id",
"createdDate",
"createdBy",
"correlationId",
"screeningReference",
"verificationRequestId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the command (UUID as string)"
},
"createdDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the command was created (milliseconds since epoch)"
},
"createdBy": {
"type": "string",
"description": "Identifier of the creator of the command (typically the scheduler)"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The correlationId of the command (UUID as string)"
},
"screeningReference": {
"type": "string",
"description": "Reference identifier for the screening case in ORMS system"
},
"verificationRequestId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The UUID of the original verification request that triggered the screening"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"x-avro-type": "map",
"default": {},
"description": "Additional context data for decision polling"
}
}
}
---
id: CollectPremium
name: Collect Premium
version: 0.0.1
summary: Command to initiate the premium collection process for a policy based on its financial status and conditions.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Collection
backgroundColor: green
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The CollectPremium command initiates the collection process for a specific policy. This command contains all the necessary information required to perform the collection, including the unique identifier of the policy and the collection date.
### Collection Workflow
1. **Trigger**: The command is typically dispatched via a scheduler or event listener based on the policy's billing cycle.
2. **Evaluation**: The policy is evaluated to determine its financial status and outstanding amounts.
3. **Collection Request**: A collection request is generated based on the policy's conditions.
4. **Processing**: The collection is processed through the configured collection provider.
### Key Concepts
- **Policy Collection**: The scheduled process of collecting premium payments from policyholders.
- **Collection Date**: The effective date for the collection, used for financial reconciliation.
- **Scheduled Collection**: This command is part of the regular billing cycle, triggered automatically by the system scheduler.
## Architecture diagram
## Payload example
```json title="Payload example"
{
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"collectionDate": "2024-03-15T00:00:00Z",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "CollectPremiumCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy to collect premium from."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
},
"collectionDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the collection process was initiated."
}
},
"required": ["policyId", "collectionDate", "correlationId"],
"additionalProperties": false
}
---
id: CoveredLifeDeceased
name: Covered Life Deceased
version: 0.0.1
summary: Command to process a covered life (non-main life) that has deceased
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Covered Life Deceased command is used to process the death of a covered life on a funeral policy. Unlike the Main Life Deceased command, this handles deaths of additional covered lives (such as extended family members) rather than the primary policyholder.
## Purpose
When the death of a covered life is reported, this command:
- Records the death against the specific product life
- Initiates claim processing for the covered life benefit
- Updates the policy to reflect the change in covered lives
- Does not lapse the policy (unlike main life death)
## Key Fields
- **productInstanceId**: Identifies the specific product instance under which the covered life was insured.
- **productLifeId**: Identifies the specific covered life record within the product.
- **deathDate**: The date of death for the covered life.
- **deathType**: The type of death (e.g., natural, accidental) which may affect benefit calculations.
- **requestOrigin**: Indicates where the request originated from.
- **requestee**: The entity that made the request.
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "CoveredLifeDeceased",
"type": "object",
"title": "CoveredLifeDeceased",
"description": "Command for processing a covered life (non-main life) that has deceased on a funeral policy.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The command creator"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The policy identifier"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The product instance identifier"
},
"productLifeId": {
"type": "string",
"format": "uuid",
"description": "The product life identifier for the covered life"
},
"deathDate": {
"type": "string",
"format": "date-time",
"description": "The date of death for the covered life"
},
"deathType": {
"type": "string",
"description": "The type of death that occurred",
"enum": ["NATURAL_DEATH", "ACCIDENTAL_DEATH", "SUICIDE", "UNKNOWN"]
},
"requestOrigin": {
"type": "string",
"description": "The origin of the request"
},
"requestee": {
"type": "string",
"description": "The entity that made the request"
}
},
"required": ["id", "policyId", "productInstanceId", "productLifeId", "deathDate", "deathType"]
}
---
id: CreateClaimForCoveredLife
name: Create Claim For Covered Life
version: 0.0.1
summary: Create a death claim for a covered life
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Creates a death claim for a covered life (a dependent or additional life insured) on a policy. This command handles claims for insured lives other than the main policyholder.
## HTTP Endpoint
```
POST /v1/claims/covered-life
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: CreateClaimForCoveredLifeCommand
name: Create Claim for Covered Life
version: 0.0.1
summary: Command to create a death claim when a covered life (dependent) has died.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Create Claim for Covered Life command initiates a death claim when a covered life (dependent) on a funeral policy has died. The policy remains active for the main life while processing the dependent's claim.
## Key Fields
- **policyId**: The policy against which the claim is being made
- **coveredLifeId**: Identifier of the covered life (dependent) who has died
- **claimantDetails**: Personal details of the person making the claim
- **correlationId**: Correlation ID for tracking
## Response
Creates a new claim record and emits a `ClaimUpdatedEventV1` with detail type `claimUpdatedCoveredLife`.
---
id: CreateClaimForMainLife
name: Create Claim For Main Life
version: 0.0.1
summary: Create a death claim for the main life insured
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Creates a death claim specifically for the main life insured on a policy. This command captures the necessary details to initiate a death claim for the primary policyholder.
## HTTP Endpoint
```
POST /v1/claims/main-life
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: CreateClaimForMainLifeCommand
name: Create Claim for Main Life
version: 0.0.1
summary: Command to create a death claim when the main life (policyholder) has died.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Create Claim for Main Life command initiates a death claim when the main life (policyholder) on a funeral policy has died. This triggers policy lookup, claim creation, and downstream payout workflows.
## Key Fields
- **policyId**: The policy against which the claim is being made
- **claimantDetails**: Personal details of the person making the claim
- **correlationId**: Correlation ID for tracking the command through the system
## Response
Creates a new claim record linked to the policy and emits a `ClaimUpdatedEventV1` with detail type `claimUpdatedMainLife`.
---
id: CreateClaimRequest
name: Create Claim Request
version: 0.0.1
summary: Initiate a new claim request
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Initiates a new claim request in the system. This is the entry point for the claims process, creating the initial claim record and triggering downstream processing.
## HTTP Endpoint
```
POST /v1/claims
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: CreateClaimRequestCommand
name: Create Claim Request
version: 0.0.1
summary: Command to create an initial claim request before full claim processing.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Create Claim Request command creates an initial claim request, which serves as the entry point for the claims process. This is distinct from full claim creation and represents the initial intake step.
## Key Fields
- **policyNumber**: The policy number for the claim
- **claimantDetails**: Initial claimant information
- **correlationId**: Correlation ID for tracking
## Response
Creates a claim request record and emits a `ClaimUpdatedEventV1` with detail type `claimRequestCreated`.
---
id: CreateCollectionAccountPreferences
name: Create Collection Account Preferences
version: 0.0.1
summary: Command to create collection account preferences for a customer
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Profile
backgroundColor: cyan
textColor: black
---
## Overview
The Create Collection Account Preferences command creates collection account details for a customer profile. This includes bank account or card information used for premium payments.
## Response
On success, emits `CollectionAccountPreferencesCreatedEventV1`. On failure, emits `CollectionAccountPreferencesCreationFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateCollectionAccountPreferences",
"title": "CreateCollectionAccountPreferences",
"description": "Command to create collection account preferences for a customer.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId", "collectionAccount"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"collectionAccount": {
"type": "object",
"required": ["method"],
"properties": {
"method": { "type": "string", "description": "BANK_ACCOUNT or CARD" },
"number": { "type": "string" },
"owner": { "type": "string" },
"currency": { "type": "string" },
"country": { "type": "string" },
"bankCode": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"expirationDate": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"securityCode": { "oneOf": [{ "type": "null" }, { "type": "string" }] }
}
}
}
}
---
id: CreateCustomerIdentity
name: Create Customer Identity
version: 0.0.1
summary: Command to create a new verified customer identity with certified attributes
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Identity
backgroundColor: teal
textColor: white
---
## Overview
The Create Customer Identity command creates a new verified customer identity record with all attributes backed by trust certificates. This establishes the baseline Global Identity for a customer.
## Purpose
This command is used when:
- A new customer completes identity verification
- Customer information is migrated from external systems
- A verified identity needs to be established from authoritative sources
## Certified Attributes
All attributes are wrapped in a certified structure containing the value and a certificate:
- **certifiedIssuedIdentity**: Required - ID document with certificate
- **certifiedPersonName**: Required - Person name with certificate
- **certifiedMobileNumber**: Optional - Mobile number with certificate
- **certifiedEmailAddress**: Optional - Email with certificate
- **certifiedAddress**: Optional - Address with certificate
- **certifiedDateOfBirth**: Optional - DOB with certificate
- **certifiedGender**: Optional - Gender with certificate
## Certificate Structure
Each certificate contains:
- `certificateId`: UUID for audit trail
- `trustLevel`: Numeric score indicating source reliability
- `creationTime`: When the verification occurred
## Response
On success, emits `CustomerIdentityCreatedEventV1`. On failure, emits `CustomerIdentityCreationFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateCustomerIdentity",
"title": "CreateCustomerIdentity",
"description": "Command to create a new verified customer identity with certified attributes.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "certifiedIssuedIdentity", "certifiedPersonName"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related operations"
},
"createdDate": {
"type": "integer",
"description": "Command creation timestamp (milliseconds since epoch)"
},
"createdBy": {
"type": "string",
"description": "Identifier of the command creator"
},
"certifiedIssuedIdentity": {
"$ref": "#/$defs/CertifiedIssuedIdentity",
"description": "Certified issued identity document"
},
"certifiedPersonName": {
"$ref": "#/$defs/CertifiedPersonName",
"description": "Certified person name"
},
"certifiedMobileNumber": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/CertifiedMobileNumber" }
],
"description": "Certified mobile number (optional)"
},
"certifiedEmailAddress": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/CertifiedEmailAddress" }
],
"description": "Certified email address (optional)"
},
"certifiedAddress": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/CertifiedAddress" }
],
"description": "Certified address (optional)"
},
"certifiedDateOfBirth": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/CertifiedDateOfBirth" }
],
"description": "Certified date of birth (optional)"
},
"certifiedGender": {
"oneOf": [
{ "type": "null" },
{ "$ref": "#/$defs/CertifiedGender" }
],
"description": "Certified gender (optional)"
}
},
"$defs": {
"Certificate": {
"type": "object",
"required": ["certificateId", "trustLevel", "creationTime"],
"properties": {
"certificateId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the certificate"
},
"trustLevel": {
"type": "number",
"description": "Trust level score (higher is more trusted)"
},
"creationTime": {
"type": "integer",
"description": "Certificate creation timestamp (milliseconds since epoch)"
}
}
},
"IssuedIdentity": {
"type": "object",
"required": ["type", "value", "countryOfIssue", "validatedWhen"],
"properties": {
"type": {
"type": "string",
"enum": ["UNKNOWN", "IDENTITY_DOCUMENT", "PASSPORT"],
"description": "Type of identity document"
},
"value": {
"type": "string",
"description": "Identity document number"
},
"countryOfIssue": {
"type": "string",
"description": "ISO country code of issuing country"
},
"expiryDate": {
"oneOf": [
{ "type": "null" },
{ "type": "integer", "description": "Expiry date (days since epoch)" }
],
"description": "Document expiry date"
},
"issuedBy": {
"oneOf": [{ "type": "null" }, { "type": "string" }],
"description": "Issuing authority"
},
"validatedBy": {
"oneOf": [{ "type": "null" }, { "type": "string" }],
"description": "Validation service"
},
"validatedWhen": {
"type": "integer",
"description": "Validation timestamp (milliseconds since epoch)"
}
}
},
"CertifiedIssuedIdentity": {
"type": "object",
"required": ["issuedIdentity", "certificate"],
"properties": {
"issuedIdentity": { "$ref": "#/$defs/IssuedIdentity" },
"certificate": { "$ref": "#/$defs/Certificate" }
}
},
"PersonName": {
"type": "object",
"required": ["name", "familyName"],
"properties": {
"name": { "type": "string", "description": "First name" },
"middleNames": {
"oneOf": [{ "type": "null" }, { "type": "array", "items": { "type": "string" } }]
},
"familyName": { "type": "string", "description": "Family name" },
"maidenName": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"generationalName": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"suffix": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"titles": {
"oneOf": [{ "type": "null" }, { "type": "array", "items": { "type": "string" } }]
},
"religiousTitles": {
"oneOf": [{ "type": "null" }, { "type": "array", "items": { "type": "string" } }]
}
}
},
"CertifiedPersonName": {
"type": "object",
"required": ["personName", "certificate"],
"properties": {
"personName": { "$ref": "#/$defs/PersonName" },
"certificate": { "$ref": "#/$defs/Certificate" }
}
},
"MobileNumber": {
"type": "object",
"required": ["phoneCountryCode", "localNumber"],
"properties": {
"phoneCountryCode": { "type": "string" },
"localNumber": { "type": "string" }
}
},
"CertifiedMobileNumber": {
"type": "object",
"required": ["mobileNumber", "certificate"],
"properties": {
"mobileNumber": { "$ref": "#/$defs/MobileNumber" },
"certificate": { "$ref": "#/$defs/Certificate" }
}
},
"CertifiedEmailAddress": {
"type": "object",
"required": ["emailAddress", "certificate"],
"properties": {
"emailAddress": { "type": "string", "format": "email" },
"certificate": { "$ref": "#/$defs/Certificate" }
}
},
"Address": {
"type": "object",
"required": ["streetAddress", "suburb", "city", "provinceOrState", "postalCode", "countryCode"],
"properties": {
"streetAddress": { "type": "string" },
"unitName": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"unitNumber": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"suburb": { "type": "string" },
"city": { "type": "string" },
"region": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"provinceOrState": { "type": "string" },
"postalCode": { "type": "string" },
"countryCode": { "type": "string" }
}
},
"CertifiedAddress": {
"type": "object",
"required": ["address", "certificate"],
"properties": {
"address": { "$ref": "#/$defs/Address" },
"certificate": { "$ref": "#/$defs/Certificate" }
}
},
"CertifiedDateOfBirth": {
"type": "object",
"required": ["dateOfBirth", "certificate"],
"properties": {
"dateOfBirth": { "type": "integer", "description": "Date of birth (days since epoch)" },
"certificate": { "$ref": "#/$defs/Certificate" }
}
},
"CertifiedGender": {
"type": "object",
"required": ["gender", "certificate"],
"properties": {
"gender": {
"type": "string",
"enum": ["MALE", "FEMALE", "NONBINARY", "PREFER_NOT_TO_SAY", "UNKNOWN"]
},
"certificate": { "$ref": "#/$defs/Certificate" }
}
}
}
}
---
id: CreateCustomerNotificationPreferences
name: Create Customer Notification Preferences
version: 0.0.1
summary: Command to create notification preferences for a customer
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Profile
backgroundColor: cyan
textColor: black
---
## Overview
The Create Customer Notification Preferences command creates communication preferences for a customer profile, including preferred SMS and email contact points.
## Response
On success, emits `CustomerNotificationPreferencesCreatedEventV1`. On failure, emits `CustomerNotificationPreferencesCreationFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateCustomerNotificationPreferences",
"title": "CreateCustomerNotificationPreferences",
"description": "Command to create notification preferences for a customer.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"smsContactPoint": {
"oneOf": [
{ "type": "null" },
{
"type": "object",
"properties": {
"countryCode": { "type": "string" },
"localNumber": { "type": "string" }
}
}
]
},
"emailContactPoint": { "oneOf": [{ "type": "null" }, { "type": "string", "format": "email" }] }
}
}
---
id: CreateDataSubject
name: Create Data Subject
version: 0.0.1
summary: Command to create a data subject record for regulatory compliance
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Compliance
backgroundColor: red
textColor: white
---
## Overview
The Create Data Subject command creates a new data subject record for tracking consent and data processing activities in compliance with POPIA and GDPR.
## Response
On success, emits `DataSubjectCreatedEventV1`. On failure, emits `DataSubjectCreationFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateDataSubject",
"title": "CreateDataSubject",
"description": "Command to create a data subject record for regulatory compliance.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "dataSubjectId", "globalCustomerId"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"dataSubjectId": { "type": "string", "format": "uuid" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"consentRecords": { "oneOf": [{ "type": "null" }, { "type": "array", "items": { "type": "object" } }] }
}
}
---
id: CreateFuneralPolicy
name: Create Funeral Policy
version: 0.0.1
summary: Command to create a funeral policy directly with all required details
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Create Funeral Policy command is used to create a funeral policy directly without going through the quote-to-policy flow. This command provides full control over all policy attributes and is typically used for policy migrations or direct integrations.
## Purpose
This command allows direct policy creation by providing:
- Complete policyholder information
- Partner and package configuration
- Product and coverage details via product deltas
- Financial details including premiums and fees
- Sales channel and broker information
- Verification configurations
## Request
The command requires comprehensive policy details including policyholder information, partner configuration, and financial details.
### Key Fields
- **policyHolder**: Complete policyholder information including personal and contact details
- **partnerId / packageId**: The partner and package identifiers for the policy
- **policyFinancialDetail**: Premium amounts, collection details, and billing configuration
- **productDeltas**: Product configuration changes to build the policy products
- **coverStartDate**: The date when coverage begins
- **verificationConfigurations**: Required verification steps for the policy
## Response
Upon successful execution, the command creates a new policy record and triggers downstream processes including document generation, collection setup, and verification workflows.
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "CreateFuneralPolicy",
"type": "object",
"title": "CreateFuneralPolicy",
"description": "Command to create a funeral policy directly without going through the quote flow. This command contains all the necessary information to create a complete policy.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy being created"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracking related operations"
},
"policyHolder": {
"type": "object",
"description": "The policyholder details including personal information and contact details"
},
"countryCode": {
"type": "string",
"description": "The country code for the policy (e.g., ZA for South Africa)"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the partner offering this policy"
},
"packageId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the partner package for this policy"
},
"packageName": {
"type": "string",
"description": "The name of the partner package"
},
"productBundleName": {
"type": "string",
"description": "The name of the product bundle"
},
"policyDocuments": {
"type": "array",
"items": {
"type": "object"
},
"description": "The policy documents associated with this policy"
},
"policyFinancialDetail": {
"type": "object",
"description": "The financial details including premiums and collection information"
},
"termsAndConditionsDetail": {
"type": "object",
"description": "The terms and conditions details for the policy"
},
"productDeltas": {
"type": "object",
"description": "The product configuration deltas used to build policy products"
},
"coverStartDate": {
"type": "string",
"format": "date-time",
"description": "The date when coverage begins"
},
"campaigns": {
"type": "array",
"items": {
"type": "object"
},
"description": "The campaigns associated with this policy"
},
"policyStatus": {
"type": "string",
"description": "The initial status of the policy"
},
"policyAdministrationFee": {
"type": "object",
"description": "The administration fee for the policy"
},
"salesChannelId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the sales channel"
},
"salesAgentId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the sales agent"
},
"brokerId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the broker"
},
"brokerPercentage": {
"type": "number",
"description": "The broker commission percentage"
},
"pricingConfigVersion": {
"type": "integer",
"description": "The version of the pricing configuration used"
},
"verificationHistories": {
"type": "array",
"items": {
"type": "object"
},
"description": "The verification history records"
},
"verificationConfigurations": {
"type": "array",
"items": {
"type": "object"
},
"description": "The verification configurations for the policy"
}
},
"required": ["id", "policyHolder", "partnerId", "packageId", "coverStartDate"]
}
---
id: CreateFuneralPolicyFromQuote
name: Create Funeral Policy From Quote
version: 0.0.1
summary: Command to create a funeral policy from an existing quote
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Create Funeral Policy From Quote command is used to convert an existing quote into an active funeral policy. This is the primary mechanism for policy creation in the quote-to-policy flow.
## Purpose
When a customer accepts a quote, this command:
- Converts the quote details into a new policy record
- Associates the policy with the partner package terms and conditions
- Generates a unique policy code for the new policy
- Initiates downstream processes such as document generation and collection setup
## Request
The command requires a valid quote object containing all the pricing, coverage, and customer details needed to create the policy.
### Key Fields
- **quote**: The complete quote object with all pricing and coverage information
- **packageTermsAndConditions**: The terms and conditions from the partner package that will govern the policy
## Response
Upon successful execution, the command triggers the policy creation process and emits relevant domain events for downstream systems.
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "CreateFuneralPolicyFromQuote",
"type": "object",
"title": "CreateFuneralPolicyFromQuote",
"description": "Command to create a funeral policy from an existing quote. This command contains all the necessary information to convert a quote into an active policy.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy being created"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracking related operations"
},
"quote": {
"type": "object",
"description": "The quote object containing all pricing and coverage details to be converted into a policy"
},
"packageTermsAndConditions": {
"type": "object",
"description": "The terms and conditions associated with the partner package"
}
},
"required": ["id", "quote"]
}
---
id: CreatePolicyRequest
name: Create Policy Request
version: 0.0.1
summary: Command to ingest a policy creation request via the Policy Importer API.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Ingestion
backgroundColor: orange
textColor: white
---
## Overview
The **Create Policy Request** command accepts JSON payloads containing policy and identity data.
Requests are validated, placed on the create-policy-request queue, and processed asynchronously.
## Request
Key fields include:
- **correlationId**: Correlation identifier for tracing
- **partnerId / packageId**: Partner and package identifiers
- **coverStartDate**: Coverage start date
- **policyFinancialDetail**: Premium and collection configuration
- **products**: Product lives and beneficiary identities
## Processing
1. API Gateway receives `POST /policies`
2. The request is enqueued to `sft-capstone-policy-importer-create-policy-request`
3. A command handler maps the request into policy and identity commands
4. Downstream services process the commands asynchronously
## Response
The API responds with `202 Accepted` once the request is queued successfully.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreatePolicyRequest",
"title": "CreatePolicyRequest",
"description": "Command payload for policy import requests submitted via the Policy Importer API.",
"type": "object",
"properties": {
"correlationId": {
"type": "string",
"description": "Correlation identifier for tracking the import request"
},
"coverStartDate": {
"type": "string",
"format": "date",
"description": "Coverage start date for the policy"
},
"partnerId": {
"type": "string",
"description": "Partner identifier"
},
"countryCode": {
"type": "string",
"description": "ISO country code"
},
"packageId": {
"type": "string",
"description": "Package identifier"
},
"policyAdministrationFee": {
"type": "number",
"description": "Administration fee for the policy"
},
"policyFinancialDetail": {
"type": "object",
"description": "Premium and collection configuration",
"properties": {
"totalPremium": { "type": "number" },
"collectionFrequency": { "type": "string" },
"collectionDay": { "type": "integer" },
"collectionMethod": { "type": "string" },
"collectionProviderName": { "type": "string" },
"collectionId": { "type": "string" },
"sourceOfFunds": { "type": "string" }
},
"additionalProperties": true
},
"products": {
"type": "array",
"description": "Products, lives, and beneficiaries included in the request",
"items": { "type": "object" }
}
},
"additionalProperties": true
}
---
id: CreateProductBundleConfig
name: Create Product Bundle Config
version: 0.0.1
summary: Command to create a new product bundle configuration for a partner.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Configuration
backgroundColor: gray
textColor: white
---
## Overview
The Create Product Bundle Config command is used to establish a new product bundle configuration. This defines the structure of a bundle including partner details, package information, included products, and coverage calculation rules.
## Purpose
This command allows creation of bundle configurations by providing:
- Partner and package identification
- Bundle name and product list
- Coverage calculation strategy and amounts
- Allowed cover terms for redemption
## Request
The command requires comprehensive configuration details including partner IDs, products, and coverage rules.
### Key Fields
- **bundleId**: Unique identifier for the bundle configuration
- **partnerId / partnerCode**: Partner identification
- **packageId / packageCode**: Package identification
- **products**: List of products included in the bundle
- **coverCalculation**: Strategy and amounts for coverage
- **allowedCoverTerms**: Valid cover terms for redemption
## Response
Upon successful execution, the command creates a new bundle configuration that can be used for inventory generation and redemption workflows.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateProductBundleConfig",
"type": "object",
"title": "CreateProductBundleConfig",
"description": "Command to create a new product bundle configuration aggregate.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for tracking"
},
"bundleId": {
"type": "string",
"description": "Unique identifier for the bundle configuration"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "Partner identifier"
},
"partnerCode": {
"type": "string",
"description": "3-digit partner code"
},
"partnerName": {
"type": "string",
"description": "Human-readable partner name"
},
"bundleName": {
"type": "string",
"description": "Human-readable bundle name"
},
"packageId": {
"type": "string",
"format": "uuid",
"description": "Package identifier"
},
"packageCode": {
"type": "string",
"description": "3-digit package code"
},
"packageName": {
"type": "string",
"description": "Human-readable package name"
},
"products": {
"type": "array",
"description": "List of products included in the bundle",
"items": {
"type": "object",
"properties": {
"productId": {
"type": "string",
"format": "uuid",
"description": "Product identifier"
},
"productShortCode": {
"type": "string",
"description": "Short code for product mapping"
},
"rules": {
"type": "object",
"description": "Product-specific rules"
}
}
}
},
"coverCalculation": {
"type": "object",
"description": "Coverage calculation configuration",
"properties": {
"strategy": {
"type": "string",
"description": "Calculation strategy (e.g., COVER_LUMP_SUM_DIVIDED_BY_TERM_UNITS)"
},
"coverLumpAmount": {
"type": "object",
"description": "Total cover lump sum amount"
}
}
},
"packagePremium": {
"type": "object",
"description": "Premium amount for the package"
},
"allowedCoverTerms": {
"type": "array",
"items": {
"type": "integer"
},
"description": "List of allowed cover terms in months"
}
},
"required": ["id", "bundleId", "partnerId", "packageId"]
}
---
id: CreateProductBundleInventoryItems
name: Create Product Bundle Inventory Items
version: 0.0.1
summary: Command to generate inventory items for a product bundle.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Inventory
backgroundColor: teal
textColor: white
---
## Overview
The Create Product Bundle Inventory Items command is used to generate a batch of inventory items for a product bundle configuration. Each item receives a unique serial number with a Damm check digit for error detection.
## Purpose
This command allows partners to generate inventory by providing:
- Bundle configuration identifier
- Number of items to generate
- Optional expiration date for the items
## Request
The command requires the bundle ID and count of items to generate.
### Key Fields
- **bundleId**: Reference to the bundle configuration
- **count**: Number of inventory items to create
- **expiresAt**: Optional expiration timestamp for the items
## Response
Upon successful execution, the command generates inventory items with unique serial numbers and emits a ProductBundleInventoryItemsCreatedEventV2 containing the list of generated serial numbers.
## Serial Number Format
Serial numbers are 16 digits: `PPP + KKK + SSSSSSSSS + C`
- **PPP**: 3-digit partner code
- **KKK**: 3-digit package code
- **SSSSSSSSS**: 9-digit sequence number
- **C**: 1-digit Damm check digit
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateProductBundleInventoryItems",
"type": "object",
"title": "CreateProductBundleInventoryItems",
"description": "Command to generate inventory items for a bundle.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for tracking"
},
"bundleId": {
"type": "string",
"description": "Reference to the bundle configuration"
},
"count": {
"type": "integer",
"minimum": 1,
"description": "Number of inventory items to create"
},
"expiresAt": {
"type": ["string", "null"],
"format": "date-time",
"description": "Optional expiration date for the items"
}
},
"required": ["id", "bundleId", "count"]
}
---
id: CreateQuote
name: Create Quote
version: 0.0.1
summary: Command to create a new insurance quote with partner and package configuration.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Create Quote command initializes a new insurance quote in the system. It establishes the partner context, package configuration, and initial product category for the quote.
## Purpose
This command creates a new quote record with:
- Partner and package identification
- Product category selection
- Sales channel and agent information
- Broker details and commission percentage
- Initial verification configurations
## Request
### Key Fields
- **partnerId**: The identifier of the distribution partner
- **packageId**: The partner package defining available products and rules
- **productCategoryId**: The product category being quoted (e.g., Funeral)
- **salesChannelId**: The channel through which the quote originated
- **correlationId**: Correlation identifier for tracking related operations
- **salesAgentId**: Optional agent identifier for commission tracking
- **brokerId**: Optional broker identifier
- **brokerPercentage**: Commission percentage for the broker
## Response
Upon successful execution, the command creates a new quote aggregate and triggers the QuoteCreatedEventV2 event.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateQuote",
"type": "object",
"title": "CreateQuote",
"description": "Command to create a new insurance quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracking related operations"
},
"partnerId": {
"type": "string",
"description": "The identifier of the partner"
},
"packageId": {
"type": "string",
"description": "The identifier of the partner package"
},
"productCategoryId": {
"type": "string",
"description": "The identifier of the product category"
},
"salesChannelId": {
"type": "string",
"description": "The identifier of the sales channel"
},
"salesAgentId": {
"type": ["null", "string"],
"description": "The identifier of the sales agent"
},
"brokerId": {
"type": ["null", "string"],
"description": "The identifier of the broker"
},
"brokerPercentage": {
"type": ["null", "integer"],
"description": "The broker commission percentage"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"correlationId",
"salesChannelId",
"partnerId",
"productCategoryId",
"packageId"
]
}
---
id: CreateQuoteDelta
name: Create Quote Delta
version: 0.0.1
summary: Delta-based command to create a new insurance quote, replacing a previous quote state.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Delta
backgroundColor: orange
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Create Quote Delta command is a delta-based variant of the standard CreateQuote command. It is used to create a new quote by describing the changes (delta) from a previous state, rather than providing the full initial state. This supports optimistic concurrency and partial updates in distributed flows.
## Purpose
This command creates a new quote with:
- Partner and package identification
- Product category selection
- Sales channel and agent information
- Broker details and commission percentage
## Delta-Based Pattern
Unlike `CreateQuote`, this command is designed to work within delta-based workflows where quote state transitions are expressed as incremental changes. The `quoteId` field references the quote being created or transitioned.
## Request
### Key Fields
- **quoteId**: The identifier of the quote being created
- **partnerId**: The distribution partner identifier
- **packageId**: The partner package defining available products and rules
- **productCategoryId**: The product category being quoted (e.g., Funeral)
- **salesChannelId**: The channel through which the quote originated
- **salesAgentId**: Optional agent identifier for commission tracking
- **brokerId**: Optional broker identifier
- **brokerPercentage**: Commission percentage for the broker
- **correlationId**: Correlation identifier for tracking related operations
## Response
Upon successful execution, creates a new quote aggregate and triggers the QuoteCreatedEventV2 event.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateQuoteDelta",
"type": "object",
"title": "CreateQuoteDelta",
"description": "Delta-based command to create a new insurance quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracking related operations"
},
"partnerId": {
"type": "string",
"description": "The identifier of the partner"
},
"packageId": {
"type": "string",
"description": "The identifier of the partner package"
},
"productCategoryId": {
"type": "string",
"description": "The identifier of the product category"
},
"salesChannelId": {
"type": "string",
"description": "The identifier of the sales channel"
},
"salesAgentId": {
"type": ["null", "string"],
"description": "The identifier of the sales agent"
},
"brokerId": {
"type": ["null", "string"],
"description": "The identifier of the broker"
},
"brokerPercentage": {
"type": ["null", "number"],
"description": "The broker commission percentage"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"partnerId",
"packageId",
"productCategoryId",
"salesChannelId"
]
}
---
id: CreateQuoteWithPolicy
name: Create Quote With Policy
version: 0.0.1
summary: Command to create a new quote based on an existing policy.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Create Quote With Policy command creates a new quote using an existing policy as the basis. This is typically used for policy amendments, requotes, or policy renewals where the existing policy details are used as a starting point.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `existingPolicyId` | UUID | Yes | The policy to base the quote on |
| `salesAgentId` | UUID | No | The sales agent for the quote |
| `brokerId` | UUID | No | The broker for the quote |
| `brokerPercentage` | Number | No | Broker commission percentage |
| `salesChannelId` | UUID | No | The sales channel |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateQuoteWithPolicy",
"type": "object",
"title": "CreateQuoteWithPolicy",
"description": "Command to create a new quote based on an existing policy.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"existingPolicyId": {
"type": "string",
"format": "uuid",
"description": "The policy to base the quote on"
},
"salesAgentId": {
"type": "string",
"format": "uuid",
"description": "The sales agent for the quote"
},
"brokerId": {
"type": "string",
"format": "uuid",
"description": "The broker for the quote"
},
"brokerPercentage": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Broker commission percentage"
},
"salesChannelId": {
"type": "string",
"format": "uuid",
"description": "The sales channel"
}
},
"required": ["id", "createdDate", "createdBy", "correlationId", "existingPolicyId"]
}
---
id: CreateTenantedIdentity
name: Create Tenanted Identity
version: 0.0.1
summary: Command to create a tenanted identity record linked to a specific tenant
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Tenanted
backgroundColor: purple
textColor: white
---
## Overview
The Create Tenanted Identity command creates a new identity record scoped to a specific tenant. It can optionally be linked to a Global Identity for cross-tenant customer recognition.
## Response
On success, emits `TenantedIdentityCreatedEventV1`. On failure, emits `TenantedIdentityCreationFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "CreateTenantedIdentity",
"title": "CreateTenantedIdentity",
"description": "Command to create a tenanted identity record.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "tenantedIdentityId", "tenantId"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"tenantedIdentityId": { "type": "string", "format": "uuid" },
"tenantId": { "type": "string" },
"globalCustomerId": { "oneOf": [{ "type": "null" }, { "type": "string", "format": "uuid" }] },
"name": { "oneOf": [{ "type": "null" }, { "type": "object" }] },
"issuedIdentity": { "oneOf": [{ "type": "null" }, { "type": "object" }] },
"mobileNumber": { "oneOf": [{ "type": "null" }, { "type": "object" }] },
"emailAddress": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"residentialAddress": { "oneOf": [{ "type": "null" }, { "type": "object" }] },
"dateOfBirth": { "oneOf": [{ "type": "null" }, { "type": "integer" }] },
"gender": { "oneOf": [{ "type": "null" }, { "type": "string" }] }
}
}
---
id: CreateUnverifiedIdentity
name: Create Unverified Identity
version: 0.0.1
summary: Outgoing command to create an unverified identity record in the Identity service.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Outgoing
backgroundColor: purple
textColor: white
---
## Overview
The Create Unverified Identity command is sent to the Identity service to create an unverified identity record. This command is used during bundle issuance workflows when new identities need to be established in the system prior to policy creation.
## Purpose
This outgoing command allows the Product Bundle Inventory Service to:
- Request creation of unverified identity records in the Identity service
- Support the bundle issuance workflow for new policies
- Establish identity baseline information before full verification
## Usage
This command is emitted during the `InitiateBundleIssuanceForNewPolicy` command execution when a new identity needs to be created as part of the policy setup process.
## Target Service
- **Service**: Identity Service
- **Relationship**: Upstream service in the event-driven architecture
---
id: DeleteFile
name: Delete File
version: 0.0.1
summary: Command to delete a file from the system
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Delete File command is used to permanently delete a file from the system. This command marks the file as deleted and triggers cleanup processes.
## Purpose
This command allows file deletion by providing:
- The file identifier to delete
- Audit information (who deleted and when)
- Correlation ID for tracking
## Request
The command requires the file identifier and standard command metadata.
### Key Fields
- **fileId**: Unique identifier of the file to delete
- **createdBy**: User or system initiating the deletion
- **createdDate**: Timestamp of the deletion request
- **correlationId**: Correlation ID for tracking
## Response
Upon successful execution, the command:
1. Marks the file record as deleted
2. Emits a `FileDeletedEventV1` event
3. Triggers storage cleanup (may be asynchronous)
## Constraints
- File must exist in the system
- File must not already be deleted
- Deletion is permanent and cannot be undone
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "DeleteFileCommand",
"title": "DeleteFileCommand",
"description": "Command to delete a file from the system. Wire format: JSON (REST API)",
"x-schema-format": "json",
"type": "object",
"required": [
"id",
"createdDate",
"createdBy",
"fileId",
"correlationId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the command"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the command was created"
},
"createdBy": {
"type": "string",
"description": "User or system that created the command"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier of the file to delete"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking"
}
}
}
---
id: DeleteProductFromQuote
name: Delete Product From Quote
version: 0.0.1
summary: Command to remove a product from a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Delete Product From Quote command removes a product from an existing quote. For requotes, this creates a product removal delta.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote containing the product |
| `productInstanceId` | UUID | Yes | The product instance to remove |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "DeleteProductFromQuote",
"type": "object",
"title": "DeleteProductFromQuote",
"description": "Command to delete a product from a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"productInstanceId": {
"type": "string",
"description": "The identifier of the product instance to delete"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"productInstanceId",
"correlationId"
]
}
---
id: DeltaBasedAddProductToQuote
name: Delta Based Add Product To Quote
version: 0.0.1
summary: Delta-based command to add an insurance product to a quote using incremental tranche changes.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Delta
backgroundColor: orange
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Delta Based Add Product To Quote command adds an insurance product to an existing quote using delta-based tranche updates. Instead of providing the full product state, it describes the incremental changes (deltas) to the product's tranches, supporting optimistic concurrency in distributed quote flows.
## Purpose
This command:
- Adds a product to the quote using delta tranche descriptions
- Captures product life information (main life, spouse, child, etc.)
- Supports calculator inputs for pricing calculations
- Handles effective dating for coverage start
## Delta-Based Pattern
The `deltaTranches` field describes incremental changes to product tranches, and `calculatorInputs` provides dynamic inputs for the pricing calculator engine. The `effectiveDate` determines when the coverage change takes effect.
## Request
### Key Fields
- **quoteId**: The quote to add the product to
- **partnerId**: The partner that owns the package configuration
- **packageId**: The partner package containing the product
- **productId**: The product definition from the partner package
- **productInstanceId**: The specific product instance on the quote
- **productCategoryId**: The product category identifier
- **quoteProductLife**: Information about the covered life
- **futureCover**: Desired cover amount (if applicable)
- **deltaTranches**: List of incremental tranche changes
- **calculatorInputs**: Dynamic key-value inputs for the pricing calculator
- **effectiveDate**: The date from which the product addition takes effect
- **correlationId**: Correlation identifier for tracking related operations
## Response
Upon successful execution, adds the product to the quote aggregate and triggers pricing recalculation.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "DeltaBasedAddProductToQuote",
"type": "object",
"title": "DeltaBasedAddProductToQuote",
"description": "Delta-based command to add a product to a quote using incremental tranche changes.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"partnerId": {
"type": "string",
"description": "The identifier of the partner"
},
"packageId": {
"type": "string",
"description": "The identifier of the partner package"
},
"productId": {
"type": "string",
"description": "The identifier of the product to add"
},
"productInstanceId": {
"type": "string",
"description": "The identifier of the product instance"
},
"productCategoryId": {
"type": "string",
"description": "The identifier of the product category"
},
"quoteProductLife": {
"type": "object",
"description": "Information about the covered life"
},
"futureCover": {
"type": ["null", "object"],
"description": "The desired cover amount"
},
"replacementCoverDetail": {
"type": ["null", "object"],
"description": "Replacement cover detail, if applicable"
},
"pricingConfigVersion": {
"type": ["null", "integer"],
"description": "Pricing configuration version used for calculations"
},
"productTerm": {
"type": ["null", "object"],
"description": "The temporal interval for the product term"
},
"deltaTranches": {
"type": ["null", "array"],
"items": {
"type": "object"
},
"description": "List of incremental tranche changes for delta-based processing"
},
"calculatorInputs": {
"type": ["null", "object"],
"additionalProperties": true,
"description": "Dynamic key-value inputs for the pricing calculator engine"
},
"effectiveDate": {
"type": ["null", "string"],
"format": "date-time",
"description": "The effective date of the product addition"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"partnerId",
"packageId",
"productId",
"productInstanceId",
"productCategoryId",
"quoteProductLife"
]
}
---
id: DeltaBasedDeleteProductFromQuote
name: Delta Based Delete Product From Quote
version: 0.0.1
summary: Delta-based command to remove a product instance from a quote with an effective date.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Delta
backgroundColor: orange
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Delta Based Delete Product From Quote command removes a specific product instance from an existing quote using a delta-based approach. It supports effective dating so the removal can be scheduled for a future date rather than taking immediate effect.
## Purpose
This command:
- Removes a product instance from the quote
- Supports effective dating for the removal
- Works within delta-based optimistic concurrency workflows
## Delta-Based Pattern
Unlike the standard `DeleteProductFromQuote`, this command operates within delta-based flows and includes an `effectiveDate` to allow deferred product removal.
## Request
### Key Fields
- **quoteId**: The quote from which the product is being removed
- **productInstanceId**: The specific product instance to remove
- **effectiveDate**: The date from which the product removal takes effect
- **correlationId**: Correlation identifier for tracking related operations
## Response
Upon successful execution, removes the product instance from the quote aggregate.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "DeltaBasedDeleteProductFromQuote",
"type": "object",
"title": "DeltaBasedDeleteProductFromQuote",
"description": "Delta-based command to remove a product instance from a quote with an effective date.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"productInstanceId": {
"type": "string",
"description": "The identifier of the product instance to remove"
},
"effectiveDate": {
"type": ["null", "string"],
"format": "date-time",
"description": "The date from which the product removal takes effect"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"productInstanceId"
]
}
---
id: DeltaUpdateProductOnQuote
name: Delta Update Product On Quote
version: 0.0.1
summary: Delta-based command to update an existing product on a quote using incremental tranche changes.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Delta
backgroundColor: orange
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Delta Update Product On Quote command updates an existing product on a quote using a delta-based approach. Rather than replacing the full product state, it describes incremental changes (deltas) to product tranches and pricing inputs, supporting optimistic concurrency in distributed flows.
## Purpose
This command:
- Updates an existing product on the quote via delta tranche changes
- Accepts dynamic calculator inputs for pricing recalculation
- Supports effective dating for the update
## Delta-Based Pattern
The `deltaTranches` field describes the incremental changes to the product's tranches. The `calculatorInputs` map provides dynamic inputs for the pricing calculator engine. The `effectiveDate` controls when the change takes effect.
## Request
### Key Fields
- **quoteId**: The quote containing the product to update
- **partnerId**: The partner that owns the package configuration
- **packageId**: The partner package containing the product
- **productId**: The product definition identifier
- **productInstanceId**: The specific product instance to update
- **productCategoryId**: The product category identifier
- **quoteProductLife**: Information about the covered life
- **deltaTranches**: List of incremental tranche changes
- **calculatorInputs**: Dynamic key-value inputs for the pricing calculator
- **effectiveDate**: The date from which the update takes effect
- **correlationId**: Correlation identifier for tracking related operations
## Response
Upon successful execution, updates the product on the quote aggregate and triggers pricing recalculation.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "DeltaUpdateProductOnQuote",
"type": "object",
"title": "DeltaUpdateProductOnQuote",
"description": "Delta-based command to update an existing product on a quote using incremental tranche changes.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"partnerId": {
"type": "string",
"description": "The identifier of the partner"
},
"packageId": {
"type": "string",
"description": "The identifier of the partner package"
},
"productId": {
"type": "string",
"description": "The identifier of the product"
},
"productInstanceId": {
"type": "string",
"description": "The identifier of the product instance to update"
},
"productCategoryId": {
"type": "string",
"description": "The identifier of the product category"
},
"quoteProductLife": {
"type": "object",
"description": "Information about the covered life"
},
"futureCover": {
"type": ["null", "object"],
"description": "The desired cover amount"
},
"replacementCoverDetail": {
"type": ["null", "object"],
"description": "Replacement cover detail, if applicable"
},
"pricingConfigVersion": {
"type": ["null", "integer"],
"description": "Pricing configuration version used for calculations"
},
"productTerm": {
"type": ["null", "object"],
"description": "The temporal interval for the product term"
},
"deltaTranches": {
"type": ["null", "array"],
"items": {
"type": "object"
},
"description": "List of incremental tranche changes for delta-based processing"
},
"calculatorInputs": {
"type": ["null", "object"],
"additionalProperties": true,
"description": "Dynamic key-value inputs for the pricing calculator engine"
},
"effectiveDate": {
"type": ["null", "string"],
"format": "date-time",
"description": "The effective date of the product update"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"partnerId",
"packageId",
"productId",
"productInstanceId",
"productCategoryId"
]
}
---
id: EncryptPdf
name: Encrypt PDF
version: 0.0.1
summary: Command to apply password encryption to an existing PDF document
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Encrypt PDF command applies password protection to an existing PDF document stored in S3. The encrypted document is saved to a new location and a signed URL is returned for secure access.
## Purpose
This command provides document security by:
- Retrieving an existing unencrypted PDF from S3
- Applying AES encryption with a specified password
- Saving the encrypted document to a new S3 location
- Generating a pre-signed URL for downloading the encrypted document
## Request Format
The command is invoked via HTTP POST with a JSON body containing:
- **bucket**: The S3 bucket containing the PDF
- **filePath**: The S3 key of the source PDF to encrypt
- **password**: The password to apply to the document
- **outputPath**: The S3 key where the encrypted PDF will be stored
- **downloadFileName**: Filename shown when downloading the encrypted document
## Security Considerations
- The password is used to encrypt the document; users must have this password to open it
- Passwords should be transmitted securely and not logged
- The encryption uses pypdf's standard PDF encryption (AES-based)
- Consider using strong, unique passwords for each document
## Response
On success, returns:
```json
{
"bucket": "my-bucket",
"key": "documents/encrypted/policy-schedule.pdf",
"link": "https://presigned-url...",
"resourceUri": "s3://my-bucket/documents/encrypted/policy-schedule.pdf"
}
```
## Error Handling
- **400 Bad Request**: Missing required parameters
- **500 Internal Server Error**: S3 access failure or encryption error
## Example Usage
```json
{
"bucket": "capstone-documents",
"filePath": "policies/POL-123/schedule.pdf",
"password": "SecureP@ssword123",
"outputPath": "policies/POL-123/schedule-encrypted.pdf",
"downloadFileName": "Policy_Schedule_Secure.pdf"
}
```
## Use Cases
Common scenarios for PDF encryption:
- **Policy Schedules**: Encrypting sensitive policy documents with the policyholder's ID number
- **Financial Documents**: Protecting documents containing financial information
- **Personal Information**: Securing documents with personally identifiable information
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "EncryptPdf",
"title": "EncryptPdf",
"x-schema-format": "json-schema",
"description": "Command to apply password encryption to an existing PDF document in S3. Based on Python lambda parameter validation.",
"type": "object",
"required": ["bucket", "filePath", "password", "outputPath"],
"properties": {
"bucket": {
"type": "string",
"description": "The S3 bucket containing the source PDF and where the encrypted PDF will be stored"
},
"filePath": {
"type": "string",
"description": "The S3 object key of the source PDF to encrypt"
},
"password": {
"type": "string",
"description": "The password to apply for document encryption"
},
"outputPath": {
"type": "string",
"description": "The S3 object key where the encrypted PDF will be stored"
},
"downloadFileName": {
"type": "string",
"description": "Filename to use in the Content-Disposition header when downloading"
}
}
}
---
id: ExpirePolicy
name: Expire Policy
version: 0.0.1
summary: Command to expire a funeral policy when it reaches end of term
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Expire Policy command is used to expire a funeral policy when it reaches the end of its coverage term or meets other expiration criteria. This command handles natural policy expiration scenarios as well as administrative expirations.
## Purpose
When a policy reaches its expiration criteria, this command:
- Transitions the policy to expired status effective from the command execution date
- Updates the policy with the appropriate expiration sub-status
- Stops all collection activities
- Terminates coverage for the policyholder
- Triggers downstream events for reporting and customer notifications
## Request
The command requires the policy identifier and the expiration sub-status to process the expiration.
### Key Fields
- **policyId**: The identifier of the policy to be expired
- **policySubStatus**: The category of expiration indicating why the policy is expiring:
- **TERM_END**: Policy has reached the end of its defined term
- **MAX_AGE_REACHED**: Policyholder has reached the maximum age for coverage
- **COVERAGE_LIMIT_REACHED**: Policy has paid out to its coverage limit
- **ADMINISTRATIVE**: Administrative expiration for other reasons
## Response
Upon successful execution, the command expires the policy and emits relevant domain events for downstream systems including collections, reporting, and customer communications.
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "ExpirePolicy",
"type": "object",
"title": "ExpirePolicy",
"description": "Command to expire a funeral policy when it reaches the end of its term or coverage period. This command handles policy expiration scenarios including natural term expiration and administrative expiration.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy to expire"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracking related operations"
},
"policySubStatus": {
"type": "string",
"description": "The sub-status indicating the specific expiration category",
"enum": [
"TERM_END",
"MAX_AGE_REACHED",
"COVERAGE_LIMIT_REACHED",
"ADMINISTRATIVE"
]
}
},
"required": ["id", "policyId", "policySubStatus"]
}
---
id: ExpireProduct
name: Expire Product
version: 0.0.1
summary: Command to expire a product within a funeral policy at a specified end date.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Cover
backgroundColor: teal
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The ExpireProduct command triggers the expiration of a specific product within a funeral policy. This command is used to end coverage for a product at a specified date, whether due to policy term completion, member removal, or other business requirements.
### Key Concepts
- **Product Expiration**: The controlled end of a product's coverage period, making it inactive from the specified end date.
- **Tranche**: The specific layer or segment within the policy structure that contains the product being expired.
- **End Date**: The effective date from which the product is no longer active and providing coverage.
### Use Cases
- Term expiration when a product reaches its natural end date
- Member removal from a policy (e.g., dependent reaching age limit)
- Product replacement where old coverage needs to be terminated
- Policy restructuring requiring product-level changes
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440005",
"createdDate": "2024-03-15T10:30:00Z",
"createdBy": "system-scheduler",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"productInstanceId": "456e7891-c23d-45f6-b78a-123456789abc",
"trancheId": "678e9012-d34e-56f7-g89h-012345678901",
"endDate": "2024-12-31T23:59:59Z"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ExpireProductCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy containing the product."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the product instance to expire."
},
"trancheId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the tranche containing the product."
},
"endDate": {
"type": "string",
"format": "date-time",
"description": "The date when the product should expire."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId", "productInstanceId", "trancheId", "endDate"],
"additionalProperties": false
}
---
id: ExpireQuote
name: Expire Quote
version: 0.0.1
summary: Command to expire a quote that has exceeded its validity period.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Expire Quote command marks a quote as expired. This is typically triggered by a scheduled job when a quote exceeds its maximum allowed age.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to expire |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "ExpireQuote",
"type": "object",
"title": "ExpireQuote",
"description": "Command to expire a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote to expire"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId"]
}
---
id: ExtractDocumentCommand
name: Extract Document Command
version: 0.0.1
summary: |
Request extraction of structured data from a document using AWS Textract or other configured providers.
Supports multiple document types and origination contexts.
---
## Overview
The **Extract Document Command** initiates document extraction processing. It routes the document to the appropriate provider adapter based on document type and triggers extraction workflows. Commands are persisted to DynamoDB and processed sequentially per origination context.
## Command Details
### Structure
```
ExtractDocumentCommandV0 {
id: UUID // Unique command identifier
createdDate: Timestamp // Command creation timestamp
createdBy: String // Command originator identifier
fileType: Enum // PDF | JPEG | JPG | PNG | TIFF | HEIC | UNKNOWN
documentType: Enum // DEATH_CERTIFICATE | BIRTH_CERTIFICATE | BI_FORM | UNKNOWN
originationType: String // POLICY | QUOTE | CLAIMS
originationId: UUID (optional) // ID of the policy/quote/claim
fileLocation: FileLocation // S3 bucket and key reference
correlationId: UUID (optional) // Tracing correlation ID
metadata: Map // Additional processing context
}
```
### FileLocation
```
{
s3Bucket: String // S3 bucket name
s3Key: String // S3 object key
s3VersionId: String (optional) // S3 version ID if versioning enabled
uri: String (optional) // Direct file URI
}
```
## Processing Flow
1. **Intake**: Command arrives via SQS from upstream service
2. **Persistence**: Command stored in DynamoDB with status=NEW
3. **Routing**: Document type evaluated and routed to appropriate provider adapter
4. **Processing**: Provider (e.g., Textract) performs extraction
5. **Status Update**: Command record updated with results (COMPLETED) or error (FAILED)
6. **Publication**: Results published via EventBridge for downstream handling
## Supported Document Types
| Document Type | Provider | Processing |
|---------------|----------|-----------|
| Death Certificate | AWS Textract | OCR + Structured field extraction |
| Birth Certificate | AWS Textract | OCR + Structured field extraction |
| BI Form | BI Form Adapter | Form recognition + Key-value pairs |
| Unknown | AWS Textract | Generic OCR (fields unmapped) |
## Origination Context
Commands include context about the originating business entity:
- **POLICY**: Document relates to a policy record
- **QUOTE**: Document relates to a quote/quotation
- **CLAIMS**: Document relates to a claim
This context helps downstream services route extracted data appropriately.
## Metadata Usage
The command metadata map allows optional processing hints:
```json
{
"skipValidation": "true", // Skip field validation in extraction
"priorityLevel": "high", // Processing priority hint
"customTemplateId": "template-123" // Custom extraction template
}
```
## Status Lifecycle
- **NEW**: Just received, awaiting provider assignment
- **PROCESSING**: Active extraction underway
- **COMPLETED**: Extraction finished successfully, results available
- **FAILED**: Processing failed, retries exhausted
## Error Handling
### Retries
- Initial backoff: 1 second
- Max backoff: 5 minutes
- Max retry attempts: Configurable (default: 5)
- Strategy: Exponential backoff with jitter
### Dead-Letter Queue
Failed commands after max retries are moved to the dead-letter queue for:
- Manual review
- Root cause investigation
- Potential resubmission
## Integration
### Triggers
- REST API call from upstream service
- Scheduled job in Policy/Quote/Claims domain
- Manual trigger via admin interface
### Response
Commands return immediately with a command ID for status polling:
```json
{
"commandId": "550e8400-e29b-41d4-a716-446655440000",
"status": "NEW",
"createdAt": "2025-03-11T10:30:00Z"
}
```
### Polling
Consumers can check extraction status using the command ID via `GetExtractionStatus` query.
---
id: FinaliseQuote
name: Finalise Quote
version: 0.0.1
summary: Command to finalise a quote, making it ready for conversion to a policy.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
- content: Critical
backgroundColor: red
textColor: white
---
## Overview
The Finalise Quote command validates and finalises a quote, making it ready for conversion to a policy. This is a critical step that ensures all quote requirements have been met.
## Purpose
This command:
- Validates all required information has been captured
- Confirms terms and conditions have been accepted
- Verifies all verification requirements are satisfied
- Marks the quote as finalised
- Triggers the QuoteFinalisedEventV2 with complete quote data
## Prerequisites
Before finalisation, the quote must have:
- At least one product with valid pricing
- Policyholder details captured
- Collection details captured (if required by partner rules)
- Terms and conditions accepted
- Required verifications completed
## Response
Upon successful execution, the command:
1. Updates quote status to FINALISED
2. Emits QuoteFinalisedEventV2 with all quote data
3. The Policy Service consumes this event to create the policy
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "FinaliseQuote",
"type": "object",
"title": "FinaliseQuote",
"description": "Command to finalise a quote for policy conversion.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote to finalise"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracking related operations"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId"]
}
---
id: FinaliseQuoteWithCollectionAndVerificationMacro
name: Finalise Quote With Collection And Verification Macro
version: 0.0.1
summary: Macro command that finalises a quote together with capturing collection details and verification in a single atomic operation.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Macro
backgroundColor: red
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Finalise Quote With Collection And Verification Macro command is a composite (macro) command that orchestrates multiple sub-commands to finalise a quote, capture collection details, and add verification — all as a single atomic operation. This prevents partial state where a quote is finalised without collection or verification data.
## Purpose
This macro command combines:
- Finalising the quote (transitioning it to finalised state)
- Capturing collection/payment details
- Adding verification configuration to the quote
By executing these as a single macro, the system ensures that all three operations succeed or fail together, maintaining quote data consistency.
## Macro Command Pattern
This command extends `QuoteMacroCommand` and contains a `commands` list of `QuoteCommand` sub-commands that are executed together. The `quoteId` at the macro level identifies which quote is being operated on.
## Request
### Key Fields
- **quoteId**: The quote to finalise
- **commands**: List of sub-commands (FinaliseQuoteCommand, CaptureCollectionDetailsCommand, AddVerificationToQuoteCommand) executed as part of this macro
- **id**: The macro command identifier
- **createdDate**: The command creation timestamp
- **createdBy**: The user or system issuing the macro command
## Response
Upon successful execution, the quote is finalised with collection and verification details applied, triggering the QuoteFinalisedEventV2 event.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "FinaliseQuoteWithCollectionAndVerificationMacro",
"type": "object",
"title": "FinaliseQuoteWithCollectionAndVerificationMacro",
"description": "Macro command that finalises a quote together with collection details and verification in a single atomic operation.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The macro command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote to finalise"
},
"commands": {
"type": "array",
"items": {
"type": "object"
},
"description": "List of sub-commands (FinaliseQuoteCommand, CaptureCollectionDetailsCommand, AddVerificationToQuoteCommand) executed as part of this macro"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"commands"
]
}
---
id: GeneratePdf
name: Generate PDF
version: 0.0.1
summary: Command to generate a PDF document from HTML content and store it in S3
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Generate PDF command accepts HTML content and configuration options to produce a PDF document. The generated document is stored in S3 and a signed URL is returned for secure access.
This command supports two implementation versions:
- **V1**: Separate Node.js handler for generation, optional Python handler for encryption
- **V2**: Unified Go handler supporting inline encryption and audit trails
## Purpose
This command initiates the PDF generation process which:
- Validates the request payload using Zod schema validation (V1) or equivalent (V2)
- Launches a headless Chromium browser via Puppeteer (V1) or embedded Chromium (V2)
- Renders each HTML page to PDF with specified formatting
- Merges multiple pages into a single PDF document if needed
- Optionally applies encryption inline (V2 only)
- Uploads the final PDF to the specified S3 bucket
- Generates a pre-signed URL valid for 7 days
## Request Format
The command is invoked via HTTP POST with a JSON body containing:
### Required Fields
- **bucket**: The S3 bucket where the document will be stored
- **key**: The S3 object key (path) for the document
- **pages**: Array of page configurations with HTML content
### Optional Fields
- **downloadFileName**: Filename shown when downloading
- **userId**: [V2 Only] User ID for audit trail and tenant isolation
- **password**: [V2 Only] Password for inline encryption (triggers PDF encryption without separate EncryptPdf command)
## Page Configuration
Each page in the `pages` array supports:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| htmlString | string | Yes | HTML content to render |
| format | string | No | Page format (default: A4) |
| margin | object | No | Page margins (top, bottom, left, right) |
| printBackground | boolean | No | Print backgrounds (default: true) |
| displayHeaderFooter | boolean | No | Show header/footer (default: false) |
| headerTemplate | string | No | Custom header HTML |
| footerTemplate | string | No | Custom footer HTML |
## Response
On success, returns:
```json
{
"bucket": "my-bucket",
"key": "documents/policy-schedule.pdf",
"link": "https://presigned-url...",
"resourceUri": "s3://my-bucket/documents/policy-schedule.pdf"
}
```
## Error Handling
- **400 Bad Request**: Invalid request payload (validation failure)
- **500 Internal Server Error**: PDF generation or S3 upload failure
## Example Usage
### V1 Example (Node.js/Python - without encryption)
```json
{
"bucket": "capstone-documents",
"key": "policies/POL-123/schedule.pdf",
"downloadFileName": "Policy_Schedule.pdf",
"pages": [
{
"htmlString": "Policy Schedule
...",
"format": "A4",
"margin": {
"top": "20px",
"bottom": "20px",
"left": "20px",
"right": "20px"
},
"displayHeaderFooter": true
}
]
}
```
### V2 Example (Go - with inline encryption)
```json
{
"bucket": "capstone-documents",
"key": "policies/POL-123/schedule.pdf",
"downloadFileName": "Policy_Schedule.pdf",
"userId": "user-12345",
"password": "secure-password-123",
"pages": [
{
"htmlString": "Policy Schedule
...",
"format": "A4",
"margin": {
"top": "20px",
"bottom": "20px",
"left": "20px",
"right": "20px"
},
"displayHeaderFooter": true
}
]
}
```
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "GeneratePdf",
"title": "GeneratePdf",
"x-schema-format": "json-schema",
"description": "Command to generate a PDF document from HTML content and store it in S3. Supports both V1 (Node.js/Python) and V2 (Go) implementations. V2 fields (userId, password) enable inline encryption and audit trails.",
"type": "object",
"required": ["bucket", "key", "pages"],
"properties": {
"bucket": {
"type": "string",
"description": "The S3 bucket where the generated PDF will be stored"
},
"key": {
"type": "string",
"description": "The S3 object key (path) for the generated PDF"
},
"downloadFileName": {
"type": "string",
"description": "Optional filename to use when the document is downloaded"
},
"userId": {
"type": "string",
"description": "[V2 Only] User ID for audit trail and tenant isolation. Required when using V2 Go implementation."
},
"password": {
"type": "string",
"description": "[V2 Only] Password for inline encryption. When provided in V2, the PDF is encrypted without requiring a separate EncryptPdf command."
},
"pages": {
"type": "array",
"description": "Array of page configurations to render and merge into the PDF",
"minItems": 1,
"items": {
"$ref": "#/$defs/PageConfiguration"
}
}
},
"$defs": {
"PageConfiguration": {
"type": "object",
"required": ["htmlString"],
"description": "Configuration for rendering a single page in the PDF",
"properties": {
"htmlString": {
"type": "string",
"description": "The HTML content to render as a PDF page"
},
"format": {
"type": "string",
"enum": ["A4"],
"description": "The page format (currently only A4 is supported)"
},
"margin": {
"$ref": "#/$defs/PageMargin",
"description": "Page margins in CSS units"
},
"printBackground": {
"type": "boolean",
"description": "Whether to print background colors and images",
"default": true
},
"displayHeaderFooter": {
"type": "boolean",
"description": "Whether to display header and footer templates",
"default": false
},
"headerTemplate": {
"type": "string",
"description": "HTML template for the page header"
},
"footerTemplate": {
"type": "string",
"description": "HTML template for the page footer"
}
}
},
"PageMargin": {
"type": "object",
"description": "Margin configuration for PDF pages in CSS units (e.g., '20px', '1in')",
"properties": {
"top": {
"type": "string",
"description": "Top margin in CSS units",
"default": "0px"
},
"bottom": {
"type": "string",
"description": "Bottom margin in CSS units",
"default": "0px"
},
"left": {
"type": "string",
"description": "Left margin in CSS units",
"default": "0px"
},
"right": {
"type": "string",
"description": "Right margin in CSS units",
"default": "0px"
}
}
}
}
}
---
id: GeneratePolicySchedule
name: Generate Policy Schedule
version: 0.0.1
summary: Command to generate a policy schedule document for a funeral policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Generate Policy Schedule command triggers the generation of a policy schedule document for a funeral policy. The policy schedule is a formal document that summarizes the key details of the insurance policy.
## Purpose
This command initiates the document generation process which:
- Compiles all relevant policy information
- Generates a formatted policy schedule document
- Stores the document for retrieval
- Makes the schedule available for download by the policyholder
## Key Fields
- **policyId**: The identifier of the policy for which to generate the schedule.
- **parentReactorEventSourceClassSimpleName**: Tracks which reactor event triggered this command, useful for auditing and debugging the event chain.
## Typical Triggers
This command is typically triggered:
- After policy issuance
- After policy amendments
- When a policyholder requests a new copy of their schedule
- After reinstatement of a lapsed policy
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "GeneratePolicySchedule",
"type": "object",
"title": "GeneratePolicySchedule",
"description": "Command to generate a policy schedule document for a funeral policy.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The command creator"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The policy identifier"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"parentReactorEventSourceClassSimpleName": {
"type": "string",
"description": "The parent reactor event source class name that triggered this command"
}
},
"required": ["id", "policyId"]
}
---
id: GeneratePreSignedUrl
name: Generate Pre-Signed URL
version: 0.0.1
summary: Command to generate a pre-signed URL for direct file upload to S3
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Generate Pre-Signed URL command creates a time-limited, authenticated URL that allows clients to upload files directly to S3 without routing through the application server. This is the preferred method for large file uploads.
## Purpose
This command enables efficient file uploads by:
- Generating a secure, time-limited upload URL
- Pre-registering the file in the system
- Enabling direct client-to-S3 uploads
- Reducing server load for large files
## Request
The command requires file metadata for pre-registration.
### Key Fields
- **fileName**: Name of the file to be uploaded
- **contentType**: MIME type of the file (optional, for validation)
- **expirationSeconds**: URL validity period (fixed at 60 seconds)
- **origination**: Source context (CLAIMS, POLICY, QUOTE)
- **originationId**: Identifier of the associated entity
- **documentType**: Business classification of the document
- **createdBy**: User or system initiating the upload
## Response
Upon successful execution, the command returns:
- **uploadUrl**: Pre-signed S3 URL for PUT operation
- **fileId**: Generated identifier for the file
- **expiresAt**: Timestamp when the URL expires
## Upload Flow
1. Client calls GeneratePreSignedUrl
2. Service creates file record with NEW status
3. Service returns pre-signed URL and file ID
4. Client uploads file directly to S3 using the URL
5. S3 triggers notification on upload completion
6. Service updates file status to UPLOADED
7. FileUploadedEventV1 is emitted
## Constraints
- URL expires after 60 seconds
- File must be uploaded before expiration
- Content type must match if specified
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "GeneratePreSignedUrlCommand",
"title": "GeneratePreSignedUrlCommand",
"description": "Command to generate a pre-signed URL for direct S3 file upload. Wire format: JSON (REST API)",
"x-schema-format": "json",
"type": "object",
"required": [
"id",
"createdDate",
"createdBy",
"fileName",
"origination",
"originationId",
"documentType",
"correlationId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the command"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the command was created"
},
"createdBy": {
"type": "string",
"description": "User or system that created the command"
},
"fileName": {
"type": "string",
"description": "Name of the file to be uploaded"
},
"expirationSeconds": {
"type": "integer",
"default": 60,
"description": "URL validity period in seconds (fixed at 60)"
},
"contentType": {
"type": ["string", "null"],
"description": "Optional MIME type of the file"
},
"origination": {
"type": "string",
"enum": ["CLAIMS", "POLICY", "QUOTE"],
"description": "Source context for the file"
},
"originationId": {
"type": "string",
"format": "uuid",
"description": "Identifier of the associated entity"
},
"documentType": {
"type": "string",
"description": "Business classification of the document"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking"
}
}
}
---
id: ImportPolicy
name: Import Policy
version: 0.0.1
summary: Import an existing policy into the system
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Imports an existing policy from an external system or migration source into the platform. This command is used during data migrations or system integrations to onboard pre-existing policies.
## HTTP Endpoint
```
POST /v1/policy/import
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: InitiateBundleIssuanceForNewPolicy
name: Initiate Bundle Issuance For New Policy
version: 0.0.1
summary: Command to initiate bundle issuance for creating a new policy.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Issuance
backgroundColor: purple
textColor: white
---
## Overview
The Initiate Bundle Issuance For New Policy command is used to start the bundle issuance process for creating a new insurance policy. This command captures all the information needed to establish a new policy from prepaid bundle coverage.
## Purpose
This command allows bundle issuance by providing:
- Bundle and partner identification
- Products with covered life details
- Policy start date and cover term
- Employment and bank details
- Compliance acknowledgments
## Request
The command requires comprehensive details for policy creation.
### Key Fields
- **bundleId**: Reference to the bundle configuration
- **partnerId / packageId**: Partner and package identification
- **products**: List of products with life and beneficiary details
- **policyStartDate**: When the coverage should begin
- **coverTerm / coverTermChronoUnit**: Coverage duration
- **policyholderEmployment**: Employment information
- **bankDetails**: Bank account for collections
- **termsAndConditionsAccepted**: T&C acceptance flag
- **popiaConsentGiven**: POPIA consent flag
## Validation
The command validates:
- Products match bundle configuration
- Cover term is allowed by configuration
- Required fields are provided
## Response
Upon successful execution, the coverage amounts are calculated based on configuration rules and a BundleIssuanceForNewPolicyEventV2 is emitted to trigger downstream policy creation.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "InitiateBundleIssuanceForNewPolicy",
"type": "object",
"title": "InitiateBundleIssuanceForNewPolicy",
"description": "Command to initiate a bundle issuance for a new policy.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for tracking"
},
"bundleId": {
"type": "string",
"description": "Reference to the bundle configuration"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "Partner identifier"
},
"packageId": {
"type": "string",
"format": "uuid",
"description": "Package identifier"
},
"products": {
"type": "array",
"description": "List of products for the new policy",
"items": {
"$ref": "#/$defs/Product"
}
},
"policyStartDate": {
"type": "string",
"format": "date-time",
"description": "Start date for the policy coverage"
},
"coverTerm": {
"type": "integer",
"description": "Duration of coverage"
},
"coverTermChronoUnit": {
"type": "string",
"enum": ["DAYS", "WEEKS", "MONTHS", "YEARS"],
"description": "Unit for the cover term"
},
"termsAndConditionsAccepted": {
"type": "boolean",
"description": "Whether T&Cs were accepted"
},
"popiaConsentGiven": {
"type": "boolean",
"description": "Whether POPIA consent was given"
},
"bundleMultiplier": {
"type": "integer",
"description": "Multiplier for coverage amounts"
},
"policyholderEmployment": {
"$ref": "#/$defs/Employment",
"description": "Employment details"
},
"bankDetails": {
"$ref": "#/$defs/BankDetails",
"description": "Bank account details"
}
},
"required": ["id", "bundleId", "products", "policyStartDate"],
"$defs": {
"Product": {
"type": "object",
"properties": {
"bundleProductShortCode": {
"type": "string",
"description": "Short code mapping to bundle product"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique product instance identifier"
},
"productLifeId": {
"type": "string",
"format": "uuid",
"description": "Product life identifier"
},
"productLifeRelationshipToMain": {
"type": "string",
"description": "Relationship to main life"
},
"beneficiaries": {
"type": "array",
"items": {
"type": "object"
}
},
"replacementCoverDetails": {
"type": "object",
"description": "Replacement cover information"
}
},
"required": ["bundleProductShortCode", "productLifeRelationshipToMain"]
},
"Employment": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "Employment status"
},
"industry": {
"type": "string",
"description": "Industry of employment"
}
}
},
"BankDetails": {
"type": "object",
"properties": {
"bankAccountName": {
"type": "string",
"description": "Name on the bank account"
},
"bankName": {
"type": "string",
"description": "Name of the bank"
},
"bankAccountNumber": {
"type": "string",
"description": "Bank account number"
},
"bankBranch": {
"type": "string",
"description": "Bank branch"
},
"accountType": {
"type": "string",
"description": "Type of account"
}
}
}
}
}
---
id: MainLifeDeceased
name: Main Life Deceased
version: 0.0.1
summary: Command to lapse a policy when the main life has passed away
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Main Life Deceased command is used to lapse a policy when the main life (primary insured) on a policy has passed away. This command is critical in the context of policy management and triggers a series of important actions within the system.
## Purpose
When the death of the main life is reported, this command:
- Freezes the policy to prevent further modifications
- Stops all collection activities
- Initiates the required status changes based on the death type
- Triggers downstream events for claims processing
## Key Fields
- **lapsedDate**: The date on which the policy is lapsed. Defaults to the current date but may be backdated in certain scenarios.
- **deathType**: The type of death (e.g., natural, accidental) which determines the policy substatus and specific actions during processing.
- **requestOrigin**: Indicates where the request originated from (system, client service portal, self-service portal, etc.).
- **requestee**: The entity that made the request (system user, agent, or policyholder).
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "MainLifeDeceased",
"type": "object",
"title": "MainLifeDeceased",
"description": "Command to lapse a policy when the main life on a policy has passed away. This command handles policy lapse scenarios when a client's death is reported, including freezing the policy, stopping collections, and initiating required status changes.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy to lapse"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"lapsedDate": {
"type": "string",
"format": "date-time",
"description": "The date on which the policy was lapsed. This defaults to the current date and time, but may need to be backdated in certain scenarios."
},
"deathType": {
"type": "string",
"description": "The type of death that led to the policy lapse. This helps determine the policy substatus and specific actions during the lapse process.",
"enum": ["NATURAL_DEATH", "ACCIDENTAL_DEATH", "SUICIDE", "UNKNOWN"]
},
"requestOrigin": {
"type": "string",
"description": "The origin of the lapse request, indicating whether the request was initiated by the system, client service portal, policyholder self-service portal, etc."
},
"requestee": {
"type": "string",
"description": "The entity that made the request, such as a system user, client service agent, or the policyholder themselves"
}
},
"required": ["id", "policyId", "lapsedDate", "deathType"]
}
---
id: OverrideRepudiatedClaim
name: Override Repudiated Claim
version: 0.0.1
summary: Override a previously repudiated claim decision
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Allows an authorised user to override a previous repudiation decision on a claim, reinstating it for further processing or payment. This command is typically used when new evidence or a review warrants reversing the repudiation.
## HTTP Endpoint
```
POST /v1/claims/override-repudiated-claim
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: OverrideRepudiatedClaimCommand
name: Override Repudiated Claim
version: 0.0.1
summary: Command to override a previously repudiated claim, reopening it for processing.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Override Repudiated Claim command reverses a repudiation decision, allowing a previously denied claim to be reopened for further processing. This is typically used when new evidence is presented or an error in the original decision is identified.
## Key Fields
- **claimId**: The repudiated claim to override
- **overrideReason**: Reason for overriding the repudiation
- **overriddenBy**: The user performing the override
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim status back to active processing and emits a `ClaimUpdatedEventV1`.
---
id: PayClaim
name: Pay Claim
version: 0.0.1
summary: Process payment for an approved claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Processes the payment for an approved claim, disbursing the calculated payout to the claimant's nominated banking details. This command transitions the claim into a paid state.
## HTTP Endpoint
```
POST /v1/claims/pay-claim
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: PayClaimCommand
name: Pay Claim
version: 0.0.1
summary: Command to initiate payout for an approved claim.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Financial
backgroundColor: green
textColor: white
---
## Overview
The Pay Claim command initiates the payout process for an approved claim. This triggers the creation of a payment instruction and emits the payout initiated event.
## Key Fields
- **claimId**: The claim to pay out
- **correlationId**: Correlation ID for tracking
## Response
Initiates the payout and emits a `PayoutInitiatedEventV1` with payment reference, amount, currency, and instruction details.
---
id: PerformAdHocPremiumCollection
name: Perform Ad-Hoc Premium Collection
version: 0.0.1
summary: Command to perform an immediate premium collection outside the normal scheduled collection cycle.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Collection
backgroundColor: green
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The PerformAdHocPremiumCollection command allows for immediate collection of premiums outside of the normal scheduled collection process. This is useful for catching up on arrears, processing one-time payments, or handling exceptional collection scenarios.
### Collection Workflow
1. **Initiation**: An operator or system triggers the ad-hoc collection for a specific policy.
2. **Amount Determination**: The collection amount is either specified explicitly or defaults to the outstanding arrears amount.
3. **Provider Selection**: The command specifies which collection provider and method to use.
4. **Processing**: The collection is submitted to the specified provider for immediate processing.
5. **Reconciliation**: Upon successful collection, the policy's financial status is updated.
### Key Concepts
- **Ad-Hoc Collection**: A manual or event-triggered collection that occurs outside the regular billing cycle.
- **Collection Method**: The payment mechanism used (e.g., DEBIT_ORDER, EFT).
- **Collection Provider**: The third-party service responsible for processing the payment.
- **Arrears Amount**: If no amount is specified, the system defaults to collecting the outstanding arrears.
### Use Cases
- **Arrears Recovery**: Collecting outstanding amounts when a policy is in arrears.
- **Premium Top-up**: Processing additional payments requested by the policyholder.
- **Payment Retry**: Re-attempting a failed scheduled collection.
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"createdDate": "2024-03-15T10:30:00Z",
"createdBy": "operator@example.com",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"collectionMethod": "DEBIT_ORDER",
"collectionProviderName": "PaymentProvider",
"collectionAmount": {
"currency": "ZAR",
"amount": 250.00
},
"collectionDate": "2024-03-16T00:00:00Z"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "PerformAdHocPremiumCollectionCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy to perform ad-hoc collection on."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
},
"collectionMethod": {
"type": "string",
"description": "The method to use for collection (e.g., DEBIT_ORDER, EFT)."
},
"collectionProviderName": {
"type": "string",
"description": "The name of the collection provider to use for processing the payment."
},
"collectionAmount": {
"type": "object",
"description": "The amount to collect. If null, defaults to the arrears amount.",
"properties": {
"currency": {
"type": "string",
"description": "The currency code (e.g., ZAR)."
},
"amount": {
"type": "number",
"description": "The monetary amount to collect."
}
}
},
"collectionDate": {
"type": "string",
"format": "date-time",
"description": "The effective date for the collection."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId", "collectionMethod", "collectionProviderName", "collectionDate"],
"additionalProperties": false
}
---
id: PerformPricingCalculation
name: Perform Pricing Calculation
version: 0.0.1
summary: Perform a pricing calculation for a given set of inputs
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Pricing
backgroundColor: yellow
textColor: black
---
## Overview
Performs a pricing calculation based on the provided inputs such as cover amounts, ages, product configurations, and partner rules. Returns the calculated premium and associated rating factors.
## HTTP Endpoint
```
POST /v1/pricing/perform-calculations
```
## Upstream Service
Proxied to the **Pricing** domain service.
---
id: RedeemInventoryItemForExistingPolicy
name: Redeem Inventory Item For Existing Policy
version: 0.0.1
summary: Command to redeem an inventory item and link it to an existing policy.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Redemption
backgroundColor: green
textColor: white
---
## Overview
The Redeem Inventory Item For Existing Policy command is used to redeem a prepaid inventory item and extend coverage on an existing insurance policy. This allows customers to top-up their existing policy with additional prepaid coverage.
## Purpose
This command allows redemption by providing:
- Serial number of the item to redeem
- Policy code of the existing policy
- Cover term for the extension
## Request
The command requires the serial number and existing policy reference.
### Key Fields
- **serialNumber**: The 16-digit serial number of the item
- **policyCode**: Reference to the existing policy
- **coverTerm**: Duration of additional coverage
- **redeemedAt**: Original redemption timestamp
## Validation
The command validates:
- Item is active and not already redeemed
- Item has not expired
- Policy code references a valid existing policy
## Response
Upon successful execution, the item is marked as redeemed with the policy reference and an InventoryItemRedeemedExistingPolicyEventV2 is emitted to trigger policy extension.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "RedeemInventoryItemForExistingPolicy",
"type": "object",
"title": "RedeemInventoryItemForExistingPolicy",
"description": "Command to process an existing policy redemption/update for an inventory item.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for tracking"
},
"serialNumber": {
"type": "string",
"pattern": "^[0-9]{16}$",
"description": "16-digit serial number of the item to redeem"
},
"policyCode": {
"type": "string",
"description": "Reference to the existing policy"
},
"redeemedAt": {
"type": "string",
"format": "date-time",
"description": "Original redemption timestamp"
},
"coverTerm": {
"type": "integer",
"description": "Duration of additional coverage in months"
}
},
"required": ["id", "serialNumber", "policyCode"]
}
---
id: RedeemInventoryItemForNewPolicy
name: Redeem Inventory Item For New Policy
version: 0.0.1
summary: Command to redeem an inventory item to create a new insurance policy.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Redemption
backgroundColor: green
textColor: white
---
## Overview
The Redeem Inventory Item For New Policy command is used to redeem a prepaid inventory item and create a new insurance policy. This is the primary redemption flow for customers who do not have an existing policy.
## Purpose
This command allows redemption by providing:
- Serial number of the item to redeem
- Products with covered life details
- Policy start date and cover term
- Beneficiary information
## Request
The command requires the serial number and product details for the new policy.
### Key Fields
- **serialNumber**: The 16-digit serial number of the item
- **products**: List of products with life and beneficiary details
- **policyStartDate**: When the coverage should begin
- **coverTerm**: Duration of coverage
- **coverTermChronoUnit**: Unit for the cover term (e.g., MONTHS)
## Validation
The command validates:
- Item is active and not already redeemed
- Item has not expired
- Products match bundle configuration
- Cover term is allowed by configuration
## Response
Upon successful execution, the item is marked as redeemed and an InventoryItemRedeemedNewPolicyEventV2 is emitted to trigger policy creation.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "RedeemInventoryItemForNewPolicy",
"type": "object",
"title": "RedeemInventoryItemForNewPolicy",
"description": "Command to redeem a product bundle inventory item for a new policy.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation identifier for tracking"
},
"serialNumber": {
"type": "string",
"pattern": "^[0-9]{16}$",
"description": "16-digit serial number of the item to redeem"
},
"products": {
"type": "array",
"description": "List of products for the new policy",
"items": {
"$ref": "#/$defs/Product"
}
},
"policyStartDate": {
"type": "string",
"format": "date-time",
"description": "Start date for the policy coverage"
},
"coverTerm": {
"type": "integer",
"description": "Duration of coverage"
},
"coverTermChronoUnit": {
"type": "string",
"enum": ["DAYS", "WEEKS", "MONTHS", "YEARS"],
"description": "Unit for the cover term"
}
},
"required": ["id", "serialNumber", "products", "policyStartDate"],
"$defs": {
"Product": {
"type": "object",
"properties": {
"bundleProductShortCode": {
"type": "string",
"description": "Short code mapping to bundle product"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "Unique product instance identifier"
},
"productLifeId": {
"type": "string",
"format": "uuid",
"description": "Product life identifier"
},
"name": {
"type": "string",
"description": "First name of the covered life"
},
"surname": {
"type": "string",
"description": "Surname of the covered life"
},
"dateOfBirth": {
"type": "string",
"format": "date",
"description": "Date of birth"
},
"gender": {
"type": "string",
"enum": ["MALE", "FEMALE"],
"description": "Gender"
},
"identification": {
"type": "object",
"description": "Identification details"
},
"productLifeRelationshipToMain": {
"type": "string",
"description": "Relationship to main life"
},
"beneficiaries": {
"type": "array",
"items": {
"$ref": "#/$defs/Beneficiary"
}
}
},
"required": ["bundleProductShortCode", "productLifeRelationshipToMain"]
},
"Beneficiary": {
"type": "object",
"properties": {
"beneficiaryId": {
"type": "string",
"format": "uuid",
"description": "Beneficiary identifier"
},
"percentageAllocation": {
"type": "number",
"description": "Percentage allocation"
},
"name": {
"type": "string",
"description": "First name"
},
"surname": {
"type": "string",
"description": "Surname"
}
}
}
}
}
---
id: RefreshPolicyScheduleLink
name: Refresh Policy Schedule Link
version: 0.0.1
summary: Refresh the download link for the policy schedule document
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Refreshes the pre-signed download link for an existing policy schedule document. Pre-signed URLs have a limited validity period, and this command generates a new valid link when the previous one has expired.
## HTTP Endpoint
```
POST /v1/policy/refresh-policy-schedule-download-link
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: RefreshScheduleDownloadLink
name: Refresh Schedule Download Link
version: 0.0.1
summary: Command to refresh the download link for a policy schedule document
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Refresh Schedule Download Link command is used to generate a new, valid download link for an existing policy schedule document. Download links typically have a limited validity period for security reasons, and this command allows refreshing an expired link.
## Purpose
This command:
- Generates a new pre-signed URL for the policy schedule document
- Extends the availability window for document download
- Maintains security by not keeping permanent download links
## Key Fields
- **policyId**: The identifier of the policy whose schedule download link should be refreshed.
## Typical Use Cases
- When a policyholder's previous download link has expired
- When sending a new notification with a fresh download link
- When re-sharing policy documents through customer service channels
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "RefreshScheduleDownloadLink",
"type": "object",
"title": "RefreshScheduleDownloadLink",
"description": "Command to refresh the download link for a policy schedule document.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The command creator"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The policy identifier"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
}
},
"required": ["id", "policyId"]
}
---
id: ReinstatePolicy
name: Reinstate Policy
version: 0.0.1
summary: Command to reinstate a previously cancelled or lapsed funeral policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Reinstate Policy command is used to restore a previously cancelled or lapsed funeral policy to active status. This command handles scenarios where a policy needs to be brought back into force after being in a non-active state.
## Purpose
When a policy needs to be reinstated, this command:
- Restores the policy to active status effective from the reinstatement date
- Updates the policy status with the appropriate reinstatement sub-status
- Resumes collection activities
- Restores coverage for the policyholder
- Triggers downstream events for collections and customer communications
## Request
The command requires the policy identifier, reinstatement date, and the reinstatement sub-status to process the reinstatement.
### Key Fields
- **policyId**: The identifier of the policy to be reinstated
- **reinstatementDate**: The effective date of the reinstatement
- **reinstatementSubStatus**: The category of reinstatement (e.g., PAYMENT_RECEIVED, ADMINISTRATIVE_CORRECTION)
- **reinstatementReason**: A detailed description explaining why the policy is being reinstated
- **requesteeOrigin**: Where the reinstatement request originated from
## Response
Upon successful execution, the command reinstates the policy and emits relevant domain events for downstream systems including collections, reporting, and customer communications.
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "ReinstatePolicy",
"type": "object",
"title": "ReinstatePolicy",
"description": "Command to reinstate a previously cancelled or lapsed funeral policy. This command handles policy reinstatement scenarios where a policy needs to be restored to active status.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy to reinstate"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracking related operations"
},
"reinstatementDate": {
"type": "string",
"format": "date-time",
"description": "The date on which the policy reinstatement takes effect"
},
"reinstatementReason": {
"type": "string",
"description": "A detailed description of the reason for reinstatement"
},
"reinstatementSubStatus": {
"type": "string",
"description": "The sub-status indicating the specific reinstatement category",
"enum": [
"PAYMENT_RECEIVED",
"ADMINISTRATIVE_CORRECTION",
"CLIENT_REQUEST",
"SYSTEM_ERROR_CORRECTION"
]
},
"requesteeOrigin": {
"type": "string",
"description": "The origin of the reinstatement request indicating whether initiated by the system, client service portal, self-service portal, etc.",
"enum": [
"SYSTEM",
"CLIENT_SERVICE_PORTAL",
"SELF_SERVICE_PORTAL",
"API",
"BATCH_PROCESS"
]
}
},
"required": ["id", "policyId", "reinstatementDate", "reinstatementSubStatus"]
}
---
id: ReinstatePolicyRequest
name: Reinstate Policy Request
version: 0.0.1
summary: Request reinstatement of a lapsed policy
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Submits a request to reinstate a policy that has lapsed due to non-payment or other reasons. Reinstatement restores the policy to active status, subject to applicable conditions and any arrears being settled.
## HTTP Endpoint
```
POST /v1/policy/reinstate-policy
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: ReinstateProductWithoutChange
name: Reinstate Product Without Change
version: 0.0.1
summary: Command to reinstate a lapsed or cancelled product within a funeral policy without modifying its terms.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Cover
backgroundColor: teal
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The ReinstateProductWithoutChange command reinstates a previously lapsed or cancelled product within a funeral policy. This command restores the product to active status without any modifications to its original terms, cover amounts, or premium structure.
### Key Concepts
- **Reinstatement**: The process of restoring a lapsed or cancelled policy/product back to active status.
- **Without Change**: Indicates that the reinstatement preserves all original terms - no underwriting changes, premium adjustments, or cover modifications are applied.
- **Product Instance**: The specific product within the policy being reinstated.
### Business Rules
- The product must have been previously active on the policy
- Reinstatement typically requires settlement of any outstanding premiums
- The original policy terms, benefits, and premium structure are preserved
- May be subject to reinstatement windows or grace period rules
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440004",
"createdDate": "2024-03-15T10:30:00Z",
"createdBy": "customer-service",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"productInstanceId": "456e7891-c23d-45f6-b78a-123456789abc"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ReinstateProductWithoutChangeCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the product instance to reinstate."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId", "productInstanceId"],
"additionalProperties": false
}
---
id: RemoveBeneficiary
name: Remove Beneficiary
version: 0.0.1
summary: Command to remove a beneficiary from a product on a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Remove Beneficiary command removes an existing beneficiary from a specific product on a quote.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote containing the beneficiary |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `productInstanceId` | UUID | Yes | The product instance the beneficiary belongs to |
| `beneficiaryId` | UUID | Yes | The beneficiary to remove |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "RemoveBeneficiary",
"type": "object",
"title": "RemoveBeneficiary",
"description": "Command to remove a beneficiary from a product on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the product instance"
},
"beneficiaryId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the beneficiary to remove"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "productInstanceId", "beneficiaryId"]
}
---
id: RemoveBeneficiaryFromPolicy
name: Remove Beneficiary From Policy
version: 0.0.1
summary: Remove a beneficiary from a policy
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Removes an existing beneficiary from a policy. The beneficiary will no longer be entitled to receive policy benefits upon the occurrence of a covered event.
## HTTP Endpoint
```
DELETE /v1/policy/beneficiary
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: RemoveBeneficiaryFromQuote
name: Remove Beneficiary From Quote
version: 0.0.1
summary: Remove a beneficiary from a quote
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Removes a previously added beneficiary from a quote. The beneficiary will no longer be associated with the quote or any resulting policy.
## HTTP Endpoint
```
DELETE /v1/quote/beneficiary
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: RemoveOptionalBenefit
name: Remove Optional Benefit
version: 0.0.1
summary: Command to remove an optional benefit from a product on a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Remove Optional Benefit command removes an optional benefit or rider from a specific product on a quote.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote containing the benefit |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `benefitId` | UUID | Yes | The benefit to remove |
| `productInstanceId` | UUID | Yes | The product instance the benefit is on |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "RemoveOptionalBenefit",
"type": "object",
"title": "RemoveOptionalBenefit",
"description": "Command to remove an optional benefit from a product on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"benefitId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the benefit to remove"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The product instance the benefit is on"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "benefitId", "productInstanceId"]
}
---
id: RemoveOptionalBenefitOnProducts
name: Remove Optional Benefit On Products
version: 0.0.1
summary: Command to remove an optional benefit from all products on a quote simultaneously.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Remove Optional Benefit On Products command removes an optional benefit from all products on a quote in a single operation. This is the counterpart to `AddOptionalBenefitToAllProducts` and is used when a global benefit needs to be removed across all product instances on the quote.
## Purpose
This command:
- Removes an optional benefit from all products on the quote
- Provides the partner and package context for validation
## Difference from RemoveOptionalBenefit
Unlike `RemoveOptionalBenefit` which targets a specific product instance, this command removes the benefit from all product instances on the quote simultaneously.
## Request
### Key Fields
- **quoteId**: The quote from which the benefit is being removed
- **benefitId**: The identifier of the optional benefit to remove
- **partnerId**: The partner that owns the benefit configuration
- **packageId**: The partner package context
- **correlationId**: Correlation identifier for tracking related operations
## Response
Upon successful execution, the optional benefit is removed from all product instances on the quote.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "RemoveOptionalBenefitOnProducts",
"type": "object",
"title": "RemoveOptionalBenefitOnProducts",
"description": "Command to remove an optional benefit from all products on a quote simultaneously.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"benefitId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the optional benefit to remove"
},
"partnerId": {
"type": "string",
"description": "The identifier of the partner"
},
"packageId": {
"type": "string",
"description": "The identifier of the partner package"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"benefitId",
"partnerId",
"packageId"
]
}
---
id: RepudiateClaim
name: Repudiate Claim
version: 0.0.1
summary: Repudiate (reject) a claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Repudiates (formally rejects) a claim that does not meet the required criteria for payout. This command records the reason for repudiation and transitions the claim to a repudiated state.
## HTTP Endpoint
```
POST /v1/claims/repudiate-claim
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: RepudiateClaimCommand
name: Repudiate Claim
version: 0.0.1
summary: Command to repudiate (deny) a claim with reason codes.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Repudiate Claim command denies a claim, recording the reason codes for repudiation. This marks a terminal negative outcome for the claim.
## Key Fields
- **claimId**: The claim to repudiate
- **repudiationReasonCodes**: List of reason codes explaining the repudiation
- **repudiatedBy**: The user or system performing the repudiation
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim status to repudiated and emits a `ClaimRepudiatedEventV1`.
---
id: RescheduleGracePeriodCheck
name: Reschedule Grace Period Check
version: 0.0.1
summary: SuperAdmin ops command that re-arms a lost or stale grace-period check for a policy.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Collection
backgroundColor: green
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The RescheduleGracePeriodCheck command is a SuperAdmin ops command, dispatched from the Agent Servicing Claims Portal (ASCP) via BFFASCP, that re-arms a grace-period check for a policy whose scheduled `CheckPaymentBeforeGracePeriod` entry was lost or never confirmed. It is the remediation path for policies left without a live grace check after the 2026-07-29 `CollectionFailedEvent` reversal-gap incident.
### Reschedule Workflow
1. **Initiation**: A SuperAdmin agent triggers the reschedule from the collections tab in ASCP, typically after a warning banner shows no live grace-period check is scheduled.
2. **Validation**: The command is rejected if a live (`ACTIVE`, future-dated) grace check is already scheduled for the policy.
3. **Stale Entry Handling**: Any existing entry that is `PENDING` (never confirmed) or past its `scheduledFor` date is marked `FAILED`, preserving it in the policy's history.
4. **Fire Date Computation**: The fire date is computed using the same grace-period-end logic applied at collection time, floored at `now + 24h` so re-arming never triggers an immediate cancellation.
5. **Scheduling**: The command requests a scheduled-command mutation (`UPSERT`) via the existing scheduling reactor, which creates the `CheckGracePmt-` EventBridge schedule and reconciles the entry to `ACTIVE`.
6. **Audit**: An audit entry is recorded naming the requesting agent and the computed fire date.
### Key Concepts
- **Grace-Period Check**: The scheduled `CheckPaymentBeforeGracePeriod` command that determines whether a policy lapses after a failed collection.
- **Stale/Lost Schedule**: A grace entry that is `PENDING` and was never confirmed by the scheduler, or whose `scheduledFor` date has already passed, leaving the policy with no live check.
- **Scheduled Command Mutation**: The existing EventBridge-backed reactor used to create, update, and reconcile scheduled commands — no new scheduling infrastructure is introduced by this command.
### Invariants
- A live `ACTIVE`, future-dated grace check is already scheduled for the policy → rejected (`GRACE_CHECK_ALREADY_SCHEDULED`).
### Use Cases
- **Incident Remediation**: Re-arming the grace-period check for policies left with no live check after the 2026-07-29 incident (e.g. a `PENDING` entry that was never confirmed).
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"createdDate": "2026-08-06T10:30:00Z",
"createdBy": "bff-ascp",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "RescheduleGracePeriodCheckCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The system identity that created the command (the BFFASCP service)."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy to reschedule the grace-period check for."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId"],
"additionalProperties": false
}
---
id: ReverseCollectionOutcome
name: Reverse Collection Outcome
version: 0.0.1
summary: SuperAdmin ops command that reverses a previously recorded successful collection outcome affected by the CollectionFailedEvent reversal gap.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Collection
backgroundColor: green
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The ReverseCollectionOutcome command is a SuperAdmin ops command, dispatched from the Agent Servicing Claims Portal (ASCP) via BFFASCP, that compensates a previously recorded **successful** collection whose `CollectionFailedEvent` was consumed before the reversal-aware `apply(CollectionFailedEvent)` shipped (2026-07-29 incident). Affected policies were left with a phantom `COLLECTION_RECEIPT` debit and a balance of `0` after a collection that actually failed.
The command applies the same reversal logic as the shipped forward fix, but as an explicit, audited, idempotent ops action for the policies whose events had already been consumed by the old code path.
### Reversal Workflow
1. **Initiation**: A SuperAdmin agent triggers the reversal from the collections tab in ASCP, after reviewing the collection history for a policy.
2. **Validation**: The command is rejected if no `COLLECTION_RECEIPT` exists for the given `collectionId`, or if a reversal credit has already been applied for it.
3. **Compensation**: A `COLLECTION_REVERSAL` credit is appended, the balance is deducted, and `runningBalanceSuccess` is decremented.
4. **Event Publication**: The existing `CollectionOutcomeReversedEvent` is emitted — the same event the forward-fixed apply path already publishes.
5. **Audit**: An audit entry is recorded naming the requesting agent (`requestedBy` / `requestedByRole`), not `SYSTEM`.
### Key Concepts
- **Reversal-Aware Apply**: The forward fix (in prd since 2026-07-29) that correctly compensates a successful collection when its failure event arrives out of order. This command re-applies that same compensation for events consumed before the fix shipped.
- **COLLECTION_RECEIPT / COLLECTION_REVERSAL**: The debit recorded for a successful collection, and the credit recorded to reverse it.
- **Idempotency**: Enforced via command-ID dedup (`executeIfNotProcessed`) and a per-collection reversal-credit gate — replaying the command for the same `collectionId` after a successful reversal is rejected, not re-applied.
### Invariants
- No `COLLECTION_RECEIPT` exists for the given `collectionId` → rejected (`COLLECTION_RECEIPT_NOT_FOUND`).
- A reversal has already been recorded for the given `collectionId` → rejected (`COLLECTION_ALREADY_REVERSED`).
### Use Cases
- **Incident Remediation**: Reversing the phantom receipts left on policies affected by the 2026-07-29 out-of-order `CollectionFailedEvent` retrospective, ahead of their scheduled grace-period checks.
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"createdDate": "2026-08-06T10:30:00Z",
"createdBy": "bff-ascp",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"collectionId": "coll-9f8e7d6c-5b4a-3210-9876-543210fedcba",
"requestedBy": "jane.agent",
"requestedByRole": "SuperAdmin"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "ReverseCollectionOutcomeCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The system identity that created the command (the BFFASCP service)."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy whose collection outcome is being reversed."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
},
"collectionId": {
"type": "string",
"description": "The identifier of the collection whose successful outcome is being reversed."
},
"requestedBy": {
"type": "string",
"description": "The username of the SuperAdmin agent who requested the reversal, recorded in the audit entry."
},
"requestedByRole": {
"type": "string",
"description": "The role of the requesting agent at the time of the request (e.g. SuperAdmin)."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId", "collectionId", "requestedBy", "requestedByRole"],
"additionalProperties": false
}
---
id: ScheduledClaimSendNotification
name: Scheduled Claim Send Notification
version: 0.0.1
summary: Command to send a scheduled claims notification when its dispatch time is reached.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Scheduled
backgroundColor: purple
textColor: white
---
## Overview
The Scheduled Claim Send Notification command is invoked by the notification scheduler when a previously scheduled claims notification reaches its dispatch time. This command triggers the notification dispatch process for a specific claim.
## Purpose
When a scheduled claim notification's dispatch time arrives, this command:
- Loads the claim notification state aggregate
- Re-evaluates trigger conditions to ensure they are still valid
- Triggers the notification dispatch if conditions pass
- Updates the state to reflect the notification was processed
## Request
The command requires the claim identifier, notification type, and scheduling metadata to process the scheduled notification.
### Key Fields
- **commandId**: Unique identifier for this command instance
- **claimId**: The claim for which the notification was scheduled
- **partnerId**: The partner identifier for configuration lookup
- **packageId**: The package identifier for notification configuration
- **notificationType**: The type of claim notification to send
- **scheduledFor**: The time the notification was scheduled for
- **correlationId**: Correlation ID for tracing
## Processing
Upon invocation:
1. Load the claim notification state aggregate
2. Verify the notification is still pending (not cancelled)
3. Re-evaluate trigger rules against current claim state
4. If rules pass, emit NotificationTriggeredEvent
5. If rules fail, notification may be cancelled or rescheduled
## Response
Successful execution triggers the notification dispatch pipeline, ultimately resulting in delivery to the claimant via email or SMS.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "ScheduledClaimSendNotification",
"x-schema-format": "JSON Schema",
"x-note": "Internal command - invoked by AWS EventBridge Scheduler",
"type": "object",
"title": "ScheduledClaimSendNotification",
"description": "Command to send a scheduled claims notification when its dispatch time is reached.",
"required": ["commandId", "claimId", "notificationType", "scheduledFor"],
"properties": {
"commandId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for this command instance"
},
"createdBy": {
"type": ["string", "null"],
"description": "The creator of the command (typically 'scheduler')"
},
"createdDate": {
"type": ["string", "null"],
"format": "date-time",
"description": "The command creation timestamp"
},
"claimId": {
"type": "object",
"description": "The claim identifier",
"required": ["value"],
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the claim ID"
}
}
},
"partnerId": {
"type": "object",
"description": "The partner identifier for configuration lookup",
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the partner ID"
}
}
},
"packageId": {
"type": "object",
"description": "The package identifier for notification configuration",
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the package ID"
}
}
},
"notificationType": {
"type": "string",
"description": "The type of claim notification to send",
"enum": [
"CLAIM_REJECTED",
"CLAIM_APPROVED_POLICY_ACTIVE",
"CLAIM_APPROVED_POLICY_LAPSED",
"CLAIM_PAYOUT_COMPLETE",
"CLAIM_SUBMISSION_RECEIVED",
"MISSING_DOCUMENTS",
"CLAIM_UNDER_INVESTIGATION"
]
},
"scheduledFor": {
"type": "string",
"format": "date-time",
"description": "The time the notification was scheduled for dispatch"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracing related operations"
}
}
}
---
id: ScheduledPolicySendNotification
name: Scheduled Policy Send Notification
version: 0.0.1
summary: Command to send a scheduled policy notification when its dispatch time is reached.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Scheduled
backgroundColor: purple
textColor: white
---
## Overview
The Scheduled Policy Send Notification command is invoked by the notification scheduler when a previously scheduled policy notification reaches its dispatch time. This command triggers the notification dispatch process for a specific policy.
## Purpose
When a scheduled notification's dispatch time arrives, this command:
- Loads the policy notification state aggregate
- Re-evaluates trigger conditions to ensure they are still valid
- Triggers the notification dispatch if conditions pass
- Updates the state to reflect the notification was processed
## Request
The command requires the policy identifier, notification type, and scheduling metadata to process the scheduled notification.
### Key Fields
- **commandId**: Unique identifier for this command instance
- **policyId**: The policy for which the notification was scheduled
- **partnerId**: The partner identifier for configuration lookup
- **packageId**: The package identifier for notification configuration
- **notificationType**: The type of notification to send
- **scheduledFor**: The time the notification was scheduled for
- **correlationId**: Correlation ID for tracing
## Processing
Upon invocation:
1. Load the policy notification state aggregate
2. Verify the notification is still pending (not cancelled)
3. Re-evaluate trigger rules against current policy state
4. If rules pass, emit NotificationTriggeredEvent
5. If rules fail, notification may be cancelled or rescheduled
## Response
Successful execution triggers the notification dispatch pipeline, ultimately resulting in delivery via email or SMS.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "ScheduledPolicySendNotification",
"x-schema-format": "JSON Schema",
"x-note": "Internal command - invoked by AWS EventBridge Scheduler",
"type": "object",
"title": "ScheduledPolicySendNotification",
"description": "Command to send a scheduled policy notification when its dispatch time is reached.",
"required": ["commandId", "policyId", "notificationType", "scheduledFor"],
"properties": {
"commandId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for this command instance"
},
"createdBy": {
"type": ["string", "null"],
"description": "The creator of the command (typically 'scheduler')"
},
"createdDate": {
"type": ["string", "null"],
"format": "date-time",
"description": "The command creation timestamp"
},
"policyId": {
"type": "object",
"description": "The policy identifier",
"required": ["value"],
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the policy ID"
}
}
},
"partnerId": {
"type": "object",
"description": "The partner identifier for configuration lookup",
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the partner ID"
}
}
},
"packageId": {
"type": "object",
"description": "The package identifier for notification configuration",
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the package ID"
}
}
},
"notificationType": {
"type": "string",
"description": "The type of notification to send",
"enum": [
"POLICY_EXPIRING_SOON",
"POLICY_EXPIRING_IN_ONE_WEEK",
"POLICY_EXPIRING_IN_TWO_WEEKS",
"POLICY_EXPIRING_TOMORROW",
"POLICY_PAYMENT_REMINDER",
"WAITING_PERIOD_COMPLETE",
"POLICY_NO_BENEFICIARIES_ADDED",
"POLICY_OUTSTANDING_BENEFICIARY_INFO"
]
},
"scheduledFor": {
"type": "string",
"format": "date-time",
"description": "The time the notification was scheduled for dispatch"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracing related operations"
}
}
}
---
id: ScheduledQuoteSendNotification
name: Scheduled Quote Send Notification
version: 0.0.1
summary: Command to send a scheduled quote notification when its dispatch time is reached.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Scheduled
backgroundColor: purple
textColor: white
- content: SQS
backgroundColor: yellow
textColor: black
---
## Overview
The Scheduled Quote Send Notification command is consumed via SQS by the `SchedQuoteSendNotificationCommandHandler` when a previously scheduled quote notification reaches its dispatch time. This command triggers the notification dispatch process for a specific quote.
## Purpose
When a scheduled quote notification's dispatch time arrives, this command:
- Loads the quote notification state aggregate
- Re-evaluates trigger conditions to ensure they are still valid
- Triggers the notification dispatch if conditions pass
- Updates the state to reflect the notification was processed
## Request
The command requires the quote identifier, notification type, and scheduling metadata to process the scheduled notification.
### Key Fields
- **commandId**: Unique identifier for this command instance
- **quoteId**: The quote for which the notification was scheduled
- **partnerId**: The partner identifier for configuration lookup
- **packageId**: The package identifier for notification configuration
- **notificationType**: The type of notification to send
- **scheduledFor**: The time the notification was scheduled for
- **correlationId**: Correlation ID for tracing
## Processing
Upon invocation:
1. Load the quote notification state aggregate
2. Verify the notification is still pending (not cancelled)
3. Re-evaluate trigger rules against current quote state
4. If rules pass, emit NotificationTriggeredEvent
5. If rules fail, notification may be cancelled
## Transport
This command is delivered via **AWS SQS**. The `SchedQuoteSendNotificationCommandHandler` reads messages from the queue and dispatches to the domain command handler. Failed messages are routed to an invalid message queue or dead-letter queue.
## Response
Successful execution triggers the notification dispatch pipeline, ultimately resulting in delivery via email or SMS.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "ScheduledQuoteSendNotification",
"x-schema-format": "JSON Schema",
"x-note": "SQS command - consumed by SchedQuoteSendNotificationCommandHandler",
"type": "object",
"title": "ScheduledQuoteSendNotification",
"description": "Command to send a scheduled quote notification when its dispatch time is reached.",
"required": ["commandId", "quoteId", "notificationType", "scheduledFor"],
"properties": {
"commandId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for this command instance"
},
"createdBy": {
"type": ["string", "null"],
"description": "The creator of the command (typically 'scheduler')"
},
"createdDate": {
"type": ["string", "null"],
"format": "date-time",
"description": "The command creation timestamp"
},
"quoteId": {
"type": "object",
"description": "The quote identifier",
"required": ["value"],
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the quote ID"
}
}
},
"partnerId": {
"type": "object",
"description": "The partner identifier for configuration lookup",
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the partner ID"
}
}
},
"packageId": {
"type": "object",
"description": "The package identifier for notification configuration",
"properties": {
"value": {
"type": "string",
"format": "uuid",
"description": "UUID value of the package ID"
}
}
},
"notificationType": {
"type": "string",
"description": "The type of notification to send (quote-related notification types)"
},
"scheduledFor": {
"type": "string",
"format": "date-time",
"description": "The time the notification was scheduled for dispatch"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracing related operations"
}
}
}
---
id: SendAdHocQuoteNotification
name: Send Ad Hoc Quote Notification
version: 0.0.1
summary: Send an ad-hoc quote notification
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Triggers an ad-hoc notification related to a quote, such as resending a quote summary or reminder to the policyholder.
## HTTP Endpoint
```
POST /api/v1/quote/notification
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: SendNotification
name: Send Notification
version: 0.0.1
summary: Command to send an enriched notification to the delivery provider gateway.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Gateway
backgroundColor: green
textColor: white
---
## Overview
The Send Notification command is the final command in the notification dispatch pipeline. It represents an enriched notification ready for delivery through the Glue notification gateway. This command is created after a notification is triggered and enriched with recipient details and rendered templates.
## Purpose
This command:
- Contains the fully rendered notification content
- Specifies the delivery channel (email or SMS)
- Includes recipient contact details
- Provides sender identity configuration
- Enables idempotent delivery through the gateway
## Request
The command contains all information needed for delivery.
### Key Fields
- **id**: Unique command identifier (used for idempotency)
- **notificationMedium**: Delivery channel (EMAIL or SMS)
- **destination**: Recipient contact details (email address or phone number)
- **senderIdentity**: Configured sender (from address, display name)
- **message**: Rendered notification content (subject, body, attachments)
- **gcid**: Global correlation ID for tracing
## Enrichment Process
Before this command is created:
1. Notification is triggered (immediate or scheduled)
2. Recipient contact details are resolved from policy/claims state
3. Templates are rendered with context data
4. Attachments are prepared if configured
5. Sender identity is resolved from partner configuration
## Response
The command is sent to the Glue notification gateway which handles:
- Email delivery via AWS SES
- SMS delivery via the configured SMS provider
- Delivery status callbacks (success/failure events)
## Idempotency
The command ID is used to ensure idempotent delivery. If the same command is received multiple times, subsequent attempts are ignored.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "SendNotification",
"x-schema-format": "JSON Schema",
"x-note": "Internal command - sent to Glue notification gateway via SQS",
"type": "object",
"title": "SendNotification",
"description": "Command to send an enriched notification to the delivery provider gateway.",
"required": ["id", "notificationMedium", "destination", "message"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for this command (used for idempotency)"
},
"gcid": {
"type": "string",
"format": "uuid",
"description": "Global correlation ID for distributed tracing"
},
"notificationMedium": {
"type": "string",
"enum": ["EMAIL", "SMS"],
"description": "The delivery channel for the notification"
},
"destination": {
"$ref": "#/$defs/Destination",
"description": "The recipient contact details"
},
"senderIdentity": {
"$ref": "#/$defs/SenderIdentity",
"description": "The configured sender identity"
},
"message": {
"$ref": "#/$defs/NotificationMessage",
"description": "The notification content"
},
"attachments": {
"type": ["array", "null"],
"items": {
"$ref": "#/$defs/Attachment"
},
"description": "Optional attachments for email notifications"
}
},
"$defs": {
"Destination": {
"type": "object",
"description": "Recipient contact details",
"properties": {
"emailAddress": {
"type": ["string", "null"],
"format": "email",
"description": "Email address for EMAIL medium"
},
"phoneNumber": {
"type": ["string", "null"],
"description": "Phone number for SMS medium"
},
"recipientName": {
"type": ["string", "null"],
"description": "Display name of the recipient"
}
}
},
"SenderIdentity": {
"type": ["object", "null"],
"description": "Configured sender identity",
"properties": {
"emailFrom": {
"type": ["string", "null"],
"format": "email",
"description": "Sender email address"
},
"emailFromName": {
"type": ["string", "null"],
"description": "Sender display name"
},
"smsFrom": {
"type": ["string", "null"],
"description": "SMS sender ID"
}
}
},
"NotificationMessage": {
"type": "object",
"description": "The notification content",
"properties": {
"subject": {
"type": ["string", "null"],
"description": "Email subject line (for EMAIL medium)"
},
"body": {
"$ref": "#/$defs/Body",
"description": "The message body content"
}
}
},
"Body": {
"type": "object",
"description": "Message body configuration",
"properties": {
"format": {
"type": "string",
"enum": ["HTML", "TEXT"],
"description": "Content format"
},
"source": {
"type": "string",
"enum": ["INLINE", "S3_OBJECT", "S3_PRESIGNED_URL"],
"description": "Where the body content is stored"
},
"content": {
"type": ["string", "null"],
"description": "Inline content (for INLINE source)"
},
"bucket": {
"type": ["string", "null"],
"description": "S3 bucket (for S3 sources)"
},
"key": {
"type": ["string", "null"],
"description": "S3 object key (for S3 sources)"
},
"presignedUrl": {
"type": ["string", "null"],
"format": "uri",
"description": "Presigned URL (for S3_PRESIGNED_URL source)"
}
}
},
"Attachment": {
"type": "object",
"description": "Email attachment configuration",
"properties": {
"filename": {
"type": "string",
"description": "Display filename for the attachment"
},
"format": {
"type": "string",
"enum": ["PDF", "PNG", "JPEG"],
"description": "Attachment file format"
},
"source": {
"type": "string",
"enum": ["INLINE", "S3_OBJECT", "S3_PRESIGNED_URL"],
"description": "Where the attachment is stored"
},
"bucket": {
"type": ["string", "null"],
"description": "S3 bucket (for S3 sources)"
},
"key": {
"type": ["string", "null"],
"description": "S3 object key (for S3 sources)"
}
}
}
}
}
---
id: SendPolicyNotification
name: Send Policy Notification
version: 0.0.1
summary: Send a policy notification to the policyholder
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Sends a notification to the policyholder regarding their policy. Notifications may include policy activation confirmations, schedule documents, premium changes, or other policy-related communications.
## HTTP Endpoint
```
POST /v1/policy/send-policy-notification
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: SendQuoteNotification
name: Send Quote Notification
version: 0.0.1
summary: Send a quote notification to the customer
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Sends a notification to the customer regarding their quote, such as a quote summary, reminder, or finalised quote document via email or SMS.
## HTTP Endpoint
```
POST /v1/quote/notification
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: SetFileOrigination
name: Set File Origination
version: 0.0.1
summary: Command to set or update the origination context of a file
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Set File Origination command is used to set or update the business context (origination) of an existing file. This enables files to be associated with their business entity after upload.
## Purpose
This command allows origination management by:
- Setting the origination context for a file
- Linking files to specific business entities
- Enabling quote-to-policy document migration
- Supporting document reassignment workflows
## Request
The command requires the file identifier and new origination details.
### Key Fields
- **fileId**: Unique identifier of the file to update
- **origination**: New source context (CLAIMS, POLICY, QUOTE)
- **originationId**: Identifier of the new associated entity
- **createdBy**: User or system making the change
- **correlationId**: Correlation ID for tracking
## Response
Upon successful execution, the command:
1. Updates the file's origination and originationId
2. Emits a `FileOriginationSetEventV1` event
3. Notifies downstream systems of the change
## Use Cases
- Files uploaded before their final business context is known
- Converting quote documents to policy documents
- Associating claim evidence with specific claims
- Reassigning documents between business contexts
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "SetFileOriginationCommand",
"title": "SetFileOriginationCommand",
"description": "Command to set or update the origination context of a file. Wire format: JSON (REST API)",
"x-schema-format": "json",
"type": "object",
"required": [
"id",
"createdDate",
"createdBy",
"fileId",
"origination",
"originationId",
"correlationId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the command"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the command was created"
},
"createdBy": {
"type": "string",
"description": "User or system that created the command"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier of the file to update"
},
"origination": {
"type": "string",
"enum": ["CLAIMS", "POLICY", "QUOTE"],
"description": "New source context for the file"
},
"originationId": {
"type": "string",
"format": "uuid",
"description": "Identifier of the new associated entity"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking"
}
}
}
---
id: SetQuoteCoverStartDate
name: Set Quote Cover Start Date
version: 0.0.1
summary: Command to set the cover start date for a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Set Quote Cover Start Date command sets when the insurance coverage will begin for the quote. This determines the effective date of the policy once the quote is converted.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote to set the cover start date for |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `coverStartDate` | ISO 8601 | Yes | The date when coverage should start |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "SetQuoteCoverStartDate",
"type": "object",
"title": "SetQuoteCoverStartDate",
"description": "Command to set the cover start date for a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"coverStartDate": {
"type": "string",
"format": "date-time",
"description": "The date when coverage should start"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "coverStartDate"]
}
---
id: SetTAndCsAccepted
name: Set Terms and Conditions Accepted
version: 0.0.1
summary: Command to record acceptance of terms and conditions on a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Set Terms and Conditions Accepted command records that the customer has accepted the terms and conditions associated with the quote. This is a required step before finalizing a quote.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote for T&Cs acceptance |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `isTermsAccepted` | Boolean | Yes | Whether the terms are accepted |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "SetTAndCsAccepted",
"type": "object",
"title": "SetTAndCsAccepted",
"description": "Command to record acceptance of terms and conditions on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"isTermsAccepted": {
"type": "boolean",
"description": "Whether the terms and conditions are accepted"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "isTermsAccepted"]
}
---
id: SetTAndCsAcceptedWithVerificationMacro
name: Set T And Cs Accepted With Verification Macro
version: 0.0.1
summary: Macro command that records Terms and Conditions acceptance together with verification in a single atomic operation.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Macro
backgroundColor: red
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Set T And Cs Accepted With Verification Macro command is a composite (macro) command that records the policyholder's acceptance of the Terms and Conditions and simultaneously adds a verification step — all as a single atomic operation.
## Purpose
This macro command combines:
- Recording T&C acceptance on the quote
- Adding verification configuration
By executing these together, the system ensures that T&C acceptance and verification are always recorded consistently.
## Macro Command Pattern
This command extends `QuoteMacroCommand` and contains a `commands` list of `QuoteCommand` sub-commands. The `quoteId` at the macro level identifies which quote is being operated on.
## Request
### Key Fields
- **quoteId**: The quote on which T&Cs are being accepted
- **commands**: List of sub-commands (SetTAndCsAcceptedCommand, AddVerificationToQuoteCommand) executed as part of this macro
- **id**: The macro command identifier
- **createdDate**: The command creation timestamp
- **createdBy**: The user or system issuing the macro command
## Response
Upon successful execution, the quote is updated with T&C acceptance and verification details applied.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "SetTAndCsAcceptedWithVerificationMacro",
"type": "object",
"title": "SetTAndCsAcceptedWithVerificationMacro",
"description": "Macro command that records Terms and Conditions acceptance together with verification in a single atomic operation.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The macro command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"commands": {
"type": "array",
"items": {
"type": "object"
},
"description": "List of sub-commands (SetTAndCsAcceptedCommand, AddVerificationToQuoteCommand) executed as part of this macro"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"commands"
]
}
---
id: SetTermsAndConditionsAccepted
name: Set Terms And Conditions Accepted
version: 0.0.1
summary: Record acceptance of terms and conditions on a quote
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Records that the customer has accepted the terms and conditions associated with a quote. This acceptance is a required step before a quote can be finalised and a policy issued.
## HTTP Endpoint
```
PUT /v1/quote/accept-terms
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: StackCover
name: Stack Cover
version: 0.0.1
summary: Command to stack additional cover amount on an existing funeral policy product.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Cover
backgroundColor: teal
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The StackCover command adds additional cover to an existing funeral policy product. Cover stacking allows policyholders to increase their total benefit amount by layering new cover on top of existing cover, rather than replacing or modifying the original policy.
### Key Concepts
- **Cover Stacking**: A mechanism to add incremental cover amounts to a policy, creating multiple layers of protection that aggregate into a total benefit.
- **Product Instance**: The specific product within the policy that the additional cover is being stacked onto.
- **Tranche**: Each stacked cover may create a new tranche (layer) within the policy structure.
### Business Benefits
- Allows policyholders to incrementally increase their coverage as their needs change
- Maintains the original policy terms while adding new cover with potentially different terms
- Provides flexibility in premium structuring for additional cover
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"createdDate": "2024-03-15T10:30:00Z",
"createdBy": "sales-portal",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"productInstanceId": "456e7891-c23d-45f6-b78a-123456789abc",
"stackCoverAmount": {
"amount": 10000.00,
"currency": "ZAR"
},
"premium": {
"amount": 150.00,
"currency": "ZAR"
},
"inceptionDate": "2024-04-01T00:00:00Z",
"term": {
"start": "2024-04-01T00:00:00Z"
},
"salesChannelId": "abc12345-d67e-89f0-g123-456789hijklm",
"salesAgentId": "def45678-g90h-12i3-j456-789012klmnop"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "StackCoverCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the product instance to stack cover on."
},
"stackCoverAmount": {
"type": "object",
"description": "The additional cover amount to stack on the existing policy.",
"properties": {
"amount": {
"type": "number",
"description": "The monetary amount."
},
"currency": {
"type": "string",
"description": "The currency code (e.g., ZAR)."
}
},
"required": ["amount", "currency"]
},
"premium": {
"type": "object",
"description": "The premium amount for the stacked cover.",
"properties": {
"amount": {
"type": "number",
"description": "The monetary amount."
},
"currency": {
"type": "string",
"description": "The currency code (e.g., ZAR)."
}
},
"required": ["amount", "currency"]
},
"inceptionDate": {
"type": "string",
"format": "date-time",
"description": "The inception date for the stacked cover."
},
"term": {
"type": "object",
"description": "The temporal interval defining the term of the stacked cover.",
"properties": {
"start": {
"type": "string",
"format": "date-time",
"description": "The start date of the term."
},
"end": {
"type": "string",
"format": "date-time",
"description": "The end date of the term."
}
},
"required": ["start"]
},
"salesChannelId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the sales channel."
},
"salesAgentId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the sales agent."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId", "productInstanceId", "stackCoverAmount", "premium", "inceptionDate", "term", "salesChannelId", "salesAgentId"],
"additionalProperties": false
}
---
id: StackCoverRequest
name: Stack Cover Request
version: 0.0.1
summary: Request to stack cover on a policy
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Submits a request to stack (add additional layers of) cover on an existing policy. Stacking cover allows policyholders to increase their total cover amount above the standard single policy limit.
## HTTP Endpoint
```
POST /v1/policy/stack-cover
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: StaggerCover
name: Stagger Cover
version: 0.0.1
summary: Command to stagger the cover amount on an existing funeral policy, phasing in benefits over time.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Cover
backgroundColor: teal
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The StaggerCover command applies staggered cover arrangements to an existing funeral policy product. Cover staggering is a mechanism where benefit amounts are phased in over time rather than being immediately available in full, typically used to manage risk during the early stages of a policy.
### Key Concepts
- **Cover Staggering**: A risk management technique where the full benefit amount becomes available gradually over defined periods, rather than from day one of the policy.
- **Waiting Period**: Related to staggering, this is the period during which reduced or no cover applies before the full benefit kicks in.
- **Product Instance**: The specific product within the policy that the staggered cover applies to.
### Business Benefits
- Reduces anti-selection risk by phasing in benefits over time
- Provides a mechanism for managing claims during the initial policy period
- Allows for different benefit levels at different stages of the policy lifecycle
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "550e8400-e29b-41d4-a716-446655440003",
"createdDate": "2024-03-15T10:30:00Z",
"createdBy": "sales-portal",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"productInstanceId": "456e7891-c23d-45f6-b78a-123456789abc",
"term": {
"start": "2024-04-01T00:00:00Z",
"end": "2025-04-01T00:00:00Z"
},
"salesChannelId": "abc12345-d67e-89f0-g123-456789hijklm",
"salesAgentId": "def45678-g90h-12i3-j456-789012klmnop"
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "StaggerCoverCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The date and time when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user who created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking the command across services."
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the product instance to stagger cover on."
},
"term": {
"type": "object",
"description": "The temporal interval defining the term of the staggered cover.",
"properties": {
"start": {
"type": "string",
"format": "date-time",
"description": "The start date of the term."
},
"end": {
"type": "string",
"format": "date-time",
"description": "The end date of the term."
}
},
"required": ["start"]
},
"salesChannelId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the sales channel."
},
"salesAgentId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the sales agent."
}
},
"required": ["id", "createdDate", "createdBy", "policyId", "correlationId", "productInstanceId", "term", "salesChannelId", "salesAgentId"],
"additionalProperties": false
}
---
id: StaggerCoverRequest
name: Stagger Cover Request
version: 0.0.1
summary: Request to stagger cover on a policy
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Submits a request to stagger the cover on a policy, distributing cover across multiple policies or time periods to achieve a desired total cover structure.
## HTTP Endpoint
```
POST /v1/policy/stagger-cover
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: SubmitClaimToCrm
name: Submit Claim To CRM
version: 0.0.1
summary: Submit claim data to the CRM system
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Submits claim data to the external CRM (Customer Relationship Management) system for case management, follow-up tracking, and customer communication purposes.
## HTTP Endpoint
```
POST /v1/claims/submit-to-crm
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: SubmitClaimToCrmCommand
name: Submit Claim to CRM
version: 0.0.1
summary: Command to submit a claim to the CRM system for servicing.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Integration
backgroundColor: orange
textColor: white
---
## Overview
The Submit Claim to CRM command packages the claim documents and submits them to the CRM system for servicing. This creates a CRM case for the claim.
## Key Fields
- **claimId**: The claim to submit to CRM
- **documentPackLink**: Link to the packaged claim documents
- **submittedBy**: The user submitting the claim
- **correlationId**: Correlation ID for tracking
## Response
Records the CRM submission and emits a `ClaimSubmittedToCrmEventV1` with detail type `claimSubmittedToCrm`.
---
id: UpdateBankingDetailsOnClaim
name: Update Banking Details On Claim
version: 0.0.1
summary: Update claimant banking details on a claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Updates the banking details recorded on a claim for the purpose of claim payout. This command allows corrections or changes to the claimant's bank account information before payment is processed.
## HTTP Endpoint
```
PUT /v1/claims/update-banking-details
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: UpdateBankingDetailsOnClaimCommand
name: Update Banking Details on Claim
version: 0.0.1
summary: Command to update claimant banking details on an existing claim.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Financial
backgroundColor: green
textColor: white
---
## Overview
The Update Banking Details on Claim command modifies the claimant's banking details on an existing claim. This is used when banking details need to be corrected or changed after initial capture.
## Key Fields
- **claimId**: The claim to update banking details on
- **bankingDetails**: Updated bank name, account number, account type, branch code
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim banking details and emits a `ClaimUpdatedEventV1` with detail type `claimUpdatedBankDetails`.
---
id: UpdateBeneficiary
name: Update Beneficiary
version: 0.0.1
summary: Command to update an existing beneficiary on a quote.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Update Beneficiary command modifies the details of an existing beneficiary on a product within a quote.
## Request
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | UUID | Yes | Command identifier |
| `createdDate` | ISO 8601 | Yes | Command creation timestamp |
| `createdBy` | String | Yes | User or system that created the command |
| `quoteId` | UUID | Yes | The quote containing the beneficiary |
| `correlationId` | UUID | Yes | Correlation ID for tracking |
| `productInstanceId` | UUID | Yes | The product instance the beneficiary belongs to |
| `beneficiaryId` | UUID | Yes | The beneficiary to update |
| `name` | String | Yes | Beneficiary's first name |
| `surname` | String | Yes | Beneficiary's surname |
| `dateOfBirth` | Date | Yes | Beneficiary's date of birth |
| `gender` | String | Yes | Beneficiary's gender |
| `identification` | Object | Yes | Beneficiary's identification details |
| `percentageAllocation` | Number | Yes | Percentage of benefit allocated to this beneficiary |
| `mobileNumber` | String | No | Beneficiary's mobile number |
| `emailAddress` | String | No | Beneficiary's email address |
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateBeneficiary",
"type": "object",
"title": "UpdateBeneficiary",
"description": "Command to update an existing beneficiary on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the product instance"
},
"beneficiaryId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the beneficiary to update"
},
"name": {
"type": "string",
"description": "The beneficiary's first name"
},
"surname": {
"type": "string",
"description": "The beneficiary's surname"
},
"dateOfBirth": {
"type": "string",
"format": "date",
"description": "The beneficiary's date of birth"
},
"gender": {
"type": "string",
"enum": ["MALE", "FEMALE"],
"description": "The beneficiary's gender"
},
"identification": {
"type": "object",
"description": "The beneficiary's identification details",
"properties": {
"type": {
"type": "string",
"description": "The type of identification"
},
"number": {
"type": "string",
"description": "The identification number"
}
}
},
"percentageAllocation": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "The percentage of benefit allocated to this beneficiary"
},
"mobileNumber": {
"type": "string",
"description": "The beneficiary's mobile number"
},
"emailAddress": {
"type": "string",
"format": "email",
"description": "The beneficiary's email address"
}
},
"required": ["id", "createdDate", "createdBy", "quoteId", "correlationId", "productInstanceId", "beneficiaryId", "name", "surname", "dateOfBirth", "gender", "identification", "percentageAllocation"]
}
---
id: UpdateBeneficiaryOnPolicy
name: Update Beneficiary On Policy
version: 0.0.1
summary: Update beneficiary details on a policy
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Updates the details of an existing beneficiary on a policy. This command allows amendments to beneficiary personal details, allocation percentages, or other beneficiary-related information.
## HTTP Endpoint
```
PUT /v1/policy/beneficiary
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: UpdateBeneficiaryOnQuote
name: Update Beneficiary On Quote
version: 0.0.1
summary: Update beneficiary details on a quote
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Updates the details of an existing beneficiary on a quote, allowing corrections to personal information or changes to allocation percentages before the quote is accepted.
## HTTP Endpoint
```
PUT /v1/quote/beneficiary
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: UpdateBillingDate
name: Update Billing Date
version: 0.0.1
summary: Command to update the billing date of a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: teal
textColor: white
---
## Overview
The Update Billing Date command is used to modify the billing date for a policy. This command allows changing when premium collections should occur, which affects the collection schedule and payment timing.
## What Can Be Updated
This command allows updates to:
- **Billing Date**: The date on which premium collections are scheduled
## Key Fields
- **policyId**: The identifier of the policy to update
- **billingDate**: The new billing date for premium collections. This date determines when the next and subsequent collections will be scheduled.
## Usage Context
This command is typically triggered when:
- A policyholder requests to change their payment date to align with salary deposits
- Business rules require adjustment of collection timing
- Reinstatement processes need to reset the billing cycle
- Administrative corrections are needed for billing alignment
- Premium holidays or skips affect the billing schedule
## Impact
Updating the billing date will:
- Modify the next scheduled collection date
- Affect future collection schedules
- May trigger recalculation of collection timelines
- Could impact grace period calculations
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "UpdateBillingDate",
"type": "object",
"title": "UpdateBillingDate",
"description": "Command to update the billing date of a policy. This command allows modification of when premium collections should occur.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy to update"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracing"
},
"billingDate": {
"type": "string",
"format": "date-time",
"description": "The new billing date for premium collections"
}
},
"required": ["id", "policyId", "billingDate"]
}
---
id: UpdateClaimDocumentVerificationStatusCommand
name: Update Claim Document Verification Status
version: 0.0.1
summary: Command to update the document verification status on a claim.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
---
## Overview
The Update Claim Document Verification Status command updates the verification status of documents attached to a claim. This tracks whether claim supporting documents have been verified.
## Key Fields
- **claimId**: The claim to update document verification for
- **documentVerificationStatus**: The new verification status
- **correlationId**: Correlation ID for tracking
## Response
Updates the document verification status on the claim.
---
id: UpdateClaimForCoveredLifeDeath
name: Update Claim For Covered Life Death
version: 0.0.1
summary: Update details on a covered life claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Updates the details of an existing covered life claim, such as death details, claimant information, or supporting documentation.
## HTTP Endpoint
```
PUT /api/v1/claims/update-claim-covered-life
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: UpdateClaimForCoveredLifeDeathCommand
name: Update Claim for Covered Life Death
version: 0.0.1
summary: Command to update claim details specific to a covered life death scenario.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Update Claim for Covered Life Death command updates claim details specific to a covered life (dependent) death scenario. This handles the claim processing differences between main life and covered life claims.
## Key Fields
- **claimId**: The claim to update
- **coveredLifeDetails**: Updated covered life details
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim for covered life death processing and emits a `ClaimUpdatedEventV1` with detail type `claimUpdatedCoveredLife`.
---
id: UpdateCollectionAccountPreferences
name: Update Collection Account Preferences
version: 0.0.1
summary: Command to update collection account preferences for a customer
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Profile
backgroundColor: cyan
textColor: black
---
## Overview
The Update Collection Account Preferences command updates the collection account details in a customer profile.
## Response
On success, emits `CollectionAccountPreferencesUpdatedEventV1`. On failure, emits `CollectionAccountPreferencesUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateCollectionAccountPreferences",
"title": "UpdateCollectionAccountPreferences",
"description": "Command to update collection account preferences for a customer.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId", "collectionAccount"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"collectionAccount": {
"type": "object",
"required": ["method"],
"properties": {
"method": { "type": "string" },
"number": { "type": "string" },
"owner": { "type": "string" },
"currency": { "type": "string" },
"country": { "type": "string" },
"bankCode": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"expirationDate": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"securityCode": { "oneOf": [{ "type": "null" }, { "type": "string" }] }
}
}
}
}
---
id: UpdateCollectionDetails
name: Update Collection Details
version: 0.0.1
summary: Command to update collection and financial details for a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: teal
textColor: white
---
## Overview
The Update Collection Details command is used to modify the financial and collection configuration of a policy. This includes bank details, collection methods, payment schedules, and related financial settings that govern how premiums are collected.
## What Can Be Updated
This command allows updates to:
- **Bank Details**: Account number, bank name, branch code, account holder name
- **Collection Configuration**: Collection method (debit order, EFT), frequency, selected day
- **Payment Settings**: Third party payer details, source of funds, authorisation status
- **Schedule Management**: Collection schedules, next collection date, grace periods
## Key Fields
- **policyId**: The identifier of the policy to update
- **policyFinancialDetail**: The complete financial detail object containing:
- Bank account details for collections
- Collection frequency and method
- Collection day selection
- Third party payer information
- Collection schedules and grace periods
- Client authorisation status
## Usage Context
This command is typically triggered when:
- A policyholder changes their bank account details
- The collection method needs to be updated (e.g., switching from debit order to EFT)
- The preferred collection day is changed
- A third party payer is added or removed
- Collection schedules need to be modified
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "UpdateCollectionDetails",
"type": "object",
"title": "UpdateCollectionDetails",
"description": "Command to update collection and financial details for a policy. This command allows modification of payment methods, bank details, collection schedules, and related financial configurations.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy to update"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracing"
},
"policyFinancialDetail": {
"type": "object",
"description": "The policy financial detail containing updated collection information",
"properties": {
"policyBalance": {
"type": "object",
"description": "The current policy balance",
"properties": {
"amount": {
"type": "number",
"description": "The balance amount"
},
"currency": {
"type": "string",
"description": "The currency code (e.g., ZAR)"
}
}
},
"nextCollectionDate": {
"type": "string",
"format": "date-time",
"description": "The next scheduled collection date"
},
"previousCollectionStatus": {
"type": "string",
"description": "Status of the previous collection attempt"
},
"latestCollectionAuthorised": {
"type": "boolean",
"description": "Whether the latest collection was authorised"
},
"latestCollectionAuthorisedDate": {
"type": "string",
"format": "date-time",
"description": "Date when the latest collection was authorised"
},
"thirdPartyPayer": {
"type": "object",
"description": "Third party payer details if applicable"
},
"thirdPartyPaymentReference": {
"type": "string",
"description": "Reference for third party payments"
},
"bankDetails": {
"type": "object",
"description": "Bank account details for collections",
"properties": {
"bankName": {
"type": "string",
"description": "Name of the bank"
},
"accountNumber": {
"type": "string",
"description": "Bank account number"
},
"branchCode": {
"type": "string",
"description": "Bank branch code"
},
"accountHolderName": {
"type": "string",
"description": "Name of the account holder"
},
"accountType": {
"type": "string",
"description": "Type of bank account"
}
}
},
"collectionFrequency": {
"type": "string",
"description": "The frequency of premium collections (e.g., MONTHLY, QUARTERLY)"
},
"collectionDaySelected": {
"type": "integer",
"description": "The day of the month selected for collections",
"minimum": 1,
"maximum": 31
},
"collectionMethod": {
"type": "string",
"description": "The method used for premium collection (e.g., DEBIT_ORDER, EFT)"
},
"collectionProviderName": {
"type": "string",
"description": "Name of the collection provider"
},
"collectionId": {
"type": "string",
"format": "uuid",
"description": "The collection identifier"
},
"clientAuthorise": {
"type": "boolean",
"description": "Whether the client has authorised collections"
},
"sourceOfFunds": {
"type": "string",
"description": "The source of funds for premium payments"
},
"collectionSchedules": {
"type": "array",
"description": "List of collection schedules",
"items": {
"type": "object"
}
},
"collectionGracePeriod": {
"type": "object",
"description": "The grace period configuration for collections"
}
}
}
},
"required": ["id", "policyId", "policyFinancialDetail"]
}
---
id: UpdateCoveredLifeClaim
name: Update Covered Life Claim
version: 0.0.1
summary: Update details on a covered life claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Updates the details on an existing claim for a covered life. This command allows amendments to covered life claim information after initial creation without recalculating the payout.
## HTTP Endpoint
```
PUT /v1/claims/update-claim-covered-life
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: UpdateCoveredLifeClaimAndCalcPayout
name: Update Covered Life Claim And Calculate Payout
version: 0.0.1
summary: Update covered life claim details and recalculate payout
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Updates the details on a covered life claim and immediately triggers a recalculation of the payout amount. This combined command is used when claim amendments for a covered life are expected to affect the payout figure.
## HTTP Endpoint
```
PUT /v1/claims/update-and-calculate-covered-life-claim
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: UpdateCoveredLifeClaimAndCalculatePayoutMacroCommand
name: Update Covered Life Claim and Calculate Payout (Macro)
version: 0.0.1
summary: Macro command that updates a covered life claim and calculates the payout in a single operation.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Macro
backgroundColor: red
textColor: white
---
## Overview
This macro command combines updating a covered life claim with payout calculation in a single atomic operation. It orchestrates the `UpdateClaimForCoveredLifeDeathCommand` followed by `CalculateClaimPayoutCommand`.
## Key Fields
- **claimId**: The claim to update and calculate payout for
- **coveredLifeDetails**: Updated covered life details
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim and calculates the payout amount in a single transaction.
---
id: UpdateCustomerAddressIdentity
name: Update Customer Address Identity
version: 0.0.1
summary: Command to update a customer's address with a new certificate
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: green
textColor: white
---
## Overview
The Update Customer Address Identity command updates the address on a Global Identity. The update requires a certificate with sufficient trust level.
## Response
On success, emits `CustomerIdentityAddressUpdatedEventV1`. On failure, emits `CustomerIdentityAddressUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateCustomerAddressIdentity",
"title": "UpdateCustomerAddressIdentity",
"description": "Command to update a customer's address with a new certificate.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId", "address", "certificate"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"address": {
"type": "object",
"required": ["streetAddress", "suburb", "city", "provinceOrState", "postalCode", "countryCode"],
"properties": {
"streetAddress": { "type": "string" },
"unitName": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"unitNumber": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"suburb": { "type": "string" },
"city": { "type": "string" },
"region": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"provinceOrState": { "type": "string" },
"postalCode": { "type": "string" },
"countryCode": { "type": "string" }
}
},
"certificate": {
"type": "object",
"required": ["certificateId", "trustLevel", "creationTime"],
"properties": {
"certificateId": { "type": "string", "format": "uuid" },
"trustLevel": { "type": "number" },
"creationTime": { "type": "integer" }
}
}
}
}
---
id: UpdateCustomerDateOfBirthIdentity
name: Update Customer Date of Birth Identity
version: 0.0.1
summary: Command to update a customer's date of birth with a new certificate
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: green
textColor: white
---
## Overview
The Update Customer Date of Birth Identity command updates the date of birth on a Global Identity. The update requires a certificate with sufficient trust level.
## Response
On success, emits `CustomerIdentityDateOfBirthUpdatedEventV1`. On failure, emits `CustomerIdentityDateOfBirthUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateCustomerDateOfBirthIdentity",
"title": "UpdateCustomerDateOfBirthIdentity",
"description": "Command to update a customer's date of birth with a new certificate.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId", "dateOfBirth", "certificate"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"dateOfBirth": { "type": "integer", "description": "Date of birth (days since epoch)" },
"certificate": {
"type": "object",
"required": ["certificateId", "trustLevel", "creationTime"],
"properties": {
"certificateId": { "type": "string", "format": "uuid" },
"trustLevel": { "type": "number" },
"creationTime": { "type": "integer" }
}
}
}
}
---
id: UpdateCustomerEmailIdentity
name: Update Customer Email Identity
version: 0.0.1
summary: Command to update a customer's email address with a new certificate
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: green
textColor: white
---
## Overview
The Update Customer Email Identity command updates the email address on a Global Identity. The update requires a certificate with sufficient trust level.
## Response
On success, emits `CustomerIdentityEmailAddressUpdatedEventV1`. On failure, emits `CustomerIdentityEmailAddressUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateCustomerEmailIdentity",
"title": "UpdateCustomerEmailIdentity",
"description": "Command to update a customer's email address with a new certificate.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId", "emailAddress", "certificate"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"emailAddress": { "type": "string", "format": "email" },
"certificate": {
"type": "object",
"required": ["certificateId", "trustLevel", "creationTime"],
"properties": {
"certificateId": { "type": "string", "format": "uuid" },
"trustLevel": { "type": "number" },
"creationTime": { "type": "integer" }
}
}
}
}
---
id: UpdateCustomerGenderIdentity
name: Update Customer Gender Identity
version: 0.0.1
summary: Command to update a customer's gender with a new certificate
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: green
textColor: white
---
## Overview
The Update Customer Gender Identity command updates the gender on a Global Identity. The update requires a certificate with sufficient trust level.
## Response
On success, emits `CustomerIdentityGenderUpdatedEventV1`. On failure, emits `CustomerIdentityGenderUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateCustomerGenderIdentity",
"title": "UpdateCustomerGenderIdentity",
"description": "Command to update a customer's gender with a new certificate.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId", "gender", "certificate"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"gender": { "type": "string", "enum": ["MALE", "FEMALE", "NONBINARY", "PREFER_NOT_TO_SAY", "UNKNOWN"] },
"certificate": {
"type": "object",
"required": ["certificateId", "trustLevel", "creationTime"],
"properties": {
"certificateId": { "type": "string", "format": "uuid" },
"trustLevel": { "type": "number" },
"creationTime": { "type": "integer" }
}
}
}
}
---
id: UpdateCustomerMobileIdentity
name: Update Customer Mobile Identity
version: 0.0.1
summary: Command to update a customer's mobile number with a new certificate
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: green
textColor: white
---
## Overview
The Update Customer Mobile Identity command updates the mobile number on a Global Identity. The update requires a certificate with sufficient trust level.
## Response
On success, emits `CustomerIdentityMobileNumberUpdatedEventV1`. On failure, emits `CustomerIdentityMobileNumberUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateCustomerMobileIdentity",
"title": "UpdateCustomerMobileIdentity",
"description": "Command to update a customer's mobile number with a new certificate.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId", "mobileNumber", "certificate"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"globalCustomerId": { "type": "string", "format": "uuid" },
"mobileNumber": {
"type": "object",
"required": ["phoneCountryCode", "localNumber"],
"properties": {
"phoneCountryCode": { "type": "string" },
"localNumber": { "type": "string" }
}
},
"certificate": {
"type": "object",
"required": ["certificateId", "trustLevel", "creationTime"],
"properties": {
"certificateId": { "type": "string", "format": "uuid" },
"trustLevel": { "type": "number" },
"creationTime": { "type": "integer" }
}
}
}
}
---
id: UpdateCustomerNameIdentity
name: Update Customer Name Identity
version: 0.0.1
summary: Command to update a customer's name with a new certificate
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: green
textColor: white
---
## Overview
The Update Customer Name Identity command updates the person name on a Global Identity. The update requires a certificate with sufficient trust level to overwrite the existing value.
## Trust Level Rules
- Higher trust level certificates can overwrite existing values
- Same trust level with later creation time takes precedence
- Lower trust level updates are rejected
## Response
On success, emits `CustomerIdentityNameUpdatedEventV1`. On failure, emits `CustomerIdentityNameUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateCustomerNameIdentity",
"title": "UpdateCustomerNameIdentity",
"description": "Command to update a customer's name with a new certificate.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "globalCustomerId", "personName", "certificate"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related operations"
},
"createdDate": {
"type": "integer",
"description": "Command creation timestamp (milliseconds since epoch)"
},
"createdBy": {
"type": "string",
"description": "Identifier of the command creator"
},
"globalCustomerId": {
"type": "string",
"format": "uuid",
"description": "Global Customer ID of the identity to update"
},
"personName": {
"$ref": "#/$defs/PersonName",
"description": "New person name"
},
"certificate": {
"$ref": "#/$defs/Certificate",
"description": "Certificate for the update"
}
},
"$defs": {
"Certificate": {
"type": "object",
"required": ["certificateId", "trustLevel", "creationTime"],
"properties": {
"certificateId": { "type": "string", "format": "uuid" },
"trustLevel": { "type": "number" },
"creationTime": { "type": "integer" }
}
},
"PersonName": {
"type": "object",
"required": ["name", "familyName"],
"properties": {
"name": { "type": "string" },
"middleNames": { "oneOf": [{ "type": "null" }, { "type": "array", "items": { "type": "string" } }] },
"familyName": { "type": "string" },
"maidenName": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"generationalName": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"suffix": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"titles": { "oneOf": [{ "type": "null" }, { "type": "array", "items": { "type": "string" } }] },
"religiousTitles": { "oneOf": [{ "type": "null" }, { "type": "array", "items": { "type": "string" } }] }
}
}
}
}
---
id: UpdateMainLifeClaim
name: Update Main Life Claim
version: 0.0.1
summary: Update details on a main life claim
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Updates the details on an existing claim for the main life insured. This command allows amendments to claim information after initial creation without recalculating the payout.
## HTTP Endpoint
```
PUT /v1/claims/update-main-life
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: UpdateMainLifeClaimAndCalcPayout
name: Update Main Life Claim And Calculate Payout
version: 0.0.1
summary: Update main life claim details and recalculate payout
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
Updates the details on a main life claim and immediately triggers a recalculation of the payout amount. This combined command is used when claim amendments are expected to affect the payout figure.
## HTTP Endpoint
```
PUT /v1/claims/update-and-calculate-main-life-claim
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: UpdateMainLifeClaimAndCalculatePayoutMacroCommand
name: Update Main Life Claim and Calculate Payout (Macro)
version: 0.0.1
summary: Macro command that updates a main life claim and calculates the payout in a single operation.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Macro
backgroundColor: red
textColor: white
---
## Overview
This macro command combines updating a main life claim with payout calculation in a single atomic operation. It orchestrates the `UpdateMainLifeClaimCommand` followed by `CalculateClaimPayoutCommand`.
## Key Fields
- **claimId**: The claim to update and calculate payout for
- **mainLifeDetails**: Updated main life details
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim and calculates the payout amount in a single transaction.
---
id: UpdateMainLifeClaimCommand
name: Update Main Life Claim
version: 0.0.1
summary: Command to update claim details specific to a main life death scenario.
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Update Main Life Claim command updates claim details specific to a main life (policyholder) death scenario. This handles the claim processing for when the main policyholder has died.
## Key Fields
- **claimId**: The claim to update
- **mainLifeDetails**: Updated main life details
- **correlationId**: Correlation ID for tracking
## Response
Updates the claim for main life death processing and emits a `ClaimUpdatedEventV1` with detail type `claimUpdatedMainLife`.
---
id: UpdateMainProductAndPolicyholderMacro
name: Update Main Product And Policyholder Macro
version: 0.0.1
summary: Macro command that updates the main product and policyholder details on a quote in a single atomic operation.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Macro
backgroundColor: red
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Update Main Product And Policyholder Macro command is a composite (macro) command that updates the main insurance product configuration and the policyholder's personal details on an existing quote in a single atomic operation.
## Purpose
This macro command combines:
- Updating the main product on the quote (UpdateProductOnQuoteCommand)
- Updating policyholder details (CapturePolicyHolderDetailsCommand)
By executing these together, the system ensures that product and policyholder updates remain in sync and prevents partial state inconsistencies.
## Macro Command Pattern
This command extends `QuoteMacroCommand` and contains a `commands` list of `QuoteCommand` sub-commands. The `quoteId` at the macro level identifies which quote is being operated on.
## Request
### Key Fields
- **quoteId**: The quote to update
- **commands**: List of sub-commands (UpdateProductOnQuoteCommand, CapturePolicyHolderDetailsCommand) executed as part of this macro
- **id**: The macro command identifier
- **createdDate**: The command creation timestamp
- **createdBy**: The user or system issuing the macro command
## Response
Upon successful execution, the main product and policyholder details are updated on the quote aggregate.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateMainProductAndPolicyholderMacro",
"type": "object",
"title": "UpdateMainProductAndPolicyholderMacro",
"description": "Macro command that updates the main product and policyholder details on a quote in a single atomic operation.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The macro command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"commands": {
"type": "array",
"items": {
"type": "object"
},
"description": "List of sub-commands (UpdateProductOnQuoteCommand, CapturePolicyHolderDetailsCommand) executed as part of this macro"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"commands"
]
}
---
id: UpdatePersonalDetails
name: Update Personal Details
version: 0.0.1
summary: Command to update personal details of a life on a policy
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: teal
textColor: white
---
## Overview
The Update Personal Details command is used to modify personal information for a specific life (insured person) on a policy. This command supports updating identity information, contact details, and other personal attributes for any product life within a policy.
## What Can Be Updated
This command allows updates to:
- **Identity Information**: First name, last name, ID number, ID type
- **Personal Details**: Date of birth, gender
- **Relationship**: The relationship of the life to the main insured
- **Status**: Whether the product life is active or inactive
## Key Fields
- **policyId**: The identifier of the policy containing the life to update
- **productInstanceId**: The specific product instance containing the life
- **policyProductLife**: The complete product life object with updated personal details, including:
- Product life type (MAIN, SPOUSE, CHILD, EXTENDED_FAMILY)
- Relationship to the main insured
- Unverified identity details (name, DOB, gender, ID)
- Active status
## Usage Context
This command is typically triggered when:
- A policyholder requests to correct personal information
- Identity verification reveals discrepancies
- Administrative updates are required for compliance
- Life events require updates to personal details (e.g., name change)
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "UpdatePersonalDetails",
"type": "object",
"title": "UpdatePersonalDetails",
"description": "Command to update personal details of a life on a policy. This command allows updating identity and personal information for a specific product instance.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy to update"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracing"
},
"productInstanceId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the product instance to update personal details on"
},
"policyProductLife": {
"type": "object",
"description": "The policy product life containing the updated personal details",
"properties": {
"productLifeId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the product life"
},
"productLifeExternalId": {
"type": "string",
"description": "The external identifier of the product life"
},
"productLifeType": {
"type": "string",
"description": "The type of product life (e.g., MAIN, SPOUSE, CHILD, EXTENDED_FAMILY)",
"enum": ["MAIN", "SPOUSE", "CHILD", "EXTENDED_FAMILY"]
},
"relationshipToMain": {
"type": "string",
"description": "The relationship of this life to the main insured"
},
"unverifiedIdentity": {
"type": "object",
"description": "The unverified identity details of the product life",
"properties": {
"firstName": {
"type": "string",
"description": "First name of the life"
},
"lastName": {
"type": "string",
"description": "Last name of the life"
},
"dateOfBirth": {
"type": "string",
"format": "date",
"description": "Date of birth of the life"
},
"gender": {
"type": "string",
"description": "Gender of the life"
},
"idNumber": {
"type": "string",
"description": "Identity document number"
},
"idType": {
"type": "string",
"description": "Type of identity document"
}
}
},
"isActive": {
"type": "boolean",
"description": "Whether this product life is currently active"
}
}
}
},
"required": ["id", "policyId", "productInstanceId", "policyProductLife"]
}
---
id: UpdatePersonalDetailsOnPolicy
name: Update Personal Details On Policy
version: 0.0.1
summary: Update personal details on a policy
owners:
- digisure-engineering
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Updates the personal details of the policyholder on an active policy, such as contact information or address.
## HTTP Endpoint
```
PUT /api/v1/policy/personal-details
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: UpdatePolicyFromQuote
name: Update Policy From Quote
version: 0.0.1
summary: Command to update an existing policy with information from a quote
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Update
backgroundColor: teal
textColor: white
---
## Overview
The Update Policy From Quote command is used to apply changes from a quote to an existing policy. This command is essential for policy amendments and endorsements, where a quote is generated to capture proposed changes and then applied to the active policy.
## What Can Be Updated
This command synchronizes the following from the quote to the policy:
- **Product Configuration**: Quote products, cover amounts, beneficiaries
- **Financial Details**: Premium amounts, administration fees, financial configuration
- **Policyholder Information**: Contact details, personal information
- **Partner Settings**: Partner rules, currency configuration
- **Terms and Conditions**: Updated T&C acceptance status
## Key Fields
- **quote**: The complete quote object containing all proposed changes:
- Quote identification and status
- Sales agent and broker information
- Product and package details
- Financial configuration and premium
- Policyholder details
- Quote deltas (captured changes)
- **policyCode**: The policy code (enriched during processing)
## Usage Context
This command is typically triggered when:
- An endorsement quote is accepted and needs to be applied
- Policy amendments are finalized after quote approval
- Changes to cover, beneficiaries, or premiums are confirmed
- Policy upgrades or downgrades are processed
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "UpdatePolicyFromQuote",
"type": "object",
"title": "UpdatePolicyFromQuote",
"description": "Command to update an existing policy with information from a quote. This command synchronizes policy data with quote changes, typically used for policy amendments and endorsements.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the policy to update"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID for tracing"
},
"policyCode": {
"type": "string",
"description": "The policy code (set through enrichment)"
},
"quote": {
"type": "object",
"description": "The quote containing the updated policy information",
"properties": {
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the quote"
},
"salesAgentId": {
"type": "string",
"format": "uuid",
"description": "The sales agent who created the quote"
},
"brokerId": {
"type": "string",
"format": "uuid",
"description": "The broker associated with the quote"
},
"brokerPercentage": {
"type": "number",
"description": "The broker commission percentage"
},
"productCategory": {
"type": "string",
"description": "The product category (e.g., FUNERAL)"
},
"existingPolicyId": {
"type": "string",
"format": "uuid",
"description": "The existing policy ID being updated"
},
"existingPolicyCode": {
"type": "string",
"description": "The existing policy code being updated"
},
"policyHolder": {
"type": "object",
"description": "The policyholder details"
},
"packageId": {
"type": "string",
"format": "uuid",
"description": "The package identifier"
},
"packageName": {
"type": "string",
"description": "The name of the selected package"
},
"countryCode": {
"type": "string",
"description": "The country code (e.g., ZA)"
},
"salesChannelId": {
"type": "string",
"format": "uuid",
"description": "The sales channel identifier"
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "The partner identifier"
},
"partnerName": {
"type": "string",
"description": "The partner name"
},
"partnerCode": {
"type": "integer",
"description": "The partner code"
},
"quoteStatus": {
"type": "string",
"description": "The current status of the quote"
},
"quoteFinancialDetail": {
"type": "object",
"description": "Financial details of the quote"
},
"coverStart": {
"type": "object",
"description": "Cover start configuration"
},
"quoteStage": {
"type": "string",
"description": "The current stage of the quote"
},
"termsAndConditionsDetail": {
"type": "object",
"description": "Terms and conditions acceptance details"
},
"quoteProducts": {
"type": "array",
"description": "List of products included in the quote",
"items": {
"type": "object"
}
},
"totalPremium": {
"type": "object",
"description": "The total premium amount",
"properties": {
"amount": {
"type": "number"
},
"currency": {
"type": "string"
}
}
},
"partnerRules": {
"type": "object",
"description": "Partner-specific business rules"
},
"policyFinancialConfiguration": {
"type": "object",
"description": "Financial configuration for the policy"
},
"currencyConfiguration": {
"type": "object",
"description": "Currency configuration"
},
"policyAdministrationFee": {
"type": "object",
"description": "The policy administration fee"
},
"quoteDeltas": {
"type": "object",
"description": "Changes/deltas captured in the quote"
}
}
}
},
"required": ["id", "quote"]
}
---
id: UpdateProductOnQuote
name: Update Product On Quote
version: 0.0.1
summary: Command to update a product on a quote, recalculating pricing as needed.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Product
backgroundColor: green
textColor: white
---
## Overview
The Update Product On Quote command modifies an existing product on a quote. Changes to cover amount or risk factors trigger premium recalculation.
## Purpose
This command:
- Updates cover amount for the product
- Updates product life risk factors
- Triggers premium recalculation
- Tracks deltas for requotes
## Request
### Key Fields
- **quoteId**: The quote containing the product
- **partnerId**: The partner that owns the package configuration
- **packageId**: The partner package containing the product
- **productId**: The product definition from the partner package
- **productInstanceId**: The specific product instance to update
- **productCategoryId**: The product category identifier
- **quoteProductLife**: Updated risk factor information
- **futureCover**: Updated cover amount
- **futurePremium**: Updated premium amount (if provided)
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateProductOnQuote",
"type": "object",
"title": "UpdateProductOnQuote",
"description": "Command to update a product on a quote.",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The command identifier"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The command creation date"
},
"createdBy": {
"type": "string",
"description": "The creator of the command"
},
"quoteId": {
"type": "string",
"format": "uuid",
"description": "The identifier of the quote"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The command correlation ID"
},
"partnerId": {
"type": "string",
"description": "The identifier of the partner"
},
"packageId": {
"type": "string",
"description": "The identifier of the partner package"
},
"productId": {
"type": "string",
"description": "The identifier of the product to update"
},
"productInstanceId": {
"type": "string",
"description": "The identifier of the product instance to update"
},
"productCategoryId": {
"type": "string",
"description": "The identifier of the product category"
},
"quoteProductLife": {
"type": "object",
"description": "Updated product life information"
},
"futureCover": {
"type": "object",
"description": "The updated cover amount"
},
"futurePremium": {
"type": "object",
"description": "The updated premium amount"
},
"replacementCoverDetail": {
"type": "object",
"description": "Replacement cover detail, if applicable"
},
"pricingConfigVersion": {
"type": "integer",
"description": "Pricing configuration version used for calculations"
},
"productTerm": {
"type": "object",
"description": "The temporal interval for the product term"
}
},
"required": [
"id",
"createdDate",
"createdBy",
"quoteId",
"correlationId",
"partnerId",
"packageId",
"productId",
"productInstanceId",
"productCategoryId",
"quoteProductLife"
]
}
---
id: UpdateTenantedIdentity
name: Update Tenanted Identity
version: 0.0.1
summary: Command to update an existing tenanted identity record
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Tenanted
backgroundColor: purple
textColor: white
---
## Overview
The Update Tenanted Identity command updates an existing tenanted identity record with new information.
## Response
On success, emits `TenantedIdentityUpdatedEventV1`. On failure, emits `TenantedIdentityUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateTenantedIdentity",
"title": "UpdateTenantedIdentity",
"description": "Command to update a tenanted identity record.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "tenantedIdentityId", "tenantId"],
"properties": {
"id": { "type": "string", "format": "uuid" },
"correlationId": { "type": "string", "format": "uuid" },
"createdDate": { "type": "integer" },
"createdBy": { "type": "string" },
"tenantedIdentityId": { "type": "string", "format": "uuid" },
"tenantId": { "type": "string" },
"globalCustomerId": { "oneOf": [{ "type": "null" }, { "type": "string", "format": "uuid" }] },
"name": { "oneOf": [{ "type": "null" }, { "type": "object" }] },
"issuedIdentity": { "oneOf": [{ "type": "null" }, { "type": "object" }] },
"mobileNumber": { "oneOf": [{ "type": "null" }, { "type": "object" }] },
"emailAddress": { "oneOf": [{ "type": "null" }, { "type": "string" }] },
"residentialAddress": { "oneOf": [{ "type": "null" }, { "type": "object" }] },
"dateOfBirth": { "oneOf": [{ "type": "null" }, { "type": "integer" }] },
"gender": { "oneOf": [{ "type": "null" }, { "type": "string" }] }
}
}
---
id: UpdateUnverifiedIdentity
name: Update Unverified Identity
version: 0.0.1
summary: Command to update an existing unverified identity record
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Unverified
backgroundColor: orange
textColor: white
---
## Overview
The Update Unverified Identity command updates an existing unverified identity record with new or corrected information.
## Purpose
This command is used when:
- Correcting customer information
- Adding missing details to an existing record
- Updating contact information
## Response
On success, emits `UnverifiedIdentityUpdatedEventV1`. On failure, emits `UnverifiedIdentityUpdateFailedEventV1`.
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UpdateUnverifiedIdentity",
"title": "UpdateUnverifiedIdentity",
"description": "Command to update an existing unverified identity record.",
"type": "object",
"required": ["id", "correlationId", "createdDate", "createdBy", "unverifiedIdentityId"],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking related operations"
},
"createdDate": {
"type": "integer",
"description": "Command creation timestamp (milliseconds since epoch)"
},
"createdBy": {
"type": "string",
"description": "Identifier of the command creator"
},
"unverifiedIdentityId": {
"type": "string",
"format": "uuid",
"description": "Identifier of the unverified identity to update"
},
"tenantId": {
"oneOf": [{ "type": "null" }, { "type": "string" }],
"description": "The tenant this identity belongs to"
},
"issuedIdentity": {
"oneOf": [{ "type": "null" }, { "type": "object" }],
"description": "Updated issued identity document"
},
"name": {
"oneOf": [{ "type": "null" }, { "type": "object" }],
"description": "Updated person name"
},
"mobileNumber": {
"oneOf": [{ "type": "null" }, { "type": "object" }],
"description": "Updated mobile number"
},
"emailAddress": {
"oneOf": [{ "type": "null" }, { "type": "string" }],
"description": "Updated email address"
},
"residentialAddress": {
"oneOf": [{ "type": "null" }, { "type": "object" }],
"description": "Updated residential address"
},
"dateOfBirth": {
"oneOf": [{ "type": "null" }, { "type": "integer" }],
"description": "Updated date of birth"
},
"gender": {
"oneOf": [{ "type": "null" }, { "type": "string" }],
"description": "Updated gender"
}
}
}
---
id: UploadFile
name: Upload File
version: 0.0.1
summary: Command to upload a file directly with base64 encoded content
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Lifecycle
backgroundColor: purple
textColor: white
---
## Overview
The Upload File command is used to upload a file directly to the system with base64 encoded content. This command is suitable for smaller files and provides immediate feedback on the upload result.
## Purpose
This command allows direct file upload by providing:
- Base64 encoded file content
- File metadata (name, type)
- Origination context (CLAIMS, POLICY, QUOTE)
- Archive scheduling configuration
- Auxiliary data for custom attributes
## Request
The command requires the file content and metadata including origination context.
### Key Fields
- **fileId**: Unique identifier for the file (generated if not provided)
- **base64body**: The file content encoded as base64
- **fileName**: Original name of the file
- **fileType**: Type of file (PDF, DOC, DOCX, XLS, XLSX, JPEG, PNG)
- **origination**: Source context (CLAIMS, POLICY, QUOTE)
- **originationId**: Identifier of the associated entity
- **archiveAt**: Optional scheduled archive date
- **auxiliaryData**: Optional key-value metadata
- **isThirdParty**: Flag indicating if file is from external source
## Response
Upon successful execution, the command:
1. Validates the file size against limits
2. Stores the file in S3
3. Creates the file aggregate record
4. Emits a `FileUploadedEventV1` event
## Constraints
- Maximum file size is enforced (see domain constants)
- File type must be in the allowed list
- Origination and originationId are required
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "UploadFileCommand",
"title": "UploadFileCommand",
"description": "Command to upload a file with base64 encoded content. Wire format: JSON (REST API)",
"x-schema-format": "json",
"type": "object",
"required": [
"id",
"createdDate",
"createdBy",
"fileId",
"base64body",
"fileName",
"fileType",
"origination",
"originationId",
"correlationId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the command"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "Timestamp when the command was created"
},
"createdBy": {
"type": "string",
"description": "User or system that created the command"
},
"fileId": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the file"
},
"base64body": {
"type": "string",
"description": "Base64 encoded file content"
},
"fileName": {
"type": "string",
"description": "Original name of the file"
},
"fileType": {
"type": "string",
"enum": ["PDF", "DOC", "DOCX", "XLS", "XLSX", "JPEG", "PNG"],
"description": "Type of the file"
},
"isThirdParty": {
"type": ["boolean", "null"],
"description": "Flag indicating if file is from external source"
},
"archiveAt": {
"type": ["string", "null"],
"format": "date-time",
"description": "Scheduled archive date"
},
"auxiliaryData": {
"type": ["object", "null"],
"additionalProperties": {
"type": "string"
},
"description": "Optional key-value metadata"
},
"origination": {
"type": "string",
"enum": ["CLAIMS", "POLICY", "QUOTE"],
"description": "Source context for the file"
},
"originationId": {
"type": "string",
"format": "uuid",
"description": "Identifier of the associated entity"
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "Correlation ID for tracking"
}
}
}
---
id: VerifyParty
name: Verify Party
version: 0.0.1
summary: Command to initiate verification of a party's information through external providers
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Gateway
backgroundColor: purple
textColor: white
---
## Overview
The `VerifyParty` command initiates a verification request for a party through the appropriate external provider based on the verification type. This is the primary entry point to the Verification Service.
## Purpose
When a party needs to be verified, this command:
- Routes the request to the appropriate verification adapter
- Triggers external provider API calls
- Initiates the verification workflow
- Results in verification outcome events being published
## Request
The command requires the party identifier, verification type, and any metadata needed for the specific verification type.
### Key Fields
- **id**: Unique identifier for this command (UUID)
- **correlationId**: Correlation ID for tracing related operations
- **verificationType**: The type of verification to perform
- **partyId**: The CIS identifier for the party to verify
- **metadata**: Additional data specific to the verification type
### Verification Types
| Type | Description | Provider |
|------|-------------|----------|
| `VERIFICATION_OF_PERSONAL_DETAILS` | Verify identity number, name, and deceased status | Astute |
| `VERIFICATION_OF_BANK_DETAILS` | Verify bank account ownership and status | QLink |
| `SANCTIONS_SCREENING` | Screen against sanctions and watchlists | ORMS |
### Metadata Requirements by Type
**VOPD (Personal Details)**
- Identity number
- First name, surname
- Date of birth
**Bank Verification**
- Bank account number
- Bank name/branch code
- Account holder name
**Sanctions Screening**
- Identity number
- Full name (first, middle, last)
- Date of birth
- Nationality
- Country of residence
## Response
The command is processed asynchronously. Outcomes are communicated through domain events:
| Outcome | Event |
|---------|-------|
| Verification passed | `VerificationSucceededEventV1` |
| Retryable failure | `VerificationSoftFailEventV1` |
| Permanent failure | `VerificationHardFailEventV1` |
| ORMS needs review | `OrmsDecisionPendingEventV1` |
| ORMS review complete | `OrmsDecisionFoundEventV1` |
## Usage Example
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"createdDate": 1706889600000,
"createdBy": "policy-service",
"correlationId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"verificationType": "VERIFICATION_OF_PERSONAL_DETAILS",
"partyId": "8f14e45f-ceea-467f-a8f8-e8d05c7eb345",
"metadata": {
"policyId": "POL-12345678",
"requestOrigin": "POLICY_CREATION"
}
}
```
## Raw Schema:schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "VerifyPartyCommandV1",
"title": "VerifyPartyCommandV1",
"description": "Command to initiate verification of a party through an external provider. This is a JSON Schema representation of the Avro schema used in production (namespace: sft.pas.verification.cg.commands.verifypartycommand.avro).",
"x-schema-format": "avro",
"x-avro-namespace": "sft.pas.verification.cg.commands.verifypartycommand.avro",
"x-avro-registry": "sft-capstone-verification-cg-commands-registry",
"type": "object",
"required": [
"id",
"createdDate",
"createdBy",
"correlationId",
"verificationType",
"partyId"
],
"properties": {
"id": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "Unique identifier for the command (UUID as string)"
},
"createdDate": {
"type": "integer",
"x-avro-logical-type": "timestamp-millis",
"description": "Timestamp when the command was created (milliseconds since epoch)"
},
"createdBy": {
"type": "string",
"description": "Identifier of the creator of the command"
},
"correlationId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The correlationId of the command (UUID as string)"
},
"verificationType": {
"type": "string",
"enum": [
"VERIFICATION_OF_PERSONAL_DETAILS",
"VERIFICATION_OF_BANK_DETAILS",
"SANCTIONS_SCREENING"
],
"x-avro-type": "enum",
"x-avro-enum-name": "AvroVerificationType",
"description": "Type of verification to be performed"
},
"partyId": {
"type": "string",
"format": "uuid",
"x-avro-logical-type": "uuid",
"description": "The UUID of the party in CIS"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"x-avro-type": "map",
"default": {},
"description": "Additional data specific to the verification request"
}
}
}
---
id: VerifyPolicyHealth
name: Verify Policy Health
version: 0.0.1
summary: Command to initiate a comprehensive health check on a policy, verifying all required compliance and operational criteria are met.
owners:
- digisure-engineering
schemaPath: schema.json
badges:
- content: Command
backgroundColor: blue
textColor: white
- content: Verification
backgroundColor: indigo
textColor: white
---
import Footer from '@catalog/components/footer.astro';
## Overview
The VerifyPolicyHealth command initiates a comprehensive health verification of a policy. Unlike the AddVerificationToPolicy command which records individual verification outcomes, this command orchestrates multiple verification checks to assess the overall compliance and operational health of a policy.
### Verification Workflow
The policy health verification follows a structured workflow:
1. **Command Initiation**: The command is triggered by a system event, scheduled job, or manual request.
2. **Scope Analysis**: The verification scope determines which aspects of the policy will be checked.
3. **Verification Orchestration**: Individual verification requests are dispatched for each scope item.
4. **Result Aggregation**: All verification outcomes are collected and analyzed.
5. **Health Assessment**: An overall health status is determined based on the verification results.
### Verification Scope Options
The command supports multiple verification scope areas:
- **PERSONAL_DETAILS**: Verify identity and personal information of policy participants
- **BANK_DETAILS**: Verify banking information for premium collection
- **SANCTIONS**: Perform sanctions screening against regulatory lists
- **PREMIUM_STATUS**: Verify premium payment status and collection arrangements
- **COVERAGE_STATUS**: Verify coverage amounts and benefit structures
- **DOCUMENT_COMPLIANCE**: Verify required documents are present and valid
### Verification Stages
Health verification can be performed at different policy lifecycle stages:
- **QUOTE**: Initial verification during quotation
- **POLICY_ACTIVE**: Periodic verification of active policies
- **POLICY_ALTERATION**: Re-verification when policy changes are made
- **CLAIM**: Enhanced verification during claims processing
### Force Revalidation
When `forceRevalidation` is set to true, the system will perform fresh verifications regardless of whether recent verification results exist. This is useful when:
- Regulatory requirements mandate fresh checks
- Previous verification data may be stale
- Manual override of cached verification results is needed
## Architecture diagram
## Payload example
```json title="Payload example"
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"createdDate": "2024-07-15T14:00:00Z",
"createdBy": "policy-health-scheduler",
"policyId": "123e4567-e89b-12d3-a456-426614174000",
"correlationId": "789e1234-b56c-78d9-e012-3456789fghij",
"partnerId": "456e7891-c23d-45f6-b78a-123456789abc",
"verificationScope": [
"PERSONAL_DETAILS",
"BANK_DETAILS",
"SANCTIONS"
],
"verificationStage": "POLICY_ACTIVE",
"triggerSource": "scheduled-health-check",
"forceRevalidation": false
}
```
## Schema
## Raw Schema:schema.json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "VerifyPolicyHealthCommand",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the command."
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "The timestamp when the command was created."
},
"createdBy": {
"type": "string",
"description": "The user or system that created the command."
},
"policyId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the policy to verify."
},
"correlationId": {
"type": "string",
"format": "uuid",
"description": "The correlation ID for tracking related operations across services."
},
"partnerId": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the partner associated with the policy."
},
"verificationScope": {
"type": "array",
"items": {
"type": "string",
"enum": [
"PERSONAL_DETAILS",
"BANK_DETAILS",
"SANCTIONS",
"PREMIUM_STATUS",
"COVERAGE_STATUS",
"DOCUMENT_COMPLIANCE"
]
},
"description": "The aspects of policy health to verify."
},
"verificationStage": {
"type": "string",
"enum": [
"QUOTE",
"POLICY_ACTIVE",
"POLICY_ALTERATION",
"CLAIM"
],
"description": "The stage of the policy lifecycle at which verification is triggered."
},
"triggerSource": {
"type": "string",
"description": "The source or event that triggered the health verification."
},
"forceRevalidation": {
"type": "boolean",
"description": "Whether to force re-verification even if recent verifications exist.",
"default": false
}
},
"required": [
"id",
"createdDate",
"createdBy",
"policyId",
"correlationId",
"partnerId",
"verificationScope",
"verificationStage"
],
"additionalProperties": false
}
---
id: CorsPreflightRequest
name: CORS Preflight Request
version: 0.0.1
summary: Handle browser CORS preflight requests for cross-origin API access
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: CORS
backgroundColor: blue
textColor: white
---
## Overview
The `CorsPreflightRequest` query handles browser-initiated preflight requests sent before making cross-origin HTTP requests. These OPTIONS requests verify the server allows the intended request.
## Request
### HTTP Method
```
OPTIONS {any-path}
```
### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Origin` | Yes | The requesting origin |
| `Access-Control-Request-Method` | Yes | The intended HTTP method |
| `Access-Control-Request-Headers` | No | Custom headers the client wants to send |
### Example Request
```bash
curl -X OPTIONS "https://bff-web.digisure.com/api/v1/quote" \
-H "Origin: https://sanlamonline.co.za" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type, x-recaptcha-token"
```
## Response
### Success Response (204 No Content)
Headers returned:
```
Access-Control-Allow-Origin: https://sanlamonline.co.za
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: content-type, x-recaptcha-token, authorization, x-request-id, x-client-id, x-authorization
Access-Control-Max-Age: 86400
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
```
## Allowed Headers
The service allows the following headers by default:
- `authorization`
- `content-type`
- `x-request-id`
- `x-client-id`
- `x-authorization`
- `x-recaptcha-token`
Additional headers requested via `Access-Control-Request-Headers` are dynamically included.
## Dev Extension Passthrough
When `devExtensionPassthru` is enabled, preflight requests from any origin receive:
```
Access-Control-Allow-Origin: *
```
This is useful for local development but must never be enabled in production.
---
id: DownloadFile
name: Download File
version: 0.0.1
summary: Download an uploaded file by streaming its contents
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: FileUpload
backgroundColor: orange
textColor: white
---
## Overview
Downloads a previously uploaded file by streaming its contents to the caller. The file is identified by its unique file ID and the response streams the file binary data directly.
## HTTP Endpoint
```
GET /v1/file-upload/{fileId}/stream
```
## Upstream Service
Proxied to the **FileUpload** domain service.
---
id: GetBinaryStream
name: Get Binary Stream
version: 0.0.1
summary: Retrieve the binary content of a file as a byte stream
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetBinaryStream` query retrieves the actual binary content of a file as a byte stream. This endpoint is used for downloading file content directly.
## Request
### HTTP Method
```
GET /files/{fileId}/content
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `fileId` | string (UUID) | Yes | The unique identifier of the file to download |
### Example Request
```bash
curl -X GET "https://api.digisure.com/file-upload/files/550e8400-e29b-41d4-a716-446655440000/content" \
-H "Authorization: Bearer {access_token}" \
-o downloaded_file.pdf
```
## Response
### Success Response (200 OK)
Returns the binary file content with appropriate headers:
```
Content-Type: application/pdf
Content-Disposition: attachment; filename="id_document.pdf"
Content-Length: 251392
```
The response body contains the raw binary file content.
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_FILE_ID` | The provided file ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions to access this file |
| 404 | `FILE_NOT_FOUND` | No file exists with the specified ID |
| 410 | `FILE_DELETED` | The file has been deleted |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
## Notes
- For large files, consider using pre-signed download URLs instead
- The response streams directly from S3 storage
- Archived files may have increased retrieval latency
---
id: GetClaim
name: Get Claim
version: 0.0.1
summary: Retrieve a single claim by its unique identifier.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetClaim` query retrieves a single claim by its unique identifier. Returns the complete claim state including claimant details, deceased information, payout status, and document verification status.
## Request
### HTTP Method
```
GET /{claimId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `claimId` | string | Yes | The unique identifier of the claim |
---
id: GetClaimByClaimNumber
name: Get Claim by Claim Number
version: 0.0.1
summary: Retrieve a claim by its human-readable claim number.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetClaimByClaimNumber` query retrieves a claim using its human-readable claim number (as opposed to the internal UUID). This is typically used by customer-facing interfaces where the claim number is the primary reference.
## Request
### HTTP Method
```
GET /by-claim-number/{claimNumber}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `claimNumber` | string | Yes | The human-readable claim number |
---
id: GetClaims
name: Get Claims
version: 0.0.1
summary: Query to retrieve claims associated with a policy
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Claims
backgroundColor: red
textColor: white
---
## Overview
The `GetClaims` query retrieves all claims associated with a policy, or a specific claim by claim number. This endpoint provides comprehensive claim information including status, death details, claimant information, and payout calculations.
## Request
### HTTP Method - By Policy ID
```
GET /claims/by-policy-id/{policyId}
```
### HTTP Method - By Claim Number
```
GET /claims/by-claim-number/{claimNumber}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `policyId` | UUID | Conditional | Policy ID to retrieve claims for |
| `claimNumber` | string | Conditional | Specific claim number |
### Example Request
```bash
curl -X GET "https://api.ascp.digisure.com/claims/by-policy-id/pol-12345678" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"claims": [
{
"claimId": "claim-aaaa-bbbb-cccc-dddd",
"claimNumber": "CLM-2024-000123",
"policyId": "pol-12345678-90ab-cdef",
"policyCode": "FUN-2024-001234",
"status": "IN_ASSESSMENT",
"highLevelStatus": "OPEN",
"stage": "DOCUMENTATION_REVIEW",
"dateOfClaim": "2024-01-20",
"deceased": {
"deceasedId": "dec-1111-2222-3333",
"firstName": "John",
"lastName": "Doe",
"idNumber": "8501015800083",
"dateOfBirth": "1985-01-01",
"lifeType": "MAIN_LIFE"
},
"deathDetail": {
"dateOfDeath": "2024-01-18",
"causeOfDeath": "NATURAL",
"placeOfDeath": "Johannesburg"
},
"claimant": {
"claimantId": "clmt-aaaa-bbbb-cccc",
"firstName": "Jane",
"lastName": "Doe",
"relationship": "SPOUSE",
"contactNumber": "+27821234567"
},
"financialDetail": {
"grossPayoutAmount": {
"amount": 5000000,
"currency": "ZAR"
},
"netPayoutAmount": {
"amount": 5000000,
"currency": "ZAR"
},
"paymentStatus": "PENDING"
},
"documents": [
{
"documentId": "doc-1111-2222-3333",
"documentType": "DEATH_CERTIFICATE",
"fileName": "death-certificate.pdf",
"uploadedAt": "2024-01-20T10:30:00Z",
"verificationStatus": "VERIFIED"
}
],
"createdAt": "2024-01-20T09:00:00Z",
"updatedAt": "2024-01-22T14:00:00Z"
}
]
}
```
## Claim Statuses
| Status | Description |
|--------|-------------|
| `SUBMITTED` | Claim has been submitted |
| `IN_ASSESSMENT` | Claim is being assessed |
| `AWAITING_DOCUMENTS` | Waiting for required documents |
| `APPROVED` | Claim has been approved |
| `REPUDIATED` | Claim has been rejected |
| `PAID` | Claim payment has been processed |
| `CLOSED` | Claim is finalized |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_REQUEST` | Invalid request parameters |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication |
| 403 | `FORBIDDEN` | Insufficient permissions |
| 404 | `NOT_FOUND` | No claims found |
| 500 | `INTERNAL_ERROR` | Server error |
---
id: GetClaimsByPolicyId
name: Get Claims by Policy ID
version: 0.0.1
summary: Retrieve all claims associated with a specific policy.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetClaimsByPolicyId` query retrieves all claims associated with a specific policy. A policy may have multiple claims (e.g., separate claims for main life and covered lives).
## Request
### HTTP Method
```
GET /by-policy/{policyId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `policyId` | string | Yes | The policy ID to retrieve claims for |
## Response
Returns an array of claim records associated with the given policy.
---
id: GetClaimsCommandStatus
name: Get Claims Command Status
version: 0.0.1
summary: Retrieve the processing status of a claims command by correlation ID.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetClaimsCommandStatus` query retrieves the processing status of a previously submitted claims command using its correlation ID. This enables async command tracking and polling for completion.
## Request
### HTTP Method
```
GET /command-status/{correlationId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `correlationId` | string | Yes | The correlation ID of the command to check |
## Response
Returns the command status including whether it succeeded, failed, or is still processing. The `ClaimsCommandStatus` enum tracks states: `PENDING`, `PROCESSING`, `COMPLETED`, `FAILED`.
---
id: GetClaimSupportTickets
name: Get Claim Support Tickets
version: 0.0.1
summary: Retrieve support tickets for a claim (ASCP-specific)
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: ASCP
backgroundColor: teal
textColor: white
---
## Overview
Retrieves all support tickets associated with a specific claim. This is an ASCP-specific query used by assessors to track outstanding queries and issues raised during the claims assessment process.
## HTTP Endpoint
```
GET /api/v1/claims/{claimId}/support-tickets
```
## Upstream Service
Proxied to the **Claims** domain service.
---
id: GetCommandStatus
name: Get Command Status
version: 0.0.1
summary: Check the status of an asynchronous command by correlation ID
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetCommandStatus` query allows clients to check the status of an asynchronous command using its correlation ID. This is useful for tracking the progress of long-running operations such as policy creation, updates, or cancellations that are processed asynchronously.
## Request
### HTTP Method
```
GET /command-status/{correlationId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `correlationId` | string (UUID) | Yes | The unique correlation ID returned when the command was submitted |
### Query Parameters
This endpoint does not accept any query parameters.
### Example Request
```bash
curl -X GET "https://api.digisure.com/policy/command-status/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
#### Pending Status
```json
{
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"commandType": "CreateFuneralPolicy",
"status": "PENDING",
"submittedAt": "2024-01-15T10:30:00Z",
"message": "Command is being processed"
}
```
#### Completed Status
```json
{
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"commandType": "CreateFuneralPolicy",
"status": "COMPLETED",
"submittedAt": "2024-01-15T10:30:00Z",
"completedAt": "2024-01-15T10:30:05Z",
"result": {
"policyId": "POL-12345678",
"policyNumber": "FUN-2024-001234"
},
"message": "Policy created successfully"
}
```
#### Failed Status
```json
{
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"commandType": "CreateFuneralPolicy",
"status": "FAILED",
"submittedAt": "2024-01-15T10:30:00Z",
"completedAt": "2024-01-15T10:30:03Z",
"error": {
"code": "VALIDATION_ERROR",
"message": "Policyholder age exceeds maximum allowed for this product",
"details": [
{
"field": "policyholder.dateOfBirth",
"message": "Policyholder must be under 65 years of age"
}
]
}
}
```
### Status Values
| Status | Description |
|--------|-------------|
| `PENDING` | Command has been received and is awaiting processing |
| `PROCESSING` | Command is currently being processed |
| `COMPLETED` | Command has been successfully processed |
| `FAILED` | Command processing failed with an error |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_CORRELATION_ID` | The provided correlation ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions to access this command status |
| 404 | `COMMAND_NOT_FOUND` | No command exists with the specified correlation ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetCoverFromPremium
name: Get Cover From Premium
version: 0.0.1
summary: Calculate the cover amount achievable for a given premium budget and risk factors
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetCoverFromPremium` query calculates the maximum cover amount that can be obtained for a specified monthly premium budget. This is used when customers have a fixed budget and want to know what coverage they can afford.
## Request
### HTTP Method
```
POST /pricing/cover-from-premium
```
### Request Body
The request contains partner configuration and a list of product queries with premium amounts:
```json
{
"partnerId": "uuid",
"packageId": "uuid",
"productCategoryId": "uuid",
"productVersion": 1,
"configurationVersion": 1,
"products": [
{
"productId": "MAIN_LIFE",
"partyId": "uuid",
"age": 35,
"gender": "MALE",
"relationship": "MAIN",
"premium": {
"amount": 15000,
"currency": "ZAR"
}
}
]
}
```
### Key Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `partnerId` | UUID | Yes | The partner identifier for pricing configuration |
| `packageId` | UUID | Yes | The package identifier |
| `productCategoryId` | UUID | Yes | The product category for pricing lookup |
| `productVersion` | integer | Yes | Product configuration version |
| `configurationVersion` | integer | Yes | Pricing configuration version |
| `products` | array | Yes | List of products to price |
| `products[].age` | integer | Yes | Age of the insured person |
| `products[].gender` | string | Yes | Gender (MALE, FEMALE) |
| `products[].relationship` | string | Yes | Relationship to main life |
| `products[].premium` | Money | Yes | Available premium budget |
## Response
### Success Response (200 OK)
```json
{
"products": [
{
"productId": "MAIN_LIFE",
"partyId": "uuid",
"premium": {
"amount": 15000,
"currency": "ZAR"
},
"coverAmount": {
"amount": 5000000,
"currency": "ZAR"
}
}
],
"totalCover": {
"amount": 5000000,
"currency": "ZAR"
}
}
```
## Calculation Process
1. Load pricing configuration for partner/product
2. Remove broker percentage from premium
3. Remove age and relationship top-up factors
4. Remove expense loadings, distribution rate, and profit margin
5. Convert monthly premium to annual premium
6. Calculate cover amount using inverse of mortality formula
7. Round to final cover amount
## Inverse Formula
The cover calculation essentially reverses the premium calculation:
```
lifePremiumExcludeBroker = (premium / brokerPercentage) - topUpExpenseFactor
lifePremiumExcludeAgeRelationship = lifePremiumExcludeBroker / (ageTopUpFactor * relationshipTopUpFactor)
lifePremiumExcludeLoadings = lifePremiumExcludeAgeRelationship * (1 - loadings)
lifeAnnualPremium = lifePremiumExcludeLoadings * 12
lifeCoverAmount = lifeAnnualPremium / lifeQx
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_REQUEST` | Request validation failed |
| 400 | `INVALID_AGE` | Age is outside acceptable range |
| 400 | `PREMIUM_TOO_LOW` | Premium insufficient for minimum cover |
| 404 | `CONFIG_NOT_FOUND` | Pricing configuration not found for partner/product |
| 500 | `CALCULATION_ERROR` | Error during cover calculation |
---
id: GetCustomer
name: Get Customer
version: 0.0.1
summary: Retrieve a customer and their associated policies by policy holder ID
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetCustomer` query retrieves a customer record by policy holder ID. This endpoint returns the complete customer profile including associated quotes and policies with their current statuses.
## Request
### HTTP Method
```
GET /customer/{policyHolderId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `policyHolderId` | string (UUID) | Yes | The unique identifier of the policy holder |
### Example Request
```bash
curl -X GET "https://api.digisure.com/customer-dp/customer/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"globalCustomerId": "550e8400-e29b-41d4-a716-446655440000",
"isActive": true,
"quoteIds": [],
"policies": [
{
"policyId": "660e8400-e29b-41d4-a716-446655440001",
"policyCode": "FUN-2024-001234",
"policyStatus": "ACTIVE",
"partnerId": "770e8400-e29b-41d4-a716-446655440002",
"packageId": "880e8400-e29b-41d4-a716-446655440003",
"policyCreatedAt": "2024-01-15T10:30:00Z"
}
],
"processedEvents": {
"POLICY_CREATED:660e8400-e29b-41d4-a716-446655440001": 5
}
}
```
### Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `globalCustomerId` | string | The unique global customer identifier |
| `isActive` | boolean | Whether the customer is active |
| `quoteIds` | array | List of quote IDs associated with the customer |
| `policies` | array | List of CustomerPolicy objects |
| `policies[].policyId` | string | Unique identifier for the policy |
| `policies[].policyCode` | string | Human-readable policy code |
| `policies[].policyStatus` | string | Current status of the policy |
| `policies[].partnerId` | string | Partner identifier |
| `policies[].packageId` | string | Package identifier |
| `policies[].policyCreatedAt` | string | ISO 8601 timestamp of policy creation |
| `processedEvents` | object | Map of event keys to logical clock readings (for debugging) |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_POLICY_HOLDER_ID` | The provided policy holder ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions to access this customer |
| 404 | `CUSTOMER_NOT_FOUND` | No customer exists with the specified policy holder ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
## Implementation
The query is handled by the `DefaultGetCustomerQueryHandler` which:
1. Validates the policy holder ID format
2. Queries the DynamoDB customer table using the policy holder ID as the partition key
3. Returns the customer aggregate with all associated policies
4. Throws `PermanentException` if the customer is not found
---
id: GetCustomerByPolicyCode
name: Get Customer By Policy Code
version: 0.0.1
summary: Retrieve a customer by policy code
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Customer
backgroundColor: teal
textColor: white
---
## Overview
Retrieves the customer record associated with a policy using its policy code. Returns the customer's personal and contact details.
## HTTP Endpoint
```
GET /api/v1/customer/by-policy-code/{policyCode}
```
## Upstream Service
Proxied to the **Customer** domain service.
---
id: GetExtractionStatus
name: Get Extraction Status Query
version: 0.0.1
summary: |
Query the processing status and results of a document extraction command.
Returns current state, timestamps, and extracted data when available.
---
## Overview
The **Get Extraction Status Query** allows clients to monitor the progress and results of submitted extraction commands. It provides real-time visibility into command lifecycle and access to extracted data upon completion.
## Query Details
### Request
```
GET /v1/extractions/{commandId}/status
```
#### Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| commandId | UUID | Yes | The ID of the extraction command |
| includeResults | Boolean | No | Include full extraction results (default: true) |
| includeMetadata | Boolean | No | Include processing metadata (default: false) |
### Response
```json
{
"commandId": "550e8400-e29b-41d4-a716-446655440000",
"status": "COMPLETED",
"originationType": "POLICY",
"originationId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"documentType": "DEATH_CERTIFICATE",
"fileType": "PDF",
"createdAt": "2025-03-11T10:30:00Z",
"startedAt": "2025-03-11T10:30:05Z",
"completedAt": "2025-03-11T10:35:22Z",
"provider": "AWS_TEXTRACT",
"correlationId": "a1b2c3d4-e5f6-47a8-9b1c-2d3e4f5a6b7c",
"results": {
"extracted_fields": {
"full_name": "John Doe",
"date_of_birth": "1950-05-15",
"date_of_death": "2025-03-10"
},
"confidence_scores": {
"full_name": 0.95,
"date_of_birth": 0.87,
"date_of_death": 0.92
},
"raw_text": "..."
},
"error": null
}
```
## Status Values
| Status | Meaning | Actionable |
|--------|---------|-----------|
| NEW | Command queued, not started | No |
| PROCESSING | Extraction in progress | No |
| COMPLETED | Extraction successful, results available | Yes |
| FAILED | Processing failed after retries | Yes (manual intervention) |
| UNKNOWN | Status cannot be determined | Contact Support |
## Response Details
### Basic Fields
- **commandId**: Unique identifier for the extraction request
- **status**: Current processing state
- **originationType/originationId**: Business context (policy, quote, claim)
- **documentType**: Type of document extracted
- **fileType**: File format of source document
### Timing
- **createdAt**: When command was received
- **startedAt**: When extraction provider began processing
- **completedAt**: When extraction finished (null if still processing)
- **duration**: Total elapsed time (completedAt - createdAt)
### Results (when status=COMPLETED)
- **extracted_fields**: Key-value pairs of extracted data
- **confidence_scores**: Confidence level (0.0-1.0) for each field
- **raw_text**: Full OCR text (if requested)
- **bounding_boxes**: Position information (optional)
### Error Information (when status=FAILED)
```json
{
"error": {
"code": "EXTRACTION_TIMEOUT",
"message": "Document extraction exceeded timeout threshold",
"retriesAttempted": 5,
"lastAttemptAt": "2025-03-11T10:45:00Z",
"suggestedAction": "MANUAL_REVIEW"
}
}
```
## Error Codes
| Code | Description | Recommended Action |
|------|-------------|-------------------|
| INVALID_DOCUMENT | Document format not supported | Re-upload valid document |
| EXTRACTION_FAILED | Provider returned error | Retry or contact support |
| EXTRACTION_TIMEOUT | Processing exceeded time limit | Retry with larger timeout |
| INVALID_FILE_TYPE | File type not supported | Convert to supported format |
| CORRUPTED_FILE | File cannot be read | Re-upload clean copy |
| PROVIDER_ERROR | Extraction provider error | Retry with backoff |
## Usage Patterns
### Polling (Synchronous)
Client repeatedly polls until status != PROCESSING:
```
1. Submit ExtractDocumentCommand
2. Wait (e.g., 5 seconds)
3. Call GetExtractionStatus
4. If status=PROCESSING, go to step 2
5. If status=COMPLETED, process results
```
### Webhook (Future)
Downstream service subscribes to extraction completion events via EventBridge.
### Batch Status Check
Query multiple command statuses:
```
GET /v1/extractions/status?commandIds=cmd-1,cmd-2,cmd-3
```
## Integration
### Callers
- Policy Service: Check policy document extraction status
- Quote Service: Monitor quote document extraction
- Claims Service: Track claim evidence extraction
- Admin Dashboard: Display extraction metrics and health
### Response Headers
```
X-Correlation-Id: a1b2c3d4-e5f6-47a8-9b1c-2d3e4f5a6b7c
X-RateLimit-Remaining: 4999
Cache-Control: no-cache, no-store
```
## Performance
- **Latency**: < 100ms for query execution
- **Caching**: Results cached in DynamoDB (read-through)
- **Rate Limiting**: 5000 queries per minute per client
## Data Retention
- **Command Records**: 90 days (configurable)
- **Extraction Results**: 30 days (configurable)
- **Audit Logs**: 1 year (compliance requirement)
---
id: GetFile
name: Get File
version: 0.0.1
summary: Retrieve file metadata by its unique identifier
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetFile` query retrieves file metadata by its unique identifier. This endpoint returns complete file details including metadata, status, and origination context without the actual file content.
## Request
### HTTP Method
```
GET /files/{fileId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `fileId` | string (UUID) | Yes | The unique identifier of the file to retrieve |
### Example Request
```bash
curl -X GET "https://api.digisure.com/file-upload/files/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"fileId": "550e8400-e29b-41d4-a716-446655440000",
"fileName": "id_document.pdf",
"fileType": "PDF",
"fileSizeKilobytes": 245.5,
"fileStatus": "UPLOADED",
"origination": "POLICY",
"originationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"documentType": "ID_DOCUMENT",
"createdBy": "user@example.com",
"uploadedAt": "2024-01-15T10:30:00Z",
"isArchived": false,
"link": "https://s3.amazonaws.com/bucket/files/...",
"auxiliaryData": {
"source": "mobile_app"
}
}
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_FILE_ID` | The provided file ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions to access this file |
| 404 | `FILE_NOT_FOUND` | No file exists with the specified ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetFileCommandStatus
name: Get File Command Status
version: 0.0.1
summary: Poll the status of an async file upload command
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: FileUpload
backgroundColor: orange
textColor: white
---
## Overview
Polls the processing status of an asynchronous file upload command using its correlation ID. Used to determine whether a file upload or delete operation has been accepted, is in progress, or has completed.
## HTTP Endpoint
```
GET /api/v1/file-upload/command-status/{correlationId}
```
## Upstream Service
Proxied to the **FileUpload** domain service.
---
id: GetFileUploadCommandStatus
name: Get File Upload Command Status
version: 0.0.1
summary: Retrieve the status of a file upload command
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetFileUploadCommandStatus` query retrieves the processing status of a file upload command. This is useful for tracking asynchronous upload operations, particularly when using pre-signed URLs.
## Request
### HTTP Method
```
GET /commands/{commandId}/status
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `commandId` | string | Yes | The unique identifier of the command to check |
### Example Request
```bash
curl -X GET "https://api.digisure.com/file-upload/commands/550e8400-e29b-41d4-a716-446655440000/status" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"commandId": "550e8400-e29b-41d4-a716-446655440000",
"status": "COMPLETED",
"fileId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"createdAt": "2024-01-15T10:30:00Z",
"completedAt": "2024-01-15T10:30:05Z",
"errorMessage": null
}
```
### Command Status Values
| Status | Description |
|--------|-------------|
| `PENDING` | Command has been received and is awaiting processing |
| `PROCESSING` | Command is currently being processed |
| `COMPLETED` | Command has been successfully processed |
| `FAILED` | Command processing failed |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_COMMAND_ID` | The provided command ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 404 | `COMMAND_NOT_FOUND` | No command exists with the specified ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
## Use Cases
- Polling for pre-signed URL upload completion
- Tracking asynchronous file processing
- Error diagnosis for failed uploads
---
id: GetFuneralPolicy
name: Get Funeral Policy
version: 0.0.1
summary: Retrieve a single funeral policy by its unique identifier
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetFuneralPolicy` query retrieves a single funeral policy by its unique identifier. This endpoint returns the complete policy details including policyholder information, coverage details, beneficiaries, and current status.
## Request
### HTTP Method
```
GET /{policyId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `policyId` | string | Yes | The unique identifier of the policy to retrieve |
### Query Parameters
This endpoint does not accept any query parameters.
### Example Request
```bash
curl -X GET "https://api.digisure.com/policy/POL-12345678" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"policyId": "POL-12345678",
"policyNumber": "FUN-2024-001234",
"status": "ACTIVE",
"productCode": "FUNERAL_BASIC",
"policyholder": {
"firstName": "John",
"lastName": "Doe",
"idNumber": "8501015800083",
"dateOfBirth": "1985-01-01",
"email": "john.doe@example.com",
"phoneNumber": "+27821234567"
},
"coverage": {
"sumAssured": 50000,
"premium": 150.00,
"paymentFrequency": "MONTHLY"
},
"beneficiaries": [
{
"firstName": "Jane",
"lastName": "Doe",
"relationship": "SPOUSE",
"percentage": 100
}
],
"effectiveDate": "2024-01-15",
"createdAt": "2024-01-10T10:30:00Z",
"updatedAt": "2024-01-15T14:20:00Z"
}
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_POLICY_ID` | The provided policy ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions to access this policy |
| 404 | `POLICY_NOT_FOUND` | No policy exists with the specified ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetGlobalIdentity
name: Get Global Identity
version: 0.0.1
summary: Retrieve a global identity by its Global Customer ID (GCID)
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetGlobalIdentity` query retrieves a single global identity record by its unique Global Customer ID (GCID). This endpoint returns the complete identity details including personal information, contact details, and certificate metadata.
## Request
### Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `globalCustomerId` | UUID | Yes | The unique Global Customer ID |
### Example Request
```java
// Using the Identity SDK
IdentitySdk sdk = IdentitySdk.builder()
.dynamoDbClient(DynamoDbClient.create())
.config(config)
.build();
Optional identity = sdk.globalIdentities()
.get("550e8400-e29b-41d4-a716-446655440000");
```
## Response
### Success Response
```json
{
"globalCustomerId": "550e8400-e29b-41d4-a716-446655440000",
"personName": {
"name": "John",
"familyName": "Doe",
"titles": ["MR"]
},
"issuedIdentity": {
"idType": "IDENTITY_DOCUMENT",
"idValue": "8501015800083",
"idCountryOfIssue": "ZA"
},
"identityMobileNumber": {
"countryCode": "+27",
"localNumber": "0821234567"
},
"identityEmailAddress": "john.doe@example.com",
"dateOfBirth": "1985-01-01",
"gender": "MALE",
"isActive": true,
"version": 3,
"certificates": {
"PERSONAL_IDENTITY": {
"certificateId": "cert-uuid",
"trustLevel": 40.0,
"creationTime": "2024-01-15T10:30:00Z"
}
}
}
```
### Not Found
Returns empty/null if no identity exists with the specified GCID.
## Error Codes
| Error | Description |
|-------|-------------|
| `INVALID_GCID` | The provided GCID format is invalid |
| `IDENTITY_NOT_FOUND` | No identity exists with the specified GCID |
---
id: GetGlobalIdentityByIssuedIdentity
name: Get Global Identity By Issued Identity
version: 0.0.1
summary: Look up a global identity by issued identity document (ID number or passport)
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetGlobalIdentityByIssuedIdentity` query looks up a global identity record by its issued identity document. This enables finding a customer's canonical identity using their ID number or passport.
## Request
### Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `idType` | string | Yes | Type of identity document (IDENTITY_DOCUMENT, PASSPORT) |
| `idValue` | string | Yes | The identity document number |
| `idCountryOfIssue` | string | Yes | ISO country code of issuing country |
### Example Request
```java
// Using the Identity SDK
IdentitySdk sdk = IdentitySdk.builder()
.dynamoDbClient(DynamoDbClient.create())
.config(config)
.build();
Optional identity = sdk.globalIdentities()
.getByIssuedIdentity("IDENTITY_DOCUMENT", "8501015800083", "ZA");
```
## Response
### Success Response
Returns the same structure as `GetGlobalIdentity` if a matching identity is found.
```json
{
"globalCustomerId": "550e8400-e29b-41d4-a716-446655440000",
"personName": {
"name": "John",
"familyName": "Doe"
},
"issuedIdentity": {
"idType": "IDENTITY_DOCUMENT",
"idValue": "8501015800083",
"idCountryOfIssue": "ZA"
},
"isActive": true
}
```
### Not Found
Returns empty/null if no identity exists with the specified issued identity.
## Use Cases
- **Customer Lookup**: Find existing customers during policy creation
- **Duplicate Prevention**: Check if identity already exists before creating new
- **Cross-Reference**: Link records from different systems using ID number
## Notes
- The lookup uses a Global Secondary Index (GSI) on the issued identity composite key
- The combination of idType, idValue, and idCountryOfIssue must be unique
---
id: GetIdentityPortfolio
name: Get Identity Portfolio
version: 0.0.1
description: Retrieve a customer's complete identity portfolio
owners:
- digisure-engineering
---
## Overview
The **GetIdentityPortfolio** query retrieves a customer's complete identity portfolio, including all active and historical quotes and policies. This query provides a consolidated view of a customer's insurance portfolio, enabling downstream services to understand the full scope of a customer's relationships with the organization.
## Purpose
- Retrieve customer portfolio information for display in customer service systems
- Support quote-to-policy lifecycle tracking
- Enable portfolio-level business logic in downstream services
- Provide audit trail of customer's insurance portfolio history
## Query Details
**Query Type:** Point Query (single aggregate retrieval)
**Input:**
- `PolicyHolderId` (UUID) - The customer's unique identifier (Global Customer ID)
**Output:**
```json
{
"globalCustomerId": "UUID",
"quoteIds": ["UUID1", "UUID2"],
"policies": [
{
"policyId": "string",
"policyCode": "string",
"policyStatus": "string",
"policyStartDate": "ISO-8601 date",
"partnerId": "string",
"partnerName": "string",
"packageId": "string",
"packageName": "string"
}
]
}
```
## Semantics
This query returns the current state of an identity portfolio:
- **Global Customer ID**: The unique identifier for the customer across the platform
- **Quote IDs**: Set of quote identifiers associated with the customer
- **Policies**: Set of policy records with complete metadata
- **policyId**: Unique policy identifier
- **policyCode**: Business-facing policy code
- **policyStatus**: Current status (ACTIVE, PENDING_FIRST_PAYMENT, CANCELLED, etc.)
- **policyStartDate**: When the policy becomes effective
- **partnerId**: Identifier of the partner associated with the policy
- **partnerName**: Display name of the partner
- **packageId**: Identifier of the insurance package
- **packageName**: Display name of the package
## Use Cases
1. **Customer Service Portal**: Display customer's complete insurance portfolio
2. **Policy Administration**: Track all policies held by a customer
3. **Quote Management**: View customer's active and historical quotes
4. **Billing Systems**: Understand customer's policy portfolio for premium calculations
5. **Claims Processing**: Identify applicable policies for claim filing
## Exception Handling
- **Invalid Policy Holder ID**: Returns HTTP 400 Bad Request if policy holder ID is not a valid UUID
- **Not Found**: Returns HTTP 404 if no portfolio exists for the given customer
- **Service Error**: Returns HTTP 500 if an internal error occurs during retrieval
## Performance Characteristics
- **Response Time**: Sub-second response from DynamoDB cache
- **Data Freshness**: Eventually consistent (updated within seconds of new quote/policy events)
- **Scalability**: O(1) retrieval by Policy Holder ID primary key
## Implementation Notes
- Query reads from a denormalized read model (DynamoDB table)
- Portfolio state is updated asynchronously via event handlers
- Events are processed in order to maintain consistency
- Supports point-in-time queries through event versioning
---
id: GetInventoryItem
name: Get Inventory Item
version: 0.0.1
summary: Retrieve an inventory item by its serial number.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Not Yet Implemented
backgroundColor: orange
textColor: black
---
## Overview
The `GetInventoryItem` query retrieves an inventory item by its unique serial number. This endpoint returns the item status, bundle information, and redemption details if redeemed.
## Request
### HTTP Method
```
GET /inventory/{serialNumber}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `serialNumber` | string | Yes | The 16-digit serial number of the inventory item |
### Example Request
```bash
curl -X GET "https://api.digisure.com/bundle-inventory/inventory/1400010000000123" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"serialNumber": "1400010000000123",
"bundleId": "BDL-12345",
"partnerName": "Blue Label",
"packageName": "Immediate Family",
"sequence": 123,
"active": true,
"redeemed": false,
"redeemedAt": null,
"coverTerm": null,
"expiresAt": "2025-12-31T23:59:59Z",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
```
### Redeemed Item Response
```json
{
"serialNumber": "1400010000000124",
"bundleId": "BDL-12345",
"partnerName": "Blue Label",
"packageName": "Immediate Family",
"sequence": 124,
"active": true,
"redeemed": true,
"redeemedAt": "2024-06-15T14:20:00Z",
"coverTerm": 3,
"coverTermChronoUnit": "MONTHS",
"expiresAt": "2025-12-31T23:59:59Z",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-06-15T14:20:00Z"
}
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_SERIAL_NUMBER` | The serial number format is invalid or check digit is incorrect |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 404 | `ITEM_NOT_FOUND` | No inventory item exists with the specified serial number |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetNotificationCommandStatusByCorrelationId
name: Get Notification Command Status By Correlation ID
version: 0.0.1
summary: Retrieve the status of a notification command using its correlation ID.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetNotificationCommandStatusByCorrelationId` query retrieves the current status of a notification command identified by its correlation ID. This is useful for tracking the processing state of asynchronous notification commands.
This query is handled by the `GetNotificationStatusByCorrIdLambdaHandler` Lambda.
## Request
### HTTP Method
```
GET /notifications/commands/{correlationId}/status
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `correlationId` | string (UUID) | Yes | The correlation ID of the notification command to look up |
### Example Request
```bash
curl -X GET "https://api.digisure.com/notifications/commands/123e4567-e89b-12d3-a456-426614174000/status" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
Returns a `GetNotificationCommandStatusByCorrelationIdModel` with the current status of the notification command.
```json
{
"correlationId": "123e4567-e89b-12d3-a456-426614174000",
"status": "DISPATCHED",
"notificationType": "POLICY_CONFIRMATION_WELCOME",
"medium": "EMAIL",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:05Z"
}
```
### Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `correlationId` | string | The correlation ID of the command |
| `status` | string | Current processing status (e.g. PENDING, DISPATCHED, PROVIDER_SEND_SUCCESS, PROVIDER_SEND_FAILED) |
| `notificationType` | string | The type of notification associated with this command |
| `medium` | string | Delivery channel (EMAIL, SMS) |
| `createdAt` | string | Timestamp when the command was created |
| `updatedAt` | string | Timestamp of the last status update |
### Notification Status Values
| Status | Description |
|--------|-------------|
| `PENDING` | Command received, not yet processed |
| `DISPATCHED` | Notification sent to the Glue gateway |
| `PROVIDER_SEND_SUCCESS` | Delivery confirmed by the provider |
| `PROVIDER_SEND_FAILED` | Delivery failed at the provider level |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_CORRELATION_ID` | The correlationId is missing or not a valid UUID |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetNotificationConfig
name: Get Notification Config
version: 0.0.1
summary: Retrieve the partner notification configuration aggregate by partner ID.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetNotificationConfig` query retrieves the partner notification configuration aggregate for a given partner. This configuration defines which notifications are enabled, their templates, triggers, scheduling rules, and sender identities per notification type and package.
This query is handled by the `GetNotificationConfigLambdaHandler` Lambda.
## Request
### HTTP Method
```
GET /notifications/config/{partnerId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `partnerId` | string (UUID) | Yes | The partner identifier to retrieve configuration for |
### Example Request
```bash
curl -X GET "https://api.digisure.com/notifications/config/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
Returns the `PartnerNotificationConfigAggregateRoot` containing all notification configurations for the partner, including per-package and per-notification-type rules.
```json
{
"partnerId": "550e8400-e29b-41d4-a716-446655440000",
"packageConfigs": [
{
"packageId": "abc12345-e29b-41d4-a716-446655440001",
"notificationConfigs": [
{
"notificationType": "POLICY_CONFIRMATION_WELCOME",
"medium": "EMAIL",
"timing": "IMMEDIATE",
"templateId": "welcome-email-v1",
"senderIdentityId": "no-reply@digisure.com",
"recipient": "POLICY_HOLDER",
"triggerRules": []
}
]
}
]
}
```
### Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `partnerId` | string | The partner identifier |
| `packageConfigs` | array | List of package-level notification configurations |
| `packageConfigs[].packageId` | string | The package identifier |
| `packageConfigs[].notificationConfigs` | array | Notification rules for this package |
| `notificationConfigs[].notificationType` | string | The type of notification |
| `notificationConfigs[].medium` | string | Delivery channel (EMAIL, SMS) |
| `notificationConfigs[].timing` | string | IMMEDIATE or SCHEDULED |
| `notificationConfigs[].templateId` | string | The notification template identifier |
| `notificationConfigs[].senderIdentityId` | string | Configured sender identity |
| `notificationConfigs[].recipient` | string | Recipient type (POLICY_HOLDER, CLAIMANT) |
| `notificationConfigs[].triggerRules` | array | Rules that must pass to trigger this notification |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_PARTNER_ID` | The partnerId path parameter is missing or empty |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions |
| 404 | `NOT_FOUND` | No notification config found for the given partner ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetNotificationDataProductByOriginId
name: Get Notification Data Product By Origin ID
version: 0.0.1
summary: Retrieve notification history for a policy or claim by its origin identifier.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetNotificationDataProductByOriginId` query retrieves the notification history for a specific policy or claim. This endpoint returns all notification data product records associated with the origin identifier, providing visibility into the notification lifecycle.
## Request
### HTTP Method
```
GET /notifications/{originId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `originId` | string | Yes | The policy ID or claim ID to query notifications for |
### Query Parameters
This endpoint does not accept any query parameters.
### Example Request
```bash
curl -X GET "https://api.digisure.com/notifications/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
[
{
"correlationId": "123e4567-e89b-12d3-a456-426614174000",
"notificationProviderCorrelationId": "789e0123-e89b-12d3-a456-426614174999",
"originId": "550e8400-e29b-41d4-a716-446655440000",
"originType": "POLICY_FUNERAL",
"notificationId": "ntf-001",
"notificationType": "POLICY_CONFIRMATION_WELCOME",
"notificationStatus": "PROVIDER_SEND_SUCCESS",
"recipient": "POLICY_HOLDER",
"notificationMedium": "EMAIL",
"createdAt": "2024-01-15T10:30:00Z"
},
{
"correlationId": "223e4567-e89b-12d3-a456-426614174001",
"notificationProviderCorrelationId": "889e0123-e89b-12d3-a456-426614174888",
"originId": "550e8400-e29b-41d4-a716-446655440000",
"originType": "POLICY_FUNERAL",
"notificationId": "ntf-002",
"notificationType": "POLICY_PAYMENT_REMINDER",
"notificationStatus": "DISPATCHED",
"recipient": "POLICY_HOLDER",
"notificationMedium": "SMS",
"createdAt": "2024-02-01T08:00:00Z"
}
]
```
### Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `correlationId` | string | Correlation ID for the notification event |
| `notificationProviderCorrelationId` | string | Provider tracking ID for delivery confirmation |
| `originId` | string | The policy or claim ID |
| `originType` | string | Source type (POLICY_FUNERAL, CLAIMS, etc.) |
| `notificationId` | string | Unique notification identifier |
| `notificationType` | string | Type of notification sent |
| `notificationStatus` | string | Current status (SCHEDULED, DISPATCHED, PROVIDER_SEND_SUCCESS, PROVIDER_SEND_FAILED) |
| `recipient` | string | Recipient type (POLICY_HOLDER, CLAIMANT) |
| `notificationMedium` | string | Delivery channel (EMAIL, SMS) |
| `createdAt` | string | Timestamp when the notification was created |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_ORIGIN_ID` | The provided origin ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetPartner
name: Get Partner
version: 0.0.1
summary: Query to retrieve partner configuration including packages, products, and business rules
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Partner
backgroundColor: indigo
textColor: white
---
## Overview
The `GetPartner` query retrieves comprehensive partner configuration details including available packages, products, pricing rules, and business configuration. This query is essential for initializing quote creation, validating product availability, and enforcing partner-specific business rules.
## Request
### HTTP Method
```
GET /partners/{partnerId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `partnerId` | string | Yes | Unique partner identifier |
### Example Request
```bash
curl -X GET "https://api.partner-service.digisure.com/partners/partner-001" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"partnerId": "partner-001",
"partnerCode": "ACME",
"partnerName": "Acme Insurance",
"partnerType": "BROKER",
"isActive": true,
"division": "RETAIL",
"subdivision": "DIRECT",
"companyRegistrationNumber": "CRN-123456",
"vatRegistrationNumber": "VAT-987654",
"packages": [
{
"packageId": "pkg-standard",
"packageName": "Standard Funeral",
"productCategory": "FUNERAL",
"isActive": true,
"products": [
{
"productId": "prod-main",
"productCode": "FUNERAL_MAIN",
"productName": "Main Life Cover",
"productType": "MAIN_LIFE",
"isRequired": true,
"configuration": {
"minCover": 1000000,
"maxCover": 10000000,
"coverIncrements": 100000,
"minAge": 18,
"maxAge": 65
},
"waitingPeriods": {
"natural": {
"unit": "MONTHS",
"value": 6
},
"accidental": {
"unit": "DAYS",
"value": 0
}
},
"pricingCalculation": {
"calculatorId": "funeral-v1",
"factorQueryId": "funeral-factors"
}
},
{
"productId": "prod-spouse",
"productCode": "FUNERAL_SPOUSE",
"productName": "Spouse Cover",
"productType": "EXTENDED_FAMILY",
"isRequired": false
}
],
"collectionMethods": ["DEBIT_ORDER", "CASH"],
"termsAndConditions": {
"version": "2024-01",
"documentUrl": "https://docs.example.com/terms/funeral-2024.pdf"
}
}
],
"rules": {
"maxBeneficiaries": 5,
"allowMultipleProducts": true,
"requireBankVerification": true
},
"notificationConfig": {
"preferredChannels": ["EMAIL", "SMS"],
"templates": {
"quoteCreated": "quote-created-v1",
"quoteExpired": "quote-expired-v1",
"policyCreated": "policy-created-v1"
}
}
}
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_PARTNER_ID` | Invalid partner ID format |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication |
| 403 | `FORBIDDEN` | Insufficient permissions |
| 404 | `PARTNER_NOT_FOUND` | Partner does not exist |
| 500 | `INTERNAL_ERROR` | Server error |
## Use Cases
### Quote Creation Initialization
When users start creating a quote, the frontend calls `GetPartner` to:
- Display available product packages
- Populate product selection options
- Show coverage limits and constraints
- Display collection method options
### Policy Validation
During policy lifecycle operations, the Policy Service calls `GetPartner` to:
- Validate product availability
- Enforce maximum beneficiary rules
- Check collection method constraints
- Apply pricing calculation logic
### Portal Configuration
The BFFWeb and BFFASCP services call `GetPartner` on startup to:
- Initialize partner-specific UI configuration
- Set validation rules for forms
- Configure notification templates
- Set pricing metadata
## Performance Considerations
- Results are cached with TTL of 1 hour
- Cache invalidation triggers on partner configuration updates
- Supports bulk queries for multiple partners (future enhancement)
## Related Queries
- **GetPartnerPackages** - Retrieve only package details for a partner
- **GetProductConfiguration** - Get detailed product configuration with pricing
---
id: GetPolicy
name: Get Policy
version: 0.0.1
summary: Retrieve a policy by ID
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Retrieves the full details of a specific policy by its unique policy ID, including cover details, beneficiaries, premium information, and current policy status.
## HTTP Endpoint
```
GET /v1/policy/{policyId}
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: GetPolicyByPolicyCode
name: Get Policy By Policy Code
version: 0.0.1
summary: Retrieve a policy by its human-readable policy code
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Retrieves the full details of a policy using its human-readable policy code. This is typically used when a policy code is known from correspondence or documentation rather than the internal policy ID.
## HTTP Endpoint
```
GET /v1/policy/by-policy-code/{policyCode}
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: GetPolicyCommandStatus
name: Get Policy Command Status
version: 0.0.1
summary: Poll the status of an asynchronous policy command
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Policy
backgroundColor: purple
textColor: white
---
## Overview
Polls the processing status of an asynchronous policy command using its correlation ID. Returns the current status (pending, completed, or failed) and any result or error details.
## HTTP Endpoint
```
GET /v1/policy/command-status/{correlationId}
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: GetPolicyCorrelatedEvents
name: Get Policy Correlated Events
version: 0.0.1
summary: Get all events correlated to a policy (ASCP-specific for claims assessment)
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: ASCP
backgroundColor: teal
textColor: white
---
## Overview
Retrieves all domain events correlated to a specific policy. This is an ASCP-specific query used during claims assessment to provide assessors with a full audit trail of events on a policy.
## HTTP Endpoint
```
GET /api/v1/policy/correlated-events/{policyId}
```
## Upstream Service
Proxied to the **Policy** domain service.
---
id: GetPolicyCorrelationIdTrace
name: Get Policy Correlation ID Trace
version: 0.0.1
summary: Retrieve all events associated with a policy grouped by correlation ID
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetPolicyCorrelationIdTrace` query retrieves all events associated with a specific policy, grouped by their correlation IDs. This endpoint is useful for tracing the flow of operations through the system, understanding the sequence of events triggered by a single command, and debugging complex workflows.
## Request
### HTTP Method
```
GET /audit/correlated-events/{policyId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `policyId` | string | Yes | The unique identifier of the policy to trace |
### Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `correlationId` | string (UUID) | No | Filter by specific correlation ID |
| `fromDate` | datetime | No | Filter events from this timestamp (ISO 8601) |
| `toDate` | datetime | No | Filter events until this timestamp (ISO 8601) |
| `page` | integer | No | Page number for pagination (default: 1) |
| `pageSize` | integer | No | Number of correlation groups per page (default: 10, max: 50) |
### Example Request
```bash
curl -X GET "https://api.digisure.com/policy/audit/correlated-events/POL-12345678?fromDate=2024-01-01T00:00:00Z" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"policyId": "POL-12345678",
"correlationGroups": [
{
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"initiatingCommand": "CreateFuneralPolicy",
"initiatedAt": "2024-01-15T10:30:00Z",
"completedAt": "2024-01-15T10:30:05Z",
"status": "COMPLETED",
"events": [
{
"eventId": "evt-001",
"eventType": "FuneralPolicyCreated",
"timestamp": "2024-01-15T10:30:02Z",
"version": 1,
"metadata": {
"userId": "user-123",
"source": "API"
}
},
{
"eventId": "evt-002",
"eventType": "PolicyholderAdded",
"timestamp": "2024-01-15T10:30:03Z",
"version": 2,
"metadata": {
"userId": "user-123",
"source": "API"
}
},
{
"eventId": "evt-003",
"eventType": "BeneficiaryAdded",
"timestamp": "2024-01-15T10:30:04Z",
"version": 3,
"metadata": {
"userId": "user-123",
"source": "API"
}
}
]
},
{
"correlationId": "660f9500-f39c-52e5-b827-557766551111",
"initiatingCommand": "UpdateBeneficiary",
"initiatedAt": "2024-01-20T14:15:00Z",
"completedAt": "2024-01-20T14:15:02Z",
"status": "COMPLETED",
"events": [
{
"eventId": "evt-004",
"eventType": "BeneficiaryUpdated",
"timestamp": "2024-01-20T14:15:01Z",
"version": 4,
"metadata": {
"userId": "user-456",
"source": "PORTAL"
}
}
]
}
],
"pagination": {
"currentPage": 1,
"pageSize": 10,
"totalPages": 1,
"totalGroups": 2
}
}
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_POLICY_ID` | The provided policy ID format is invalid |
| 400 | `INVALID_DATE_FORMAT` | Date parameters must be in ISO 8601 format |
| 400 | `INVALID_CORRELATION_ID` | The provided correlation ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions to access audit data |
| 404 | `POLICY_NOT_FOUND` | No policy exists with the specified ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetPolicyEventList
name: Get Policy Event List
version: 0.0.1
summary: Retrieve all events for a policy in chronological order
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetPolicyEventList` query retrieves the complete event history for a specific policy in chronological order. This endpoint provides a full audit trail of all changes made to the policy, enabling compliance reporting, debugging, and historical analysis.
## Request
### HTTP Method
```
GET /audit/events/{policyId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `policyId` | string | Yes | The unique identifier of the policy |
### Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `eventType` | string | No | Filter by specific event type |
| `fromDate` | datetime | No | Filter events from this timestamp (ISO 8601) |
| `toDate` | datetime | No | Filter events until this timestamp (ISO 8601) |
| `fromVersion` | integer | No | Filter events from this version number |
| `toVersion` | integer | No | Filter events up to this version number |
| `page` | integer | No | Page number for pagination (default: 1) |
| `pageSize` | integer | No | Number of events per page (default: 50, max: 200) |
| `sortOrder` | string | No | Sort order: ASC (oldest first) or DESC (newest first, default) |
### Example Request
```bash
curl -X GET "https://api.digisure.com/policy/audit/events/POL-12345678?sortOrder=ASC&pageSize=20" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"policyId": "POL-12345678",
"events": [
{
"eventId": "evt-001",
"eventType": "FuneralPolicyCreated",
"version": 1,
"timestamp": "2024-01-15T10:30:02Z",
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"policyNumber": "FUN-2024-001234",
"productCode": "FUNERAL_BASIC",
"sumAssured": 50000,
"premium": 150.00
},
"metadata": {
"userId": "user-123",
"source": "API",
"ipAddress": "192.168.1.100"
}
},
{
"eventId": "evt-002",
"eventType": "PolicyholderAdded",
"version": 2,
"timestamp": "2024-01-15T10:30:03Z",
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"firstName": "John",
"lastName": "Doe",
"idNumber": "8501015800083",
"dateOfBirth": "1985-01-01"
},
"metadata": {
"userId": "user-123",
"source": "API",
"ipAddress": "192.168.1.100"
}
},
{
"eventId": "evt-003",
"eventType": "BeneficiaryAdded",
"version": 3,
"timestamp": "2024-01-15T10:30:04Z",
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"beneficiaryId": "ben-001",
"firstName": "Jane",
"lastName": "Doe",
"relationship": "SPOUSE",
"percentage": 100
},
"metadata": {
"userId": "user-123",
"source": "API",
"ipAddress": "192.168.1.100"
}
},
{
"eventId": "evt-004",
"eventType": "PolicyActivated",
"version": 4,
"timestamp": "2024-01-15T10:30:05Z",
"correlationId": "550e8400-e29b-41d4-a716-446655440000",
"data": {
"effectiveDate": "2024-01-15",
"previousStatus": "PENDING",
"newStatus": "ACTIVE"
},
"metadata": {
"userId": "system",
"source": "WORKFLOW",
"triggeredBy": "AutoActivation"
}
}
],
"pagination": {
"currentPage": 1,
"pageSize": 20,
"totalPages": 1,
"totalEvents": 4
},
"summary": {
"firstEventAt": "2024-01-15T10:30:02Z",
"lastEventAt": "2024-01-15T10:30:05Z",
"currentVersion": 4,
"totalEventCount": 4
}
}
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_POLICY_ID` | The provided policy ID format is invalid |
| 400 | `INVALID_DATE_FORMAT` | Date parameters must be in ISO 8601 format |
| 400 | `INVALID_VERSION_RANGE` | fromVersion must be less than or equal to toVersion |
| 400 | `PAGE_SIZE_EXCEEDED` | Page size exceeds maximum allowed (200) |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions to access audit data |
| 404 | `POLICY_NOT_FOUND` | No policy exists with the specified ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetPremiumFromCover
name: Get Premium From Cover
version: 0.0.1
summary: Calculate the monthly premium amount for a given cover amount and risk factors
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetPremiumFromCover` query calculates the monthly premium amount based on a specified cover amount and the insured person's risk factors. This is the primary pricing operation used during the quote generation process.
## Request
### HTTP Method
```
POST /pricing/premium-from-cover
```
### Request Body
The request contains partner configuration and a list of product queries with risk factors:
```json
{
"partnerId": "uuid",
"packageId": "uuid",
"productCategoryId": "uuid",
"productVersion": 1,
"configurationVersion": 1,
"products": [
{
"productId": "MAIN_LIFE",
"partyId": "uuid",
"age": 35,
"gender": "MALE",
"relationship": "MAIN",
"coverAmount": {
"amount": 5000000,
"currency": "ZAR"
}
}
]
}
```
### Key Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `partnerId` | UUID | Yes | The partner identifier for pricing configuration |
| `packageId` | UUID | Yes | The package identifier |
| `productCategoryId` | UUID | Yes | The product category for pricing lookup |
| `productVersion` | integer | Yes | Product configuration version |
| `configurationVersion` | integer | Yes | Pricing configuration version |
| `products` | array | Yes | List of products to price |
| `products[].age` | integer | Yes | Age of the insured person |
| `products[].gender` | string | Yes | Gender (MALE, FEMALE) |
| `products[].relationship` | string | Yes | Relationship to main life |
| `products[].coverAmount` | Money | Yes | Desired cover amount |
## Response
### Success Response (200 OK)
```json
{
"products": [
{
"productId": "MAIN_LIFE",
"partyId": "uuid",
"premium": {
"amount": 15000,
"currency": "ZAR"
},
"coverAmount": {
"amount": 5000000,
"currency": "ZAR"
}
}
],
"totalPremium": {
"amount": 15000,
"currency": "ZAR"
}
}
```
## Calculation Process
1. Load pricing configuration for partner/product
2. Look up age-based mortality factors (QX)
3. Apply relationship and gender adjustments
4. Calculate base premium from actuarial formula
5. Add expense loadings and profit margin
6. Apply distribution rate
7. Round to final premium amount
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_REQUEST` | Request validation failed |
| 400 | `INVALID_AGE` | Age is outside acceptable range |
| 404 | `CONFIG_NOT_FOUND` | Pricing configuration not found for partner/product |
| 500 | `CALCULATION_ERROR` | Error during premium calculation |
---
id: GetProductBundleConfig
name: Get Product Bundle Config
version: 0.0.1
summary: Retrieve a product bundle configuration by its identifier.
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Not Yet Implemented
backgroundColor: orange
textColor: black
---
## Overview
The `GetProductBundleConfig` query retrieves a product bundle configuration by its unique identifier. This endpoint returns the complete configuration details including partner, package, products, and coverage rules.
## Request
### HTTP Method
```
GET /bundles/{bundleId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `bundleId` | string | Yes | The unique identifier of the bundle configuration |
### Example Request
```bash
curl -X GET "https://api.digisure.com/bundle-inventory/bundles/BDL-12345" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"bundleId": "BDL-12345",
"partnerId": "7a9dd2f9-e88e-464e-9a04-c511f17d891f",
"partnerCode": "140",
"partnerName": "Blue Label",
"packageId": "d63aa3ad-bea9-49ae-90f1-2a6f336f6a3b",
"packageCode": "001",
"packageName": "Immediate Family",
"bundleName": "Blue Label - Immediate Family - 3 Months",
"products": [
{
"productId": "460604d5-859f-4855-ad48-d61d17dcb8fc",
"productShortCode": "MAIN",
"rules": {
"coverPercentage": 100
}
}
],
"coverCalculation": {
"strategy": "COVER_LUMP_SUM_DIVIDED_BY_TERM_UNITS",
"coverLumpAmount": {
"currency": "ZAR",
"amount": 150000
}
},
"allowedCoverTerms": [3, 6, 12],
"currentSequence": 1000
}
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_BUNDLE_ID` | The provided bundle ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 404 | `BUNDLE_NOT_FOUND` | No bundle exists with the specified ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: GetProductRulesByRelationship
name: Get Product Rules By Relationship
version: 0.0.1
summary: Get product rules for a specific partner, package, and product combination
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Partner
backgroundColor: gray
textColor: white
---
## Overview
Retrieves the product rules applicable to a specific combination of partner, package, and product. These rules govern eligibility, cover limits, and configuration options available for the given relationship.
## HTTP Endpoint
```
GET /v1/partner/{partnerId}/package/{packageId}/product/{productId}/rules
```
## Upstream Service
Proxied to the **Partner** domain service.
---
id: GetQuote
name: Get Quote
version: 0.0.1
summary: Retrieve a quote by ID
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Retrieves the full details of a specific quote by its unique quote ID, including products, beneficiaries, pricing, and current status.
## HTTP Endpoint
```
GET /v1/quote/{quoteId}
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: GetQuoteCommandStatus
name: Get Quote Command Status
version: 0.0.1
summary: Poll the status of an asynchronous quote command
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Quote
backgroundColor: green
textColor: white
---
## Overview
Polls the processing status of an asynchronous quote command using its correlation ID. Returns the current status (pending, completed, or failed) and any result or error details.
## HTTP Endpoint
```
GET /v1/quote/status/{correlationId}
```
## Upstream Service
Proxied to the **Quote** domain service.
---
id: GetTenantedIdentity
name: Get Tenanted Identity
version: 0.0.1
summary: Retrieve a tenanted identity by tenant ID and identity ID
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `GetTenantedIdentity` query retrieves a single tenanted identity record by its tenant ID and identity ID. This enables tenant-specific identity lookups.
## Request
### Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `tenantId` | string | Yes | The tenant identifier |
| `identityId` | UUID | Yes | The unique identity ID within the tenant |
### Example Request
```java
// Using Lambda Query Handler
TenantedIdentityQueryRequest request = TenantedIdentityQueryRequest.builder()
.tenantId("digisure-funeral.identities")
.identityId("550e8400-e29b-41d4-a716-446655440000")
.build();
```
## Response
### Success Response
```json
{
"tenantId": "digisure-funeral.identities",
"identityId": "550e8400-e29b-41d4-a716-446655440000",
"globalCustomerId": "gcid-uuid-if-linked",
"name": {
"name": "John",
"familyName": "Doe"
},
"issuedIdentity": {
"idType": "IDENTITY_DOCUMENT",
"idValue": "8501015800083",
"idCountryOfIssue": "ZA"
},
"mobileNumber": {
"countryCode": "+27",
"localNumber": "0821234567"
},
"emailAddress": "john.doe@example.com",
"dateOfBirth": "1985-01-01",
"gender": "MALE",
"isActive": true,
"version": 1
}
```
### Not Found
Returns empty/null if no identity exists with the specified tenant and identity ID.
## Tenant Configuration
Common tenant IDs include:
- `digisure-funeral.identities` - Funeral policy identities
- `digisure-funeral.beneficiaries` - Funeral policy beneficiaries
---
id: GetTenantedIdentityBatch
name: Get Tenanted Identity Batch
version: 0.0.1
summary: Retrieve multiple tenanted identities in a single batch request
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Batch
backgroundColor: orange
textColor: black
---
## Overview
The `GetTenantedIdentityBatch` query retrieves multiple tenanted identity records in a single request. This is optimized for scenarios where multiple identities need to be fetched, such as loading all beneficiaries for a policy.
## Request
### Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `tenantId` | string | Yes | The tenant identifier |
| `identityIds` | array | Yes | List of identity IDs to retrieve |
### Example Request
```java
// Using Lambda Query Handler
TenantedIdentityBatchQueryRequest request = TenantedIdentityBatchQueryRequest.builder()
.tenantId("digisure-funeral.beneficiaries")
.identityIds(Arrays.asList(
"uuid-1",
"uuid-2",
"uuid-3"
))
.build();
```
## Response
### Success Response
```json
{
"identities": [
{
"tenantId": "digisure-funeral.beneficiaries",
"identityId": "uuid-1",
"name": {
"name": "Jane",
"familyName": "Doe"
},
"isActive": true
},
{
"tenantId": "digisure-funeral.beneficiaries",
"identityId": "uuid-2",
"name": {
"name": "James",
"familyName": "Doe"
},
"isActive": true
}
],
"notFound": ["uuid-3"]
}
```
## Batch Limits
- Maximum 100 identities per batch request
- Uses DynamoDB BatchGetItem for efficient retrieval
- Automatically handles unprocessed items with retries
## Use Cases
- **Beneficiary Loading**: Fetch all beneficiaries for a policy
- **Family Group Display**: Load family members for display
- **Bulk Verification**: Validate multiple identities at once
---
id: GetUserBankingDetails
name: Get User Banking Details
version: 0.0.1
summary: Retrieve the authenticated user's banking details
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Customer
backgroundColor: teal
textColor: white
---
## Overview
Retrieves the banking details on record for the currently authenticated user. This information is used for debit order setup and payout processing.
## HTTP Endpoint
```
GET /v1/user/banking-details
```
## Upstream Service
Proxied to the **Customer** domain service.
---
id: GetVerificationStatus
name: Get Verification Status
version: 0.0.1
summary: Retrieve the current status of a verification request by correlation ID
owners:
- digisure-engineering
status: planned
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Planned
backgroundColor: gray
textColor: white
---
> **STATUS:** This query is currently planned and not yet implemented in the Verification Service codebase. It is documented here as a planned feature for future development.
## Overview
The `GetVerificationStatus` query retrieves the current status of a verification request using its correlation ID. This endpoint is useful for tracking the progress of long-running verifications, particularly ORMS sanctions screenings that may require analyst review.
## Request
### HTTP Method
```
GET /verification/status/{correlationId}
```
### Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `correlationId` | string | Yes | The correlation ID of the verification request |
### Example Request
```bash
curl -X GET "https://api.digisure.com/verification/status/7c9e6679-7425-40de-944b-e07fc1f90ae7" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"correlationId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"verificationType": "SANCTIONS_SCREENING",
"status": "PENDING_DECISION",
"partyId": "8f14e45f-ceea-467f-a8f8-e8d05c7eb345",
"provider": "ORMS",
"createdAt": "2024-01-15T10:30:00Z",
"lastUpdatedAt": "2024-01-15T10:35:00Z",
"externalToken": "ORMS-12345",
"result": null,
"pendingDetails": {
"screeningEventId": 12345,
"riskIndicator": "MEDIUM",
"flaggedWatchlists": "PEP-GLOBAL"
}
}
```
### Completed Verification Response
```json
{
"correlationId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"verificationType": "VERIFICATION_OF_PERSONAL_DETAILS",
"status": "COMPLETED",
"partyId": "8f14e45f-ceea-467f-a8f8-e8d05c7eb345",
"provider": "ASTUTE",
"createdAt": "2024-01-15T10:30:00Z",
"lastUpdatedAt": "2024-01-15T10:31:00Z",
"externalToken": "AST-67890",
"result": {
"outcome": "SUCCESS",
"completedAt": "2024-01-15T10:31:00Z"
}
}
```
## Status Values
| Status | Description |
|--------|-------------|
| `PENDING` | Request created, awaiting processing |
| `IN_PROGRESS` | Request sent to provider |
| `PENDING_DECISION` | ORMS screening awaiting analyst decision |
| `COMPLETED` | Verification finished |
| `FAILED` | Request could not be processed |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_CORRELATION_ID` | The provided correlation ID format is invalid |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 404 | `VERIFICATION_NOT_FOUND` | No verification exists with the specified correlation ID |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: HealthcheckRequest
name: Healthcheck Request
version: 0.0.1
summary: Check the health and availability of the BFF Web service
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Infrastructure
backgroundColor: gray
textColor: white
---
## Overview
The `HealthcheckRequest` query provides a simple endpoint for monitoring systems to verify the BFF Web service is running and responsive.
## Request
### HTTP Method
```
GET /__ping
```
### Headers
No special headers required. CORS headers are still applied if Origin is present.
### Example Request
```bash
curl -X GET "https://bff-web.digisure.com/__ping"
```
## Response
### Success Response (200 OK)
```
ok
```
The response is a plain text "ok" string with:
- Status code: 200
- CORS headers applied (if Origin present)
- Security headers applied
## Processing
The healthcheck endpoint:
- Bypasses CAPTCHA validation
- Bypasses proxy logic
- Returns immediately from the worker
## Use Cases
- **Load Balancer Health Checks**: Verify worker availability
- **Uptime Monitoring**: External monitoring services
- **Deployment Verification**: Confirm new deployments are responsive
- **Incident Response**: Quick availability verification
---
id: PerformCalculation
name: Perform Calculation
version: 0.0.1
summary: Execute dynamic calculations using partner-configured calculator instances
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `PerformCalculation` query executes one or more dynamic calculations using partner-configured calculator instances. This provides flexibility for partners to define custom calculation logic through configuration rather than code.
## Request
### HTTP Method
```
POST /pricing/calculate
```
### Request Body
The request contains a list of calculation requests, each specifying calculator instances and input values:
```json
{
"calculations": [
{
"id": "calc-1",
"calculatorInstanceIds": [
{ "value": "main-life-calculator-v1" }
],
"queryInstanceIds": [
{ "value": "age-factor-query" }
],
"valuesMap": {
"age": 35,
"gender": "MALE",
"relationship": "MAIN",
"coverAmount": 5000000
},
"cover": 5000000,
"premium": null
}
]
}
```
### Key Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `calculations` | array | Yes | List of calculations to perform |
| `calculations[].id` | string | Yes | Unique identifier for this calculation |
| `calculations[].calculatorInstanceIds` | array | Yes | Calculator instances to execute |
| `calculations[].queryInstanceIds` | array | No | Query instances for data lookup |
| `calculations[].valuesMap` | object | Yes | Input values for the calculation |
| `calculations[].cover` | decimal | No | Initial cover amount |
| `calculations[].premium` | decimal | No | Initial premium amount |
## Response
### Success Response (200 OK)
```json
{
"calculations": [
{
"id": "calc-1",
"calculatorInstanceIds": [
{ "value": "main-life-calculator-v1" }
],
"valuesMap": {
"age": 35,
"gender": "MALE",
"relationship": "MAIN",
"coverAmount": 5000000,
"lifeQx": 0.00234,
"monthlyPremium": 150.00
},
"cover": 5000000,
"premium": 150.00
}
],
"totalCover": 5000000,
"totalPremium": 150.00
}
```
## Dynamic Calculator Configuration
Calculator instances are configured in the database with:
- **Calculator Instance ID**: Unique identifier for the configuration
- **Calculator ID**: The base calculator type
- **Calculator Name**: Human-readable name
- **Calculation Configs**: List of calculation expressions
- **Version**: Configuration version
- **Partner ID**: Partner this configuration applies to
- **Rounding Config**: How to round results
## Calculation Expression Types
Expressions can be:
- **Literal**: Fixed values
- **Variable**: References to valuesMap entries
- **Operation**: Mathematical operations (add, subtract, multiply, divide)
## Use Cases
1. **Custom Pricing Logic**: Partners with unique pricing requirements
2. **A/B Testing**: Testing new pricing formulas alongside existing ones
3. **Product Experimentation**: Trying new product configurations
4. **Batch Calculations**: Processing multiple calculations efficiently
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `EMPTY_CALCULATIONS` | Calculations array is null or empty |
| 400 | `INVALID_CALCULATOR` | Calculator instance not found |
| 400 | `MISSING_VALUE` | Required value missing from valuesMap |
| 500 | `CALCULATION_ERROR` | Error during calculation execution |
---
id: PerformPricingCalculation
name: Perform Pricing Calculation
version: 0.0.1
summary: Query to calculate premium and cover amounts for insurance products
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Pricing
backgroundColor: pink
textColor: black
---
## Overview
The `PerformPricingCalculation` query calculates premium amounts for insurance products based on the provided risk factors. This is used during the quote process to determine pricing for different cover amounts and policyholder profiles.
## Request
### HTTP Method
```
POST /pricing/perform-calculations
```
### Request Body
```json
{
"partnerId": "partner-001",
"packageId": "pkg-standard",
"productId": "prod-main",
"calculationType": "PREMIUM_FROM_COVER",
"riskFactors": {
"dateOfBirth": "1985-01-01",
"gender": "MALE",
"smoker": false
},
"coverAmount": {
"amount": 5000000,
"currency": "ZAR"
}
}
```
### Request Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `partnerId` | string | Yes | Partner identifier |
| `packageId` | string | Yes | Package identifier |
| `productId` | string | Yes | Product identifier |
| `calculationType` | string | Yes | `PREMIUM_FROM_COVER` or `COVER_FROM_PREMIUM` |
| `riskFactors` | object | Yes | Risk factors for calculation |
| `coverAmount` | Money | Conditional | Cover amount (for PREMIUM_FROM_COVER) |
| `premiumAmount` | Money | Conditional | Premium amount (for COVER_FROM_PREMIUM) |
## Response
### Success Response (200 OK)
```json
{
"calculationId": "calc-12345678-90ab-cdef",
"calculationType": "PREMIUM_FROM_COVER",
"inputCoverAmount": {
"amount": 5000000,
"currency": "ZAR"
},
"calculatedPremium": {
"amount": 15000,
"currency": "ZAR"
},
"premiumBreakdown": {
"basePremium": {
"amount": 12000,
"currency": "ZAR"
},
"loadings": [
{
"type": "AGE_LOADING",
"amount": {
"amount": 2000,
"currency": "ZAR"
},
"percentage": 16.67
}
],
"discounts": [
{
"type": "NON_SMOKER_DISCOUNT",
"amount": {
"amount": -1000,
"currency": "ZAR"
},
"percentage": -8.33
}
]
},
"escalationConfiguration": {
"premiumEscalationPercentage": 10,
"coverEscalationPercentage": 5,
"escalationInterval": {
"unit": "YEARS",
"value": 1
}
},
"effectiveFrom": "2024-01-15",
"validUntil": "2024-02-15"
}
```
## Calculation Types
| Type | Description |
|------|-------------|
| `PREMIUM_FROM_COVER` | Calculate premium given a cover amount |
| `COVER_FROM_PREMIUM` | Calculate maximum cover given a premium budget |
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_REQUEST` | Invalid calculation parameters |
| 400 | `COVER_OUT_OF_RANGE` | Cover amount outside allowed range |
| 400 | `AGE_OUT_OF_RANGE` | Policyholder age outside allowed range |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication |
| 404 | `PRODUCT_NOT_FOUND` | Product not found for partner |
| 500 | `CALCULATION_ERROR` | Pricing calculation failed |
---
id: ProxyHttpRequest
name: Proxy HTTP Request
version: 0.0.1
summary: Proxy any HTTP request from web clients to the backend BFF API
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
- content: Proxy
backgroundColor: gray
textColor: white
---
## Overview
The `ProxyHttpRequest` query represents any HTTP request that is proxied from web clients through the BFF Web service to the backend BFF API. This is the primary function of the service.
## Request
### HTTP Methods
All standard HTTP methods are supported:
- `GET` - Retrieve resources
- `POST` - Create resources
- `PUT` - Replace resources
- `PATCH` - Partial update resources
- `DELETE` - Remove resources
### Headers
| Header | Required | Description |
|--------|----------|-------------|
| `Origin` | Yes | The requesting origin for CORS validation |
| `Authorization` | No | Bearer token for authenticated requests |
| `x-api-key` | No | API key for authenticated requests |
| `x-recaptcha-token` | Conditional | Required for unauthenticated mutations |
| `Content-Type` | Conditional | Required for requests with body |
### Example Request
```bash
curl -X POST "https://bff-web.digisure.com/api/v1/quote" \
-H "Origin: https://sanlamonline.co.za" \
-H "Content-Type: application/json" \
-H "x-recaptcha-token: {token}" \
-d '{"productCode": "FUNERAL_BASIC"}'
```
## Processing
The request goes through the following pipeline:
1. **CORS Validation** - Origin checked against allowlist
2. **CAPTCHA Validation** - Token verified for mutations without auth
3. **SigV4 Signing** - Request signed if AWS signing enabled
4. **Proxy** - Request forwarded to upstream backend
## Response
The response from the backend is returned with:
- Original status code and body
- CORS headers added
- Security headers added
- Sensitive headers removed
### Error Responses
| Status | Error | Description |
|--------|-------|-------------|
| 403 | `forbidden_origin` | Origin not in allowlist |
| 401 | `recaptcha_failed` | CAPTCHA validation failed |
| 500 | `recaptcha_misconfigured` | Server CAPTCHA config error |
| 500 | `sigv4_misconfigured` | Server AWS signing error |
| 502 | `upstream_unavailable` | Backend unreachable |
---
id: QueryFuneralPolicy
name: Query Funeral Policy
version: 0.0.1
summary: Search policies with filters and pagination
owners:
- digisure-engineering
badges:
- content: Query
backgroundColor: cyan
textColor: black
---
## Overview
The `QueryFuneralPolicy` query allows searching for funeral policies using various filter criteria. This endpoint supports pagination and returns a list of policies matching the specified filters.
## Request
### HTTP Method
```
GET /query
```
### Path Parameters
This endpoint does not have path parameters.
### Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `policyNumber` | string | No | Filter by policy number (partial match supported) |
| `idNumber` | string | No | Filter by policyholder ID number |
| `status` | string | No | Filter by policy status (ACTIVE, LAPSED, CANCELLED, PENDING) |
| `productCode` | string | No | Filter by product code |
| `effectiveDateFrom` | date | No | Filter policies effective from this date (ISO 8601) |
| `effectiveDateTo` | date | No | Filter policies effective until this date (ISO 8601) |
| `page` | integer | No | Page number for pagination (default: 1) |
| `pageSize` | integer | No | Number of results per page (default: 20, max: 100) |
| `sortBy` | string | No | Field to sort by (createdAt, effectiveDate, policyNumber) |
| `sortOrder` | string | No | Sort order (ASC, DESC) |
### Example Request
```bash
curl -X GET "https://api.digisure.com/policy/query?status=ACTIVE&productCode=FUNERAL_BASIC&page=1&pageSize=10" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
```
## Response
### Success Response (200 OK)
```json
{
"data": [
{
"policyId": "POL-12345678",
"policyNumber": "FUN-2024-001234",
"status": "ACTIVE",
"productCode": "FUNERAL_BASIC",
"policyholder": {
"firstName": "John",
"lastName": "Doe",
"idNumber": "8501015800083"
},
"coverage": {
"sumAssured": 50000,
"premium": 150.00
},
"effectiveDate": "2024-01-15",
"createdAt": "2024-01-10T10:30:00Z"
},
{
"policyId": "POL-87654321",
"policyNumber": "FUN-2024-001235",
"status": "ACTIVE",
"productCode": "FUNERAL_BASIC",
"policyholder": {
"firstName": "Jane",
"lastName": "Smith",
"idNumber": "9002025800084"
},
"coverage": {
"sumAssured": 75000,
"premium": 225.00
},
"effectiveDate": "2024-01-20",
"createdAt": "2024-01-18T09:15:00Z"
}
],
"pagination": {
"currentPage": 1,
"pageSize": 10,
"totalPages": 5,
"totalItems": 48
}
}
```
## Error Codes
| Status Code | Error Code | Description |
|-------------|------------|-------------|
| 400 | `INVALID_QUERY_PARAMS` | One or more query parameters are invalid |
| 400 | `INVALID_DATE_FORMAT` | Date parameters must be in ISO 8601 format |
| 400 | `PAGE_SIZE_EXCEEDED` | Page size exceeds maximum allowed (100) |
| 401 | `UNAUTHORIZED` | Missing or invalid authentication token |
| 403 | `FORBIDDEN` | Insufficient permissions to query policies |
| 500 | `INTERNAL_ERROR` | An unexpected server error occurred |
---
id: BFFASCPService
name: BFFASCP Service
version: 0.0.1
summary: |
Backend for Frontend service providing API orchestration for the Agent Servicing Claims Portal,
enabling agents to manage quotes, policies, claims, and customer interactions.
owners:
- digisure-engineering
receives:
# Commands - Quote Operations
- id: CreateQuote
- id: AddProductToQuote
- id: UpdateProductOnQuote
- id: DeleteProductFromQuote
- id: CapturePolicyholder
- id: CaptureCollectionDetails
- id: CaptureSalesAgent
- id: AddBeneficiaryToQuote
- id: UpdateBeneficiaryOnQuote
- id: RemoveBeneficiaryFromQuote
- id: AddOptionalBenefit
- id: RemoveOptionalBenefit
- id: SetTermsAndConditionsAccepted
- id: SetQuoteCoverStartDate
- id: FinaliseQuote
- id: AcceptQuote
- id: SendAdHocQuoteNotification
# Commands - Policy Operations
- id: AddBeneficiaryToPolicy
- id: UpdateBeneficiaryOnPolicy
- id: RemoveBeneficiaryFromPolicy
- id: UpdatePersonalDetailsOnPolicy
- id: AddVerificationToPolicy
- id: CancelPolicy
- id: GeneratePolicySchedule
- id: RefreshPolicyScheduleLink
- id: MainLifeDeceased
- id: CoveredLifeDeceased
# Commands - Claims Operations
- id: CreateClaimRequest
- id: CreateClaimForMainLife
- id: CreateClaimForCoveredLife
- id: CaptureClaimant
- id: UpdateMainLifeClaim
- id: UpdateMainLifeClaimAndCalcPayout
- id: UpdateCoveredLifeClaimAndCalcPayout
- id: UpdateClaimForCoveredLifeDeath
- id: CalculateClaimPayout
- id: PayClaim
- id: RepudiateClaim
- id: OverrideRepudiatedClaim
- id: AssessorResponse
# Commands - File Operations
- id: UploadFile
- id: GeneratePreSignedUrl
- id: DeleteFile
# Queries
- id: GetQuote
- id: GetQuoteCommandStatus
- id: GetPolicy
- id: GetPolicyByPolicyCode
- id: GetPolicyCommandStatus
- id: GetPolicyCorrelatedEvents
- id: GetClaims
- id: GetClaim
- id: GetClaimByClaimNumber
- id: GetClaimsByPolicyId
- id: GetClaimsCommandStatus
- id: GetClaimSupportTickets
- id: GetCustomer
- id: GetCustomerByPolicyCode
- id: GetPartner
- id: PerformPricingCalculation
- id: DownloadFile
- id: GetFileCommandStatus
sends:
# Commands forwarded to Quote Domain
- id: CreateQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: AcceptQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: FinaliseQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: AddBeneficiaryToQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: UpdateBeneficiaryOnQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: RemoveBeneficiaryFromQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: AddProductToQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: UpdateProductOnQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: DeleteProductFromQuoteCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: CapturePolicyholderCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: CaptureCollectionDetailsCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: CaptureSalesAgentCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
- id: SetTermsAndConditionsAcceptedCommand
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.commands'
parameters:
env: prd
# Commands forwarded to Policy Domain
- id: AddBeneficiaryToPolicyCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: UpdateBeneficiaryOnPolicyCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: RemoveBeneficiaryFromPolicyCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: UpdatePersonalDetailsOnPolicyCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: AddVerificationToPolicyCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: CancelPolicyCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: GeneratePolicyScheduleCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: RefreshPolicyScheduleLinkCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: MainLifeDeceasedCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: CoveredLifeDeceasedCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: ReverseCollectionOutcomeCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
- id: RescheduleGracePeriodCheckCommand
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
# Commands forwarded to Claims Domain
- id: CreateClaimForMainLifeCommand
version: 0.0.1
to:
- id: 'sft-capstone-claims.{env}.commands'
parameters:
env: prd
- id: CreateClaimForCoveredLifeCommand
version: 0.0.1
to:
- id: 'sft-capstone-claims.{env}.commands'
parameters:
env: prd
- id: UpdateMainLifeClaimCommand
version: 0.0.1
to:
- id: 'sft-capstone-claims.{env}.commands'
parameters:
env: prd
- id: UpdateClaimForCoveredLifeDeathCommand
version: 0.0.1
to:
- id: 'sft-capstone-claims.{env}.commands'
parameters:
env: prd
- id: CalculateClaimPayoutCommand
version: 0.0.1
to:
- id: 'sft-capstone-claims.{env}.commands'
parameters:
env: prd
- id: PayClaimCommand
version: 0.0.1
to:
- id: 'sft-capstone-claims.{env}.commands'
parameters:
env: prd
- id: RepudiateClaimCommand
version: 0.0.1
to:
- id: 'sft-capstone-claims.{env}.commands'
parameters:
env: prd
- id: OverrideRepudiatedClaimCommand
version: 0.0.1
to:
- id: 'sft-capstone-claims.{env}.commands'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-bff-ascp
badges:
- content: BFF Service
backgroundColor: teal
textColor: white
---
## Overview
The **BFFASCP Service** is the Backend for Frontend service that powers the Agent Servicing Claims Portal (ASCP). It provides a unified API layer that orchestrates communication between the ASCP frontend and various Capstone domain services.
## Architecture
The service follows a clean/hexagonal architecture pattern:
- **Domain Layer**: Command definitions, handlers, and business logic
- **Application Layer**: Use case orchestration and request handling
- **Infrastructure Layer**: HTTP clients, SQS dispatchers, and Lambda functions
```
ASCP Frontend
|
v
BFFASCP Service (API Gateway + Lambda)
|
+---> Quote Domain
+---> Policy Domain
+---> Claims Domain
+---> Customer Domain
+---> Partner Domain
+---> Pricing Service
+---> File Upload Service
```
## Capabilities
### Quote Management
- Create and configure quotes with products and beneficiaries
- Capture policyholder and collection details
- Set terms and conditions acceptance
- Finalise and accept quotes
### Policy Servicing
- Manage beneficiaries on existing policies
- Update personal and contact details
- Generate and refresh policy schedules
- Cancel policies
- Record deceased notifications
### Claims Processing
- Create claims for main life and covered life deaths
- Update claim details and documentation
- Calculate claim payouts
- Process claim payments
- Handle claim repudiation and overrides
### File Management
- Generate pre-signed URLs for document uploads
- Download uploaded files
- Delete files
- Track file upload status
### Query Operations
- Retrieve quotes, policies, claims, and customer data
- Get partner and package configuration
- Perform pricing calculations
- Track command processing status
## Technical Stack
- **Runtime**: Java 21 on AWS Lambda
- **Framework**: Custom clean architecture
- **Messaging**: AWS SQS for command dispatching
- **HTTP Client**: Java HTTP Client for domain service calls
- **Serialization**: Jackson for JSON processing
- **Resilience**: Resilience4j for fault tolerance
---
id: BFFWebService
name: BFF Web Service
version: 0.0.1
summary: |
Java Lambda-based Backend for Frontend service providing API orchestration for web clients,
proxying requests to Quote, Policy, Claims, Customer, Partner, Pricing and File Upload domain services.
owners:
- digisure-engineering
receives:
# Queries - Customer
- id: GetCustomer
- id: GetUserBankingDetails
# Queries - Partner
- id: GetPartner
- id: GetProductRulesByRelationship
# Queries - Quote
- id: GetQuote
- id: GetQuoteCommandStatus
# Queries - Policy
- id: GetPolicy
- id: GetPolicyByPolicyCode
- id: GetPolicyCommandStatus
# Queries - Claims
- id: GetClaim
- id: GetClaimByClaimNumber
- id: GetClaimsByPolicyId
- id: GetClaimsCommandStatus
# Queries - File Upload
- id: DownloadFile
- id: GetFileUploadCommandStatus
# Queries - Infrastructure
- id: CorsPreflightRequest
- id: HealthcheckRequest
# Commands - Claims
- id: CreateClaimRequest
- id: CreateClaimForMainLife
- id: CreateClaimForCoveredLife
- id: CalculateClaimPayout
- id: OverrideRepudiatedClaim
- id: PayClaim
- id: RepudiateClaim
- id: UpdateBankingDetailsOnClaim
- id: CaptureDeathDetails
- id: SubmitClaimToCrm
- id: CaptureClaimant
- id: UpdateMainLifeClaim
- id: UpdateMainLifeClaimAndCalcPayout
- id: UpdateCoveredLifeClaimAndCalcPayout
- id: UpdateCoveredLifeClaim
# Commands - Policy
- id: AddBeneficiaryToPolicy
- id: CancelPolicy
- id: MainLifeDeceased
- id: CoveredLifeDeceased
- id: GeneratePolicySchedule
- id: RefreshPolicyScheduleLink
- id: SendPolicyNotification
- id: ImportPolicy
- id: UpdatePersonalDetails
- id: RemoveBeneficiaryFromPolicy
- id: UpdateBeneficiaryOnPolicy
- id: StackCoverRequest
- id: StaggerCoverRequest
- id: ReinstatePolicyRequest
- id: AddVerificationToPolicy
# Commands - Quote
- id: CreateQuote
- id: CreateQuoteWithPolicy
- id: AcceptQuote
- id: FinaliseQuote
- id: SendQuoteNotification
- id: AddBeneficiaryToQuote
- id: AddOptionalBenefit
- id: RemoveOptionalBenefit
- id: AddOptionalBenefitToAllProducts
- id: RemoveOptionalBenefitOnProducts
- id: RemoveBeneficiaryFromQuote
- id: UpdateBeneficiaryOnQuote
- id: UpdateProductOnQuote
- id: DeleteProductFromQuote
- id: AddProductToQuote
- id: SetTermsAndConditionsAccepted
- id: SetQuoteCoverStartDate
- id: CaptureSalesAgent
- id: CaptureCollectionDetails
- id: CaptureReplacementCoverDetails
# Commands - File Upload
- id: UploadFile
- id: DeleteFile
- id: GeneratePreSignedUrl
# Commands - Pricing
- id: PerformPricingCalculation
sends:
# Observability Log Events (emitted to stdout/CloudWatch logs)
- id: RequestReceivedEventV1
version: 0.0.1
- id: CorsPreflightHandledEventV1
version: 0.0.1
- id: CaptchaValidatedEventV1
version: 0.0.1
- id: CaptchaFailedEventV1
version: 0.0.1
- id: ProxyRequestSentEventV1
version: 0.0.1
- id: ProxyResponseReceivedEventV1
version: 0.0.1
- id: ProxyUpstreamErrorEventV1
version: 0.0.1
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-bff-web
badges:
- content: BFF Service
backgroundColor: teal
textColor: white
- content: AWS Lambda
backgroundColor: orange
textColor: white
---
## Overview
The **BFF Web Service** is a Java Lambda-based Backend for Frontend service that provides a unified API entry point for web clients interacting with the Capstone PAS system. It orchestrates requests across Quote, Policy, Claims, Customer, Partner, Pricing, and File Upload domain services.
## Architecture
- **Runtime**: Java 21 on AWS Lambda
- **API Gateway**: AWS API Gateway triggers individual Lambda handlers
- **Handler count**: 69 Lambda handlers
- **Pattern**: One Lambda handler per HTTP endpoint
```
Web Client
|
v
AWS API Gateway
|
v
BFF Web Lambda Handlers (69)
|
+---> Quote Domain
+---> Policy Domain
+---> Claims Domain
+---> Customer Domain
+---> Partner Domain
+---> Pricing Service
+---> File Upload Service
```
## Capabilities
### Quote Management (26 handlers)
- Create quotes and quotes linked to policies
- Manage products, beneficiaries, and optional benefits
- Capture policyholder, sales agent, and collection details
- Set terms, cover start dates, and replacement cover details
- Finalise and accept quotes
### Policy Servicing (20 handlers)
- Manage beneficiaries and personal details
- Generate and refresh policy schedules
- Cancel, reinstate, stack, and stagger cover
- Record deceased notifications
- Import policies and add verifications
### Claims Processing (19 handlers)
- Create claims for main life and covered life deaths
- Update claim details, banking details, and death details
- Calculate payouts and process payments
- Repudiate and override claims
- Submit claims to CRM
### Customer & Partner Queries (4 handlers)
- Retrieve customer details and banking information
- Retrieve partner configuration and product rules
### Pricing (1 handler)
- Perform pricing calculations
### File Management (5 handlers)
- Upload, download, and delete files
- Generate pre-signed S3 URLs
- Track file command status
## Technical Stack
- **Runtime**: Java 21 on AWS Lambda
- **Framework**: Custom clean architecture with Google Guice DI
- **Messaging**: AWS SQS for async command dispatching
- **HTTP Client**: Java HTTP Client for domain service calls
- **Serialization**: Jackson for JSON processing
- **Resilience**: Resilience4j for fault tolerance
## Observability Events
The service emits structured JSON log events for observability:
- **RequestReceivedEventV1** - Every incoming HTTP request
- **CaptchaValidatedEventV1** / **CaptchaFailedEventV1** - CAPTCHA outcomes
- **ProxyRequestSentEventV1** / **ProxyResponseReceivedEventV1** - Proxy lifecycle
- **ProxyUpstreamErrorEventV1** - Backend connectivity failures
---
id: CollectionsCommandGatewayService
name: Collections Command Gateway Service
version: 0.0.1
summary: |
External command gateway that publishes collection creation, schedule creation,
and collection outcome events for downstream consumers.
owners:
- digisure-engineering
sends:
- id: CollectionCreationSucceededEventV4
version: 0.0.1
to:
- id: 'collections.{env}.events'
parameters:
env: prd
- id: CollectionCreationFailedEventV4
version: 0.0.1
to:
- id: 'collections.{env}.events'
parameters:
env: prd
- id: CollectionSucceededEventV5
version: 0.0.1
to:
- id: 'collections.{env}.events'
parameters:
env: prd
- id: CollectionFailedEventV5
version: 0.0.1
to:
- id: 'collections.{env}.events'
parameters:
env: prd
- id: ScheduleCreationSucceededEventV2
version: 0.0.1
to:
- id: 'collections.{env}.events'
parameters:
env: prd
badges:
- content: Command Gateway
backgroundColor: green
textColor: white
---
## Overview
The Collections Command Gateway publishes collection lifecycle events used by policy
services to reconcile payment outcomes and schedule information.
---
id: CustomerDPService
name: Customer DP Service
version: 0.0.1
summary: |
Data product service providing unified customer views by consuming policy and quote events
and projecting them into a queryable customer aggregate.
owners:
- digisure-engineering
receives:
# Events from Policy Channel (consumed via Kinesis/SQS)
- id: PolicyCreatedEventV1
version: 0.0.1
from:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyCancelledEventV1
version: 0.0.1
from:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyExpiredEventV1
version: 0.0.1
from:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyVerificationCompletedEventV1
version: 0.0.1
from:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
# Events from Quote Channel (consumed via Kinesis/SQS)
- id: PolicyHolderAddedToQuoteEventV2
version: 0.0.1
from:
- id: 'sft-capstone-quote.{env}.events'
parameters:
env: prd
# Queries
- id: GetCustomer
sends:
# This service does not emit domain events - it is a read-model/data product
[]
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-customer-dp
badges:
- content: Data Product
backgroundColor: teal
textColor: white
---
## Overview
The **Customer DP Service** is a data product service within the Capstone PAS that provides a unified view of customer data. It consumes events from the Policy and Quote domains and projects them into a queryable customer aggregate stored in DynamoDB.
## Architecture
- **Event Sourced Projection**: Consumes domain events to build customer read model
- **Lambda-based Consumers**: Separate Lambda functions for policy and quote events
- **DynamoDB Storage**: Customer state stored in DynamoDB with GSI for efficient queries
- **Idempotent Processing**: Logical clock readings ensure exactly-once semantics
## Event Processing
### Quote Events
The service consumes quote events via the `quote-events` SQS queue:
| Event | Handler | Effect |
|-------|---------|--------|
| PolicyHolderAddedToQuoteEvent | `PolicyHolderAddedToQuoteEventHandler` | Creates customer if not exists, associates quote |
### Policy Events
The service consumes policy events via the `policy-events` SQS queue:
| Event | Handler | Effect |
|-------|---------|--------|
| PolicyCreatedEvent | `PolicyCreatedFromQuoteEventHandler` | Removes quote reference, adds policy to customer |
| PolicyCancelledEvent | `PolicyCancelledEventHandler` | Updates policy status to CANCELLED |
| PolicyExpiredEvent | `PolicyExpiredEventHandler` | Updates policy status to EXPIRED |
| PolicyVerificationCompletedEvent | `PolicyVerificationCompletedEventHandler` | Updates policy status from verification result |
## Query Interface
The service exposes a single query endpoint:
| Query | Description |
|-------|-------------|
| GetCustomer | Retrieves customer by policy holder ID |
## Infrastructure
```
Kinesis (Policy Events) ─> SQS (policy-events) ─> Lambda (PolicyEventsHandler)
│
Kinesis (Quote Events) ─> SQS (quote-events) ─> Lambda (QuoteEventsHandler)
│
▼
DynamoDB (Customer Table)
│
▼
Lambda (GetCustomer API)
```
## Replay Support
Failed events can be replayed through dedicated replay queues:
- Policy events: Redrive from DLQ to `policy-events` queue
- Quote events: Redrive from DLQ to `quote-events` queue
Invalid payloads are routed to Invalid Message Queues (IMQs) for investigation.
---
id: DocumentExtractionCGService
name: Document Extraction Command Gateway Service
version: 0.0.1
summary: |
Command Gateway service for extracting structured data from documents using AWS Textract
and provider adapters. Handles document routing, extraction workflows, and outcome publishing.
owners:
- digisure-engineering
receives:
# Commands (SQS from upstream services)
- id: ExtractDocumentCommand
# Queries (REST API for status checks)
- id: GetExtractionStatus
sends:
# Status events published via EventBridge
- id: DocumentExtractionCompletedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-document-extraction.{env}.events'
parameters:
env: prd
- id: DocumentExtractionFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-document-extraction.{env}.events'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-document-extraction-cg
badges:
- content: Command Gateway
backgroundColor: indigo
textColor: white
- content: AWS Textract Integration
backgroundColor: orange
textColor: white
---
## Overview
The **Document Extraction Command Gateway Service** is a supporting domain service within the Capstone PAS that provides intelligent document processing and data extraction capabilities. It routes document extraction commands to specialized provider adapters (starting with AWS Textract), manages processing workflows, and publishes results for downstream consumption.
## Architecture
- **Event-Driven Command Processing**: SQS-based command routing with sequential processing guarantees
- **Provider Adapters**: Pluggable architecture for multiple extraction providers (Textract, BI Form adapter)
- **Resilient Processing**: Exponential backoff retries and dead-letter queue handling
- **Command Store**: DynamoDB persistence for tracking command lifecycle and status
- **EventBridge Integration**: Event-driven routing to specialized processing adapters
- **Kinesis Publishing**: Future event publication for audit trail and downstream integration
## Infrastructure
### AWS Lambda Handlers
| Handler | Trigger | Purpose |
|---------|---------|---------|
| ExtractDocumentCommandLambdaHandler | SQS | Main document extraction command processor |
| ExtractBiFormLambdaHandler | EventBridge | Specialized handler for BI Form document extraction |
| GetExtractionStatusQueryLambdaHandler | API Gateway | Retrieve extraction command status and results |
### AWS Resources
- **SQS Queues**:
- `sft-capstone-document-extraction-{env}-command-queue`: Incoming extraction commands
- `sft-capstone-document-extraction-{env}-invalid-message-queue`: Malformed message handling
- `sft-capstone-document-extraction-{env}-dead-letter-queue`: Failed command retention
- **DynamoDB Table**: Stores extraction command records with status tracking
- **EventBridge Rules**: Route commands to provider-specific processors
- **AWS Textract**: Primary extraction provider for document analysis
- **Kinesis Stream**: (Future) Event publishing for audit and downstream integration
## Capabilities
### Document Extraction
- Extract structured data from PDF, JPEG, PNG, TIFF, HEIC documents
- Support for multiple document types: Death Certificate, Birth Certificate, BI Form
- AWS Textract integration for OCR and form recognition
- Context-aware extraction based on document classification
### Processing Modes
- **Sequential Processing**: Ensures ordered extraction execution per origination context
- **Adaptive Routing**: Route to specialized adapters based on document type
- **Provider Flexibility**: Pluggable adapter pattern for multi-provider support
### Command Lifecycle
- **NEW**: Command received and queued
- **PROCESSING**: Active extraction with provider
- **COMPLETED**: Successful extraction, results available
- **FAILED**: Processing failure, retries exhausted
### Status Tracking
- Monitor extraction progress via GetExtractionStatus query
- Track correlationId for request tracing across systems
- Store command metadata for audit compliance
## Supported Document Types
| Document Type | Extraction Method | Adapter |
|---------------|------------------|---------|
| Death Certificate | OCR + Field Extraction | AWS Textract |
| Birth Certificate | OCR + Field Extraction | AWS Textract |
| BI Form | Form Recognition + Key-Value Extraction | BI Form Adapter |
## Integration Points
### Receives From
- **API Gateway**: REST queries for extraction status
- **SQS Queues**: Commands from upstream services (Policy, Quote, Claims)
- **EventBridge**: Routed commands for specialized processing
### Publishes To
- **EventBridge**: Processing outcome events (for adapter-specific handling)
- **Kinesis Stream**: (Future) Audit events and extraction results
- Policy Service: Extracted policy document data
- Quote Service: Supporting document analysis during quoting
- Claims Service: Claim evidence and documentation extraction
### Origination Context Support
- **POLICY**: Policy-related document extraction
- **QUOTE**: Quote-related document extraction
- **CLAIMS**: Claim-related document extraction
## File Compatibility
### Supported File Types
- PDF
- JPEG / JPG
- PNG
- TIFF
- HEIC
### Supported Encodings
- Base64 (for direct command inclusion)
- S3 references (S3 bucket and key location)
## Processing Guarantees
- **At-Least-Once Delivery**: SQS + command store ensure no command loss
- **Ordered Processing**: Sequential execution per origination context
- **Exponential Backoff**: Resilient retries with configurable intervals
- **Dead-Letter Isolation**: Failed commands preserved for manual review
---
id: FileUploadService
name: File Upload Service
version: 0.0.1
summary: |
Service managing file uploads, downloads, archival, and deletion for policy-related documents
across Claims, Policy, and Quote contexts.
owners:
- digisure-engineering
receives:
# Infrastructure Events (from AWS S3)
# Note: S3FileUploadCompletedEvent is an AWS S3Event mapped to FileUploadCompletedEvent internally
# Commands (REST API)
- id: UploadFile
- id: DeleteFile
- id: ArchiveFile
- id: GeneratePreSignedUrl
- id: SetFileOrigination
# Queries (REST API)
- id: GetFile
- id: GetBinaryStream
- id: GetFileUploadCommandStatus
sends:
# File Events - Published to Kinesis via Avro serialization
- id: FileUploadedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-file-upload.{env}.events'
parameters:
env: prd
- id: FileDeletedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-file-upload.{env}.events'
parameters:
env: prd
- id: FileOriginationSetEventV1
version: 0.0.1
to:
- id: 'sft-capstone-file-upload.{env}.events'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-file-upload
badges:
- content: Supporting Service
backgroundColor: teal
textColor: white
---
## Overview
The **File Upload Service** is a supporting domain service within the Capstone PAS responsible for managing the complete lifecycle of file uploads. It provides secure file storage using AWS S3 and supports both direct upload (base64) and pre-signed URL upload patterns.
## Architecture
- **Event Sourcing**: File state changes are persisted as events
- **CQRS**: Separate read and write models for optimized queries
- **S3 Integration**: Direct integration with AWS S3 for file storage
- **Pre-signed URLs**: Secure, time-limited URLs for direct S3 access
- **Kinesis Publishing**: Domain events published to Kinesis streams with Avro serialization
## Infrastructure
### AWS Lambda Handlers
| Handler | Trigger | Purpose |
|---------|---------|---------|
| UploadFileLambdaHandler | API Gateway | Direct file upload with base64 content |
| GeneratePreSignedUrlLambdaHandler | API Gateway | Generate pre-signed URL for S3 upload |
| S3FileUploadCompletedEventLambdaHandler | S3 Event | Process upload completion from S3 |
| GetFileLambdaHandler | API Gateway | Retrieve file metadata |
| GetBinaryStreamLambdaHandler | API Gateway | Download file content |
| DeleteFileLambdaHandler | API Gateway | Delete a file |
| ArchiveFileLambdaHandler | API Gateway | Archive a file |
| SetFileOriginationLambdaHandler | API Gateway | Update file origination |
| GetFileUploadCommandStatusQueryLambdaHandler | API Gateway | Check command status |
### Event Publishing
Events are serialized using Avro format and published to Kinesis:
- **Registry**: AWS Glue Schema Registry (`sft-capstone-file-upload-event-stream-registry`)
- **Stream**: `sft-capstone-file-upload-{env}-event-stream`
## Capabilities
### File Upload
- Upload files via base64 encoded content (UploadFile command)
- Generate pre-signed URLs for direct S3 uploads (GeneratePreSignedUrl command)
- Support for multiple file types: PDF, DOC, DOCX, XLS, XLSX, JPEG, PNG
- File size validation enforced (DomainConstants.MAX_FILE_SIZE_KB)
### File Retrieval
- Retrieve file metadata by file ID (GetFile query)
- Download file binary content as stream (GetBinaryStream query)
- Generate pre-signed download URLs
### File Lifecycle
- Archive files based on retention policy (ArchiveFile command)
- Delete files permanently (DeleteFile command)
- Track file status through lifecycle states: NEW -> UPLOADED -> ARCHIVED/DELETED
### Origination Management
- Associate files with business contexts: CLAIMS, POLICY, QUOTE
- Update file origination post-upload (SetFileOrigination command)
- Emit FileOriginationSetEventV1 for downstream processing
## Event Flow
### Direct Upload Flow
```
UploadFile Command -> FileAggregateRoot -> FileUploadedEventV1 -> Kinesis
```
### Pre-signed URL Upload Flow
```
GeneratePreSignedUrl -> File (NEW) -> S3 Upload -> S3Event ->
FileUploadCompletedEvent -> FileAggregateRoot -> FileUploadedEventV1 -> Kinesis
```
## File Status Lifecycle
```
NEW ---------> UPLOADED ---------> ARCHIVED
|
+--------------> DELETED
```
## Integration Points
### Receives From
- **AWS S3**: S3Event notifications when pre-signed URL uploads complete
- **API Gateway**: REST commands and queries from clients
### Publishes To
- **Kinesis Stream**: Domain events for downstream consumers
- Policy Service: Document attachments for policies
- Quote Service: Supporting documents during quoting
- Claims Service: Claim evidence and documentation
---
id: IdentityService
name: Identity Service
version: 0.0.1
summary: |
Service managing customer identities across the platform including global identities,
unverified identities, customer profiles, and data subject records.
owners:
- digisure-engineering
receives:
# Commands - Customer Identity
- id: CreateCustomerIdentity
- id: UpdateCustomerNameIdentity
- id: UpdateCustomerEmailIdentity
- id: UpdateCustomerMobileIdentity
- id: UpdateCustomerAddressIdentity
- id: UpdateCustomerDateOfBirthIdentity
- id: UpdateCustomerGenderIdentity
# Commands - Unverified Identity
- id: CreateUnverifiedIdentity
- id: UpdateUnverifiedIdentity
# Commands - Tenanted Identity
- id: CreateTenantedIdentity
- id: UpdateTenantedIdentity
# Commands - Data Subject
- id: CreateDataSubject
# Commands - Customer Profile
- id: CreateCollectionAccountPreferences
- id: UpdateCollectionAccountPreferences
- id: CreateCustomerNotificationPreferences
# Queries
- id: GetGlobalIdentity
- id: GetGlobalIdentityByIssuedIdentity
- id: GetTenantedIdentity
- id: GetTenantedIdentityBatch
sends:
# Customer Identity Events
- id: CustomerIdentityCreatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityCreationFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityNameUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityNameUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityEmailAddressUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityEmailAddressUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityMobileNumberUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityMobileNumberUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityAddressUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityAddressUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityDateOfBirthUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityDateOfBirthUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityGenderUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerIdentityGenderUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
# Unverified Identity Events
- id: UnverifiedIdentityCreatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: UnverifiedIdentityCreationFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: UnverifiedIdentityUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: UnverifiedIdentityUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
# Tenanted Identity Events
- id: TenantedIdentityCreatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: TenantedIdentityCreationFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: TenantedIdentityUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: TenantedIdentityUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
# Data Subject Events
- id: DataSubjectCreatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: DataSubjectCreationFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
# Customer Profile Events
- id: CollectionAccountPreferencesCreatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CollectionAccountPreferencesCreationFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CollectionAccountPreferencesUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CollectionAccountPreferencesUpdateFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerNotificationPreferencesCreatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerNotificationPreferencesCreationFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
- id: CustomerNotificationPreferencesUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.events'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-identity
badges:
- content: Supporting Service
backgroundColor: teal
textColor: white
---
## Overview
The **Identity Service** is a supporting domain service within the Capstone PAS responsible for managing customer identity information across the platform. It provides a unified identity layer that supports multi-tenant configurations, certificate-based trust management, and regulatory compliance.
## Architecture
- **Event Sourcing**: Identity state changes are persisted as events
- **CQRS**: Separate read and write models for optimized queries
- **Multi-Tenant**: Supports tenant-scoped identity records
- **Certificate-Based Trust**: Attribute updates require certificates with sufficient trust levels
## Capabilities
### Global Identity Management
- Create canonical customer identities with Global Customer ID (GCID)
- Update identity attributes (name, email, mobile, address, DOB, gender)
- Enforce certificate trust levels for updates
- Look up identities by issued identity (ID number, passport)
### Unverified Identity Handling
- Create unverified identities during onboarding
- Update unverified identity details
- Support tenant-specific identity storage
### Customer Profile Management
- Create and update notification preferences (SMS, email)
- Manage collection account preferences
- Support multiple collection accounts per customer
### Data Subject Tracking
- Create data subject records for compliance
- Track consent and data processing activities
## SDK
The Identity Service provides a Java SDK for direct DynamoDB access:
```java
IdentitySdk sdk = IdentitySdk.builder()
.dynamoDbClient(DynamoDbClient.create())
.config(IdentitySdkConfig.builder()
.tenantedIdentityTable("UNVERIFIED_IDENTITY_TABLE")
.globalIdentityTable("GLOBAL_IDENTITY_TABLE")
.customerProfileTable("CUSTOMER_PROFILE_TABLE")
.globalIdentityGuardTable("GLOBAL_IDENTITY_GUARD_TABLE")
.build())
.build();
sdk.globalIdentities().getByIssuedIdentity("ID", "1234567890", "ZA");
```
## Event Flow
```
Command -> Aggregate -> Domain Event -> Event Store -> Projection
-> Kinesis -> Downstream Services
```
---
id: NotificationService
name: Notification Service
version: 0.0.1
summary: |
Core service managing notification lifecycle for funeral insurance policies and claims,
including triggering, scheduling, dispatch, and multi-channel delivery.
owners:
- digisure-engineering
receives:
# External Events from Policy Service
- id: PolicyCreatedEventV1
version: 0.0.1
- id: PolicyCancelledEventV1
version: 0.0.1
- id: PolicyLapsedEventV1
version: 0.0.1
- id: PolicyExpiredEventV1
version: 0.0.1
- id: PolicyReinstatedEventV1
version: 0.0.1
- id: PolicyBeneficiaryAddedEventV1
version: 0.0.1
- id: PolicyBeneficiaryRemovedEventV1
version: 0.0.1
- id: PolicyBeneficiaryUpdatedEventV1
version: 0.0.1
- id: PolicyPremiumCollectedEventV1
version: 0.0.1
- id: PolicyCoverEscalationAppliedEventV1
version: 0.0.1
- id: PolicyCoverStackedEventV1
version: 0.0.1
- id: PolicyCoverStaggeredEventV1
version: 0.0.1
- id: PolicyScheduleGeneratedEventV1
version: 0.0.1
- id: PolicyPersonalDetailsUpdatedEventV1
version: 0.0.1
- id: PolicyCollectionDetailsUpdatedEventV1
version: 0.0.1
- id: PolicyVerificationCompletedEventV1
version: 0.0.1
# External Events from Claims Service (Claims domain not yet documented in EventCatalog)
- id: ClaimCreatedEventV1
version: 0.0.1
- id: ClaimSuccessfulEventV1
version: 0.0.1
- id: ClaimRepudiatedEventV1
version: 0.0.1
- id: ClaimPayoutCompleteEventV1
version: 0.0.1
# Commands
- id: ScheduledPolicySendNotification
- id: ScheduledClaimSendNotification
- id: ScheduledQuoteSendNotification
- id: SendNotification
# Queries
- id: GetNotificationDataProductByOriginId
- id: GetNotificationConfig
- id: GetNotificationCommandStatusByCorrelationId
sends:
# Notification Events (V2)
- id: NotificationDispatchedEventV2
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
- id: NotificationScheduledEventV2
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
- id: NotificationScheduledProcessCancelledEventV2
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
- id: NotificationSentSucceededEventV2
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
- id: NotificationSendFailedEventV2
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
- id: NotificationTriggeredEventV1
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
# Deprecated Events (V1)
- id: NotificationDispatchedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
- id: NotificationScheduledEventV1
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
- id: NotificationScheduleCancelledEventV1
version: 0.0.1
to:
- id: 'sft-capstone-notifications.{env}.events'
parameters:
env: prd
# External Commands to Glue Gateway
- id: SendEmailNotificationCommand
version: 0.0.1
to:
- id: 'glue-notification-gateway'
- id: SendSmsNotificationCommand
version: 0.0.1
to:
- id: 'glue-notification-gateway'
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-notification
badges:
- content: Supporting Service
backgroundColor: orange
textColor: white
---
## Overview
The **Notification Service** is a supporting domain service within the Capstone PAS responsible for managing the complete notification lifecycle. It reacts to policy and claims events to trigger, schedule, and dispatch notifications through email and SMS channels.
## Architecture
- **Event-Driven**: Reacts to policy and claims domain events
- **State Machine**: Tracks notification state through pending, scheduled, and dispatched phases
- **Multi-Channel**: Routes to email (SES) and SMS providers via Glue Gateway
- **Configuration-Driven**: Notification rules defined per package and partner
## Capabilities
### Notification Triggering
- React to policy lifecycle events (created, cancelled, lapsed, expired)
- React to claims events (created, approved, rejected, payout complete)
- Evaluate trigger rules against current policy/claims state
- Support immediate and scheduled notification timing
### Notification Scheduling
- Schedule future notifications based on policy dates
- Calculate dispatch times using configurable offsets
- Support recurring notifications with frequency settings
- Cancel scheduled notifications when conditions change
### Multi-Channel Dispatch
- Route to email provider (AWS SES) for email notifications
- Route to SMS provider for text message notifications
- Build enriched commands with recipient details and templates
- Track provider correlation IDs for delivery confirmation
### Notification Tracking
- Log notification status changes to data product
- Support queries by origin ID (policy/claim)
- Track correlation IDs across the notification lifecycle
## Event Flow
```
Policy/Claims Event → Reactor → State Aggregate → Trigger Evaluation
→ Schedule or Immediate
→ Dispatch to Glue Gateway
→ Data Product Logging
```
---
id: PartnerService
name: Partner Service
version: 0.0.1
summary: |
Read-only service providing partner configuration and product package details.
Enables API consumers to retrieve partner setup, available products, pricing metadata,
and business rules for quote creation and policy management.
owners:
- digisure-engineering
receives:
# Queries
- id: GetPartner
- id: GetPartnerPackages
- id: GetProductConfiguration
sends: []
badges:
- content: Supporting Service
backgroundColor: green
textColor: white
---
## Overview
The **Partner Service** is a read-only service that provides partner configuration details to enable quote creation, policy management, and customer-facing portal operations. It supplies partner metadata, available product packages, product configurations with pricing metadata, and partner-specific business rules.
## Architecture
The service implements a clean/hexagonal architecture:
```
Partner Portal / BFFASCP / BFFWeb / Other Services
|
v
Partner Service (API Gateway + Lambda)
|
+---> DynamoDB (Partner Configuration Store)
+---> Caching Layer (Partner data cache)
```
## Key Features
### Partner Configuration
- Partner organization details (ID, code, name, type)
- Partner status and business classification
- Registration information (company number, VAT, etc.)
### Product Packages
- Product bundles available per partner
- Package status and active state
- Collection methods supported
- Terms and conditions versions
### Product Configuration
- Product definitions within packages
- Pricing calculation metadata
- Age and cover amount constraints
- Waiting periods (natural, accidental)
- Required vs. optional products
### Business Rules
- Maximum number of beneficiaries
- Multi-product allowance rules
- Bank verification requirements
- Payment collection constraints
### Notification Configuration
- Partner notification preferences
- Template selections per event type
- Communication channel configuration
## API Capabilities
### Query Operations
- Retrieve partner configuration by ID
- Fetch available packages for a partner
- Get product details with pricing metadata
- Query pricing calculation factors
## Technical Stack
- **Runtime**: Java 21 on AWS Lambda
- **Persistence**: DynamoDB
- **Caching**: ElastiCache or in-memory
- **API Framework**: Custom clean architecture
- **Serialization**: Jackson for JSON processing
## Integration Points
The Partner Service is consumed by:
- **Quote Domain** - Validates product availability and constraints during quote creation
- **Policy Domain** - Enforces partner rules during policy lifecycle
- **BFFWeb** - Retrieves partner config for web portal initialization
- **BFFASCP** - Provides partner details for agent portal operations
- **Pricing Service** - Uses pricing metadata for calculations
- **Notifications Service** - Uses notification config for message delivery
## Design Principles
1. **Read-Only**: No write operations; configuration managed externally
2. **Configuration-Driven**: Downstream services respect partner rules implicitly
3. **Caching**: Partner data cached with TTL for performance
4. **Immutability**: Configuration values treated as immutable within service lifecycle
---
id: PDFGeneratorService
name: PDF Generator Service
version: 0.0.1
summary: |
Serverless service for generating and encrypting PDF documents from HTML templates.
Provides secure document storage and retrieval via signed URLs.
owners:
- digisure-engineering
receives:
# Commands
- id: GeneratePdf
- id: EncryptPdf
sends:
# Events
- id: PDFGeneratedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-pdf-generator.{env}.events'
parameters:
env: prd
- id: PDFEncryptedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-pdf-generator.{env}.events'
parameters:
env: prd
repository:
language: TypeScript
url: https://github.com/sanlam-digisure/sft-capstone-pdf-generator
badges:
- content: Serverless
backgroundColor: orange
textColor: white
- content: AWS Lambda
backgroundColor: yellow
textColor: black
---
## Overview
The **PDF Generator Service** is a serverless microservice responsible for generating PDF documents from HTML content. It leverages AWS Lambda functions with Puppeteer (Chromium) for HTML-to-PDF rendering and pypdf for document encryption.
## Architecture
The PDF Generator Service has two implementation versions deployed in parallel:
### V1: Node.js/Python Implementation
#### PDF Generation Lambda (Node.js/TypeScript)
- Uses `@sparticuz/chromium` for headless browser rendering
- Renders HTML content to PDF using Puppeteer
- Supports multi-page document generation and merging
- Uploads generated documents to S3
- Returns pre-signed URLs for secure document access
#### PDF Encryption Lambda (Python)
- Downloads existing PDF from S3
- Applies password encryption using pypdf
- Uploads encrypted document to S3
- Returns pre-signed URL for the encrypted document
### V2: Go Implementation (provided.al2023 Runtime)
- Single unified handler supporting both generation and encryption
- Uses headless Chromium on Lambda with provided.al2023 runtime
- Supports inline encryption via `password` parameter (no separate EncryptPdf command required)
- Includes `userId` field for audit trail and tenant isolation
- Single Lambda function replaces separate Node.js and Python handlers
- Improved performance with Go's concurrency model
## Technical Stack
### V1 Stack
- **Runtimes**: Node.js 20.x (generation), Python 3.9 (encryption)
- **PDF Rendering**: Puppeteer with Chromium Lambda layer
- **PDF Manipulation**: pdf-lib (merging), pypdf (encryption)
- **Validation**: Zod schema validation
### V2 Stack
- **Runtime**: Go with provided.al2023 custom runtime
- **PDF Rendering**: headless Chromium on Lambda
- **Storage**: Amazon S3 (both versions)
- **Infrastructure**: AWS Lambda, API Gateway
## Capabilities
### Document Generation
- Convert HTML to PDF with full CSS support
- Configure page size, margins, and orientation
- Add headers and footers with page numbers
- Print backgrounds and images
- Merge multiple pages into single document
### Document Security
- Password-protect sensitive documents
- Generate time-limited signed URLs (7-day expiry)
- Content disposition headers for download filename
### Page Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| format | string | A4 | Page format |
| margin | object | 0px | Page margins (top, bottom, left, right) |
| printBackground | boolean | true | Include background colors/images |
| displayHeaderFooter | boolean | false | Show header/footer templates |
| headerTemplate | string | empty | Custom header HTML |
| footerTemplate | string | page number | Custom footer HTML |
## Integration
The service is invoked via API Gateway and returns document references that can be used by downstream services for:
- Sending documents via email/SMS
- Storing document references on policies
- Providing download links to customers
## Event Flow
```
API Gateway → Lambda → Puppeteer/Chromium → PDF Generation
→ S3 Upload → Signed URL Generation
→ Response with document location
```
---
id: PolicyImporterService
name: Policy Importer Service
version: 0.0.1
summary: |
Batch and API ingestion service that converts external policy data into Policy and Identity
commands for the Capstone PAS.
owners:
- digisure-engineering
receives:
# Batch imports from S3 (CSV uploads)
# API ingestion (JSON)
- id: CreatePolicyRequest
version: 0.0.1
from:
- id: 'sft-capstone-policy-importer.{env}.commands'
parameters:
env: prd
sends:
# Policy domain commands
- id: CreateFuneralPolicy
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.commands'
parameters:
env: prd
# Identity domain commands
- id: CreateUnverifiedIdentity
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.commands'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-policy-importer
badges:
- content: Supporting Service
backgroundColor: teal
textColor: white
- content: Batch Processing
backgroundColor: orange
textColor: white
---
## Overview
The **Policy Importer Service** ingests policy data from external systems and transforms it into
Capstone policy and identity commands. It supports both batch CSV uploads and JSON ingestion via
HTTP, enabling migrations and partner integrations.
## Ingestion Paths
### Batch CSV (S3)
- CSV files uploaded to `sft-capstone-{env}-bulk-policy-import-risk`
- `PolicyBatchImporterLambdaHandler` parses rows into policy and identity commands
- Failed rows are written to `sft-capstone-{env}-bulk-policy-import-risk-failed`
### JSON API
- `POST /policies` handled by `CreatePolicyRequestHttpIngestionLambdaHandler`
- Requests are enqueued to `sft-capstone-policy-importer-{env}-create-policy-request-queue`
- `CreatePolicyRequestCommandLambdaHandler` validates and dispatches downstream commands
## Command Dispatch
- **Policy Service**: `CreateFuneralPolicy` commands sent to the policy command queue
- **Identity Service**: `CreateUnverifiedIdentity` commands sent to the identity command queue
## Failure Handling
- Invalid messages are routed to IMQ/DLQ queues
- Failed CSV rows are exported with an error column for reprocessing
## Infrastructure
- **Lambdas**: batch importer, HTTP ingestion, SQS command handler
- **Queues**: create-policy-request, IMQ, DLQ
- **Buckets**: risk import bucket, failed-row bucket
- **Observability**: Datadog integration enabled for non-sandbox environments
---
id: PolicyService
name: Policy Service
version: 0.0.1
summary: |
Core service managing funeral insurance policy lifecycle, beneficiaries, premium collection,
cover escalation, and verification workflows.
owners:
- digisure-engineering
receives:
# External Events from Verification Channel
- id: VerificationSucceededEventV1
version: 0.0.1
- id: VerificationSoftFailEventV1
version: 0.0.1
- id: VerificationHardFailEventV1
version: 0.0.1
# External Events from Collections Channel
- id: CollectionCreationSucceededEventV4
version: 0.0.1
- id: CollectionCreationFailedEventV4
version: 0.0.1
- id: CollectionSucceededEventV5
version: 0.0.1
- id: CollectionFailedEventV5
version: 0.0.1
- id: ScheduleCreationSucceededEventV2
version: 0.0.1
# External Events from File Upload Channel
- id: FileUploadedEventV1
version: 0.0.1
- id: FileOriginationSetEventV1
version: 0.0.1
# Commands
- id: CreateFuneralPolicyFromQuote
- id: CreateFuneralPolicy
- id: CancelPolicy
- id: ReinstatePolicy
- id: ExpirePolicy
- id: AddBeneficiary
- id: RemoveBeneficiary
- id: UpdateBeneficiary
- id: UpdatePersonalDetails
- id: UpdateCollectionDetails
- id: UpdatePolicyFromQuote
- id: UpdateBillingDate
- id: CaptureReplacementCoverDetails
- id: AddVerificationToPolicy
- id: VerifyPolicyHealth
- id: CollectPremium
- id: PerformAdHocPremiumCollection
- id: CheckPaymentBeforeGracePeriod
# Commands - Ops (SuperAdmin, via ASCP)
- id: ReverseCollectionOutcome
- id: RescheduleGracePeriodCheck
- id: ApplyCoverEscalation
- id: ApplyPremiumEscalation
- id: StackCover
- id: StaggerCover
- id: ReinstateProductWithoutChange
- id: ExpireProduct
- id: MainLifeDeceased
- id: CoveredLifeDeceased
- id: GeneratePolicySchedule
- id: RefreshScheduleDownloadLink
# Queries
- id: GetFuneralPolicy
- id: QueryFuneralPolicy
- id: GetCommandStatus
- id: GetPolicyCorrelationIdTrace
- id: GetPolicyEventList
sends:
# Identity Commands (CIS)
- id: CreateUnverifiedIdentity
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.commands'
parameters:
env: prd
- id: UpdateUnverifiedIdentity
version: 0.0.1
to:
- id: 'sft-capstone-identity.{env}.commands'
parameters:
env: prd
# Lifecycle Events
- id: PolicyCreatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyCancelledEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyLapsedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyExpiredEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyReinstatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
# Beneficiary Events
- id: PolicyBeneficiaryAddedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyBeneficiaryRemovedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyBeneficiaryUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
# Update Events
- id: PolicyPersonalDetailsUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyCollectionDetailsUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyBillingDateUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyUpdatedFromQuoteEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyUpdatedFromQuoteFailedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyReplacementCoverDetailsUpdatedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
# Collection Events
- id: PolicyPremiumCollectedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyCollectionAnalysisEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyAdHocCollectionRequestedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: NoPolicyCollectionReceivedWithinGracePeriodEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
# Cover/Escalation Events
- id: PolicyCoverEscalationAppliedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyPremiumEscalationAppliedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyCoverStackedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyCoverStaggeredEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyProductExpiredEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
# Verification Events
- id: PolicyVerificationRequestedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyVerificationCompletedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyVerificationSucceededEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyVerificationSoftFailEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyVerificationHardFailEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
# Other Events
- id: PolicyCoveredLifeDeceasedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
- id: PolicyScheduleGeneratedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-policy.{env}.events'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-policy
badges:
- content: Core Service
backgroundColor: green
textColor: white
---
## Overview
The **Policy Service** is the core domain service within the Capstone PAS responsible for managing the complete lifecycle of funeral insurance policies. It implements an event-sourced architecture where all state changes are captured as domain events.
## Architecture
The Policy Service implements:
- **Event Sourcing**: All policy state changes are persisted as events
- **CQRS**: Separate read and write models for optimized queries
- **Domain-Driven Design**: Rich domain model with aggregates and value objects
### CQRS Command/Query Flow
Commands and queries follow separate paths for optimal performance:
```mermaid
flowchart LR
subgraph Commands["Command Path (Write)"]
direction TB
C1["API Gateway / SQS"]
C2["Command Lambda Handler"]
C3["Enrichment Service"]
C4["Command Handler"]
C5["Policy Aggregate"]
C6["Domain Events"]
C7["DynamoDB"]
C8["Event Publisher"]
C1 --> C2
C2 --> C3
C3 -->|"Partner/Config Data"| C4
C4 --> C5
C5 --> C6
C6 --> C7
C6 --> C8
end
subgraph Queries["Query Path (Read)"]
direction TB
Q1["API Gateway"]
Q2["Query Lambda Handler"]
Q3["Query Handler"]
Q4["DynamoDB"]
Q5["Policy Projection"]
Q1 --> Q2
Q2 --> Q3
Q3 --> Q4
Q4 --> Q5
end
style Commands fill:#fff3e0,stroke:#e65100
style Queries fill:#e3f2fd,stroke:#1565c0
```
**Command Flow:**
1. Command arrives via API Gateway or SQS queue
2. Lambda handler deserializes and validates command
3. Enrichment service fetches partner/configuration data from external services
4. Command handler loads aggregate, applies command, generates domain events
5. Events persisted to DynamoDB and published to Kinesis/EventBridge
**Query Flow:**
1. Query arrives via API Gateway (REST)
2. Query handler retrieves projection directly from DynamoDB
3. Returns optimized read model to caller
## Capabilities
### Policy Lifecycle
- Create policies from quotes or directly
- Cancel policies with reason tracking
- Handle policy lapse due to non-payment
- Reinstate lapsed policies
- Expire policies at term end
### Beneficiary Management
- Add beneficiaries with percentage allocation
- Update beneficiary details
- Remove beneficiaries
- Validate allocation totals to 100%
### Premium Collection
- Schedule premium collections
- Process collection results
- Handle failed collections and grace periods
- Support ad-hoc collections
### Cover Management
- Apply annual cover escalations
- Apply premium escalations
- Stack additional cover
- Stagger cover across dates
### Verification
- Request identity verification
- Request bank account verification
- Process verification results
- Handle soft and hard failures
## Event Flow
Domain events are published to both EventBridge (for event routing) and Kinesis (for streaming to downstream services):
```mermaid
flowchart TB
subgraph PolicyService["Policy Service"]
AGG["Policy Aggregate"]
EP["Event Publisher"]
KP["Kinesis Publisher"]
EBP["EventBridge Publisher"]
end
subgraph EventBridge["EventBridge"]
EB["SftCapstonePolicyEvents Bus"]
R1["Policy Created Rule"]
R2["Policy Lapsed Rule"]
R3["Premium Collected Rule"]
R4["Verification Rule"]
end
subgraph Kinesis["Kinesis Streaming"]
KS["policy-event-stream"]
KSH["Event Shards"]
end
subgraph Consumers["Downstream Consumers"]
NS["Notifications Service"]
CS["Collections Service"]
CDP["Customer Data Platform"]
ER["Event Reactors"]
CLAIMS["Claims Service"]
end
AGG -->|"Domain Event"| EP
EP --> KP
EP --> EBP
KP -->|"Avro Serialized"| KS
KS --> KSH
EBP -->|"JSON"| EB
EB --> R1
EB --> R2
EB --> R3
EB --> R4
R1 -->|"SQS"| NS
R2 -->|"SQS"| NS
R3 -->|"SQS"| CS
R4 -->|"SQS"| NS
KSH -->|"Stream"| CDP
KSH -->|"Stream"| ER
KSH -->|"Stream"| CLAIMS
style PolicyService fill:#e1f5fe,stroke:#01579b
style EventBridge fill:#fff3e0,stroke:#e65100
style Kinesis fill:#f3e5f5,stroke:#4a148c
style Consumers fill:#e8f5e9,stroke:#1b5e20
```
**Publishing Mechanisms:**
- **EventBridge**: Event bus (`SftCapstonePolicyEvents`) routes events via rules to SQS queues consumed by downstream services
- **Kinesis**: Event stream (`policy-event-stream`) provides ordered, durable event streaming with Avro serialization
**Key Events Published:**
| Event | Consumers |
|-------|-----------|
| `PolicyCreatedEventV1` | Notifications (welcome), Collections (schedule setup) |
| `PolicyLapsedEventV1` | Notifications, Claims (block) |
| `PolicyReinstatedEventV1` | Notifications, Collections (resume) |
| `PolicyPremiumCollectedEventV1` | Notifications (receipt), Analytics |
| `PolicyVerificationSucceededEventV1` | Notifications, Identity Service |
| `PolicyCoverEscalationAppliedEventV1` | Notifications (annual increase) |
| `PolicyScheduleGeneratedEventV1` | Document Service |
## AWS Infrastructure
The Policy Service runs on AWS serverless infrastructure:
```mermaid
flowchart TB
subgraph Clients["Client Layer"]
APIGW["API Gateway"]
BFF["BFF Services"]
end
subgraph Compute["Compute Layer"]
direction TB
subgraph CommandLambdas["Command Lambdas (28)"]
CL1["CreatePolicy"]
CL2["CancelPolicy"]
CL3["CollectPremium"]
CL4["...25+ more"]
end
subgraph QueryLambdas["Query Lambdas (5)"]
QL1["GetFuneralPolicy"]
QL2["QueryFuneralPolicy"]
QL3["GetCommandStatus"]
QL4["GetPolicyEventList"]
QL5["GetCorrelationTrace"]
end
subgraph ReactorLambdas["Event Reactors (6)"]
RL1["CollectionSucceeded Reactor"]
RL2["CollectionFailed Reactor"]
RL3["VerificationCompleted Reactor"]
RL4["ScheduleCreated Reactor"]
end
subgraph ScheduledLambdas["Scheduled Jobs (3)"]
SL1["PolicyHealthCheck"]
SL2["EscalationProcessor"]
SL3["GracePeriodChecker"]
end
end
subgraph Messaging["Messaging Layer"]
SQS["SQS Command Queues"]
DLQ["Dead Letter Queues"]
IMQ["Idempotency Marker Queues"]
EB2["EventBridge Bus"]
KIN2["Kinesis Stream"]
end
subgraph Storage["Storage Layer"]
DDB["DynamoDB"]
DDB1["policy-table"]
DDB2["command-store"]
end
subgraph External["External Services"]
COLL["Collections Service"]
VERIF["Verification Service"]
IDENTITY["Identity Service"]
QUOTE["Quote Service"]
DOCS["Document Service"]
end
APIGW -->|"GET"| QueryLambdas
BFF -->|"POST"| SQS
SQS --> CommandLambdas
CommandLambdas -->|"Store"| DDB1
CommandLambdas -->|"Idempotency"| DDB2
CommandLambdas -->|"Publish"| EB2
CommandLambdas -->|"Stream"| KIN2
CommandLambdas -.->|"Send"| IDENTITY
CommandLambdas -.->|"Request"| COLL
SQS -->|"Failed"| DLQ
SQS --> IMQ
KIN2 --> ReactorLambdas
EB2 -->|"Route"| ReactorLambdas
QueryLambdas --> DDB1
ScheduledLambdas --> SQS
QUOTE -->|"QuoteFinalised"| CommandLambdas
COLL -->|"CollectionResult"| ReactorLambdas
VERIF -->|"VerificationResult"| ReactorLambdas
style Clients fill:#e8f5e9,stroke:#1b5e20
style Compute fill:#e3f2fd,stroke:#1565c0
style Messaging fill:#fff3e0,stroke:#e65100
style Storage fill:#fce4ec,stroke:#880e4f
style External fill:#f5f5f5,stroke:#616161
```
**Infrastructure Components:**
| Component | Count | Purpose |
|-----------|-------|---------|
| **Lambda Functions** | 42 | Command handlers (28), Query handlers (5), Event reactors (6), Scheduled jobs (3) |
| **SQS Queues** | 35+ | One per command type, plus DLQs and IMQs |
| **DynamoDB Tables** | 2 | Policy aggregate store, Command status store |
| **Kinesis Stream** | 1 | Event streaming (`policy-event-stream`) |
| **EventBridge Bus** | 1 | Event routing (`SftCapstonePolicyEvents`) |
| **API Gateway** | 1 | REST API for queries |
**Lambda Configuration:**
- Runtime: Java 21 with SnapStart
- Memory: 2048 MB
- Timeout: 30 seconds
- VPC: Private subnets with security groups
- Batch Size: 10 (SQS triggers)
## Service Dependencies
---
id: PortfolioService
name: Portfolio Service
version: 0.0.1
summary: |
Service managing customer identity portfolios, tracking quotes and policies
associated with each customer across their lifecycle.
owners:
- digisure-engineering
receives:
# Events - Quote
- id: PolicyHolderAddedToQuoteEventV2
# Events - Policy
- id: PolicyCreatedEventV1
sends: []
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-identity
badges:
- content: Supporting Service
backgroundColor: teal
textColor: white
---
## Overview
The **Portfolio Service** is a supporting service within the Identity domain that manages customer identity portfolios. It tracks the relationship between customers (identified by Global Customer ID), their active and historical quotes, and their policies. The service acts as a centralized view model for portfolio information, consuming events from the Quote and Policy services to maintain an up-to-date portfolio state.
## Architecture
- **Event Sourcing**: Portfolio state changes are driven by domain events from Quote and Policy services
- **Read Model**: Maintains a denormalized view of customer portfolios for efficient querying
- **Multi-Tenant**: Supports customer identification across different tenants
- **Certificate-Based Trust**: Links to Identity Service for trust-verified customer information
## Capabilities
### Portfolio Retrieval
- Query customer identity portfolio by Policy Holder ID
- Retrieve all active and historical quotes associated with a customer
- Retrieve all active and historical policies associated with a customer
- Access policy metadata including code, status, partner, and package information
### Quote to Policy Lifecycle
- Track quote addition to a customer's portfolio
- Track quote-to-policy conversion when policies are created from quotes
- Maintain historical records of all policies and quotes
### Portfolio State Management
- Aggregate policy information from multiple sources (quote and policy services)
- Provide single view of customer's insurance portfolio
- Support policy metadata tracking (code, status, partner, package, product)
## Query Handlers
The Portfolio Service exposes queries for retrieving portfolio information:
- **GetIdentityPortfolio** - Retrieve a customer's complete portfolio including quotes and policies
## Event Handlers
The Portfolio Service consumes events from upstream services:
- **PolicyHolderAddedToQuoteEvent** - Updates portfolio when a policy holder is added to a quote
- **FuneralPolicyCreatedFromQuoteEvent** - Updates portfolio when a quote transitions to a policy
## SDK
The Identity Portfolio module provides a query handler for direct portfolio access:
```java
GetIdentityPortfolioQueryHandler portfolioHandler = injector.getInstance(GetIdentityPortfolioQueryHandler.class);
IdentityPortfolio portfolio = portfolioHandler.handle(new PolicyHolderId(customerId));
```
## API
### GetIdentityPortfolio Query
**Endpoint:** `GET /v1/customers/{identityPortfolioId}/portfolio`
**Path Parameters:**
- `identityPortfolioId` (UUID) - The customer's Global Customer ID (Policy Holder ID)
**Response:** IdentityPortfolio containing:
- Global Customer ID
- Set of Quote IDs
- Set of Policies with metadata
**Example Response:**
```json
{
"globalCustomerId": "550e8400-e29b-41d4-a716-446655440000",
"quoteIds": ["650e8400-e29b-41d4-a716-446655440001"],
"policies": [
{
"policyId": "POL-2024-001",
"policyCode": "FUN-001",
"policyStatus": "ACTIVE",
"policyStartDate": "2024-01-15",
"partnerId": "PARTNER-001",
"partnerName": "Partner Name",
"packageId": "PKG-001",
"packageName": "Package Name"
}
]
}
```
## Event Flow
```
Quote Service -> PolicyHolderAddedToQuoteEvent -> Portfolio Service -> Updates Portfolio View
Policy Service -> FuneralPolicyCreatedFromQuoteEvent -> Portfolio Service -> Updates Portfolio View
Portfolio Service <- GetIdentityPortfolio Query -> Returns Customer Portfolio
```
---
id: PricingService
name: Pricing Service
version: 0.0.1
summary: |
Calculation service providing premium and cover amount computations for funeral insurance products.
Supports both static calculator types and dynamic partner-configurable calculations.
owners:
- digisure-engineering
receives:
# Queries (synchronous API calls)
- id: GetPremiumFromCover
- id: GetCoverFromPremium
- id: PerformCalculation
# Note: Pricing Service is stateless and query-only
# It does not publish events (sends:) or consume events from other domains
# All interactions are synchronous via API Gateway
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-pricing
badges:
- content: Supporting Service
backgroundColor: teal
textColor: white
- content: Stateless
backgroundColor: gray
textColor: white
- content: Query-Only
backgroundColor: blue
textColor: white
---
## Overview
The **Pricing Service** is a stateless calculation service within the Capstone PAS that computes insurance premiums and cover amounts. It implements actuarial formulas and supports configurable calculation engines for partner-specific pricing.
## Architecture
- **Stateless**: No persistent state; all calculations are pure functions
- **Query-based**: Exposes calculation endpoints via API Gateway
- **Configurable**: Pricing factors loaded from configuration per partner/product
- **Extensible**: Dynamic calculator support for custom calculation logic
## Capabilities
### Premium from Cover Calculation
Given a cover amount and risk factors, calculates the monthly premium:
```
Input: Cover Amount, Age, Gender, Relationship, Partner/Product Config
Output: Monthly Premium Amount
```
### Cover from Premium Calculation
Given a premium budget and risk factors, calculates the achievable cover:
```
Input: Premium Amount, Age, Gender, Relationship, Partner/Product Config
Output: Cover Amount
```
### Dynamic Calculations
Executes partner-configured calculation expressions:
```
Input: Calculator Instance IDs, Values Map, Initial Cover/Premium
Output: Calculated Results with intermediate values
```
## Calculator Types
| Calculator | Use Case |
|------------|----------|
| **MainLifeCalculator** | Primary insured life premium calculation |
| **CoveredLifeCalculator** | Extended family member calculations |
| **AccidentalCalculator** | Accidental death benefit add-on |
| **AccidentalOnlyCalculator** | Short-term accidental pricing |
| **RepatriationCalculator** | Repatriation benefit pricing |
| **StillBirthAndNewBornCalculator** | Stillbirth/newborn benefit pricing |
| **DynamicCalculator** | Partner-configurable expressions |
## API Endpoints
### POST /pricing/premium-from-cover
Calculate premium from cover amount.
### POST /pricing/cover-from-premium
Calculate cover amount from premium budget.
### POST /pricing/calculate
Perform dynamic calculations using configured calculators.
## Pricing Formula Overview
The core pricing formula for main life calculations:
```
lifeQx = accidentalFactor * (constant + (base/100) * baseQxFactor + aids * aidsQxFactor)
lifeAnnualPremium = coverAmount * lifeQx
lifeMonthlyPremium = lifeAnnualPremium / 12
lifeExpenses = underwritingExpense/durationFactor + initialExpense + recurringExpense
lifeDistributionRate = (1 + intermediaryDiscount) * (1 + asAndWhenCommission) * (1 + difLoading) - 1
lifeProfit = max(0, (initialTarget/100) * factor1Impact)
lifePremPreProfit = (lifeMonthlyPremium + lifeExpenses) / (1 - (expenseLoading/100 + rewardExpense + distributionRate + profit))
finalPremium = (lifePremPreProfit * ageTopUpFactor * relationshipTopUpFactor) + topUpExpenseFactor
```
## Configuration
Pricing configurations are stored per partner and product category:
- Partner ID
- Product Category ID
- Product Version
- Configuration Version
Each configuration contains all necessary factors, rates, and loadings for calculations.
## Cross-Domain Integration
The Pricing Service is a **stateless, query-only** service. It:
- **Does NOT publish events** - No domain events are emitted
- **Does NOT consume events** - Does not listen to any event streams
- **Provides synchronous APIs** - All interactions are request/response via API Gateway
### Consumers
The Pricing Service is consumed synchronously by:
| Consumer | Usage |
|----------|-------|
| **Quote Service** | Calculates premiums during quote generation |
| **Policy Service** | Recalculates premiums during policy changes and escalations |
| **BFFASCP Service** | Provides pricing for agent-assisted sales flows |
| **BFF Web Service** | Supports self-service pricing in web applications |
### Data Dependencies
The Pricing Service reads configuration data from:
- **DynamoDB** - Calculator configurations and pricing factors
- **RDS (MySQL)** - Dynamic query configurations and rate tables
---
id: ProductBundleInventoryService
name: Product Bundle Inventory Service
version: 0.0.1
summary: |
Core service managing prepaid funeral insurance product bundles, inventory items,
and redemption workflows for partner distribution channels.
owners:
- digisure-engineering
receives:
# Commands
- id: CreateProductBundleConfig
- id: CreateProductBundleInventoryItems
- id: RedeemInventoryItemForNewPolicy
- id: RedeemInventoryItemForExistingPolicy
- id: InitiateBundleIssuanceForNewPolicy
# Queries (not yet implemented)
# - id: GetProductBundleConfig
# - id: GetInventoryItem
sends:
# Inventory Events
- id: ProductBundleInventoryItemsCreatedEventV2
version: 0.0.1
to:
- id: 'sft-capstone-product-bundle.{env}.events'
parameters:
env: prd
- id: InventoryItemRedeemedNewPolicyEventV2
version: 0.0.1
to:
- id: 'sft-capstone-product-bundle.{env}.events'
parameters:
env: prd
- id: InventoryItemRedeemedExistingPolicyEventV2
version: 0.0.1
to:
- id: 'sft-capstone-product-bundle.{env}.events'
parameters:
env: prd
# Bundle Issuance Events
- id: BundleIssuanceForNewPolicyEventV2
version: 0.0.1
to:
- id: 'sft-capstone-product-bundle.{env}.events'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-product-bundle-inventory
badges:
- content: Supporting Service
backgroundColor: teal
textColor: white
---
## Overview
The **Product Bundle Inventory Service** manages prepaid funeral insurance product bundles that partners can distribute through their channels. It handles the complete lifecycle from bundle configuration through inventory generation and redemption.
## Architecture
- **Event Sourcing**: All state changes are persisted as domain events
- **Aggregate Design**: Two aggregates - ProductBundleConfig and InventoryItem
- **Domain-Driven Design**: Rich domain model with value objects and invariants
## Capabilities
### Bundle Configuration
- Create bundle configurations with partner and package details
- Define included products with coverage rules
- Configure allowed cover terms and calculation strategies
- Set coverage lump amounts and premium structures
### Inventory Management
- Generate batches of inventory items with unique serial numbers
- Serial numbers use Damm check digit for error detection
- Set expiration dates for time-limited bundles
- Track item status (active, redeemed, expired)
### Redemption Workflows
- **New Policy Redemption**: Redeem an item to create a new insurance policy
- **Existing Policy Redemption**: Link an item to extend coverage on an existing policy
- Validate products against bundle configuration rules
- Calculate coverage amounts based on relationship percentages
### Bundle Issuance
- Initiate bundle issuance for new policy creation
- Validate terms and conditions acceptance
- Capture employment and bank details for policy setup
- Emit events for downstream policy creation
## Event Flow
```
Command -> Aggregate -> Domain Event -> Event Store -> Kinesis -> Policy Service
-> Data Product
```
## Infrastructure Handlers
The service is supported by several AWS Lambda handlers:
- **S3 Importer**: Batch import of inventory items from S3 files
- **Bundle Inventory Reactor**: Internal event reactor for state coordination
- **Bundle Inventory Data Product**: Materializes inventory events for analytics
- **Data Product Policy Event Handler**: Consumes upstream PolicyCreatedEventV1 events
## Outgoing Commands
During the bundle issuance workflow, this service sends:
- **CreateUnverifiedIdentity**: Command to Identity service to establish unverified identity records for new policy holders
---
id: QuoteService
name: Quote Service
version: 0.0.1
summary: |
Core service managing insurance quote creation, product configuration, pricing,
policyholder capture, and quote-to-policy conversion workflows.
owners:
- digisure-engineering
receives:
# External Events from Verification Channel
- id: VerificationSucceededEventV1
version: 0.0.1
- id: VerificationSoftFailEventV1
version: 0.0.1
- id: VerificationHardFailEventV1
version: 0.0.1
# External Events from File Upload Channel
- id: FileUploadedEventV1
version: 0.0.1
- id: FileDeletedEventV1
version: 0.0.1
# Commands
- id: CreateQuote
- id: AcceptQuote
- id: FinaliseQuote
- id: CancelQuote
- id: ExpireQuote
- id: AddProductToQuote
- id: UpdateProductOnQuote
- id: DeleteProductFromQuote
- id: AddBeneficiary
- id: UpdateBeneficiary
- id: RemoveBeneficiary
- id: CapturePolicyHolderDetails
- id: CaptureCollectionDetails
- id: SetTAndCsAccepted
- id: AddVerificationToQuote
- id: AddOptionalBenefit
- id: RemoveOptionalBenefit
# Queries
- id: GetQuote
- id: GetQuoteCommandStatus
sends:
# Lifecycle Events
- id: QuoteCreatedEventV2
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.events'
parameters:
env: prd
- id: QuoteFinalisedEventV2
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.events'
parameters:
env: prd
- id: QuoteConvertedEventV2
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.events'
parameters:
env: prd
- id: QuoteExpiredEventV2
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.events'
parameters:
env: prd
# Policyholder Events
- id: PolicyHolderAddedToQuoteEventV2
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.events'
parameters:
env: prd
# Resume Link Events
- id: ResumeLinkAddedToQuoteEventV2
version: 0.0.1
to:
- id: 'sft-capstone-quote.{env}.events'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-quote
badges:
- content: Core Service
backgroundColor: green
textColor: white
---
## Overview
The **Quote Service** is the core domain service within the Capstone PAS responsible for managing the complete lifecycle of insurance quotes. It implements an event-sourced architecture where all state changes are captured as domain events.
## Architecture
The Quote Service implements:
- **Event Sourcing**: All quote state changes are persisted as events
- **CQRS**: Separate read and write models for optimized queries
- **Domain-Driven Design**: Rich domain model with aggregates and value objects
### CQRS Command/Query Flow
Commands and queries follow separate paths for optimal performance:
```mermaid
flowchart LR
subgraph Commands["Command Path (Write)"]
direction TB
C1["API Gateway / SQS"]
C2["Command Lambda Handler"]
C3["Enrichment Service"]
C4["Command Handler"]
C5["Quote Aggregate"]
C6["Domain Events"]
C7["DynamoDB"]
C8["Event Publisher"]
C1 --> C2
C2 --> C3
C3 -->|"Partner/Pricing Data"| C4
C4 --> C5
C5 --> C6
C6 --> C7
C6 --> C8
end
subgraph Queries["Query Path (Read)"]
direction TB
Q1["API Gateway"]
Q2["Query Lambda Handler"]
Q3["Query Handler"]
Q4["DynamoDB"]
Q5["Quote Projection"]
Q1 --> Q2
Q2 --> Q3
Q3 --> Q4
Q4 --> Q5
end
style Commands fill:#fff3e0,stroke:#e65100
style Queries fill:#e3f2fd,stroke:#1565c0
```
**Command Flow:**
1. Command arrives via API Gateway or SQS queue
2. Lambda handler deserializes and validates command
3. Enrichment service fetches partner/pricing data from external services
4. Command handler loads aggregate, applies command, generates domain events
5. Events persisted to DynamoDB and published to Kinesis/EventBridge
**Query Flow:**
1. Query arrives via API Gateway (REST)
2. Query handler retrieves projection directly from DynamoDB
3. Returns optimized read model to caller
## Capabilities
### Quote Lifecycle
- Create quotes with partner and package configuration
- Configure products with pricing from the pricing engine
- Capture policyholder personal details
- Capture collection and banking details
- Finalise quotes for policy conversion
- Cancel or expire incomplete quotes
### Product Management
- Add products to quotes with risk factor inputs
- Update product cover amounts and recalculate premiums
- Delete products from quotes
- Add optional benefits (Top Up, Accidental Death)
### Beneficiary Management
- Add beneficiaries with percentage allocation
- Update beneficiary details
- Remove beneficiaries
- Validate allocation totals
### Verification Workflows
- Configure required verification steps
- Track verification history
- Record verification outcomes
### Quote Conversion
- Validate all quote requirements are met
- Emit QuoteFinalisedEvent for policy creation
- Update status to Converted upon policy creation
## Event Flow
Domain events are published to both EventBridge (for event routing) and Kinesis (for streaming to downstream services):
```mermaid
flowchart TB
subgraph QuoteService["Quote Service"]
AGG["Quote Aggregate"]
EP["Event Publisher"]
KP["Kinesis Publisher"]
EBP["EventBridge Publisher"]
end
subgraph EventBridge["EventBridge"]
EB["SftCapstoneQuoteEvents Bus"]
R1["Quote Finalised Rule"]
R2["Quote Converted Rule"]
R3["PolicyHolder Added Rule"]
end
subgraph Kinesis["Kinesis Streaming"]
KS["quote-event-stream"]
KSH["Event Shards"]
end
subgraph Consumers["Downstream Consumers"]
PS["Policy Service"]
NS["Notifications Service"]
CDP["Customer Data Platform"]
ER["Event Reactors"]
end
AGG -->|"Domain Event"| EP
EP --> KP
EP --> EBP
KP -->|"Avro Serialized"| KS
KS --> KSH
EBP -->|"JSON"| EB
EB --> R1
EB --> R2
EB --> R3
R1 -->|"SQS"| PS
R2 -->|"SQS"| NS
KSH -->|"Stream"| CDP
KSH -->|"Stream"| ER
style QuoteService fill:#e1f5fe,stroke:#01579b
style EventBridge fill:#fff3e0,stroke:#e65100
style Kinesis fill:#f3e5f5,stroke:#4a148c
style Consumers fill:#e8f5e9,stroke:#1b5e20
```
**Publishing Mechanisms:**
- **EventBridge**: Event bus (`SftCapstoneQuoteEvents`) routes events via rules to SQS queues consumed by downstream services
- **Kinesis**: Event stream (`quote-event-stream`) provides ordered, durable event streaming with Avro serialization
**Key Events Published:**
| Event | Consumers |
|-------|-----------|
| `QuoteCreatedEventV2` | Notifications (welcome) |
| `QuoteFinalisedEventV2` | Policy Service (create policy) |
| `QuoteConvertedEventV2` | Notifications, Customer DP |
| `QuoteExpiredEventV2` | Analytics |
| `PolicyHolderAddedToQuoteEventV2` | Identity Service |
| `ResumeLinkAddedToQuoteEventV2` | Notifications (resume email) |
## AWS Infrastructure
The Quote Service runs on AWS serverless infrastructure:
```mermaid
flowchart TB
subgraph Clients["Client Layer"]
APIGW["API Gateway"]
BFF["BFF Services"]
end
subgraph Compute["Compute Layer"]
direction TB
subgraph CommandLambdas["Command Lambdas (27)"]
CL1["CreateQuote"]
CL2["FinaliseQuote"]
CL3["AddProduct"]
CL4["...20+ more"]
end
subgraph QueryLambdas["Query Lambdas (2)"]
QL1["GetQuote"]
QL2["GetCommandStatus"]
end
subgraph ReactorLambdas["Event Reactors (4)"]
RL1["QuoteFinalised Reactor"]
RL2["QuoteConverted Reactor"]
end
end
subgraph Messaging["Messaging Layer"]
SQS["SQS Command Queues"]
DLQ["Dead Letter Queues"]
IMQ["Idempotency Marker Queues"]
EB2["EventBridge Bus"]
KIN2["Kinesis Stream"]
end
subgraph Storage["Storage Layer"]
DDB["DynamoDB"]
DDB1["quote-table"]
DDB2["command-store"]
end
subgraph External["External Services"]
PRICING["Pricing Service"]
PARTNER["Partner Service"]
IDENTITY["Identity Service"]
POLICY["Policy Service"]
end
APIGW -->|"GET"| QL1
APIGW -->|"GET"| QL2
BFF -->|"POST"| SQS
SQS --> CommandLambdas
CommandLambdas -->|"Store"| DDB1
CommandLambdas -->|"Idempotency"| DDB2
CommandLambdas -->|"Publish"| EB2
CommandLambdas -->|"Stream"| KIN2
CommandLambdas -.->|"Enrich"| PRICING
CommandLambdas -.->|"Enrich"| PARTNER
SQS -->|"Failed"| DLQ
SQS --> IMQ
KIN2 --> ReactorLambdas
EB2 -->|"Route"| POLICY
QL1 --> DDB1
QL2 --> DDB2
style Clients fill:#e8f5e9,stroke:#1b5e20
style Compute fill:#e3f2fd,stroke:#1565c0
style Messaging fill:#fff3e0,stroke:#e65100
style Storage fill:#fce4ec,stroke:#880e4f
style External fill:#f5f5f5,stroke:#616161
```
**Infrastructure Components:**
| Component | Count | Purpose |
|-----------|-------|---------|
| **Lambda Functions** | 33 | Command handlers (27), Query handlers (2), Event reactors (4) |
| **SQS Queues** | 30+ | One per command type, plus DLQs and IMQs |
| **DynamoDB Tables** | 2 | Quote aggregate store, Command status store |
| **Kinesis Stream** | 1 | Event streaming (`quote-event-stream`) |
| **EventBridge Bus** | 1 | Event routing (`SftCapstoneQuoteEvents`) |
| **API Gateway** | 1 | REST API for queries |
**Lambda Configuration:**
- Runtime: Java 21 with SnapStart
- Memory: 2048 MB
- Timeout: 30 seconds
- VPC: Private subnets with security groups
- Batch Size: 10 (SQS triggers)
## Service Dependencies
---
id: VerificationService
name: Verification Service
version: 0.0.1
summary: |
Command gateway service that orchestrates party verification through external providers
including Astute (VOPD), QLink (bank verification), and ORMS (sanctions screening).
owners:
- digisure-engineering
receives:
# Commands
- id: VerifyParty
version: 0.0.1
- id: CheckPendingOrmsDecision
version: 0.0.1
# External Events for ORMS Decision Polling
- id: OrmsScreeningCompletedEventV1
version: 0.0.1
- id: OrmsDecisionPendingEventV1
version: 0.0.1
sends:
# Verification Result Events
- id: VerificationSucceededEventV1
version: 0.0.1
to:
- id: 'sft-capstone-verification.{env}.events'
parameters:
env: prd
- id: VerificationHardFailEventV1
version: 0.0.1
to:
- id: 'sft-capstone-verification.{env}.events'
parameters:
env: prd
- id: VerificationSoftFailEventV1
version: 0.0.1
to:
- id: 'sft-capstone-verification.{env}.events'
parameters:
env: prd
# ORMS-specific Events
- id: OrmsScreeningCompletedEventV1
version: 0.0.1
to:
- id: 'sft-capstone-verification.{env}.events'
parameters:
env: prd
- id: OrmsDecisionPendingEventV1
version: 0.0.1
to:
- id: 'sft-capstone-verification.{env}.events'
parameters:
env: prd
- id: OrmsDecisionFoundEventV1
version: 0.0.1
to:
- id: 'sft-capstone-verification.{env}.events'
parameters:
env: prd
repository:
language: Java
url: https://github.com/sanlam-digisure/sft-capstone-verification
badges:
- content: Command Gateway
backgroundColor: green
textColor: white
---
## Overview
The **Verification Service** is a command gateway that orchestrates party verification through multiple external providers. It receives verification commands and routes them to the appropriate adapter based on verification type.
## Architecture
The service follows a **hexagonal architecture** with:
- **Command Gateway**: Entry point receiving `VerifyPartyCommandV1` and `CheckPendingOrmsDecisionCommandV1` from Kinesis
- **Adapters**: Provider-specific implementations for each verification type (Astute, QLink, ORMS, Xtnd)
- **Event Publishers**: Emit verification results to downstream consumers
```
VerifyPartyCommand -> Command Gateway -> Adapter Router
|
+-------------------------+-------------------------+
| | |
Astute Adapter QLink Adapter ORMS Adapter
| | |
VOPD Check Bank Verification Sanctions Screen
| | |
+-------------------------+-------------------------+
|
Verification Event
(Success/Soft/Hard Fail)
```
## Adapters
### Astute Adapter (VOPD)
Handles personal details verification:
- Validates identity number format and existence
- Checks name matching against official records
- Verifies deceased status through Home Affairs
- Returns success or fail based on validation results
### QLink Adapter (Bank Verification)
Handles bank account verification:
- Validates account number and bank branch
- Verifies account holder name matching
- Checks account status (active/closed)
- Returns verification result with confidence scores
### ORMS Adapter (Sanctions Screening)
Handles sanctions and watchlist screening:
- Submits party details for screening
- Handles immediate GO/STOP decisions
- Manages pending cases requiring analyst review
- Polls for analyst decisions on flagged cases
### Xtnd Adapter (Enhanced Verification)
Handles enhanced verification checks:
- Additional risk assessment scoring
- Extended identity verification with multiple databases
- Historical transaction pattern analysis
- Behavioral risk indicators
- Cross-reference with internal watchlists
- Returns enhanced verification results with risk scores
## Event Flow
### Immediate Verification (Astute/QLink)
```
1. Receive VerifyPartyCommand
2. Route to appropriate adapter
3. Call external provider API
4. Parse response and determine result
5. Emit VerificationSucceeded/SoftFail/HardFail event
```
### ORMS Screening Flow
```
1. Receive VerifyPartyCommand (SANCTIONS_SCREENING)
2. Submit to ORMS for screening
3. If GO -> Emit VerificationSucceededEvent
4. If STOP (clear) -> Emit VerificationHardFailEvent
5. If STOP (pending) -> Emit OrmsDecisionPendingEvent
-> Start decision polling
-> When resolved -> Emit OrmsDecisionFoundEvent
-> Then emit final Verification event
```
## Capabilities
### Personal Details Verification
- ID number validation
- Name and surname matching
- Date of birth verification
- Deceased status check
- Smart ID card validation
### Bank Account Verification
- Account number validation
- Bank and branch verification
- Account holder name matching
- Account status verification
### Sanctions Screening
- Global watchlist screening
- PEP (Politically Exposed Persons) checking
- Local sanctions list checking
- Risk indicator assessment
- Analyst decision integration
## Error Handling
| Scenario | Result | Event |
|----------|--------|-------|
| Provider timeout | Soft Fail | VerificationSoftFailEventV1 |
| Invalid response | Soft Fail | VerificationSoftFailEventV1 |
| ID not found | Hard Fail | VerificationHardFailEventV1 |
| Person deceased | Hard Fail | VerificationHardFailEventV1 |
| Sanctions match | Hard Fail | VerificationHardFailEventV1 |
| Clear screening | Success | VerificationSucceededEventV1 |
---
id: policy-correlation-id-trace
name: Policy Correlation ID Trace
version: 0.0.1
summary: Correlation-based rollups of policy and verification events for traceability.
owners:
- digisure-engineering
badges:
- content: Data Product
backgroundColor: teal
textColor: white
- content: Traceability
backgroundColor: indigo
textColor: white
inputs:
- id: PolicyBeneficiaryAddedEventV1
- id: PolicyBeneficiaryRemovedEventV1
- id: PolicyBeneficiaryUpdatedEventV1
- id: PolicyBillingDateUpdatedEventV1
- id: PolicyCancelledEventV1
- id: PolicyCollectionAnalysisEventV1
- id: PolicyCollectionDetailsUpdatedEventV1
- id: PolicyCoveredLifeDeceasedEventV1
- id: PolicyCoverEscalationAppliedEventV1
- id: PolicyCoverStackedEventV1
- id: PolicyCoverStaggeredEventV1
- id: PolicyCreatedEventV1
- id: PolicyExpiredEventV1
- id: PolicyLapsedEventV1
- id: PolicyPersonalDetailsUpdatedEventV1
- id: PolicyPremiumCollectedEventV1
- id: PolicyPremiumEscalationAppliedEventV1
- id: PolicyProductExpiredEventV1
- id: PolicyReinstatedEventV1
- id: PolicyReplacementCoverDetailsUpdatedEventV1
- id: PolicyScheduleGeneratedEventV1
- id: PolicyUpdatedFromQuoteEventV1
- id: PolicyVerificationCompletedEventV1
- id: PolicyVerificationHardFailEventV1
- id: PolicyVerificationSucceededEventV1
- id: PolicyVerificationRequestedEventV1
- id: PolicyVerificationSoftFailEventV1
- id: NoPolicyCollectionReceivedWithinGracePeriodEventV1
- id: VerificationSucceededEventV1
- id: VerificationSoftFailEventV1
- id: VerificationHardFailEventV1
outputs:
- id: policy-correlation-id-trace-table
version: 0.0.1
contract:
path: policy-correlation-id-trace.schema.json
name: Policy Correlation ID Trace Schema
type: json-schema
---
## Overview
The Policy Correlation ID Trace data product groups policy and verification events by correlation ID. It enables end-to-end tracing across distributed workflows, showing which events belong to the same transaction or orchestration flow.
## Storage
Rollups are stored in DynamoDB keyed by `policyId`, with per-correlation ID event sets ordered by `noticedDate`.
## Access
Use the `GetPolicyCorrelationIdTrace` query to retrieve correlation rollups for a policy.
---
id: policy-event-list
name: Policy Event List
version: 0.0.1
summary: Flat, chronological list of all policy lifecycle events for a single policy.
owners:
- digisure-engineering
badges:
- content: Data Product
backgroundColor: teal
textColor: white
- content: Audit Trail
backgroundColor: blue
textColor: white
inputs:
- id: PolicyBeneficiaryAddedEventV1
- id: PolicyBeneficiaryRemovedEventV1
- id: PolicyBeneficiaryUpdatedEventV1
- id: PolicyBillingDateUpdatedEventV1
- id: PolicyCancelledEventV1
- id: PolicyCollectionAnalysisEventV1
- id: PolicyCollectionDetailsUpdatedEventV1
- id: PolicyCoveredLifeDeceasedEventV1
- id: PolicyCoverEscalationAppliedEventV1
- id: PolicyCoverStackedEventV1
- id: PolicyCoverStaggeredEventV1
- id: PolicyCreatedEventV1
- id: PolicyExpiredEventV1
- id: PolicyLapsedEventV1
- id: PolicyPersonalDetailsUpdatedEventV1
- id: PolicyPremiumCollectedEventV1
- id: PolicyPremiumEscalationAppliedEventV1
- id: PolicyProductExpiredEventV1
- id: PolicyReinstatedEventV1
- id: PolicyReplacementCoverDetailsUpdatedEventV1
- id: PolicyScheduleGeneratedEventV1
- id: PolicyUpdatedFromQuoteEventV1
- id: PolicyVerificationCompletedEventV1
- id: PolicyVerificationHardFailEventV1
- id: PolicyVerificationSucceededEventV1
- id: PolicyVerificationRequestedEventV1
- id: PolicyVerificationSoftFailEventV1
- id: NoPolicyCollectionReceivedWithinGracePeriodEventV1
outputs:
- id: policy-event-list-table
version: 0.0.1
contract:
path: policy-event-list.schema.json
name: Policy Event List Schema
type: json-schema
---
## Overview
The Policy Event List data product provides a flat, chronological audit trail of all policy lifecycle events. Events are ordered by `noticedDate`, giving a consistent view of how the policy evolved over time.
## Storage
This data product is persisted in DynamoDB and keyed by `policyId`. Each policy stores a sorted event set for fast retrieval.
## Access
Use the `GetPolicyEventList` query to retrieve the full history for a policy, optionally filtered by event type or time range.
---
id: policy-report
name: Policy Report
version: 0.0.1
summary: CSV-based policy reporting feed for new business and verification outcomes.
owners:
- digisure-engineering
badges:
- content: Data Product
backgroundColor: teal
textColor: white
- content: CSV
backgroundColor: orange
textColor: white
inputs:
- id: PolicyCreatedEventV1
- id: PolicyVerificationCompletedEventV1
- id: PolicyVerificationHardFailEventV1
- id: PolicyVerificationSoftFailEventV1
- id: PolicyVerificationSucceededEventV1
- id: PolicyCancelledEventV1
outputs:
- id: policy-report-bucket
version: 0.0.1
contract:
path: policy-report-row.schema.json
name: Policy Report Row Schema
type: json-schema
---
## Overview
The Policy Report data product generates a CSV report of policy sales and verification outcomes. It provides a compact reporting feed used by analytics and operational reporting teams.
## Storage
The report is written to an S3 bucket as `NewPoliciesReport.csv` and updated incrementally as new events arrive.
## Access
The CSV file is consumed by downstream reporting pipelines and BI tooling.
---
id: BFFASCP
name: BFFASCP Domain
version: 0.0.1
summary: |
Backend for Frontend service for the Agent Servicing Claims Portal (ASCP), providing API
orchestration between the ASCP frontend and various Capstone domain services.
owners:
- digisure-engineering
services:
- id: BFFASCPService
version: 0.0.1
entities:
- id: Quote
- id: Policy
- id: Claim
- id: Customer
- id: Partner
- id: Beneficiary
badges:
- content: BFF Service
backgroundColor: teal
textColor: white
---
## Overview
The BFFASCP (Backend for Frontend - Agent Servicing Claims Portal) Domain provides a unified API layer that orchestrates communication between the ASCP frontend application and various backend domain services within the Capstone PAS ecosystem.
## Key Responsibilities
- **API Orchestration**: Aggregate data from multiple domain services (Policy, Quote, Claims, Customer, Partner) into unified responses
- **Command Forwarding**: Transform and forward commands from the frontend to appropriate domain services
- **Query Aggregation**: Combine data from multiple sources to provide comprehensive views
- **File Upload Management**: Handle document uploads and pre-signed URL generation
- **Pricing Calculations**: Coordinate pricing calculations for quotes
## Architecture
The BFFASCP follows a clean architecture pattern with three layers:
- **Domain Layer**: Core business logic and command/query definitions
- **Application Layer**: Use case orchestration and handler implementations
- **Infrastructure Layer**: External integrations including HTTP clients, SQS dispatchers, and Lambda functions
## Integration Points
The BFF integrates with the following domain services:
| Service | Purpose |
|---------|---------|
| Policy Domain | Policy lifecycle and beneficiary management |
| Quote Domain | Quote creation and management |
| Claims Domain | Claim submission and processing |
| Customer Domain | Customer information retrieval |
| Partner Domain | Partner and package configuration |
| Pricing Service | Premium calculations |
| File Upload Service | Document management |
## Entity Relationships
---
id: BFFWeb
name: BFF Web Domain
version: 0.0.1
summary: |
Backend for Frontend (Web) domain providing a secure API gateway layer between web clients
and backend services with CORS management, CAPTCHA validation, and AWS SigV4 signing.
owners:
- digisure-engineering
services:
- id: BFFWebService
version: 0.0.1
entities:
- id: PartnerConfig
- id: ProxyRequest
- id: CaptchaValidation
- id: AwsCredentials
- id: CorsSettings
badges:
- content: Edge Service
backgroundColor: orange
textColor: white
---
## Overview
The BFF Web Domain provides a Backend for Frontend (BFF) layer specifically designed for web clients. It acts as an API gateway that handles cross-cutting concerns such as security, authentication, and request proxying to backend services.
## Key Responsibilities
- **Request Proxying**: Forward web client requests to backend BFF API services
- **CORS Management**: Handle cross-origin resource sharing with configurable allowed origins
- **CAPTCHA Validation**: Integrate reCAPTCHA v3 for bot protection on sensitive endpoints
- **AWS SigV4 Signing**: Sign requests for AWS API Gateway authentication
- **Security Headers**: Apply security headers (HSTS, X-Frame-Options, etc.) to all responses
- **Request Logging**: Structured JSON logging for observability
## Architecture
The BFF Web service is deployed as a Cloudflare Worker at the edge, providing:
- **Low Latency**: Edge deployment close to users
- **Global Distribution**: Automatic geographic distribution
- **Serverless**: No infrastructure management required
## Request Flow
```
Web Client -> Cloudflare Worker -> CORS Check -> CAPTCHA Validation -> SigV4 Signing -> Backend BFF API
```
## Partner Configuration
The service supports multi-tenant configuration per partner, allowing customization of:
- Allowed origins for CORS
- CAPTCHA requirements and thresholds
- Backend API endpoints
- AWS signing configuration
## Entity Relationships
---
id: CapstonePAS
name: " Capstone PAS"
version: 0.0.1
summary: |
Capstone Policy Administration System (PAS) for funeral insurance products.
Manages the complete policy lifecycle from quote acceptance through to claim settlement.
owners:
- digisure-engineering
domains:
- id: Policy
version: 0.0.2
- id: Quote
version: 0.0.1
- id: Claims
version: 0.0.1
- id: Identity
version: 0.0.1
- id: Partner
version: 0.0.1
- id: Pricing
version: 0.0.1
- id: Notifications
version: 0.0.1
- id: PolicyImporter
version: 0.0.1
- id: ProductBundleInventory
version: 0.0.1
- id: CustomerDP
version: 0.0.1
- id: BFFWeb
version: 0.0.1
- id: BFFASCP
version: 0.0.1
- id: FileUpload
version: 0.0.1
- id: PDFGenerator
version: 0.0.1
badges:
- content: Insurance Domain
backgroundColor: purple
textColor: white
---
## Overview
The Capstone PAS (Policy Administration System) is a comprehensive insurance policy management platform designed for funeral insurance products. It handles the complete policy lifecycle including:
- Policy creation and onboarding
- Premium collection and financial management
- Beneficiary management
- Cover escalation and staggering
- Policy verification workflows
- Death claim processing
## Subdomains
The Capstone PAS is organized into bounded contexts:
- **Policy** - Core policy aggregate management including lifecycle, beneficiaries, and financial operations
- **Quote** - Quote creation, finalization, and conversion to policies
- **Claims** - Death claim lifecycle management, payout processing, CRM integration, and document verification
- **Identity** - Customer identity management, verification, and data subject handling
- **Partner** - Partner configuration, product package availability, and business rules for distribution channels
- **Pricing** - Supporting domain for premium and cover amount calculations using actuarial formulas
- **Notifications** - Supporting domain for notification orchestration, scheduling, and multi-channel delivery
- **PolicyImporter** - Bulk policy import from external systems
- **ProductBundleInventory** - Product bundle configuration and inventory management
- **CustomerDP** - Customer Data Platform providing unified customer views across quotes and policies
- **BFFWeb** - Backend for Frontend (Web) providing secure API gateway with CORS, CAPTCHA, and request proxying
- **BFFASCP** - Backend for Frontend (ASCP) for agent/admin portal operations
- **FileUpload** - File upload, storage, and lifecycle management
- **PDFGenerator** - Supporting domain for PDF document generation, formatting, and encryption
## Architecture
The system follows an event-driven architecture using:
- **Event Sourcing** for policy state management
- **CQRS** for read/write separation
- **Kinesis** for event streaming
- **Domain-Driven Design** for bounded context organization
---
id: Claims
name: Claims
version: 0.0.1
summary: |
Core subdomain of CapstonePAS handling death claim lifecycle, payout processing,
CRM integration, claimant and deceased capture, and document verification.
owners:
- digisure-engineering
services:
- id: ClaimsService
version: 0.0.1
badges:
- content: Core Subdomain
backgroundColor: blue
textColor: white
---
## Overview
The Claims subdomain is a core bounded context within the Capstone PAS domain, responsible for managing funeral insurance death claims. It encompasses the complete claim lifecycle from initial claim creation through payout or repudiation, using event sourcing and CQRS patterns.
## Key Responsibilities
- **Claim Lifecycle Management**: Create claims for main life and covered life scenarios, track claim status through to resolution
- **Claimant & Deceased Capture**: Capture claimant personal details, banking details, and deceased information
- **Death Details Capture**: Record date and cause of death for claim processing
- **Payout Calculation & Processing**: Calculate claim payouts based on policy terms and initiate payment
- **Repudiation Handling**: Repudiate invalid claims with reason codes, with override capability
- **CRM Integration**: Submit claims to CRM systems and capture CRM servicing outcomes
- **Document Verification**: Track and update document verification status for claims
- **Banking Details Management**: Capture and update claimant banking details for payout processing
## Aggregate Root
The **Claim** entity serves as the aggregate root, ensuring consistency across all claim operations. It encapsulates the complete claim state including claimant details, deceased information, death details, CRM submissions, payout information, and document verification status.
## Event Detail Types
The Claims domain uses 16 distinct event detail types to categorize state changes:
| Detail Type | Description |
|---|---|
| `claimSuccessfulLapsedPolicy` | Claim created successfully against a lapsed policy |
| `claimSuccessfulPolicyActive` | Claim created successfully against an active policy |
| `claimUpdatedMainLife` | Claim updated for main life deceased scenario |
| `claimUpdatedCoveredLife` | Claim updated for covered life deceased scenario |
| `claimUpdatedBankDetails` | Banking details updated on the claim |
| `claimantBankingDetailsCaptured` | Claimant banking details initially captured |
| `ahvRequested` | Anti-money laundering / high-value verification requested |
| `claimRepudiated` | Claim was repudiated (denied) |
| `claimRequestCreated` | Initial claim request created |
| `claimDeathDetailsCaptured` | Death details (date, cause) captured |
| `deceasedCaptured` | Deceased person details captured |
| `claimantCaptured` | Claimant person details captured |
| `policyLinkageResolved` | Policy linked to claim resolved |
| `claimSubmittedToCrm` | Claim submitted to CRM for servicing |
| `crmOutcomeCaptured` | CRM servicing outcome captured |
| `payoutInitiated` | Payout initiated for the claim |
## Hexagonal Architecture
```mermaid
flowchart TB
subgraph External["External Systems"]
API["API Gateway"]
SQS["SQS Queues"]
KIN["Kinesis"]
CRM["CRM System"]
POLICY["Policy Service"]
end
subgraph Infrastructure["Infrastructure Layer"]
direction TB
LH["Lambda Handlers"]
KP["Kinesis Publisher"]
DR["DynamoDB Repository"]
HP["HTTP Adapters"]
end
subgraph Application["Application Layer"]
direction TB
CH["Command Handlers"]
QH["Query Handlers"]
ES["Enrichment Services"]
end
subgraph Domain["Domain Layer"]
direction TB
AGG["Claim Aggregate Root"]
VO["Value Objects"]
DE["Domain Events"]
INV["Invariants & Rules"]
end
API --> LH
SQS --> LH
LH --> CH
LH --> QH
CH --> ES
ES --> HP
HP --> POLICY
HP --> CRM
CH --> AGG
QH --> DR
AGG --> DE
AGG --> INV
AGG --> VO
DE --> KP
KP --> KIN
DR --> AGG
style Domain fill:#e1f5fe,stroke:#01579b
style Application fill:#fff3e0,stroke:#e65100
style Infrastructure fill:#f3e5f5,stroke:#4a148c
style External fill:#e8f5e9,stroke:#1b5e20
```
**Layer Responsibilities:**
- **Domain Layer**: Pure business logic - Claim aggregate, value objects (ClaimId, DeathDetail, CrmSubmission, CrmOutcome, BankDetails), domain events, and business rules
- **Application Layer**: Orchestration - command/query handlers, enrichment services (policy lookup, payout calculation)
- **Infrastructure Layer**: Technical adapters - Lambda handlers, repositories (DynamoDB), event publishers (Kinesis), HTTP clients (Policy, CRM)
## Domain Events
The Claims subdomain emits 6 domain events covering:
- Claim updates (main life, covered life, banking details changes)
- Claim repudiation
- Payout initiation
- CRM submission and outcome capture
- Death details capture
---
id: Collections
name: Collections
version: 0.0.1
summary: |
External collections command gateway domain responsible for premium collection scheduling
and payment processing events used by Capstone PAS services.
owners:
- digisure-engineering
domains:
- id: CommandGateway
version: 0.0.1
badges:
- content: External System
backgroundColor: gray
textColor: white
---
## Overview
The Collections domain represents the command gateway used for premium collections and
payment processing. It emits collection lifecycle events that downstream services consume
for policy financial updates.
---
id: CommandGateway
name: Collections Command Gateway
version: 0.0.1
summary: |
Command gateway for collections processing. Publishes collection creation, schedule,
and transaction outcome events.
owners:
- digisure-engineering
services:
- id: CollectionsCommandGatewayService
version: 0.0.1
badges:
- content: Command Gateway
backgroundColor: green
textColor: white
---
## Overview
The Collections Command Gateway receives collection requests from upstream systems and
publishes events for schedule creation and collection outcomes. Capstone PAS services
consume these events to update policy financial state.
---
id: CustomerDP
name: Customer Data Platform
version: 0.0.1
summary: |
Customer Data Platform (CDP) providing a unified view of customer data across quotes and policies.
Aggregates customer information from policy events to enable customer-centric queries and analytics.
owners:
- digisure-engineering
services:
- id: CustomerDPService
version: 0.0.1
entities:
- id: Customer
- id: CustomerPolicy
- id: PolicyHolder
- id: Identification
- id: GlobalCustomerId
badges:
- content: Data Product
backgroundColor: teal
textColor: white
---
## Overview
The Customer Data Platform (CustomerDP) is a bounded context within the Capstone PAS responsible for maintaining a unified view of customer data. It consumes events from the Policy and Quote domains to build a comprehensive customer profile that spans quotes and policies.
## Key Responsibilities
- **Customer Aggregation**: Build unified customer profiles from quote and policy events
- **Policy Association**: Track all policies associated with a customer
- **Quote Tracking**: Maintain references to customer quotes
- **Event Projection**: Project policy lifecycle events onto customer state
- **Customer Queries**: Provide efficient customer lookup by policy holder ID
## Architecture
The CustomerDP follows the Data Product pattern:
- **Event Consumers**: Lambda functions consuming events from Policy and Quote streams
- **State Projection**: DynamoDB-based read model for customer state
- **Idempotent Processing**: Logical clock readings ensure exactly-once event processing
- **Query Interface**: REST API for customer retrieval
## Domain Events Consumed
The CustomerDP consumes the following events to build customer state:
| Event | Source | Effect |
|-------|--------|--------|
| PolicyHolderAddedToQuoteEvent | Quote Service | Creates/updates customer with quote reference |
| PolicyCreatedEvent | Policy Service | Associates policy with customer |
| PolicyCancelledEvent | Policy Service | Updates policy status to CANCELLED |
| PolicyExpiredEvent | Policy Service | Updates policy status to EXPIRED |
| PolicyVerificationCompletedEvent | Policy Service | Updates policy status based on verification |
## Aggregate Root
The **Customer** entity serves as the aggregate root, maintaining consistency across all customer data including associated quotes and policies.
## Entity Relationships
---
id: FileUpload
name: File Upload Domain
version: 0.0.1
summary: |
File management domain handling secure file uploads, storage, retrieval, and archival
for policy-related documents across Claims, Policy, and Quote contexts.
owners:
- digisure-engineering
services:
- id: FileUploadService
version: 0.0.1
entities:
- id: File
- id: FileUploadLink
- id: FileDownloadLink
badges:
- content: Supporting Domain
backgroundColor: teal
textColor: white
---
## Overview
The File Upload Domain is a supporting bounded context within the Capstone PAS responsible for managing file operations. It provides secure file storage, retrieval, and lifecycle management for documents associated with policies, quotes, and claims.
## Key Responsibilities
- **File Upload**: Upload files via base64 encoding or pre-signed URLs
- **File Retrieval**: Download files or retrieve binary streams
- **File Archival**: Archive files after a specified retention period
- **File Deletion**: Permanently delete files when required
- **Origination Tracking**: Associate files with their source context (Policy, Quote, Claims)
## Aggregate Root
The **File** entity serves as the aggregate root, ensuring consistency across all file operations. All file state changes including uploads, archival, and deletion flow through the File aggregate.
## Domain Events
The File Upload Domain emits 3 domain events covering:
- File lifecycle (uploaded, deleted)
- Origination changes (origination set)
## Integration Points
The File Upload service integrates with:
- **Policy Service**: Document attachments for policies
- **Quote Service**: Supporting documents during quoting
- **Claims Service**: Claim evidence and documentation
- **S3**: Backend storage for file content
## Entity Relationships
---
id: Identity
name: Identity Domain
version: 0.0.1
summary: |
Identity management domain handling global customer identities, unverified identities,
tenanted identities, customer profiles, and data subject records across the insurance platform.
owners:
- digisure-engineering
services:
- id: IdentityService
version: 0.0.1
- id: PortfolioService
version: 0.0.1
entities:
- id: GlobalIdentity
- id: CustomerIdentity
- id: UnverifiedIdentity
- id: TenantedIdentity
- id: DataSubject
- id: CustomerProfile
- id: IdentityPortfolio
- id: IdentityPortfolioPolicy
- id: Address
- id: PersonName
- id: IssuedIdentity
- id: MobileNumber
- id: EmailAddress
- id: Certificate
- id: NotificationPreferences
- id: CollectionAccount
- id: AuditDetails
badges:
- content: Supporting Domain
backgroundColor: teal
textColor: white
---
## Overview
The Identity Domain is a supporting bounded context within the Capstone PAS responsible for managing customer identity information and portfolios across the platform. It provides a unified view of customer identities while supporting multi-tenant configurations, verification workflows, and portfolio management.
## Key Responsibilities
- **Global Identity Management**: Create and maintain canonical customer identities with verified information
- **Unverified Identity Handling**: Store and manage identity information prior to verification
- **Tenanted Identity Support**: Handle tenant-specific identity records for multi-tenant deployments
- **Customer Profile Management**: Manage notification preferences and collection account preferences
- **Portfolio Management**: Track customer quotes and policies in a unified portfolio view
- **Data Subject Tracking**: Maintain data subject records for POPIA/GDPR compliance
- **Certificate-Based Trust**: Track trust levels for identity attributes using certificates
## Aggregate Roots
- **GlobalIdentity**: The canonical identity record linked by Global Customer ID (GCID)
- **UnverifiedIdentity**: Tenant-scoped identity records awaiting verification
- **CustomerProfile**: Customer preferences for notifications and collection accounts
- **IdentityPortfolio**: Customer's portfolio of quotes and policies
## Domain Events
The Identity Domain emits domain events covering:
- Identity creation and updates (customer, global, unverified, tenanted)
- Attribute updates (name, email, mobile, address, gender, date of birth)
- Profile preferences (notification, collection account)
- Data subject lifecycle events
- Failure events for validation errors and trust level conflicts
## Entity Relationships
---
id: Notifications
name: Notifications Domain
version: 0.0.1
summary: |
Notification orchestration domain handling policy and claims notification lifecycle,
scheduling, dispatch, and multi-channel delivery via email and SMS.
owners:
- digisure-engineering
services:
- id: NotificationService
version: 0.0.1
entities:
- id: NotificationState
- id: NotificationConfig
- id: NotificationDataProduct
- id: ScheduledNotification
- id: PartnerNotificationConfig
- id: PackageNotificationConfig
- id: NotificationSenderIdentity
badges:
- content: Supporting Domain
backgroundColor: orange
textColor: white
---
## Overview
The Notifications Domain is a supporting bounded context within the Capstone PAS responsible for managing the complete notification lifecycle for funeral insurance policies and claims. It orchestrates multi-channel notifications (email and SMS) triggered by policy events.
## Key Responsibilities
- **Notification Triggering**: React to policy and claims events to trigger appropriate notifications
- **Notification Scheduling**: Schedule future notifications based on policy state and configuration
- **Multi-Channel Dispatch**: Route notifications to email and SMS providers
- **Notification Tracking**: Track notification status through the data product
- **Template Management**: Process notification templates with policy/claims context
## Aggregate Roots
The domain maintains two aggregate roots:
- **FuneralPolicyStateAggregateRoot**: Tracks policy notification state including pending, scheduled, and dispatched notifications
- **ClaimStateAggregateRoot**: Tracks claims notification state for claim-related notifications
## Notification Types
The domain supports various notification categories:
### Policy Notifications
- Welcome/confirmation emails
- Policy cancellation notices
- Expiry warnings and reminders
- Payment reminders
- Beneficiary updates
- Cover stagger notifications
### Claims Notifications
- Claim submission confirmations
- Claim approval/rejection notices
- Payout completion notices
## Entity Relationships
---
id: Partner
name: Partner Domain
version: 0.0.1
summary: |
Partner domain managing partner configuration, product package availability, business rules,
and distribution channel setup. Provides read-only access to partner and package configuration
required for quote creation and policy management.
owners:
- digisure-engineering
services:
- id: PartnerService
version: 0.0.1
entities:
- id: Partner
- id: Package
- id: Product
- id: PartnerConfig
badges:
- content: Supporting Domain
backgroundColor: green
textColor: white
---
## Overview
The Partner Domain is a supporting bounded context within the Capstone PAS responsible for managing partner configuration and product availability. It provides read-only access to partner setup, product packages, pricing rules, and business constraints that govern quote creation and policy operations.
## Key Responsibilities
- **Partner Configuration**: Manage partner organization details, types, and active status
- **Package Management**: Define and maintain product packages available to each partner
- **Product Configuration**: Configure products within packages with pricing and availability rules
- **Collection Methods**: Specify allowed payment collection methods per partner
- **Business Rules**: Define partner-specific validation rules and constraints
- **Terms and Conditions**: Manage terms and conditions versions per product package
- **Pricing Integration**: Provide pricing calculation metadata to pricing service
- **Notification Configuration**: Store partner-specific notification preferences and templates
## Aggregate Root
The **Partner** entity serves as the aggregate root, encompassing all partner-related configuration including packages, products, rules, and terms.
## Domain Model
### Partner Hierarchy
```
Partner (Aggregate Root)
├── Package 1
│ ├── Product 1 (Main Life)
│ ├── Product 2 (Spouse/Extended)
│ ├── OptionalBenefit
│ ├── CollectionMethods
│ └── TermsAndConditions
├── Package 2
│ └── ...
├── Rules
│ ├── maxBeneficiaries
│ ├── allowMultipleProducts
│ └── requireBankVerification
└── NotificationConfig
├── Template 1
└── Template 2
```
## Read-Only Access
The Partner Domain provides **read-only queries** to support downstream services:
- **BFFWeb** - Retrieves partner configuration for web portal initialization
- **BFFASCP** - Retrieves partner details for agent portal
- **Quote Service** - Validates product availability and package configuration
- **Policy Service** - Enforces partner-specific rules during policy lifecycle
- **Pricing Service** - Uses partner pricing configuration for calculations
## Domain Events
The Partner Domain emits minimal events, focusing on configuration changes:
- **PartnerConfigurationUpdatedEvent** - When partner setup changes
- **ProductAvailabilityChangedEvent** - When products become available/unavailable
- **PricingRulesUpdatedEvent** - When partner pricing configuration changes
---
id: PDFGenerator
name: PDF Generator Domain
version: 0.0.1
summary: |
PDF document generation domain responsible for creating, formatting, and encrypting PDF documents
from HTML templates. Provides document storage and signed URL generation for secure download access.
owners:
- digisure-engineering
services:
- id: PDFGeneratorService
version: 0.0.1
entities:
- id: PDFDocument
- id: PageConfiguration
- id: PageMargin
badges:
- content: Supporting Domain
backgroundColor: teal
textColor: white
---
## Overview
The PDF Generator Domain is a supporting bounded context within the Capstone PAS responsible for generating PDF documents from HTML content. It provides capabilities for rendering multi-page documents, merging PDFs, and encrypting documents with password protection.
## Key Responsibilities
- **PDF Generation**: Convert HTML templates to formatted PDF documents
- **Multi-Page Support**: Generate and merge multiple pages into a single PDF
- **Document Encryption**: Password-protect sensitive PDF documents
- **Secure Storage**: Upload documents to S3 with signed URL generation for secure access
- **Template Rendering**: Support for custom headers, footers, and page formatting
## Technical Architecture
The domain consists of two AWS Lambda functions:
1. **PDF Generation Lambda** (Node.js/TypeScript) - Uses Puppeteer with Chromium to render HTML to PDF
2. **PDF Encryption Lambda** (Python) - Uses pypdf to apply password encryption to existing PDFs
## Integration Points
The PDF Generator service is consumed by other domains to generate:
- Policy schedule documents
- Welcome letters
- Certificate of insurance documents
- Claim acknowledgment letters
- Any document requiring PDF format
## Entity Relationships
---
id: Policy
name: Policy
version: 0.0.2
summary: |
Core subdomain of CapstonePAS handling funeral insurance policy lifecycle, beneficiary management,
premium collection, cover and premium escalation, verification workflows, and document generation.
owners:
- digisure-engineering
services:
- id: PolicyService
version: 0.0.1
data-products:
- id: policy-event-list
version: 0.0.1
- id: policy-correlation-id-trace
version: 0.0.1
- id: policy-report
version: 0.0.1
entities:
- id: Policy
- id: PolicyHolder
- id: Beneficiary
- id: Product
- id: Tranche
- id: PolicyProductLife
- id: PolicyFinancialDetail
- id: PolicyDocument
- id: BankDetails
- id: Address
- id: Employment
- id: Campaign
- id: VerificationConfiguration
- id: UnverifiedIdentity
- id: CollectionSchedule
- id: TermsAndConditionsDetail
- id: CollectionDetails
- id: Party
- id: ThirdPartyPayer
- id: ReplacementCoverDetail
- id: Credits
- id: Debits
- id: PolicyStatusHistory
badges:
- content: Core Subdomain
backgroundColor: blue
textColor: white
---
## Overview
The Policy subdomain is a core bounded context within the Capstone PAS domain, responsible for managing funeral insurance policies. It encompasses the complete policy lifecycle from creation (including quote conversion) through expiration or cancellation, using event sourcing and CQRS patterns.
## Key Responsibilities
- **Policy Lifecycle Management**: Create, reinstate, cancel, lapse, and expire policies
- **Quote-to-Policy Conversion**: Create policies from quotes and update existing policies from requotes
- **Beneficiary Management**: Add, update, and remove policy beneficiaries
- **Premium Collection**: Process premium payments, ad-hoc collections, and billing date management
- **Cover Management**: Apply cover escalations, stack cover, and stagger cover across products
- **Premium Escalation**: Apply annual premium escalations separately from cover escalations
- **Verification Workflows**: Coordinate identity, bank, and employment verification with success/fail handling
- **Document Management**: Generate policy schedules and manage schedule download links
- **Personal Details Management**: Update policyholder personal details and collection details
- **Deceased Processing**: Handle covered life and main life deceased scenarios
- **Policy Health Verification**: Scheduled health checks to maintain policy integrity
## Aggregate Root
The **Policy** entity serves as the aggregate root, ensuring consistency across all policy operations. It encapsulates the complete policy state including products, beneficiaries, financial details, verification configurations, and documents. The aggregate supports idempotency through tracked processed commands and events.
## Hexagonal Architecture
The Policy domain implements a clean hexagonal (ports and adapters) architecture with three distinct layers:
```mermaid
flowchart TB
subgraph External["External Systems"]
API["API Gateway"]
EB["EventBridge"]
KIN["Kinesis"]
SQS["SQS Queues"]
COLL["Collections Service"]
VERIF["Verification Service"]
end
subgraph Infrastructure["Infrastructure Layer"]
direction TB
LH["Lambda Handlers"]
KP["Kinesis Publisher"]
EBP["EventBridge Publisher"]
DR["DynamoDB Repository"]
HP["HTTP Adapters"]
ER["Event Reactors"]
end
subgraph Application["Application Layer"]
direction TB
CH["Command Handlers"]
QH["Query Handlers"]
ES["Enrichment Services"]
DEC["Decorators"]
SCHED["Schedulers"]
end
subgraph Domain["Domain Layer"]
direction TB
AGG["Policy Aggregate Root"]
VO["Value Objects"]
DE["Domain Events"]
INV["Invariants & Rules"]
CF["Command Factories"]
end
API --> LH
SQS --> LH
COLL --> ER
VERIF --> ER
LH --> CH
LH --> QH
ER --> CH
CH --> ES
ES --> HP
CH --> AGG
QH --> DR
AGG --> DE
AGG --> INV
AGG --> VO
DE --> KP
DE --> EBP
KP --> KIN
EBP --> EB
DR --> AGG
SCHED --> CH
style Domain fill:#e1f5fe,stroke:#01579b
style Application fill:#fff3e0,stroke:#e65100
style Infrastructure fill:#f3e5f5,stroke:#4a148c
style External fill:#e8f5e9,stroke:#1b5e20
```
**Layer Responsibilities:**
- **Domain Layer**: Pure business logic - Policy aggregate, value objects (Money, Percentage, BankDetails), domain events, and business rules (invariants for lapse, reinstatement, escalation)
- **Application Layer**: Orchestration - command/query handlers, enrichment services, schedulers (health checks, escalation jobs), and cross-cutting concerns via decorators
- **Infrastructure Layer**: Technical adapters - Lambda handlers, event reactors (for Collections/Verification events), repositories (DynamoDB), event publishers (Kinesis/EventBridge), HTTP clients
## Domain Events
The Policy subdomain emits 29 domain events covering:
- Lifecycle changes (created, cancelled, lapsed, expired, reinstated, updated from quote)
- Beneficiary changes (added, removed, updated)
- Collection events (premium collected, ad-hoc collection requested, billing date updated, collection details updated)
- Verification events (requested, completed, succeeded, hard fail, soft fail)
- Cover events (escalation applied, cover stacked, cover staggered)
- Premium events (escalation applied)
- Document events (schedule generated, schedule link refreshed)
- Personal details events (personal details updated, replacement cover details updated)
- Deceased events (covered life deceased, main life deceased)
- Product events (product expired)
- Grace period events (no collection received within grace period)
## Entity Relationships
---
id: PolicyImporter
name: Policy Importer
version: 0.0.1
summary: |
Supporting capability for bulk policy imports from external systems into the Capstone PAS.
Converts CSV and JSON payloads into policy and identity commands.
owners:
- digisure-engineering
services:
- id: PolicyImporterService
version: 0.0.1
badges:
- content: Supporting Service
backgroundColor: teal
textColor: white
- content: Ingestion
backgroundColor: orange
textColor: white
---
## Overview
The Policy Importer provides ingestion paths for migrating and onboarding policies from external
sources. It accepts batch CSV uploads or JSON requests, maps records to Capstone commands, and
publishes import status events for monitoring.
## Key Responsibilities
- **Batch ingestion** from S3 CSV uploads for large-scale migrations
- **JSON ingestion** via HTTP for single or small-batch policy creation
- **Command dispatch** to Policy and Identity services
- **Failure handling** with failed-row exports and retry queues
## Integration Points
- **S3**: `sft-capstone-{env}-bulk-policy-import-risk` for CSV uploads
- **S3 (failed)**: `sft-capstone-{env}-bulk-policy-import-risk-failed` for failed rows
- **SQS**: `sft-capstone-policy-importer-{env}-create-policy-request-queue` for API ingestion
- **Policy Commands**: `sft-capstone-policy-create-policy` queue
- **Identity Commands**: Parameter Store-backed create-identity queue
- **SNS**: `sft-capstone-policy-importer-{env}-events-topic` for import status
---
id: Pricing
name: Pricing Domain
version: 0.0.1
summary: |
Supporting domain providing insurance premium and cover amount calculations for funeral products.
Implements actuarial formulas and configurable calculation engines.
owners:
- digisure-engineering
services:
- id: PricingService
version: 0.0.1
entities:
- id: PricingConfiguration
- id: Calculator
- id: Calculation
- id: CalculationResults
badges:
- content: Supporting Domain
backgroundColor: teal
textColor: white
---
## Overview
The Pricing Domain is a supporting bounded context within the Capstone PAS responsible for calculating insurance premiums and cover amounts. It provides calculation services used by the Policy domain during quote generation and policy updates.
## Key Responsibilities
- **Premium Calculation**: Calculate monthly premiums based on cover amounts and risk factors
- **Cover Calculation**: Calculate cover amounts based on premium budgets and risk factors
- **Dynamic Calculations**: Execute configurable calculation expressions defined per partner
- **Risk Factor Application**: Apply age, gender, relationship, and mortality factors
## Calculation Types
The domain supports multiple calculator types for different product categories:
| Calculator | Purpose |
|------------|---------|
| MainLifeCalculator | Calculates pricing for the main insured life |
| CoveredLifeCalculator | Calculates pricing for additional covered lives |
| AccidentalCalculator | Handles accidental death benefit calculations |
| RepatriationCalculator | Calculates repatriation benefit pricing |
| StillBirthAndNewBornCalculator | Calculates stillbirth and newborn benefit pricing |
| DynamicCalculator | Executes partner-configurable calculation expressions |
## Pricing Factors
Calculations incorporate multiple actuarial factors:
- **Base QX Factor**: Base mortality rate by age
- **AIDS QX Factor**: HIV/AIDS mortality adjustment
- **Accidental Factor**: Accidental death multiplier
- **Age Top-Up Factor**: Age-based premium loading
- **Relationship Top-Up Factor**: Relationship type loading
- **Expense Loading**: Administrative and operational costs
- **Distribution Rate**: Commission and distribution costs
- **Profit Margin**: Target profit loading
## Integration Points
The Pricing Service is consumed by:
- **Quote Service**: For generating premium quotes during sales
- **Policy Service**: For recalculating premiums during policy changes
- **Escalation Processing**: For calculating escalated premiums and cover
---
id: ProductBundleInventory
name: Product Bundle Inventory Domain
version: 0.0.1
summary: |
Product bundle inventory management for prepaid funeral insurance bundles.
Handles bundle configuration, inventory item generation, and redemption workflows.
owners:
- digisure-engineering
services:
- id: ProductBundleInventoryService
version: 0.0.1
entities:
- id: ProductBundleConfig
- id: InventoryItem
- id: BundleProduct
- id: SerialNumber
badges:
- content: Supporting Domain
backgroundColor: teal
textColor: white
---
## Overview
The Product Bundle Inventory Domain is a supporting bounded context within the Capstone PAS responsible for managing prepaid funeral insurance product bundles. It enables partners to purchase bundles of insurance coverage that can be distributed and redeemed by end customers.
## Key Responsibilities
- **Bundle Configuration Management**: Define product bundle configurations with partner, package, and coverage rules
- **Inventory Generation**: Generate serialized inventory items with unique serial numbers
- **Item Redemption**: Process redemption of inventory items for new or existing policies
- **Coverage Calculation**: Calculate cover amounts based on term and bundle configuration
## Aggregate Roots
The domain has two aggregate roots:
1. **ProductBundleConfig** - Manages bundle configuration including products, coverage calculations, and allowed terms
2. **InventoryItem** - Manages individual inventory items identified by serial numbers
## Domain Events
The Product Bundle Inventory Domain emits 4 domain events:
- **ProductBundleInventoryItemsCreatedEventV2** - When new inventory items are generated
- **InventoryItemRedeemedNewPolicyEventV2** - When an item is redeemed for a new policy
- **InventoryItemRedeemedExistingPolicyEventV2** - When an item is linked to an existing policy
- **BundleIssuanceForNewPolicyEventV2** - When bundle issuance is initiated for a new policy
## Entity Relationships
---
id: Quote
name: Quote Domain
version: 0.0.1
summary: |
Quote domain managing insurance quote lifecycle from creation through conversion to policy,
including product configuration, optional benefits, policyholder and beneficiary management,
collection details capture, verification workflows, and pricing integration.
owners:
- digisure-engineering
services:
- id: QuoteService
version: 0.0.1
entities:
- id: Quote
- id: QuoteProduct
- id: QuotePolicyHolder
- id: QuoteBeneficiary
- id: QuoteFinancialDetail
- id: QuoteTranche
badges:
- content: Core Domain
backgroundColor: blue
textColor: white
---
## Overview
The Quote Domain is the bounded context within the Capstone PAS responsible for managing insurance quotes. It handles the complete quote lifecycle from initial creation through finalisation and conversion to a policy.
## Key Responsibilities
- **Quote Lifecycle Management**: Create, accept, finalise, cancel, and expire quotes
- **Product Configuration**: Add, update, and remove products from quotes
- **Optional Benefit Management**: Add and remove optional benefits on quote products
- **Policyholder Capture**: Collect and validate policyholder personal details
- **Beneficiary Management**: Add, update, and remove beneficiaries on quote products
- **Collection Details**: Capture bank account and payment method information
- **Verification Workflows**: Configure and track verification requirements
- **Terms and Conditions**: Accept terms and conditions for quote finalisation
- **Cover Start Date**: Set and manage quote cover start dates
- **Sales Agent Capture**: Capture sales agent information for the quote
- **Replacement Cover**: Capture replacement cover details for products
- **Pricing Integration**: Calculate premiums based on product configuration and risk factors
- **Quote Conversion**: Convert finalised quotes to active policies
- **Document Management**: Upload and manage quote-related documents
## Aggregate Root
The **Quote** entity serves as the aggregate root, ensuring consistency across all quote operations. All changes to products, beneficiaries, and financial details flow through the Quote aggregate.
## Hexagonal Architecture
The Quote domain implements a clean hexagonal (ports and adapters) architecture with three distinct layers:
```mermaid
flowchart TB
subgraph External["External Systems"]
API["API Gateway"]
EB["EventBridge"]
KIN["Kinesis"]
SQS["SQS Queues"]
end
subgraph Infrastructure["Infrastructure Layer"]
direction TB
LH["Lambda Handlers"]
KP["Kinesis Publisher"]
EBP["EventBridge Publisher"]
DR["DynamoDB Repository"]
HP["HTTP Adapters"]
end
subgraph Application["Application Layer"]
direction TB
CH["Command Handlers"]
QH["Query Handlers"]
ES["Enrichment Services"]
DEC["Decorators"]
end
subgraph Domain["Domain Layer"]
direction TB
AGG["Quote Aggregate Root"]
VO["Value Objects"]
DE["Domain Events"]
INV["Invariants & Rules"]
CF["Command Factories"]
end
API --> LH
SQS --> LH
LH --> CH
LH --> QH
CH --> ES
ES --> HP
CH --> AGG
QH --> DR
AGG --> DE
AGG --> INV
AGG --> VO
DE --> KP
DE --> EBP
KP --> KIN
EBP --> EB
DR --> AGG
style Domain fill:#e1f5fe,stroke:#01579b
style Application fill:#fff3e0,stroke:#e65100
style Infrastructure fill:#f3e5f5,stroke:#4a148c
style External fill:#e8f5e9,stroke:#1b5e20
```
**Layer Responsibilities:**
- **Domain Layer**: Pure business logic - aggregates, value objects, domain events, and business rules (invariants)
- **Application Layer**: Orchestration - command/query handlers, enrichment services, and cross-cutting concerns via decorators
- **Infrastructure Layer**: Technical adapters - Lambda handlers, repositories (DynamoDB), event publishers (Kinesis/EventBridge), HTTP clients
## Domain Events
The Quote Domain emits domain events covering:
- **Lifecycle changes**: QuoteCreatedEvent, QuoteFinalisedEvent, QuoteConvertedEvent, QuoteExpiredEvent
- **Policyholder capture**: PolicyHolderAddedToQuoteEvent
- **Resume workflow**: ResumeLinkAddedToQuoteEvent
## Entity Relationships
---
id: Trustflow
name: Trustflow
version: 0.0.1
summary: |
Domain for verification and trust-related services.
Manages identity verification, document validation, and trust scoring across the platform.
owners:
- digisure-engineering
domains:
- id: Verifications
version: 0.0.1
badges:
- content: Trust Domain
backgroundColor: blue
textColor: white
---
## Overview
Trustflow is a comprehensive domain for verification and trust-related services across the platform. It provides the core infrastructure for establishing and maintaining trust through:
- Identity verification workflows
- Document validation and processing
- Trust scoring mechanisms
- Verification status management
- Cross-platform trust integration
## Subdomains
The Trustflow domain is organized into bounded contexts:
- **Verifications** - Core verification aggregate management including identity checks, document validation, and verification workflows
## Architecture
The system follows an event-driven architecture using:
- **Event Sourcing** for verification state management
- **CQRS** for read/write separation
- **Kinesis** for event streaming
- **Domain-Driven Design** for bounded context organization
---
id: Verifications
name: Verifications Domain
version: 0.0.1
summary: |
Core verification domain handling party verification workflows including identity verification,
bank account verification, and sanctions screening through external providers.
owners:
- digisure-engineering
services:
- id: VerificationService
version: 0.0.1
entities:
- id: Party
- id: VerificationRequest
- id: VerificationResult
badges:
- content: Core Domain
backgroundColor: blue
textColor: white
---
## Overview
The Verifications Domain is a bounded context within the Trustflow domain responsible for verifying party information through external providers. It acts as a command gateway that orchestrates verification requests across multiple verification types and external services.
## Key Responsibilities
- **Personal Details Verification (VOPD)**: Verify identity documents and personal information through Astute
- **Bank Account Verification**: Validate bank account details and ownership through QLink
- **Sanctions Screening**: Screen parties against watchlists and sanctions lists through ORMS
## Verification Types
| Type | Provider | Description |
|------|----------|-------------|
| VERIFICATION_OF_PERSONAL_DETAILS | Astute | Validates identity number, name, and deceased status |
| VERIFICATION_OF_BANK_DETAILS | QLink | Validates bank account ownership and account status |
| SANCTIONS_SCREENING | ORMS | Screens party against global sanctions and watchlists |
## Architecture
The service implements a **Command Gateway** pattern:
1. **Receive**: Accept `VerifyPartyCommandV1` from upstream services
2. **Route**: Route to appropriate adapter based on verification type
3. **Execute**: Call external provider APIs
4. **Publish**: Emit verification result events (Success, SoftFail, HardFail)
## Adapter Pattern
Each external provider has a dedicated adapter implementing:
- Command enrichment with provider-specific data
- Request mapping to provider API format
- Response parsing and result determination
- Event publishing for verification outcomes
## Domain Events
The Verification Service emits 6 core events:
- `VerificationSucceededEventV1` - Verification passed successfully
- `VerificationSoftFailEventV1` - Verification failed but is retryable
- `VerificationHardFailEventV1` - Verification failed permanently
- `OrmsScreeningCompletedEventV1` - ORMS initial screening completed
- `OrmsDecisionPendingEventV1` - Case requires manual analyst review
- `OrmsDecisionFoundEventV1` - Analyst decision received for pending case
## Entity Relationships
---
id: digisure-engineering
name: Digisure Engineering
summary: Engineering team responsible for the Capstone Policy Administration System
members:
- jannikrichter
email: engineering@digisure.co.za
slackDirectMessageUrl: https://sanlam.slack.com/channels/digisure-engineering
---
The Digisure Engineering team is responsible for building and maintaining the Capstone Policy Administration System (PAS), which handles funeral insurance policies including policy lifecycle management, premium collection, beneficiary management, and verification workflows.
## Responsibilities
- Policy Service development and maintenance
- Event-driven architecture implementation
- Domain modeling and bounded context design
- Integration with external verification and collection systems
---
id: Address
name: Address
version: 1.0.0
summary: Postal or residential address captured for an identity.
properties:
- name: streetAddress
type: String
required: true
description: Primary street address line
- name: unitName
type: Optional
required: false
description: Optional unit or complex name
- name: unitNumber
type: Optional
required: false
description: Optional unit number
- name: suburb
type: String
required: true
description: Suburb or locality
- name: city
type: String
required: true
description: City or town
- name: region
type: Optional
required: false
description: Optional region or district
- name: provinceOrState
type: String
required: true
description: Province or state
- name: postalCode
type: String
required: true
description: Postal or ZIP code
- name: countryCode
type: CountryCode
required: true
description: Country code
---
## Overview
The **Address** value object represents a structured postal or residential address used in identity records.
## Notes
- Optional fields are represented as empty values when not provided.
- The `countryCode` follows the ISO country code used in the domain.
---
id: AuditDetails
name: Audit Details
version: 1.0.0
summary: Audit trail information for tracking changes to identity records.
properties:
- name: user
type: string
required: true
description: The identifier of the user who made the change
- name: updatedAt
type: DateTime
required: true
description: The timestamp when the change was made
- name: changeReason
type: string
required: false
description: The reason for the change
- name: changeCommand
type: string
required: false
description: The command that triggered the change
---
## Overview
The **Audit Details** value object captures audit trail information for changes to identity records. Each modification to an entity creates an audit entry, enabling compliance and debugging.
## Structure
```json
{
"user": "system@digisure.com",
"updatedAt": "2024-01-15T10:30:00Z",
"changeReason": "Customer requested update",
"changeCommand": "UpdateCustomerNameIdentity"
}
```
## Fields
| Field | Description |
|-------|-------------|
| user | System user or service account that made the change |
| updatedAt | ISO 8601 timestamp of the change |
| changeReason | Optional human-readable reason for the change |
| changeCommand | The command name that triggered the change |
## Usage
Audit details are stored as a list on aggregate roots:
- GlobalIdentity
- UnverifiedIdentity
- CustomerProfile
This enables a complete history of changes for compliance and debugging purposes.
---
id: AwsCredentials
name: AWS Credentials
version: 1.0.0
identifier: accessKeyId
aggregateRoot: false
summary: AWS IAM credentials used for SigV4 request signing to authenticate with AWS API Gateway.
properties:
- name: accessKeyId
type: string
required: true
description: AWS access key ID for the IAM user or role
- name: secretAccessKey
type: string
required: true
description: AWS secret access key (sensitive, stored in secrets manager)
- name: sessionToken
type: string
required: false
description: AWS session token for temporary credentials (STS)
---
## Overview
The **AwsCredentials** entity represents the AWS IAM credentials required for signing requests to AWS API Gateway using SigV4. The BFF Web service uses these credentials to authenticate proxy requests to the backend BFF API.
## Credential Resolution
Credentials are resolved from multiple sources in priority order:
1. **Secrets Store (AWS_SIGV4_CONFIG_JSON)** - JSON object in Cloudflare secrets
2. **Environment Variables** - Direct environment variable binding
3. **Generated Defaults** - From partner configuration
## Security Considerations
- **Never log credentials** - The service redacts credentials in debug logs
- **Use temporary credentials** - Session tokens from STS are preferred
- **Rotate regularly** - Credentials should be rotated per security policy
- **Least privilege** - IAM user should only have execute-api:Invoke permission
## Credential Types
### Long-term Credentials
```
accessKeyId: AKIAIOSFODNN7EXAMPLE
secretAccessKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```
### Temporary Credentials (STS)
```
accessKeyId: ASIAIOSFODNN7EXAMPLE
secretAccessKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
sessionToken: FwoGZXIvYXdzEBYaDCvP...
```
## Related Configuration
| Setting | Description |
|---------|-------------|
| `awsSigv4Enabled` | Master toggle for SigV4 signing |
| `awsRegion` | AWS region for signing (default: eu-west-1) |
| `awsService` | AWS service name (default: execute-api) |
---
id: BankDetails
name: BankDetails
version: 1.0.0
summary: Bank account details used for premium collection.
properties:
- name: bankAccountName
type: String
required: false
description: Name on the bank account
- name: bankName
type: String
required: false
description: Bank name
- name: bankAccountNumber
type: String
required: false
description: Bank account number
- name: bankBranch
type: String
required: false
description: Bank branch or branch code
- name: accountType
type: String
required: false
description: Account type
---
## Overview
The **BankDetails** value object stores the account information required to process collections for a policy.
---
id: Beneficiary
name: Beneficiary
version: 1.0.0
identifier: beneficiaryId
summary: Person who receives a benefit allocation on a product.
properties:
- name: beneficiaryId
type: BeneficiaryId
required: true
description: Unique identifier for the beneficiary
- name: name
type: String
required: false
description: Given name derived from unverified identity
- name: surname
type: String
required: false
description: Family name derived from unverified identity
- name: dateOfBirth
type: LocalDate
required: false
description: Date of birth derived from unverified identity
- name: gender
type: Gender
required: false
description: Gender derived from unverified identity
- name: identification
type: Identification
required: false
description: Identity document details derived from unverified identity
- name: emailAddress
type: EmailAddress
required: false
description: Email address derived from unverified identity
- name: mobileNumber
type: MobileNumber
required: false
description: Mobile number derived from unverified identity
- name: percentageAllocation
type: Percentage
required: false
description: Allocation percentage for this beneficiary
- name: lastActiveDate
type: Instant
required: false
description: Date when the beneficiary was last active
- name: isActive
type: Boolean
required: true
description: Whether the beneficiary is active
---
## Overview
The **Beneficiary** entity represents a covered beneficiary for a policy product. It inherits party information from an unverified identity and adds allocation details.
---
id: BundleProduct
name: Bundle Product
version: 1.0.0
identifier: productId
aggregateRoot: false
summary: A product definition within a bundle configuration that specifies coverage rules.
properties:
- name: productId
type: UUID
required: true
description: Unique identifier for the product
- name: productShortCode
type: string
required: true
description: Short code for product mapping (e.g., MAIN, SPOUSE, CHILD)
- name: rules
type: BundleProductRules
required: false
description: Product-specific rules for coverage and validation
references: BundleProductRules
---
## Overview
The **BundleProduct** entity defines a specific insurance product included in a bundle configuration. It contains the product identifier, a short code for mapping during redemption, and rules that govern coverage percentages based on the relationship to the main life.
## Properties
| Property | Type | Description |
|----------|------|-------------|
| productId | UUID | Unique identifier for the product |
| productShortCode | string | Short code for product mapping |
| rules | BundleProductRules | Coverage and validation rules |
## Rules Structure
The `rules` object (BundleProductRules) contains:
| Rule | Description |
|------|-------------|
| relationshipToMainTypes | Allowed relationship types (MAIN, SPOUSE, CHILD, etc.) |
| fieldRules | Required field validations (MUST_HAVE_DATE_OF_BIRTH, etc.) |
| maxAllowedBeneficiaries | Maximum beneficiaries per product (null = unlimited) |
| coverPercentagesByRelationship | Cover percentage allocation by relationship |
## Relationship to Bundle Config
BundleProduct is a child entity of ProductBundleConfig. A bundle configuration contains one or more products, each defining what insurance products are available when the bundle is redeemed.
## Example
```json
{
"productId": "460604d5-859f-4855-ad48-d61d17dcb8fc",
"productShortCode": "MAIN",
"rules": {
"relationshipToMainTypes": [
{ "relationships": ["MAIN"], "allowedAmount": 1 }
],
"fieldRules": ["MUST_HAVE_DATE_OF_BIRTH", "MUST_HAVE_IDENTITY"],
"maxAllowedBeneficiaries": 10,
"coverPercentagesByRelationship": {
"MAIN": 100
}
}
}
```
---
id: Calculation
name: Calculation
version: 1.0.0
identifier: calculationId
summary: A pricing calculation request and result containing input values and computed outputs.
owners:
- digisure-engineering
properties:
- name: calculationId
type: CalculationId
required: true
description: Unique identifier for this calculation (extends Entity)
- name: calculatorInstanceIds
type: array
required: true
description: List of calculator instances to execute in sequence
items:
type: CalculatorInstanceId
- name: queryInstanceIds
type: array
required: false
description: List of query instances for dynamic data lookup (factor tables, rates)
items:
type: QueryInstanceId
- name: valuesMap
type: Map
required: true
description: Input values and calculated intermediate results (key-value pairs)
- name: cover
type: BigDecimal
required: false
description: Cover amount - can be input for premium calculation or output of cover calculation
- name: premium
type: BigDecimal
required: false
description: Premium amount - can be input for cover calculation or output of premium calculation
relationships:
- type: uses
target: Calculator
description: Calculation uses one or more calculator instances
- type: aggregatedBy
target: CalculationResults
description: Multiple calculations are aggregated into CalculationResults
---
## Overview
The **Calculation** entity represents a single pricing calculation, containing both the input parameters and the calculated results. Multiple calculations can be batched together for efficient processing.
## Lifecycle
```
Request → Validation → Configuration Load → Calculation → Result
```
1. **Request**: Client submits calculation with inputs
2. **Validation**: Inputs are validated
3. **Configuration Load**: Calculator and query configs are loaded
4. **Calculation**: Formula is executed
5. **Result**: Outputs are returned with intermediate values
## Values Map
The `valuesMap` serves dual purposes:
### Input Values
```json
{
"age": 35,
"gender": "MALE",
"relationship": "MAIN",
"coverAmount": 5000000
}
```
### Calculated Values (Added During Processing)
```json
{
"age": 35,
"gender": "MALE",
"relationship": "MAIN",
"coverAmount": 5000000,
"baseQxFactor": 0.00156,
"aidsQxFactor": 0.00078,
"lifeQx": 0.00234,
"annualPremium": 1800.00,
"monthlyPremium": 150.00
}
```
## Calculation Results
Results are aggregated in `CalculationResults`:
```java
public class CalculationResults {
private final List calculations;
private final BigDecimal totalCover;
private final BigDecimal totalPremium;
}
```
Example JSON response:
```json
{
"calculations": [...],
"totalCover": 10000000,
"totalPremium": 300.00
}
```
## Dynamic Query Support
Calculations can reference dynamic queries:
| Query Type | Purpose |
|------------|---------|
| Factor Lookup | Load age/gender-specific factors |
| Rate Tables | Access mortality and expense tables |
| Partner Config | Load partner-specific settings |
## Usage Patterns
### Single Product Pricing
```json
{
"calculations": [
{
"id": "main-life",
"calculatorInstanceIds": [{"value": "main-life-v1"}],
"valuesMap": {"age": 35, "coverAmount": 5000000}
}
]
}
```
### Multi-Product Pricing
```json
{
"calculations": [
{"id": "main-life", ...},
{"id": "spouse", ...},
{"id": "child-1", ...}
]
}
```
### Benefit Add-ons
```json
{
"calculations": [
{"id": "main-life", ...},
{"id": "repatriation", "calculatorInstanceIds": [{"value": "repatriation-v1"}], ...}
]
}
```
---
id: CalculationResults
name: Calculation Results
version: 1.0.0
identifier: N/A
summary: Aggregate containing multiple calculation results with totals for cover and premium amounts.
owners:
- digisure-engineering
properties:
- name: calculations
type: List
required: true
description: List of individual calculation results
- name: totalCover
type: BigDecimal
required: true
description: Sum of all cover amounts from calculations
- name: totalPremium
type: BigDecimal
required: true
description: Sum of all premium amounts from calculations
relationships:
- type: aggregates
target: Calculation
description: Aggregates multiple Calculation entities
---
## Overview
The **CalculationResults** entity represents the aggregate response from a pricing calculation request. It contains multiple individual calculations along with their aggregated totals, making it easy to get both detailed and summary information from a single request.
## Structure
```java
@Getter
@AllArgsConstructor
@Builder
public class CalculationResults {
private final List calculations;
private final BigDecimal totalCover;
private final BigDecimal totalPremium;
}
```
## Example Response
```json
{
"calculations": [
{
"id": "main-life",
"calculatorInstanceIds": [{"value": "main-life-v1"}],
"valuesMap": {
"age": 35,
"gender": "MALE",
"relationship": "MAIN",
"coverAmount": 5000000,
"monthlyPremium": 150.00
},
"cover": 5000000,
"premium": 150.00
},
{
"id": "spouse",
"calculatorInstanceIds": [{"value": "covered-life-v1"}],
"valuesMap": {
"age": 33,
"gender": "FEMALE",
"relationship": "SPOUSE",
"coverAmount": 3000000,
"monthlyPremium": 80.00
},
"cover": 3000000,
"premium": 80.00
}
],
"totalCover": 8000000,
"totalPremium": 230.00
}
```
## Use Cases
### Multi-Life Pricing
When pricing a family funeral policy with multiple covered lives, each life is calculated separately and the results are aggregated:
- Main Life: R5,000,000 cover @ R150/month
- Spouse: R3,000,000 cover @ R80/month
- Total: R8,000,000 cover @ R230/month
### Product Bundle Pricing
When pricing a product bundle with multiple benefits:
- Life Cover: R500,000 @ R120/month
- Accidental Benefit: R100,000 @ R15/month
- Repatriation: R50,000 @ R5/month
- Total: R650,000 cover @ R140/month
## Calculation Flow
```
PerformCalculationQuery
|
v
[Calculation 1] --> Calculator --> Result
[Calculation 2] --> Calculator --> Result
[Calculation N] --> Calculator --> Result
|
v
CalculationResults (aggregated)
```
---
id: Calculator
name: Calculator
version: 1.0.0
identifier: calculatorId
summary: A pricing calculation component that implements specific actuarial formulas for insurance premium and cover calculations.
owners:
- digisure-engineering
properties:
- name: calculatorId
type: CalculatorId
required: true
description: Unique identifier for the calculator type (e.g., MAIN_LIFE, COVERED_LIFE, DYNAMIC)
- name: calculatorInstanceId
type: CalculatorInstanceId
required: true
description: Unique identifier for this specific calculator instance/configuration
- name: calculatorName
type: string
required: true
description: Human-readable name of the calculator
- name: partnerId
type: PartnerId
required: false
description: Partner this calculator is configured for (required for dynamic calculators)
- name: version
type: integer
required: true
description: Version of the calculator configuration
- name: calculationConfigs
type: array
required: false
description: Configuration for dynamic calculations (only for dynamic calculator type)
items:
type: CalculationConfig
- name: roundingConfig
type: RoundingConfig
required: false
description: Rounding rules for calculation results (cover and premium)
relationships:
- type: uses
target: PricingConfiguration
description: Calculator uses pricing configuration to obtain actuarial factors
- type: produces
target: Calculation
description: Calculator produces calculation results
---
## Overview
The **Calculator** entity represents a pricing calculation component. Calculators implement specific formulas for different product types and can be either built-in (Java classes) or dynamically configured through expressions.
## Calculator Types
### Built-in Calculators
| Calculator | Purpose | Formula Type |
|------------|---------|--------------|
| MainLifeCalculator | Primary insured premium | Full pricing formula |
| CoveredLifeCalculator | Extended family premium | Simplified formula |
| AccidentalCalculator | Accidental death benefit | Benefit-based |
| AccidentalOnlyCalculator | Short-term accidental | Factor-based |
| RepatriationCalculator | Repatriation benefit | Fixed amount add-on |
| StillBirthAndNewBornCalculator | Stillbirth/newborn benefit | Fixed amount add-on |
### Dynamic Calculators
Dynamic calculators are configured through:
```json
{
"calculatorInstanceId": "partner-custom-v1",
"calculatorId": "DYNAMIC",
"calculatorName": "Partner Custom Calculator",
"calculationConfigs": [
{
"name": "monthlyPremium",
"expression": {
"type": "OPERATION",
"operator": "MULTIPLY",
"operands": [...]
}
}
],
"roundingConfig": {
"scale": 2,
"mode": "HALF_UP"
}
}
```
## Calculator Interface
All calculators implement:
```java
interface Calculator {
BigDecimal performCalculation(CalculationParameters data, CoverAmount cover, Boolean fixedPrice);
BigDecimal performCalculation(CalculationParameters data, PremiumAmount premium, Boolean fixedPrice);
PremiumAmount performBenefitCalculation(PolicyBenefitConfig config, PremiumAmount premium);
}
```
## Calculation Parameters
Calculators receive standardized parameters through the `CalculationParameters` record:
| Parameter | Type | Description |
|-----------|------|-------------|
| accidentalFactor | BigDecimal | Accidental death multiplier |
| pricingFactorsValue | PricingFactorCalculationParameter | Base, AIDS, constant factors |
| baseQxFactor | BigDecimal | Base mortality rate (QX) |
| aidsQxFactor | BigDecimal | AIDS mortality adjustment |
| underWritingExpense | BigDecimal | Underwriting cost |
| durationFactor | BigDecimal | Duration-based factor |
| initialExpense | BigDecimal | Initial setup expense |
| recurringExpense | BigDecimal | Recurring administrative expense |
| topUpExpenseFactor | BigDecimal | Top-up expense adjustment |
| expenseLoading | BigDecimal | Expense percentage loading |
| rewardExpenseValue | BigDecimal | Rewards program cost |
| intermediaryDiscount | BigDecimal | Intermediary discount rate |
| asAndWhenCommission | BigDecimal | As-and-when commission rate |
| difLoading | BigDecimal | Distribution Incentive Fund loading |
| distributionRate | BigDecimal | Combined distribution cost |
| initialTargetValue | BigDecimal | Initial profit target |
| factor1Impact | BigDecimal | Factor 1 impact multiplier |
| ageTopUpfactorValue | AgeTopUpCalculationParameter | Age-based loading |
| relationshiopTopUpfactorValue | BigDecimal | Relationship-based loading |
| brokerPercentage | BigDecimal | Broker commission percentage |
## RoundingConfig
Rounding configuration for calculation results:
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| coverScale | int | 0 | Decimal places for cover amounts |
| coverRoundingMode | RoundingMode | HALF_UP | Rounding mode for cover |
| premiumScale | int | 2 | Decimal places for premium amounts |
| premiumRoundingMode | RoundingMode | HALF_UP | Rounding mode for premium |
## CalculationConfig (Dynamic Calculators)
Configuration for a single calculation step in a dynamic calculator:
| Property | Type | Description |
|----------|------|-------------|
| calculationName | string | Name of this calculation step |
| outputVariable | string | Variable name to store the result (e.g., "cover", "premium") |
| calculationExpression | Expression | The expression tree to evaluate |
## Expression Types
Dynamic calculators support multiple expression types:
| Type | Description | Example |
|------|-------------|---------|
| LiteralExpression | Fixed numeric value | `{ "type": "LITERAL", "value": 100 }` |
| VariableExpression | Reference to a variable | `{ "type": "VARIABLE", "name": "age" }` |
| OperationExpression | Arithmetic/conditional operation | `{ "type": "OPERATION", "operation": "multiply", "operands": [...] }` |
### Supported Operations
- **add**: Sum all operands
- **subtract**: Subtract second operand from first
- **multiply**: Multiply all operands
- **divide**: Divide first operand by second
- **if**: Conditional (requires comparator and 4 operands: left, right, then, else)
---
id: Campaign
name: Campaign
version: 1.0.0
identifier: id
summary: Campaign metadata associated with a policy.
properties:
- name: id
type: CampaignId
required: true
description: Unique identifier for the campaign
- name: campaignAppliedDate
type: Instant
required: false
description: When the campaign was applied
- name: campaignTermLimit
type: Integer
required: false
description: Optional term limit applied by the campaign
- name: campaignPartnerId
type: PartnerId
required: false
description: Partner identifier linked to the campaign
- name: isActive
type: Boolean
required: true
description: Whether the campaign is active
---
## Overview
The **Campaign** entity captures campaign attribution data tied to a policy at the time of creation or update.
---
id: CaptchaValidation
name: CAPTCHA Validation
version: 1.0.0
identifier: requestId
aggregateRoot: false
summary: Result of reCAPTCHA v3 token validation for bot protection.
properties:
- name: requestId
type: string
required: true
description: Request ID for correlation
- name: ok
type: boolean
required: true
description: Whether validation passed
- name: provider
type: string
required: true
description: CAPTCHA provider (recaptcha_v3)
- name: score
type: number
required: false
description: Risk score from reCAPTCHA (0.0-1.0)
- name: reason
type: string
required: false
description: Failure reason if validation failed
- name: action
type: string
required: false
description: reCAPTCHA action from token
- name: hostname
type: string
required: false
description: Hostname from reCAPTCHA response
- name: challengeTs
type: string
required: false
description: Timestamp of challenge from reCAPTCHA
---
## Overview
The **CaptchaValidation** entity represents the result of validating a reCAPTCHA v3 token. It captures the validation outcome and provides detailed information for debugging and monitoring.
## Validation Flow
```
1. Extract token from x-recaptcha-token header
2. Check if validation is required:
- Skip if request has Bearer auth
- Skip if GET request to polling endpoint
- Required for POST/PUT/PATCH/DELETE
- Required for GET /api/v1/partner/*
3. Resolve CAPTCHA secret from config/secrets
4. Call Google siteverify API
5. Evaluate response against thresholds
6. Return validation result
```
## Score Interpretation
reCAPTCHA v3 returns a score indicating likelihood of human interaction:
| Score | Interpretation | Typical Action |
|-------|----------------|----------------|
| 0.9+ | Almost certainly human | Allow |
| 0.7-0.9 | Likely human | Allow |
| 0.5-0.7 | Uncertain | Consider additional verification |
| 0.3-0.5 | Likely automated | Block or challenge |
|| <0.3 | Almost certainly bot | Block |
## Failure Reasons
| Reason | Description | Resolution |
|--------|-------------|------------|
| `missing_token` | No token header | Client must provide x-recaptcha-token |
| `missing_secret` | Server not configured | Check RECAPTCHA_SECRET env var |
| `low_score` | Score below threshold | May be bot, or adjust threshold |
| `verification_failed` | Google rejected token | Token may be expired or invalid |
| `action_mismatch` | Wrong action | Client using wrong reCAPTCHA config |
| `hostname_mismatch` | Wrong hostname | Token generated for different domain |
## Bypass Mechanism
For automated testing, a bypass mechanism allows skipping CAPTCHA:
1. Configure `RECAPTCHA_BYPASS_SECRET` environment variable
2. Send `x-recaptcha-bypass` header with the secret value
3. CAPTCHA validation is skipped
This should only be enabled in test environments with proper access controls.
## Advisory Mode
When `recaptchaAdvisory` is enabled:
- Failed validations are logged but don't block requests
- Useful for monitoring before enforcing in production
- Default enabled in non-production environments
---
id: Certificate
name: Certificate
version: 1.0.0
summary: A trust indicator attached to identity attributes, tracking source reliability.
properties:
- name: certificateId
type: UUID
required: true
description: Unique identifier for the certificate
- name: trustLevel
type: number
required: true
description: Numeric trust score (higher is more trusted)
- name: creationTime
type: DateTime
required: true
description: When the certificate was created
---
## Overview
The **Certificate** value object represents the trust level and provenance of an identity attribute. It enables the system to manage conflicting updates from different sources by comparing trust levels.
## Trust Level Rules
1. **Higher trust wins**: An update with a higher trust level certificate can overwrite existing values
2. **Same trust, later wins**: For equal trust levels, the more recent certificate takes precedence
3. **Lower trust rejected**: Updates with lower trust levels are rejected with a failure event
## Trust Level Examples
| Source | Trust Level |
|--------|-------------|
| Self-declaration | 10 |
| Sales agent input | 20 |
| Document upload | 30 |
| Credit bureau check | 40 |
| Government verification | 50 |
## Example
```json
{
"certificateId": "550e8400-e29b-41d4-a716-446655440000",
"trustLevel": 40.0,
"creationTime": "2024-01-15T10:30:00Z"
}
```
## Field Groups
Certificates are associated with field groups:
- `PERSONAL_IDENTITY`: name, gender, dateOfBirth
- `EMAIL_IDENTITY`: emailAddress
- `MOBILE_IDENTITY`: mobileNumber
- `ADDRESS`: address
---
id: Claim
name: Claim
version: 1.0.0
identifier: claimId
summary: A request for benefit payment following the death of a covered life.
properties:
- name: claimId
type: UUID
required: true
description: Unique identifier for the claim
- name: claimNumber
type: string
required: true
description: Human-readable claim reference number
- name: policyId
type: UUID
required: true
description: Associated policy identifier
- name: policyCode
type: string
required: true
description: Associated policy code
- name: status
type: string
required: true
description: Current processing status
enum: ['SUBMITTED', 'IN_ASSESSMENT', 'AWAITING_DOCUMENTS', 'APPROVED', 'REPUDIATED', 'PAID', 'CLOSED']
- name: highLevelStatus
type: string
required: true
description: High-level status category
enum: ['OPEN', 'CLOSED']
- name: stage
type: string
required: true
description: Current workflow stage
- name: dateOfClaim
type: Date
required: true
description: Date the claim was submitted
- name: deceased
type: object
required: true
description: Information about the deceased person
- name: deathDetail
type: object
required: true
description: Details about the death event
- name: claimant
type: object
required: true
description: Person who submitted the claim
- name: claimMethod
type: string
required: true
description: Channel through which claim was submitted
enum: ['PORTAL', 'CALL_CENTER', 'BRANCH', 'EMAIL']
- name: requestOrigin
type: string
required: true
description: System from which claim originated
- name: claimCategory
type: string
required: true
description: Category affecting waiting period application
enum: ['NATURAL', 'ACCIDENTAL']
- name: financialDetail
type: object
required: false
description: Payout calculation results
- name: documents
type: array
required: false
description: Supporting documents
- name: statusHistory
type: array
required: false
description: History of status changes
- name: createdAt
type: DateTime
required: true
description: When the claim was created
---
## Overview
The **Claim** entity represents a request for benefit payment in the BFFASCP domain. It is created when a covered life (main life or extended family member) passes away and tracks the entire claims process from submission through to payment.
## Claim Statuses
| Status | Description |
|--------|-------------|
| SUBMITTED | Initial claim submission received |
| IN_ASSESSMENT | Claim is being reviewed by assessors |
| AWAITING_DOCUMENTS | Additional documentation required |
| APPROVED | Claim approved for payment |
| REPUDIATED | Claim rejected (may be overridden) |
| PAID | Payment has been processed |
| CLOSED | Claim is finalized |
## Claim Categories
| Category | Description | Waiting Period |
|----------|-------------|----------------|
| NATURAL | Natural cause of death | Standard waiting period applies |
| ACCIDENTAL | Accidental death | Reduced or no waiting period |
## Processing Workflow
1. **Submission**: Claim created with death details and claimant info
2. **Document Collection**: Required documents uploaded and verified
3. **Assessment**: Claim validated against policy terms
4. **Payout Calculation**: Benefit amounts calculated
5. **Approval/Repudiation**: Claim decision made
6. **Payment**: Funds transferred to beneficiaries
7. **Closure**: Claim finalized
## Key Relationships
- **Policy**: The associated insurance policy
- **Deceased**: Information about the covered life
- **Claimant**: Person submitting the claim
- **Documents**: Supporting documentation
- **Financial Detail**: Payout calculations
---
id: CollectionAccount
name: Collection Account
version: 1.0.0
summary: A customer's bank account or card details used for premium collection.
properties:
- name: method
type: string
required: true
description: The collection method type
enum: ['BANK_ACCOUNT', 'CARD']
- name: number
type: string
required: true
description: The account or card number (masked)
- name: owner
type: string
required: true
description: The name of the account holder
- name: currency
type: string
required: true
description: The currency code (e.g., ZAR)
- name: country
type: string
required: true
description: The ISO country code
- name: bankCode
type: string
required: false
description: The bank code or BIC for bank accounts
- name: expirationDate
type: Date
required: false
description: The expiration date for cards
- name: securityCode
type: string
required: false
description: The card security code (masked/encrypted)
- name: accountType
type: string
required: false
description: The type of bank account (e.g., SAVINGS, CHEQUE)
---
## Overview
The **Collection Account** value object represents a customer's payment details used for premium collection. It supports both bank accounts and credit/debit cards.
## Collection Methods
| Method | Description |
|--------|-------------|
| BANK_ACCOUNT | Direct debit from a bank account |
| CARD | Credit or debit card payment |
## Bank Account Example
```json
{
"method": "BANK_ACCOUNT",
"number": "****5678",
"owner": "John Doe",
"currency": "ZAR",
"country": "ZA",
"bankCode": "ABSA",
"accountType": "CHEQUE"
}
```
## Card Example
```json
{
"method": "CARD",
"number": "****1234",
"owner": "John Doe",
"currency": "ZAR",
"country": "ZA",
"expirationDate": "2026-12-31"
}
```
## Security
- Account numbers are stored in masked format
- Full numbers are only used during transaction processing
- Security codes are encrypted and never displayed
---
id: CollectionDetails
name: CollectionDetails
version: 1.0.0
summary: Details of a premium collection attempt including status, outcome, and retry information.
properties:
- name: collectionEffectiveDate
type: LocalDate
required: true
description: The effective date of the collection attempt
- name: collectionRequestOutcome
type: CollectionRequestOutcome
required: true
description: The outcome of the collection request (SUCCESS, FAILED, PENDING)
- name: collectionStatus
type: CollectionStatus
required: true
description: Current status of the collection
- name: collectionStatusReason
type: String
required: false
description: Reason for the current collection status
- name: collectionConsecutiveFails
type: Integer
required: false
description: Number of consecutive failed collection attempts
- name: collectionConsecutiveSuccesses
type: Integer
required: false
description: Number of consecutive successful collection attempts
- name: retriesMade
type: Integer
required: false
description: Number of retry attempts made for this collection
- name: createdAt
type: Instant
required: true
description: Timestamp when the collection details were created
---
## Overview
The **CollectionDetails** value object captures the state and history of a premium collection attempt. It tracks the outcome, consecutive success/failure counts, and retry information.
## Collection Flow
1. Collection is initiated on the `collectionEffectiveDate`
2. The `collectionRequestOutcome` indicates immediate result
3. `collectionStatus` reflects the final state after processing
4. Failed collections increment `collectionConsecutiveFails` and may trigger retries
## Grace Period Integration
Consecutive failures are tracked to determine when a policy enters grace period or lapses. The `collectionConsecutiveFails` counter is used by policy health checks.
---
id: CollectionSchedule
name: CollectionSchedule
version: 1.0.0
identifier: scheduleId
summary: A schedule instance linked to a policy's collection preferences.
properties:
- name: scheduleId
type: UUID
required: true
description: Unique identifier for the schedule
- name: createdAt
type: Instant
required: false
description: When the schedule was created
- name: isActive
type: boolean
required: true
description: Whether the schedule is active
- name: scheduleActivatedAt
type: Instant
required: false
description: When the schedule was activated
---
## Overview
The **CollectionSchedule** record represents a schedule instance captured for a policy's collections.
---
id: CorsSettings
name: CORS Settings
version: 1.0.0
identifier: partnerId
aggregateRoot: false
summary: Cross-Origin Resource Sharing configuration controlling which web origins can access the API.
properties:
- name: allowedOrigins
type: array
required: true
description: List of allowed origins (e.g., https://example.com)
- name: allowedMethods
type: string
required: true
description: Comma-separated HTTP methods (GET,POST,PUT,DELETE,OPTIONS)
- name: allowedHeaders
type: array
required: true
description: List of headers clients are allowed to send
- name: maxAge
type: integer
required: true
description: Preflight cache duration in seconds (default 86400)
- name: devExtensionPassthru
type: boolean
required: true
description: Allow all origins in development mode
---
## Overview
The **CorsSettings** entity defines the Cross-Origin Resource Sharing (CORS) policy for the BFF Web service. CORS controls which web browser origins are permitted to make requests to the API.
## Default Allowed Headers
The service allows these headers by default:
- `authorization` - Bearer tokens and API keys
- `content-type` - Request body format
- `x-request-id` - Client correlation ID
- `x-client-id` - Client application identifier
- `x-authorization` - Forwarded authorization for SigV4
- `x-recaptcha-token` - CAPTCHA validation token
Additional headers can be requested via `Access-Control-Request-Headers` in preflight requests.
## Origin Validation
Origins are validated by exact match including protocol:
```
Allowed: https://sanlamonline.co.za
Request: https://sanlamonline.co.za -> ALLOWED
Request: http://sanlamonline.co.za -> DENIED (wrong protocol)
Request: https://evil.com -> DENIED (not in list)
```
## Preflight Handling
When a browser sends an OPTIONS request:
1. Extract requested method and headers
2. Check origin against allowed list
3. Return 204 with appropriate CORS headers
4. Cache preflight for maxAge seconds
## Response Headers Applied
All responses include these CORS headers:
| Header | Value |
|--------|-------|
| `Access-Control-Allow-Origin` | Matched origin or omitted |
| `Access-Control-Allow-Methods` | Requested or default methods |
| `Access-Control-Allow-Headers` | Merged header list |
| `Access-Control-Max-Age` | 86400 (preflight only) |
| `Vary` | Origin, Access-Control-Request-* |
## Development Mode
When `devExtensionPassthru` is enabled:
- Any origin is allowed with `Access-Control-Allow-Origin: *`
- Useful for local development and testing
- **Must never be enabled in production**
---
id: Credits
name: Credits
version: 1.0.0
summary: Record of a credit entry on a policy's financial ledger.
properties:
- name: creditEntryDate
type: Instant
required: true
description: When the credit was recorded in the system
- name: creditDate
type: Instant
required: true
description: Effective date of the credit
- name: creditAmount
type: BigDecimal
required: true
description: Amount of the credit in ZAR
- name: creditType
type: CreditAndDebitType
required: true
description: Type of credit (COLLECTION, REFUND, ADJUSTMENT, etc.)
- name: creditExternalReference
type: String
required: false
description: External reference number (e.g., bank transaction ID)
- name: collectionId
type: String
required: false
description: Link to the collection that generated this credit
---
## Overview
The **Credits** value object represents money received on a policy. This includes premium collections, refunds, and manual adjustments. Credits are tracked in the `PolicyFinancialDetail` entity.
## Credit Types
| Type | Description |
|------|-------------|
| COLLECTION | Premium payment received |
| REFUND | Refund from prior overpayment |
| ADJUSTMENT | Manual adjustment by admin |
| REVERSAL | Reversal of prior debit |
## Audit Trail
Each credit maintains a link to its source through `collectionId` and `creditExternalReference`, enabling full audit trails and reconciliation.
---
id: CurrencyConfiguration
name: Currency Configuration
version: 1.0.0
summary: Currency settings for monetary calculations on a quote.
properties:
- name: defaultCurrency
type: string
required: true
description: ISO 4217 currency code (e.g., ZAR, USD)
- name: currencyRoundingRules
type: CurrencyRoundingRules
required: false
description: Rules for rounding monetary amounts
properties:
- name: roundingMode
type: RoundingMode
required: false
description: Rounding mode (e.g., HALF_UP, HALF_DOWN)
- name: decimalPlaces
type: integer
required: false
description: Number of decimal places for rounding
---
## Overview
The **CurrencyConfiguration** record defines currency settings for a partner, including the default currency and rounding rules for monetary calculations.
## Default Currency
The default currency is used for all Money value objects on the quote. For South African insurance products, this is typically ZAR.
## Rounding Rules
Rounding rules control how monetary amounts are rounded during calculations:
| Rounding Mode | Description |
|---------------|-------------|
| HALF_UP | Round towards nearest neighbor, rounding up on .5 |
| HALF_DOWN | Round towards nearest neighbor, rounding down on .5 |
| UP | Round away from zero |
| DOWN | Round towards zero |
## Usage
Currency configuration is:
- Defined at the partner level
- Copied to quotes upon creation
- Used by pricing calculations for consistent rounding
- Applied when calculating premiums, cover amounts, and totals
---
id: Customer
name: Customer
version: 1.0.0
identifier: globalCustomerId
aggregateRoot: true
summary: The central aggregate root representing a unified customer view across quotes and policies.
properties:
- name: globalCustomerId
type: string
required: true
description: Unique global identifier for the customer (derived from policy holder ID)
- name: isActive
type: boolean
required: true
description: Whether the customer record is active
- name: quoteIds
type: array
required: false
description: Set of quote IDs associated with this customer
items:
type: string
format: uuid
- name: policies
type: array
required: false
description: Set of policies associated with this customer
references: CustomerPolicy
referencesIdentifier: policyId
relationType: hasMany
- name: processedEvents
type: object
required: false
description: Map of event keys to logical clock readings for idempotency tracking
---
## Overview
The **Customer** entity is the aggregate root of the CustomerDP domain. It represents a unified view of a customer across all their interactions with the insurance platform, including quotes and policies.
## Identity
The customer is identified by their **Global Customer ID (GCID)**, which is derived from the policy holder's identification. This allows the system to recognize the same person across different quotes and policies.
## Event Application
The Customer aggregate applies domain events through dedicated methods:
| Method | Event | Effect |
|--------|-------|--------|
| `apply(PolicyHolderAddedToQuoteEvent)` | Quote created | Associates quote with customer |
| `apply(PolicyCreatedEvent)` | Policy created | Removes quote, adds policy |
| `apply(PolicyCancelledEvent)` | Policy cancelled | Updates policy status to CANCELLED |
| `apply(PolicyExpiredEvent)` | Policy expired | Updates policy status to EXPIRED |
| `apply(PolicyVerificationCompletedEvent)` | Verification done | Updates policy status |
## Idempotency
The Customer extends `DataProduct` which provides idempotent event processing:
- Each event has a logical clock reading
- Processed events are tracked in `processedEvents` map
- Events with lower or equal clock readings are skipped
- This ensures exactly-once semantics even with event replay
## Invariants
- A customer can have at most one active quote at a time
- Quote IDs are removed when converted to policies
- Policy status updates require the policy to exist on the customer
- All events require non-null policy/quote IDs
## Entity Relationships
```
Customer (1) ──── hasMany ────> (N) CustomerPolicy
│
└──── hasMany ────> (N) QuoteId (value objects)
```
---
id: CustomerIdentity
name: Customer Identity
version: 1.0.0
identifier: globalCustomerId
summary: The verified identity information associated with a customer, created from authoritative sources.
properties:
- name: globalCustomerId
type: UUID
required: true
description: Global Customer ID linking to the canonical identity
- name: certifiedIssuedIdentity
type: object
required: true
description: Verified issued identity with certificate
- name: certifiedPersonName
type: object
required: true
description: Verified person name with certificate
- name: certifiedMobileNumber
type: object
required: false
description: Verified mobile number with certificate
- name: certifiedEmailAddress
type: object
required: false
description: Verified email address with certificate
- name: certifiedAddress
type: object
required: false
description: Verified address with certificate
- name: certifiedDateOfBirth
type: object
required: false
description: Verified date of birth with certificate
- name: certifiedGender
type: object
required: false
description: Verified gender with certificate
- name: certificateIds
type: array
required: true
description: List of certificate IDs used to verify this identity
---
## Overview
The **Customer Identity** represents verified customer information created from authoritative sources. Each attribute is paired with a certificate that tracks the verification source and trust level.
## Certified Attributes
All attributes are wrapped in a certified structure containing:
- The attribute value
- A certificate with trust level, creation time, and certificate ID
## Required vs Optional
- **Required**: Issued Identity, Person Name
- **Optional**: Mobile Number, Email Address, Address, Date of Birth, Gender
## Trust Management
Customer Identities are created with certificates that establish baseline trust levels. These certificates enable the Global Identity to accept or reject future updates based on trust level comparisons.
---
id: CustomerPolicy
name: CustomerPolicy
version: 1.0.0
identifier: policyId
summary: A policy reference within the customer aggregate, containing essential policy information.
properties:
- name: policyId
type: string
required: true
format: uuid
description: Unique identifier for the policy
references: Policy
referencesIdentifier: policyId
- name: policyCode
type: object
required: true
description: Human-readable policy code
properties:
- name: value
type: string
description: The policy code value
- name: policyCreatedAt
type: DateTime
required: true
description: Timestamp when the policy was created
- name: partnerId
type: string
required: false
description: Unique identifier for the partner
- name: packageId
type: string
required: false
description: Unique identifier for the package
- name: policyStatus
type: string
required: true
description: Current status of the policy
enum: ['NOT_TAKEN_UP', 'NEW', 'ACTIVE', 'PENDING_VERIFICATION', 'PENDING_FIRST_PAYMENT', 'PENDING_MAKE_UP_PAYMENT', 'CANCELLED', 'LAPSED', 'EXPIRED', 'PAUSED']
---
## Overview
The **CustomerPolicy** entity represents the association between a customer and their insurance policy within the CustomerDP domain. It contains a subset of policy information relevant to the customer view, enabling efficient customer-centric queries without requiring full policy details.
## Purpose
CustomerPolicy serves as a denormalized projection of policy data optimized for:
- Quick lookup of all policies for a customer
- Status tracking across multiple policies
- Customer analytics and reporting
- Reduced coupling to the full Policy aggregate
## Status Lifecycle
| Status | Description |
|--------|-------------|
| NOT_TAKEN_UP | Policy was not accepted |
| NEW | Newly created policy |
| ACTIVE | Policy is in force |
| PENDING_VERIFICATION | Awaiting identity/bank verification |
| PENDING_FIRST_PAYMENT | Awaiting first premium collection |
| PENDING_MAKE_UP_PAYMENT | Awaiting arrears payment |
| CANCELLED | Policy was cancelled |
| LAPSED | Policy lapsed due to non-payment |
| EXPIRED | Policy reached end of term |
| PAUSED | Policy is temporarily paused |
## Immutability
CustomerPolicy is an immutable value object. When a policy status changes, a new CustomerPolicy instance is created with the updated status, replacing the previous one in the Customer aggregate.
## Ordering
CustomerPolicy implements `Comparable` and orders policies by their creation date, enabling chronological display of a customer's policy history.
---
id: CustomerProfile
name: Customer Profile
version: 1.0.0
identifier: sanlamGlobalCustomerId
aggregateRoot: true
summary: Customer preferences for notifications and collection accounts.
properties:
- name: sanlamGlobalCustomerId
type: UUID
required: true
description: Link to the Global Identity (partition key)
- name: notificationPreferences
type: object
required: false
description: Preferred communication channels
references: NotificationPreferences
relationType: hasOne
- name: collectionAccountPreferences
type: array
required: false
description: Collection account details for premium payments
references: CollectionAccount
relationType: hasMany
- name: isActive
type: boolean
required: true
description: Whether the profile is active
- name: version
type: integer
required: true
description: Version number for optimistic concurrency
- name: processedCommands
type: array
required: false
description: Set of processed command IDs for idempotency
- name: auditDetails
type: array
required: false
description: Audit trail of changes to this profile
references: AuditDetails
relationType: hasMany
---
## Overview
The **Customer Profile** stores a customer's communication preferences and collection account details. It is linked to the Global Customer ID and used across all policies for that customer.
## Notification Preferences
```json
{
"smsContactPoint": {
"countryCode": "+27",
"localNumber": "0821234567"
},
"emailContactPoint": "user@example.com"
}
```
## Collection Account Preferences
```json
{
"method": "BANK_ACCOUNT",
"number": "****1234",
"owner": "John Doe",
"currency": "ZAR",
"country": "ZA",
"bankCode": "ABSA",
"accountType": "CHEQUE"
}
```
## Supported Collection Methods
- `BANK_ACCOUNT`: Direct debit from bank account
- `CARD`: Credit or debit card
## Lifecycle
1. Created when collection account preferences or notification preferences are first set
2. Updated as customer changes their preferences
3. Linked to policies for premium collection and notifications
---
id: DataSubject
name: Data Subject
version: 1.0.0
identifier: dataSubjectId
summary: A record representing an individual whose personal data is processed, for regulatory compliance.
properties:
- name: dataSubjectId
type: UUID
required: true
description: Unique identifier for the data subject record
- name: globalCustomerId
type: UUID
required: true
description: Link to the Global Identity
- name: consentRecords
type: array
required: false
description: Records of consent given by the data subject
- name: processingActivities
type: array
required: false
description: Records of data processing activities
- name: createdDate
type: DateTime
required: true
description: When the data subject record was created
- name: lastUpdatedDate
type: DateTime
required: false
description: When the record was last updated
---
## Overview
The **Data Subject** entity tracks consent and data processing activities for regulatory compliance with POPIA (Protection of Personal Information Act) and GDPR (General Data Protection Regulation).
## Purpose
- Track consent for data processing
- Maintain audit trail of data handling
- Support data subject rights requests
- Enable compliance reporting
## Data Subject Rights
The record supports:
- Right to access
- Right to rectification
- Right to erasure
- Right to data portability
- Right to object to processing
---
id: Debits
name: Debits
version: 1.0.0
summary: Record of a debit entry on a policy's financial ledger.
properties:
- name: debitEntryDate
type: Instant
required: true
description: When the debit was recorded in the system
- name: debitDate
type: Instant
required: true
description: Effective date of the debit
- name: debitAmount
type: BigDecimal
required: true
description: Amount of the debit in ZAR
- name: debitType
type: CreditAndDebitType
required: true
description: Type of debit (PREMIUM, FEE, ADJUSTMENT, etc.)
- name: adjustmentReason
type: DebitsAdjustmentReason
required: false
description: Reason for the adjustment if this is an adjustment debit
- name: debitExternalReference
type: String
required: false
description: External reference number
- name: collectionId
type: String
required: false
description: Link to the collection associated with this debit
---
## Overview
The **Debits** value object represents amounts owed or charged on a policy. This includes premiums due, fees, and adjustments. Debits are tracked in the `PolicyFinancialDetail` entity.
## Debit Types
| Type | Description |
|------|-------------|
| PREMIUM | Monthly premium charge |
| FEE | Administrative or service fee |
| ADJUSTMENT | Manual adjustment |
| REVERSAL | Reversal of prior credit |
## Balance Calculation
Policy balance is calculated as the sum of all Credits minus the sum of all Debits. Positive balance indicates overpayment, negative balance indicates arrears.
---
id: EmailAddress
name: Email Address
version: 1.0.0
summary: An email address used for identity and communication.
properties:
- name: emailAddress
type: string
required: true
description: The email address
---
## Overview
The **Email Address** value object represents an email address used for identity verification and customer communication.
## Validation
Email addresses are validated for:
- Proper format (user@domain.tld)
- Valid domain structure
- No illegal characters
## Usage
Email addresses serve as:
- Identity marker (can uniquely identify a customer)
- Communication channel
- Authentication credential
---
id: Employment
name: Employment
version: 1.0.0
summary: Employment attributes for a policyholder.
properties:
- name: status
type: EmploymentStatus
required: false
description: Employment status of the policyholder
- name: industry
type: Industry
required: false
description: Industry or sector of employment
---
## Overview
The **Employment** value object captures the policyholder's employment status and industry. This information may be used for risk assessment and pricing.
## Employment Status
Common employment statuses include:
- EMPLOYED
- SELF_EMPLOYED
- UNEMPLOYED
- RETIRED
- STUDENT
## Industry Classification
Industry information helps categorize the policyholder's occupation sector for underwriting purposes.
## Usage
Employment is captured as part of the PolicyHolder entity during the quote process.
---
id: File
name: File
version: 1.0.0
identifier: fileId
aggregateRoot: true
summary: The central aggregate root representing a file stored in the system.
owners:
- digisure-engineering
properties:
- name: fileId
type: UUID
required: true
description: Unique identifier for the file (FileId value object)
- name: fileName
type: string
required: true
description: Original name of the uploaded file
- name: fileType
type: FileType
required: false
description: Type/format of the file
enum: ['PDF', 'DOC', 'DOCX', 'XLS', 'XLSX', 'JPEG', 'PNG']
- name: fileSizeKilobytes
type: number
required: false
description: Size of the file in kilobytes
- name: fileStatus
type: FileStatus
required: true
description: Current lifecycle status of the file
enum: ['NEW', 'UPLOADED', 'ARCHIVED', 'DELETED']
- name: filePath
type: string
required: false
description: Storage path/bucket where the file is located
- name: fileKey
type: string
required: false
description: S3 object key of the file in the bucket
- name: link
type: string
required: false
description: Download link for the file
- name: origination
type: Origination
required: false
description: Source context of the file
enum: ['CLAIMS', 'POLICY', 'QUOTE']
- name: originationId
type: UUID
required: false
description: Identifier of the associated business entity (policy, quote, or claim)
- name: documentType
type: string
required: false
description: Business classification of the document
- name: createdBy
type: string
required: false
description: User or system that created the file
- name: isThirdParty
type: boolean
required: false
description: Flag indicating if file is from external source
- name: uploadedAt
type: Instant
required: false
description: Timestamp when the file was successfully uploaded
- name: archiveAt
type: Instant
required: false
description: Scheduled archive date for the file
- name: archivedAt
type: Instant
required: false
description: Timestamp when the file was archived
- name: isArchived
type: boolean
required: false
description: Flag indicating if the file is archived
- name: auxiliaryData
type: Map
required: false
description: Additional key-value metadata for custom attributes
- name: version
type: integer
required: false
description: Aggregate version for optimistic concurrency control
---
## Overview
The **File** entity is the aggregate root of the File Upload domain. It encapsulates the complete state of an uploaded file including metadata, storage information, and lifecycle status.
## Aggregate Design
The File aggregate follows DDD principles:
- **FileId**: Strong-typed identifier (value object)
- **Event Sourcing**: State changes tracked via domain events
- **Invariants**: Business rules enforced through specifications
## Lifecycle States
| Status | Description |
|--------|-------------|
| NEW | File record created, awaiting upload completion |
| UPLOADED | File successfully uploaded and available |
| ARCHIVED | File moved to long-term storage |
| DELETED | File has been permanently deleted |
## State Transitions
```
NEW -----> UPLOADED -----> ARCHIVED
|
+-----------> DELETED
```
## Key Relationships
- **Origination**: Links to Policy, Quote, or Claims context via originationId
- **FileUploadLink**: Pre-signed URL for upload operations (value object)
- **FileDownloadLink**: Pre-signed URL for download operations (value object)
## Invariants
The aggregate enforces these business rules:
1. **FileSizeLimit**: File size must be within configured maximum (DomainConstants.MAX_FILE_SIZE_KB)
2. **ArchiveAtNotInFuture**: Archive timestamp must not be in the future
3. **HasArchivedAtWhenArchived**: Archived files must have an archivedAt timestamp
4. **FileHasValidUploadedAtTime**: uploadedAt must not be in the future when status is UPLOADED
5. **MandatoryFieldPresence**: Required fields must be present based on status
## Business Rules
- Files can only transition from NEW to UPLOADED
- Deleted files cannot be restored
- Archive can only occur from UPLOADED status
- File type must be in the allowed list (PDF, DOC, DOCX, XLS, XLSX, JPEG, PNG)
- Origination and originationId are required for business context
## Domain Events
The File aggregate emits:
- **FileUploadedEventV1**: When file upload is completed
- **FileDeletedEventV1**: When file is deleted
- **FileOriginationSetEventV1**: When origination context is set/updated
---
id: FileDownloadLink
name: File Download Link
version: 1.0.0
summary: A pre-signed URL allowing secure file download from S3 storage.
owners:
- digisure-engineering
properties:
- name: downloadLink
type: string
required: true
description: Pre-signed S3 URL for GET operation
---
## Overview
The **FileDownloadLink** is a value object (Java record) representing a time-limited, pre-signed URL for downloading files directly from S3 storage. This enables secure, efficient file retrieval without exposing storage credentials.
## Implementation
```java
public record FileDownloadLink(String downloadLink) {}
```
## Usage Flow
1. Client requests file download via GetFile or GetBinaryStream query
2. Service validates file exists and is accessible
3. Service generates pre-signed download URL
4. Client downloads file directly from S3 using the URL
## Security Features
- URLs include embedded AWS credentials (temporary)
- URLs have configurable expiration time
- HTTPS required for all downloads
- Access control validated before URL generation
- Bucket policies enforce additional restrictions
## Features
- Direct S3 download bypasses application server
- Supports HTTP range requests for partial downloads
- Appropriate Content-Type header set based on file type
- Content-Disposition header for file name preservation
- Download progress tracking available on client side
## Constraints
- URL expires after configured time period
- File must exist and be in UPLOADED status
- Archived files may have increased retrieval latency (S3 storage class)
- Deleted files cannot generate download links
---
id: FileUploadLink
name: File Upload Link
version: 1.0.0
summary: A pre-signed POST URL allowing direct file upload to S3 storage.
owners:
- digisure-engineering
properties:
- name: uploadLink
type: string
required: true
description: The S3 POST endpoint URL for uploading
- name: fields
type: Map
required: true
description: Required form fields for the POST request (immutable map)
---
## Overview
The **FileUploadLink** is a value object (Java record) representing a time-limited, pre-signed POST URL for uploading files directly to S3 storage. This enables efficient, scalable uploads by bypassing the application server.
## Implementation
```java
public record FileUploadLink(String uploadLink, Map fields) {}
```
## Usage Flow
1. Client requests a pre-signed URL via GeneratePreSignedUrl command
2. Service creates File record with NEW status
3. Service generates pre-signed POST URL with required form fields
4. Client uploads file directly to S3 using POST request with form data
5. S3 triggers S3Event notification on upload completion
6. Lambda handler processes the event and updates file status to UPLOADED
7. FileUploadedEventV1 is emitted
## Security Features
- URLs include embedded AWS credentials
- URLs expire after 60 seconds (configurable)
- Content-type validation enforced via form fields
- HTTPS required for all uploads
- Bucket policies enforce additional access controls
## Form Fields
The `fields` map contains required S3 presigned POST fields:
- AWS signature fields
- Policy document
- Content constraints
- Bucket/key information
## Constraints
- Single use per URL
- Must complete upload before expiration
- File size limits enforced by S3 policy
- Content type must match if specified in fields
---
id: GlobalCounters
name: GlobalCounters
version: 1.0.0
summary: Global counters tracking collection attempts and client actions for a policy.
properties:
- name: collectionMonthsTotal
type: Integer
required: false
description: Total number of collection months
- name: collectionAttemptedMonthsTotal
type: Integer
required: false
description: Total number of months where collection was attempted
- name: runningBalanceFail
type: Integer
required: false
description: Count of failed running balance attempts
- name: runningBalanceSuccess
type: Integer
required: false
description: Count of successful running balance attempts
- name: runningBalanceSkip
type: Integer
required: false
description: Count of skipped running balance attempts
- name: runningBalanceOther
type: Integer
required: false
description: Count of other running balance outcomes
- name: noOfClientCancellations
type: Integer
required: false
description: Number of client-initiated cancellations
- name: noOfClientReinstatements
type: Integer
required: false
description: Number of client-initiated reinstatements
- name: noOfClientPauses
type: Integer
required: false
description: Number of client-initiated pauses
---
## Overview
The **GlobalCounters** value object tracks cumulative collection metrics and client action counts for a policy's financial detail.
---
id: GlobalCustomerId
name: GlobalCustomerId
version: 1.0.0
summary: A globally unique identifier for a customer across all systems and domains.
properties:
- name: value
type: string
required: true
description: The unique identifier value (typically derived from policy holder ID)
---
## Overview
The **GlobalCustomerId** (GCID) is a value object that uniquely identifies a customer across the entire insurance platform. It serves as the identity for the Customer aggregate root.
## Purpose
The GCID enables:
- **Cross-domain identification**: Same customer recognized in Policy, Quote, Claims domains
- **Data aggregation**: All customer data can be linked using a single identifier
- **Customer 360 view**: Complete customer profile from multiple sources
- **Deduplication**: Prevent duplicate customer records
## Derivation
The GCID is derived from the policy holder's identification:
```
PolicyHolder.identification.idValue + idType + idCountryOfIssue
│
▼
Hash/Transform
│
▼
GlobalCustomerId
```
In the current implementation, the GCID is typically the policy holder ID itself, but the abstraction allows for alternative derivation strategies.
## Implementation
GlobalCustomerId extends the `Identity` base class, which provides:
- Value-based equality (two GCIDs are equal if their values are equal)
- Immutability (value cannot change after construction)
- String serialization support
## Usage
```java
// Creating a GCID
GlobalCustomerId customerId = new GlobalCustomerId("550e8400-e29b-41d4-a716-446655440000");
// Using as Customer identity
Customer customer = new Customer(customerId);
// Retrieving value
String value = customerId.getValue();
```
## Best Practices
- Never expose the derivation logic externally
- Treat GCID as opaque outside the CustomerDP domain
- Use GCID for all cross-domain customer references
- Log GCID for customer-related audit trails
---
id: GlobalIdentity
name: Global Identity
version: 1.0.0
identifier: globalCustomerId
aggregateRoot: true
summary: The canonical customer identity record across the platform, identified by a Global Customer ID (GCID).
properties:
- name: globalCustomerId
type: UUID
required: true
description: Unique Global Customer ID (GCID) identifying the identity
- name: personName
type: object
required: false
description: The person's structured name
references: PersonName
relationType: hasOne
- name: issuedIdentity
type: object
required: false
description: Official identity document information
references: IssuedIdentity
relationType: hasOne
- name: identityMobileNumber
type: object
required: false
description: Mobile number as identity marker
references: MobileNumber
relationType: hasOne
- name: identityEmailAddress
type: object
required: false
description: Email address as identity marker
references: EmailAddress
relationType: hasOne
- name: identityAddress
type: object
required: false
description: Physical address
references: Address
relationType: hasOne
- name: dateOfBirth
type: Date
required: false
description: The person's date of birth
- name: gender
type: string
required: false
description: The person's gender
enum: ['MALE', 'FEMALE', 'NONBINARY', 'PREFER_NOT_TO_SAY', 'UNKNOWN']
- name: certificates
type: map
required: false
description: Map of field groups to their trust certificates
references: Certificate
relationType: hasMany
- name: version
type: integer
required: true
description: Version number for optimistic concurrency
- name: isActive
type: boolean
required: true
description: Whether the identity is active
- name: processedCommands
type: array
required: false
description: Set of processed command IDs for idempotency
- name: auditDetails
type: array
required: false
description: Audit trail of changes to this identity
references: AuditDetails
relationType: hasMany
---
## Overview
The **Global Identity** entity is the aggregate root of the Identity domain. It represents the canonical identity record for a customer across the entire platform, identified by a unique Global Customer ID (GCID).
## Identity Markers
At least one of the following must be present:
- Issued Identity (ID document or passport)
- Mobile Number
- Email Address
## Certificate-Based Trust
Each attribute field group has an associated certificate tracking:
- **Trust Level**: Numeric score indicating source reliability
- **Creation Time**: When the certificate was issued
- **Certificate ID**: Unique identifier for audit trail
Updates require a certificate with equal or higher trust level than the existing value.
## Field Groups
| Field Group | Attributes |
|-------------|------------|
| PERSONAL_IDENTITY | personName, gender, dateOfBirth |
| EMAIL_IDENTITY | identityEmailAddress |
| MOBILE_IDENTITY | identityMobileNumber |
| ADDRESS | identityAddress |
## Invariants
- At least one identity marker must be present
- Updates require valid certificates
- Trust level rules are enforced on updates
---
id: Identification
name: Identification
version: 1.0.0
summary: Identity document details used to uniquely identify a person.
properties:
- name: idType
type: string
required: true
description: Type of identification document
enum: ['SA_ID', 'PASSPORT', 'ASYLUM_SEEKER', 'REFUGEE_ID', 'FOREIGN_ID']
- name: idValue
type: string
required: true
description: The identification number or value
- name: idExpiryDate
type: date
required: false
description: Expiry date of the identification document
- name: idCountryOfIssue
type: string
required: true
description: ISO 3166-1 alpha-3 country code of the issuing authority
- name: idIssuedBy
type: string
required: false
description: Entity that issued the identification document
- name: idValidatedBy
type: string
required: false
description: Entity or system that validated the identification
- name: idValidatedWhen
type: DateTime
required: false
description: Timestamp when the identification was validated
---
## Overview
The **Identification** record is a value object that encapsulates identity document information. It is critical for:
- Uniquely identifying customers across the platform
- Deriving the Global Customer ID
- Regulatory compliance (FICA, FAIS)
- Identity verification workflows
## Validation Rules
The Identification record enforces the following validations on construction:
| Field | Validation |
|-------|------------|
| idType | Must not be null |
| idValue | Must not be null or empty |
| idCountryOfIssue | Must be a valid ISO 3166-1 alpha-3 country code |
| idValidatedWhen | If provided, must be in the past |
## ID Types
| Type | Description |
|------|-------------|
| SA_ID | South African ID number (13 digits) |
| PASSPORT | International passport |
| ASYLUM_SEEKER | Asylum seeker permit |
| REFUGEE_ID | Refugee identification |
| FOREIGN_ID | Other foreign identification |
## Country Codes
The `idCountryOfIssue` field uses ISO 3166-1 alpha-3 country codes:
- **ZAF** - South Africa
- **NAM** - Namibia
- **BWA** - Botswana
- **GBR** - United Kingdom
- etc.
## Expiry Checking
The `hasIdExpired()` method checks if the identification document has passed its expiry date. Expired identification may require re-verification before policy issuance.
## Immutability
Identification is implemented as a Java record, making it immutable. Any updates to identification require creating a new instance.
---
id: IdentityPortfolio
name: Identity Portfolio
version: 1.0.0
summary: "Aggregate root tracking a customer's quotes and policies."
description: |
The IdentityPortfolio is the root aggregate of the identity portfolio domain,
responsible for tracking all quotes and policies associated with a customer
identified by their Global Customer ID. It maintains a consolidated view of
a customer's insurance portfolio across their entire lifecycle.
---
## Overview
The **IdentityPortfolio** is an aggregate root that manages the relationship between a customer (identified by Global Customer ID) and their associated quotes and policies. It serves as a central hub for portfolio-level operations and queries, providing a complete view of a customer's insurance portfolio.
## Key Attributes
- **globalCustomerId** (GlobalCustomerId, required) - The unique identifier for the customer across the platform. Serves as the aggregate root identifier.
- **quoteIds** (`Set`) - The set of quote IDs associated with this customer. Typically contains the customer's active quote(s).
- **policies** (`Set`) - The set of policies held by the customer, including complete policy metadata.
- **version** (Integer) - The version number of the portfolio aggregate for concurrency control.
- **processedEvents** (`Map`) - A map tracking which events have been processed for idempotency.
## Responsibilities
### Quote Management
- Track all active and historical quotes associated with a customer
- Maintain quote IDs for quote retrieval and correlation
- Support quote lifecycle transitions
### Policy Management
- Maintain a complete record of all policies held by the customer
- Store comprehensive policy metadata (code, status, partner, package information)
- Support policy lifecycle tracking from creation through cancellation
- Enable portfolio-level policy queries and analytics
### Portfolio Lifecycle
- Initialize empty portfolio when customer is created
- Add quotes to portfolio when policy holder details are captured
- Add policies when quotes are converted to policies
- Maintain historical records of all quotes and policies
### Event Processing
- Apply QuoteEvents (PolicyHolderAddedToQuoteEvent) to update quote associations
- Apply PolicyEvents (PolicyCreatedEventV1) to update policy records
- Ensure idempotent event processing through version tracking
## Domain Events
The IdentityPortfolio aggregate responds to and processes the following domain events:
### Consumed Events
- **PolicyHolderAddedToQuoteEventV2** - Emitted by Quote Service when policy holder details are captured. Updates the portfolio's quote IDs.
- **PolicyCreatedEventV1** - Emitted by Policy Service when a quote is converted to a policy. Adds the policy to the portfolio's policy set.
## Invariants
1. **Valid Global Customer ID** - The portfolio's global customer ID must be a valid UUID
2. **Consistent Quote/Policy Count** - The number of quotes should typically be low (usually 0-1 active quote)
3. **Policy Uniqueness** - Each policy ID should appear only once in the policies set
4. **Event Ordering** - Events must be processed in order to maintain consistency
5. **Idempotency** - Processing the same event multiple times should not change the portfolio state
## Use Cases
### Portfolio Retrieval
- Customer service representatives querying a customer's complete portfolio
- Billing systems retrieving policy information for premium calculations
- Claims systems identifying applicable policies for claims processing
- Analytics systems analyzing customer portfolio composition
### Quote-to-Policy Conversion
- Tracking when customer quotes convert to active policies
- Maintaining historical record of quote progression
- Supporting quote expiration and abandonment tracking
### Customer Onboarding
- Initializing portfolio when new customer is created
- Tracking quote progression during onboarding
- Recording first policy acquisition
### Customer Portfolio Analysis
- Understanding customer's insurance product mix
- Analyzing policy overlap and coverage gaps
- Supporting customer retention strategies
## Related Entities
- **GlobalCustomerId** - The unique identifier for the customer
- **QuoteId** - References to associated quotes
- **IdentityPortfolioPolicy** - Policy information in the portfolio
- **PolicyCode** - Business-facing policy identifier
- **IdentityProfile** - Customer's notification and collection preferences in the same domain
- **GlobalIdentity** - Customer's verified identity information in the same domain
## Event Flow
```
Quote Service
|
+-> PolicyHolderAddedToQuoteEventV2
|
v
IdentityPortfolio (updates quoteIds)
Policy Service
|
+-> PolicyCreatedEventV1
|
v
IdentityPortfolio (adds to policies set)
```
## State Diagram
```
[Empty Portfolio]
|
| PolicyHolderAddedToQuoteEventV2
v
[Portfolio with Quote]
|
| PolicyCreatedEventV1
v
[Portfolio with Quote + Policy]
|
| PolicyCreatedEventV1 (for additional policies)
v
[Portfolio with Multiple Policies]
```
## Implementation Notes
- The portfolio is implemented as a DataProduct aggregate using event sourcing
- Portfolio state is maintained in DynamoDB
- The aggregate uses semantic versioning for concurrency control
- The aggregate is immutable after creation (values are replaced via events)
- Event handlers ensure idempotent processing through logical clock readings
---
id: IdentityPortfolioPolicy
name: Identity Portfolio Policy
version: 1.0.0
summary: "A policy record within a customer's identity portfolio."
description: |
IdentityPortfolioPolicy represents an insurance policy held by a customer
as recorded in their identity portfolio. It captures comprehensive policy
metadata including identification, status, dates, and organizational information
to provide a complete picture of a customer's policy holdings.
---
## Overview
The **IdentityPortfolioPolicy** is a value object that represents a single policy within an identity portfolio. Unlike the Policy Service's full policy aggregate, IdentityPortfolioPolicy is a lightweight data structure optimized for portfolio queries, containing essential policy metadata needed for customer service and analytics.
## Key Attributes
- **policyId** (String, required) - The unique system identifier for the policy
- **policyCode** (String, required) - The business-facing policy code used by customers and agents
- **policyStatus** (String, required) - Current status of the policy (e.g., ACTIVE, PENDING_FIRST_PAYMENT, CANCELLED, LAPSED)
- **policyStartDate** (Instant, required) - The effective date when the policy coverage begins
- **policyHolderId** (String, required) - The unique identifier for the policy holder (Global Customer ID)
- **quoteId** (String, optional) - The quote ID from which this policy was created (if applicable)
- **partnerId** (String, required) - The identifier of the partner/distribution channel associated with the policy
- **partnerName** (String, required) - The display name of the partner
- **packageId** (String, required) - The identifier of the insurance package
- **packageName** (String, required) - The display name of the package
- **productCategoryId** (String, optional) - The identifier of the product category
- **productCategoryName** (String, optional) - The display name of the product category
- **division** (String, optional) - Organizational division for reporting/analytics
- **subdivision** (String, optional) - Organizational subdivision for reporting/analytics
## Purpose and Usage
### Portfolio Representation
Provides a lightweight representation of policies in a customer's portfolio without loading the full policy aggregate from the Policy Service.
### Customer Service
Enables quick lookup and display of customer policy information in customer service systems, including:
- Policy codes for agent reference
- Current policy status
- Policy start dates
- Partner and package information
### Billing and Collections
Supports billing systems in identifying:
- Which policies are active and billable
- Partner-specific billing requirements
- Package-based billing configurations
### Analytics and Reporting
Facilitates reporting on:
- Customer policy holdings by partner
- Policy status distribution
- Package popularity
- Division-level analytics
## Composition
IdentityPortfolioPolicy is a composition of value objects:
- **PolicyCode** - Business identifier for the policy
- **PolicyId** - System identifier for the policy
- **PolicyStatus** - Enumeration of policy lifecycle states
- **GlobalCustomerId** / **PolicyHolderId** - Reference to policy holder
- **QuoteId** - Optional reference to originating quote
## Policy Status Values
Typical policy status values include:
- **ACTIVE** - Policy is in force and collecting premiums
- **PENDING_FIRST_PAYMENT** - Policy created but first payment not yet received
- **GRACE_PERIOD** - Policy in grace period after premium collection failure
- **SUSPENDED** - Policy suspended pending customer action
- **LAPSED** - Policy coverage ended due to non-payment
- **CANCELLED** - Policy deliberately cancelled by customer or company
- **EXPIRED** - Policy reached natural expiration date
- **REINSTATED** - Previously lapsed policy brought back into force
## Related Entities
- **IdentityPortfolio** - The parent aggregate containing multiple policies
- **GlobalCustomerId** - The customer who holds the policy
- **PolicyCode** - Business identifier for the policy
- **PolicyId** - System identifier for the policy
- **QuoteId** - The quote from which this policy may have been created
- **Partner** - The distribution partner or channel
## Example Usage
```json
{
"policyId": "POL-2024-001-ABC",
"policyCode": "FUN-2024-001",
"policyStatus": "ACTIVE",
"policyStartDate": "2024-01-15T00:00:00Z",
"policyHolderId": "550e8400-e29b-41d4-a716-446655440000",
"quoteId": "QUOTE-2024-001-ABC",
"partnerId": "PARTNER-001",
"partnerName": "Digital Insurance Partner",
"packageId": "PKG-FUNERAL-BASIC",
"packageName": "Basic Funeral Cover",
"productCategoryId": "CAT-FUNERAL",
"productCategoryName": "Funeral Insurance",
"division": "RETAIL",
"subdivision": "DIRECT"
}
```
## Design Rationale
### Lightweight Design
IdentityPortfolioPolicy is designed as a lightweight value object to support efficient portfolio queries without requiring full policy aggregate hydration.
### De-normalization
The portfolio maintains de-normalized policy metadata from the Policy Service events. This allows for fast queries but requires eventual consistency.
### Event-Driven Updates
Policy information is updated in the portfolio whenever PolicyCreatedEventV1 is published by the Policy Service, ensuring the portfolio stays eventually consistent.
### Immutability
Policy records in the portfolio are immutable once created. Updates to policy status or other attributes in the Policy Service propagate through new events.
## Constraints
1. **Unique Within Portfolio** - Each policyId should appear only once in a customer's portfolio
2. **Valid Policy Holder ID** - The policyHolderId must match the portfolio's globalCustomerId
3. **Valid Dates** - policyStartDate should be a valid historical or current date
4. **Required Fields** - All marked fields are required for portfolio consistency
5. **Reference Integrity** - partnerId and packageId should reference valid entities in the system
---
id: InventoryItem
name: Inventory Item
version: 1.0.0
identifier: serialNumber
aggregateRoot: true
summary: A single redeemable inventory item identified by its unique serial number.
properties:
- name: serialNumber
type: string
required: true
description: 16-digit unique identifier (partner+package+sequence+check)
references: SerialNumber
- name: bundleId
type: string
required: true
description: Reference to the bundle configuration
- name: partnerName
type: string
required: true
description: Partner name for display
- name: packageName
type: string
required: true
description: Package name for display
- name: sequence
type: long
required: true
description: Sequence number within the bundle
- name: active
type: boolean
required: true
description: Whether the item is active
- name: redeemed
type: boolean
required: true
description: Whether the item has been redeemed
- name: redeemedAt
type: DateTime
required: false
description: Timestamp when the item was redeemed
- name: coverTerm
type: integer
required: false
description: Cover term selected at redemption
- name: coverTermChronoUnit
type: string
required: false
description: Unit for the cover term (e.g., MONTHS)
- name: expiresAt
type: DateTime
required: false
description: When the item expires
- name: createdAt
type: DateTime
required: true
description: When the item was created
- name: updatedAt
type: DateTime
required: true
description: When the item was last modified
---
## Overview
The **InventoryItem** entity is an aggregate root representing a single prepaid insurance coverage unit. Each item is uniquely identified by its serial number and tracks its lifecycle from creation through redemption.
## Lifecycle States
| State | Description |
|-------|-------------|
| Active + Not Redeemed | Available for redemption |
| Active + Redeemed | Already used for a policy |
| Expired | Past expiration date, cannot be redeemed |
| Inactive | Disabled by administrator |
## Serial Number Format
The serial number is 16 digits with the format:
```
PPP + KKK + SSSSSSSSS + C
```
- **PPP**: 3-digit partner code
- **KKK**: 3-digit package code
- **SSSSSSSSS**: 9-digit sequence number
- **C**: 1-digit Damm check digit
## Invariants
- Cannot redeem inactive items
- Cannot redeem already redeemed items
- Cannot redeem expired items
- Serial number must have valid check digit
---
id: IssuedIdentity
name: Issued Identity
version: 1.0.0
summary: An official identity document issued by an authority such as a national ID or passport.
properties:
- name: idType
type: string
required: true
description: Type of identity document
enum: ['IDENTITY_DOCUMENT', 'PASSPORT', 'UNKNOWN']
- name: idValue
type: string
required: true
description: The identity document number
- name: idCountryOfIssue
type: string
required: true
description: ISO country code of issuing country
- name: idExpiryDate
type: Date
required: false
description: Document expiry date (required for passports)
- name: idIssuedBy
type: string
required: false
description: Issuing authority
- name: idValidatedBy
type: string
required: false
description: Validation service or authority
- name: idValidatedWhen
type: DateTime
required: false
description: When the document was validated
---
## Overview
The **Issued Identity** value object represents an official identity document such as a national ID card or passport. It is a key identifier for linking customer records and verifying identity.
## Document Types
| Type | Description |
|------|-------------|
| IDENTITY_DOCUMENT | National ID card or similar government-issued ID |
| PASSPORT | International travel document |
| UNKNOWN | Unclassified document type |
## South African ID Number
South African ID numbers (13 digits) encode:
- Date of birth (YYMMDD)
- Gender indicator
- Citizenship status
- Checksum digit
## Example
```json
{
"idType": "IDENTITY_DOCUMENT",
"idValue": "8501015800083",
"idCountryOfIssue": "ZA",
"idExpiryDate": null,
"idIssuedBy": "Department of Home Affairs",
"idValidatedBy": "HomeAffairs API",
"idValidatedWhen": "2024-01-15T10:30:00Z"
}
```
## Validation
Identity documents are validated for:
- Format correctness per country rules
- Expiry date (for passports)
- Checksum validation (for SA ID numbers)
---
id: MobileNumber
name: Mobile Number
version: 1.0.0
summary: A mobile phone number with country code.
properties:
- name: countryCode
type: string
required: true
description: International dialing code (e.g., +27). In Avro schemas this field is named phoneCountryCode.
- name: localNumber
type: string
required: true
description: Local phone number without country code
---
## Overview
The **Mobile Number** value object represents a mobile phone number used for identity verification and communication.
## Example
```json
{
"countryCode": "+27",
"localNumber": "0821234567"
}
```
## Field Naming
Note: The field name varies slightly across contexts:
- **DynamoDB Data Model**: `countryCode`
- **Avro Schemas**: `phoneCountryCode`
This is a legacy naming inconsistency that is maintained for backward compatibility.
## Formatting
- Country code should include the + prefix
- Local number can include leading zero (will be normalized)
- The `internationalNumberE164()` method concatenates both for E.164 format
## Common Country Codes
| Country | Code |
|---------|------|
| South Africa | +27 |
| United States | +1 |
| United Kingdom | +44 |
| Botswana | +267 |
| Namibia | +264 |
---
id: Money
name: Money
version: 1.0.0
summary: Represents a monetary amount with currency.
properties:
- name: amount
type: BigDecimal
required: true
description: The numeric value of the monetary amount
- name: currency
type: string
required: true
description: The ISO 4217 currency code (e.g., ZAR, USD)
---
## Overview
The **Money** value object represents a monetary amount with its associated currency. It is implemented using the JavaMoney (JSR 354) `org.javamoney.moneta.Money` class.
## Usage
Money is used throughout the Quote domain for:
- Premium amounts (currentPremium, futurePremium, deltaPremium, effectivePremium)
- Cover amounts (currentCover, futureCover, deltaCover, effectiveCover)
- Total premium calculations
- Tranche cover and premium amounts
- Policy administration fees
- Income values in risk calculations
## Arithmetic Operations
Money supports standard arithmetic operations:
- Addition and subtraction
- Multiplication and division by scalars
- Comparison operations
## Currency Handling
The currency is typically configured at the partner level and defaults to ZAR (South African Rand) for South African insurance products.
---
id: NotificationConfig
name: Notification Configuration
version: 1.0.0
identifier: notificationType
summary: Configuration defining when and how a notification should be sent.
properties:
- name: notificationType
type: NotificationType
required: true
description: The type of notification this configuration applies to
enum: ['POLICY_CONFIRMATION_WELCOME', 'POLICY_CANCELLED', 'POLICY_EXPIRED', 'POLICY_EXPIRING_SOON', 'POLICY_EXPIRING_IN_ONE_WEEK', 'POLICY_EXPIRING_IN_TWO_WEEKS', 'POLICY_EXPIRING_TOMORROW', 'POLICY_SEND_SCHEDULE', 'PREMIUM_COLLECTED', 'POLICY_ALTERATION', 'POLICY_NO_BENEFICIARIES_ADDED', 'POLICY_BENEFICIARIES_UPDATED', 'POLICY_OUTSTANDING_BENEFICIARY_INFO', 'POLICY_REINSTATEMENT', 'POLICY_COVER_STAGGERED', 'POLICY_PAYMENT_REMINDER', 'POLICY_REFUND_DUE', 'POLICY_OUTSTANDING_ADDED_LIVES_INFO', 'POLICY_SECOND_MISSED_PAYMENT_WARNING', 'POLICY_APPLICATION_DENIED', 'POLICY_CONFIRMATION_PENDING', 'CLAIM_REJECTED', 'CLAIM_APPROVED_POLICY_ACTIVE', 'CLAIM_APPROVED_POLICY_LAPSED', 'CLAIM_PAYOUT_COMPLETE', 'WAITING_PERIOD_COMPLETE', 'CLAIM_SUBMISSION_RECEIVED', 'MISSING_DOCUMENTS', 'CLAIM_UNDER_INVESTIGATION', 'QUOTE_EXPIRED', 'SCHEDULED_RESUME_QUOTE_REMINDER', 'AD_HOC_RESUME_QUOTE_REMINDER']
- name: triggerRules
type: array
required: true
description: Rules that must be satisfied for the notification to trigger
- name: scheduleCancelationRules
type: array
required: false
description: Rules that cause scheduled notifications to be cancelled
- name: scheduleReinstatementRules
type: array
required: false
description: Rules that reinstate cancelled notifications
- name: notificationMediums
type: array
required: true
description: Delivery channels (EMAIL, SMS) with template configuration
- name: notificationTiming
type: NotificationTiming
required: true
description: When to send - IMMEDIATE or SCHEDULED
enum: ['IMMEDIATE', 'SCHEDULED']
- name: notificationTimingFieldRef
type: NotificationTimingFieldRef
required: false
description: Policy field to base scheduled timing on
enum: ['NEXT_COLLECTION_DATE', 'POLICY_START_DATE', 'POLICY_END_DATE']
- name: notificationFrequency
type: NotificationFrequency
required: false
description: How often to send - ONCE or RECURRING
enum: ['ONCE', 'RECURRING']
- name: notificationFrequencyTemporalUnit
type: ChronoUnit
required: false
description: Temporal unit for recurring frequency (DAYS, WEEKS, MONTHS)
- name: notificationFrequencyTemporalUnitCount
type: integer
required: false
description: Number of temporal units between recurring notifications
- name: notificationTimingOffset
type: integer
required: false
description: Offset in temporal units from the timing field (negative for before, positive for after)
- name: notificationDelayChronoUnit
type: ChronoUnit
required: false
description: Temporal unit for the timing offset (DAYS, WEEKS, MONTHS)
- name: recipients
type: array
required: true
description: Who receives the notification
enum: ['POLICY_HOLDER', 'CLAIMANT']
---
## Overview
The **NotificationConfig** entity defines the rules and configuration for a specific notification type. It controls when notifications are triggered, how they are delivered, and who receives them.
## Trigger Rules
Trigger rules define conditions that must be met:
| Rule Type | Description |
|-----------|-------------|
| STATE_FIELD_EQUALS | Policy field must equal a specific value |
| STATE_FIELD_NOT_NULL | Policy field must have a value |
| STATE_FIELD_TRUE | Boolean policy field must be true |
## Timing Configuration
### Immediate Notifications
- `notificationTiming`: IMMEDIATE
- Sent as soon as trigger rules are satisfied
### Scheduled Notifications
- `notificationTiming`: SCHEDULED
- `notificationTimingFieldRef`: Base date field
- `notificationTimingOffset`: Offset from base date
- Example: Send 7 days before POLICY_END_DATE
## Cancellation Rules
Scheduled notifications can be cancelled when:
- Policy status changes (cancelled, lapsed)
- Condition is satisfied (beneficiaries added)
- Conflicting notification triggers
## Example Configuration
```json
{
"notificationType": "POLICY_EXPIRING_SOON",
"triggerRules": [
{ "field": "POLICY_STATUS", "operator": "EQUALS", "value": "ACTIVE" },
{ "field": "HAS_EXPIRY_DATE", "operator": "TRUE" }
],
"notificationTiming": "SCHEDULED",
"notificationTimingFieldRef": "POLICY_END_DATE",
"notificationTimingOffset": -14,
"notificationDelayChronoUnit": "DAYS",
"notificationMediums": [{ "medium": "EMAIL", "templateId": "expiry-reminder" }],
"recipients": ["POLICY_HOLDER"]
}
```
---
id: NotificationDataProduct
name: Notification Data Product
version: 1.0.0
identifier: notificationId
summary: Analytics record tracking notification delivery status and history.
properties:
- name: correlationId
type: UUID
required: true
description: Correlation identifier linking related notification events
- name: notificationProviderCorrelationId
type: UUID
required: false
description: Provider tracking ID for delivery confirmation
- name: originId
type: string
required: true
description: The policy ID or claim ID that triggered the notification
- name: originType
type: string
required: true
description: Source type (POLICY_FUNERAL, CLAIMS, etc.)
- name: notificationId
type: string
required: true
description: Unique identifier for this notification record
- name: notificationType
type: string
required: true
description: Type of notification (POLICY_CONFIRMATION_WELCOME, etc.)
- name: notificationStatus
type: string
required: true
description: Current status (SCHEDULED, DISPATCHED, SUCCESS, FAILED)
enum: ['SCHEDULED', 'DISPATCHED', 'PROVIDER_SEND_SUCCESS', 'PROVIDER_SEND_FAILED']
- name: recipient
type: string
required: false
description: Recipient type (POLICY_HOLDER, CLAIMANT)
- name: notificationMedium
type: string
required: false
description: Delivery channel (EMAIL, SMS)
- name: createdAt
type: DateTime
required: true
description: Timestamp when the notification record was created
---
## Overview
The **NotificationDataProduct** entity represents an analytics record for a single notification event. It captures the complete lifecycle of a notification from scheduling through delivery, enabling reporting and auditing.
## Status Progression
Notifications progress through statuses:
| Status | Description |
|--------|-------------|
| SCHEDULED | Notification is queued for future delivery |
| DISPATCHED | Notification has been sent to the provider |
| PROVIDER_SEND_SUCCESS | Provider confirmed successful delivery |
| PROVIDER_SEND_FAILED | Provider reported delivery failure |
## Correlation IDs
The data product tracks multiple correlation IDs:
- **correlationId**: Links related domain events
- **notificationProviderCorrelationId**: Provider's tracking ID for delivery status
## Use Cases
### Operational Monitoring
- Track notification delivery rates
- Identify failed notifications
- Monitor provider performance
### Audit Trail
- Record what notifications were sent
- Track when and to whom
- Link to originating events
### Analytics
- Notification volume by type
- Success/failure rates by medium
- Partner/package notification patterns
## Event Handlers
The data product is updated by:
- `NotificationDispatchedEventHandler`: Records dispatched notifications
- `NotificationScheduledEventHandler`: Records scheduled notifications
- Provider callback handlers: Update delivery status
---
id: NotificationPreferences
name: Notification Preferences
version: 1.0.0
summary: Customer preferences for receiving communications via SMS and email.
properties:
- name: smsContactPoint
type: object
required: false
description: Mobile number for SMS notifications
references: MobileNumber
relationType: hasOne
- name: emailContactPoint
type: string
required: false
description: Email address for email notifications
---
## Overview
The **Notification Preferences** value object stores a customer's communication preferences. It is part of the Customer Profile and specifies how the customer wishes to receive notifications about their policies.
## Structure
```json
{
"smsContactPoint": {
"countryCode": "+27",
"localNumber": "0821234567"
},
"emailContactPoint": "user@example.com"
}
```
## Contact Points
- **SMS Contact Point**: Mobile number for SMS-based notifications
- **Email Contact Point**: Email address for email-based notifications
Both contact points are optional, but at least one should be provided for effective communication.
## Usage
Notification preferences are used by:
- Notifications Service for policy communications
- Collections Service for payment reminders
- Marketing for promotional communications (with consent)
---
id: NotificationSenderIdentity
name: Notification Sender Identity
version: 1.0.0
summary: Configuration defining the sender identity for notifications.
properties:
- name: emailFrom
type: string
required: false
description: Email address used as the sender (e.g., noreply@partner.co.za)
- name: emailFromName
type: string
required: false
description: Display name shown as the sender (e.g., Partner Insurance)
- name: smsFrom
type: string
required: false
description: SMS sender ID for text messages (alphanumeric, max 11 chars)
---
## Overview
The **NotificationSenderIdentity** entity defines the sender identity used when dispatching notifications. It configures how the sender appears to recipients for both email and SMS channels.
## Email Configuration
For email notifications:
- **emailFrom**: The verified email address in AWS SES from which emails are sent
- **emailFromName**: The display name shown in email clients (e.g., "Sanlam Insurance" instead of just the email address)
## SMS Configuration
For SMS notifications:
- **smsFrom**: The sender ID displayed on the recipient's device
- Must comply with South African sender ID regulations
- Typically an alphanumeric string up to 11 characters
## Partner Customization
Each partner can customize their sender identity to:
- Use their own branded email addresses
- Display their company name to policyholders
- Maintain consistent branding across communications
## Verification Requirements
Email sender addresses must be:
- Verified in AWS SES for the deployment environment
- Configured with appropriate SPF/DKIM records
- Compliant with anti-spam regulations
## Usage
The sender identity is:
- Configured per package in `PackageNotificationConfig`
- Passed through the notification dispatch pipeline
- Used by the Glue notification gateway for delivery
---
id: NotificationState
name: Notification State
version: 1.0.0
identifier: policyId
aggregateRoot: true
summary: The aggregate root tracking notification lifecycle for a policy or claim.
properties:
- name: policyId
type: PolicyId (UUID)
required: true
description: Unique identifier for the policy (aggregate identifier)
- name: partnerId
type: PartnerId (UUID)
required: true
description: Partner identifier for configuration lookup
- name: packageId
type: PackageId (UUID)
required: true
description: Package identifier for notification configuration
- name: policyState
type: PolicyState
required: true
description: Snapshot of policy state for trigger evaluation and template context
- name: processedEvents
type: Set
required: true
description: Set of event IDs already processed (idempotency)
- name: processedCommands
type: Set
required: true
description: Set of command IDs already processed (idempotency)
- name: processedDomainEvents
type: Set
required: true
description: Set of domain event IDs already processed (idempotency)
- name: pendingNotifications
type: List
required: true
description: Notifications awaiting trigger evaluation with associated event data
- name: scheduledNotifications
type: List
required: true
description: Notifications scheduled for future dispatch with schedule metadata
- name: dispatchedNotifications
type: List
required: true
description: Notifications that have been dispatched with delivery status
- name: version
type: integer
required: true
description: Aggregate version for optimistic concurrency control
- name: packageNotificationConfig
type: PackageNotificationConfig
required: false
description: Cached notification configuration for the package
---
## Overview
The **NotificationState** entity is the aggregate root for tracking the notification lifecycle of a policy. It maintains state about which notifications are pending, scheduled, and dispatched, and ensures idempotent processing of events and commands.
## Lifecycle States
Notifications progress through states:
| State | Description |
|-------|-------------|
| PENDING | Notification trigger rules are being evaluated |
| SCHEDULED | Notification is queued for future dispatch |
| DISPATCHED | Notification has been sent to the delivery provider |
## Key Responsibilities
- **Idempotency**: Track processed events and commands to prevent duplicate notifications
- **Trigger Evaluation**: Evaluate notification rules against current policy state
- **Schedule Management**: Manage scheduled notifications and cancellations
- **State Tracking**: Track dispatched notifications for audit and reporting
## Aggregate Variants
The notification service maintains two aggregate root implementations:
- **FuneralPolicyStateAggregateRoot**: For funeral policy notifications
- **ClaimStateAggregateRoot**: For claims notifications
## Invariants
- Each notification type can only be pending or scheduled once per policy
- Processed event IDs must be unique (idempotency)
- Scheduled notifications must have a valid schedule process ID
- Version must increment with each state change
---
id: OptionalBenefit
name: Optional Benefit
version: 1.0.0
identifier: benefitId
summary: An optional benefit that can be added to a product for additional cover or premium modifications.
properties:
- name: benefitId
type: UUID
required: true
description: Unique identifier for the optional benefit
- name: benefitType
type: OptionalBenefitType
required: true
description: Type of optional benefit
enum: ['TOP_UP', 'ACCIDENTAL_DEATH']
- name: coverModifier
type: Modifier
required: false
description: Modifier applied to the cover amount
- name: premiumModifier
type: Modifier
required: false
description: Modifier applied to the premium amount
- name: isActive
type: boolean
required: true
description: Whether the benefit is currently active
- name: createdDate
type: DateTime
required: true
description: When the benefit was added to the product
- name: startDate
type: DateTime
required: false
description: When the benefit coverage begins
- name: endDate
type: DateTime
required: false
description: When the benefit coverage ends
---
## Overview
The **OptionalBenefit** entity represents an optional benefit that can be added to a product. Optional benefits modify the base cover and/or premium amounts.
## Benefit Types
| Type | Description |
|------|-------------|
| TOP_UP | Additional cover as a percentage increase |
| ACCIDENTAL_DEATH | Extra cover for accidental death events |
## Modifiers
Each benefit has cover and premium modifiers that define how the benefit affects the product:
- **PERCENTAGE**: Applies a percentage increase (e.g., 10% additional cover)
- **FIXED**: Applies a fixed amount increase
## Lifecycle
Optional benefits can be:
- Added to a product during quote configuration
- Removed from a product
- Activated or deactivated
## Impact on Pricing
When optional benefits are active:
- `effectiveCover` = base cover + benefit cover modifier
- `effectivePremium` = base premium + benefit premium modifier
---
id: PackageNotificationConfig
name: Package Notification Configuration
version: 1.0.0
identifier: packageId
summary: Configuration containing all notification settings for a specific package.
properties:
- name: packageId
type: string (UUID)
required: true
description: Unique identifier for the package this configuration applies to
- name: notificationConfigs
type: List
required: true
description: List of notification configurations for this package
- name: senderIdentity
type: NotificationSenderIdentity
required: true
description: Default sender identity for notifications from this package
---
## Overview
The **PackageNotificationConfig** entity groups all notification configurations for a specific insurance package. It defines which notifications are enabled for the package and provides the default sender identity for all communications.
## Sender Identity
The sender identity defines:
| Field | Description |
|-------|-------------|
| emailFrom | Email address used as the sender (e.g., noreply@partner.co.za) |
| emailFromName | Display name for the sender (e.g., Partner Insurance) |
| smsFrom | SMS sender ID for text messages |
## Notification Configurations
Each package can have multiple notification configurations for different types:
### Policy Notifications
- Welcome/confirmation emails
- Cancellation notices
- Expiry reminders
- Payment reminders
- Beneficiary update reminders
### Claims Notifications
- Claim submission confirmations
- Approval/rejection notices
- Payout completion notices
## Configuration Lookup
When processing a notification event:
1. Load the PartnerNotificationConfig for the partner
2. Find the PackageNotificationConfig matching the policy's package
3. Locate the NotificationConfig for the specific notification type
4. Apply trigger rules to determine if notification should be sent
## Relationships
- Part of `PartnerNotificationConfig` aggregate
- Contains multiple `NotificationConfig` entries
- References `NotificationSenderIdentity` for sender details
---
id: PageConfiguration
name: Page Configuration
version: 1.0.0
identifier: htmlString
summary: Configuration settings for rendering a single page in a PDF document.
properties:
- name: htmlString
type: string
required: true
description: The HTML content to render as a PDF page
- name: format
type: string
required: false
description: Page format specification
enum: ['A4']
- name: margin
type: PageMargin
required: false
description: Page margins configuration (top, bottom, left, right in CSS units)
references: PageMargin
relationType: hasOne
- name: printBackground
type: boolean
required: false
description: Whether to print background colors and images
- name: displayHeaderFooter
type: boolean
required: false
description: Whether to display header and footer templates
- name: headerTemplate
type: string
required: false
description: HTML template for the page header
- name: footerTemplate
type: string
required: false
description: HTML template for the page footer
---
## Overview
The **Page Configuration** entity defines how a single page should be rendered when generating a PDF document. It encapsulates the HTML content and all formatting options that control the visual output.
## HTML Content
The `htmlString` property contains the full HTML document to render, including:
- HTML structure (``, ``, ``)
- Inline CSS styles or `