On this page8 min left
At a glance
Claims and financing are long-running case workflows whose states, authority, evidence, and deadlines must be explicit.
Database changes and external side effects need a reliable event boundary; implicit callbacks are not a durable workflow.
Document extraction can accelerate review, but confidence thresholds and accountable human decisions remain essential for health and financial data.
01The operating problem
Two journeys, one case system
A hospital case can begin with an insured patient who needs help navigating a claim, or with a patient who needs a separate financing path. The customer experiences urgency and uncertainty; the system experiences documents, identity checks, status transitions, external organisations, money movement, deadlines, and human decisions.
- Claim-support journey: collect minimum intake data, establish authority, obtain policy and hospital documents, coordinate insurer queries, and track the claim to resolution.
- Financing journey: collect a separate application, perform authorised verification and assessment, record an accountable decision, establish repayment terms, and reconcile collections.
- Shared case operations: identity, consent or authority, documents, tasks, communication, audit history, deadlines, and role-based access.
Loading diagram…
- Hospital intake establishes the patient or representative and creates a case.
- An insured journey collects policy evidence and coordinates the claim lifecycle.
- A separate financing journey performs authorised application, assessment, decision, and agreement steps.
- Both journeys use shared document, task, communication, deadline, and audit services.
- Claim decisions remain owned by the insurer and authorised operations.
- Financing decisions remain owned by the authorised lender and reviewers.
- The case timeline records resolution, settlement, repayment, closure, and any correction path.
02The source of truth
Model the case, not a collection of screens
Mobile intake and back-office portals are views over one case lifecycle. The domain model should remain stable when the frontend, vendor, or communication channel changes.
- Case identity: a non-recycled internal identifier; phone numbers and government identifiers are attributes, not durable primary keys.
- Participants and roles: patient, representative, hospital agent, operator, reviewer, insurer, lender, and payment provider.
- State and reason: every transition records who initiated it, the reason, evidence, policy version, and timestamp.
- Tasks and deadlines: required documents, insurer queries, reviews, follow-ups, payment events, and escalation dates.
- Documents by reference: encrypted object identity, document type, version, retention class, extraction state, and access policy.
03Case orchestration
Make claim progress observable
A claim workflow crosses organisational boundaries that do not share one API or clock. The platform needs a durable timeline that can represent documents requested, queries raised, responses submitted, approvals, partial settlements, rejections, appeals, and closure without collapsing them into one mutable status string.
- Validate the transition. Check the case type, current state, actor role, required evidence, and duplicate external reference.
- Commit state and event intent together. The database transaction writes the case change and an outbox event.
- Publish asynchronously. A dispatcher sends committed outbox records to the appropriate task or event channel.
- Perform idempotent side effects. Notifications and vendor calls use stable operation identifiers and record their result.
- Expose the timeline. Operators and customers see a filtered view of the same durable history.
Django signals can notify receivers when framework actions occur, but Django’s own signal guidance warns that signals can make code difficult to understand, adjust, and debug. Explicit application commands and domain events make core workflow dependencies easier to test.
04Recurring collection
Treat a payment mandate as its own state machine
A recurring repayment instruction is not a boolean called auto_pay. Registration, activation, scheduling, presentation, settlement, failure, retry, pause, cancellation, and reconciliation happen at different times and may be reported by different parties.
Loading diagram…
- Create a mandate request under the applicable participant and provider rules.
- Track registration separately from activation and rejection.
- An active mandate schedules distinct debit attempts with stable identities.
- A presented debit waits for authoritative settlement or failure status.
- Successful debits reconcile against the repayment ledger.
- Failed debits follow a policy-controlled retry, communication, or review path.
- The mandate can pause, change, cancel, expire, or complete without rewriting prior attempts.
- Scheduled reconciliation finds missing or inconsistent provider outcomes.
NPCI’s NACH overview describes NACH as infrastructure for high-volume, repetitive electronic transactions and mandate management. Actual participant roles, limits, notices, dispute processes, and regulatory obligations must be implemented from the applicable current rules and provider contract.
- Separate mandate and debit identity. One mandate can produce many scheduled collection attempts.
- Reconcile provider reports. API acceptance does not prove bank settlement; ingest authoritative status and settlement files or events.
- Make retries policy-driven. Respect attempt limits, dates, customer communication, and applicable rules.
- Preserve adjustments. Pauses, cancellations, changed schedules, refunds, and write-offs remain visible in the ledger and audit trail.
05Reliable side effects
Use an outbox between state and communication
A notification should be caused by a committed business event, not by hoping a background task was published after a database save. The transactional-outbox pattern writes the event in the same transaction as the case change, then publishes it independently.
def transition_case(case_id, command, actor):
with database.transaction():
case = cases.lock(case_id)
transition = policy.validate(case, command, actor)
case.apply(transition)
cases.save(case)
outbox.append(
event_id=stable_event_id(case.id, case.version),
event_type="case.status_changed",
aggregate_id=case.id,
payload={
"from": transition.previous_state,
"to": transition.next_state,
"reason_code": transition.reason_code,
},
)
return case.snapshot()
def publish_outbox(record):
broker.publish(
topic=record.event_type,
key=record.aggregate_id,
payload=record.payload,
idempotency_key=record.event_id,
)
outbox.mark_published(record.event_id)06External truth
Ingest status updates as untrusted events
Some partners provide structured webhooks or APIs; others still send automated email. Prefer authenticated structured integration when it exists. When polling a mailbox is unavoidable, treat email as an external protocol with identity, parsing, replay, and quarantine concerns.
- Keep the raw message. Store an immutable reference and cryptographic digest according to retention policy before parsing.
- Identify idempotently. Use mailbox identity, provider message ID, attachment digest, and external claim reference.
- Parse into a candidate event. Extract sender, claim identifier, status, reason, dates, and confidence without updating the case directly.
- Validate correlation. Confirm sender policy, case identity, allowed transition, and whether the message supersedes an earlier update.
- Quarantine ambiguity. Unknown templates, conflicting references, and low-confidence results go to an operator queue.
07Know Your Policy
Extract, validate, then summarise
A policy document can contain dozens of pages of definitions, exclusions, schedules, limits, and endorsements. The goal of a KYP summary is not merely OCR. It is a traceable, human-reviewed transformation from source pages into a compact explanation.
Loading diagram…
- The authorised user uploads a policy through a scoped object-storage path.
- Media validation confirms identity, type, checksum, and security policy.
- A durable queue sends the document to a versioned extraction worker.
- OCR and layout or field extraction preserve page-level source coordinates.
- Deterministic validation checks types, cross-field rules, missing values, and contradictions.
- Low-confidence or conflicting fields become explicit review tasks.
- A summary draft uses only validated fields and cited source passages.
- An authorised reviewer corrects and approves the one-page KYP output.
- The system records versions, evidence, reviewer, and retention state.
| Decision | TextOCR only | FieldsSchema extraction | ReasoningLLM-assisted review |
|---|---|---|---|
| Best for | Searchable text, page coordinates, and documents with downstream deterministic parsing. | Known fields, repeated document families, tables, and confidence-driven review. | Drafting explanations across variable clauses when every claim can cite source spans. |
| You own | Reading order, tables, field rules, normalization, and validation. | Schema versions, labelled evaluation data, field validation, and vendor lifecycle. | Grounding, prompt/version control, evaluation, abstention, and mandatory review. |
| Trade-off | Transparent baseline, but weak for varied layouts and semantic fields. | More structured output with model-specific errors and migrations. | Flexible language with a higher risk of unsupported interpretation. |
| Examples | Text and bounding boxes from scanned pages. | Azure Document Intelligence custom extraction as a dated example. | Draft a summary from validated fields and cited policy passages. |
Text
OCR only
- Best for
- Searchable text, page coordinates, and documents with downstream deterministic parsing.
- You own
- Reading order, tables, field rules, normalization, and validation.
- Trade-off
- Transparent baseline, but weak for varied layouts and semantic fields.
- Examples
- Text and bounding boxes from scanned pages.
Fields
Schema extraction
- Best for
- Known fields, repeated document families, tables, and confidence-driven review.
- You own
- Schema versions, labelled evaluation data, field validation, and vendor lifecycle.
- Trade-off
- More structured output with model-specific errors and migrations.
- Examples
- Azure Document Intelligence custom extraction as a dated example.
Reasoning
LLM-assisted review
- Best for
- Drafting explanations across variable clauses when every claim can cite source spans.
- You own
- Grounding, prompt/version control, evaluation, abstention, and mandatory review.
- Trade-off
- Flexible language with a higher risk of unsupported interpretation.
- Examples
- Draft a summary from validated fields and cited policy passages.
The service formerly described as Form Recognizer is now documented as Azure Document Intelligence. It remains a dated example; service selection should be based on representative policies, field-level evaluation, data handling, regional availability, lifecycle, and cost.
08Sensitive data
Design for health, identity, and financial data
A case may contain medical documents, identity records, policy details, credit information, bank mandates, contact history, and decisions with real consequences. Security and privacy requirements belong in the domain model and workflow—not only in infrastructure configuration.
- Minimise collection. Gather only the fields and documents required for the authorised case purpose.
- Separate roles. Hospital intake, claims operations, financing review, payment operations, support, and administration need different access.
- Encrypt and isolate. Protect data in transit and at rest, separate environments and tenants, and keep secrets outside application records.
- Audit reads and changes. Record evidence access, export, decision, override, document version, and policy version.
- Retain by data class. Source documents, extracted fields, communication, payment records, and derived summaries can require different schedules.
- Keep human accountability. Credit, coverage, medical, claim, and enforcement decisions remain owned by authorised people and organisations.
09Production behavior
Optimise turnaround time without hiding failure
Asynchronous work protects the request path, but queue depth and retries can quietly turn into customer delay. Operational metrics must connect infrastructure state to case outcomes.
- Measure age, not only count. Track the oldest ready task, processing time, retry age, and time spent awaiting a person or partner.
- Make tasks idempotent. Celery’s task guidance notes that redelivery can occur and recommends idempotent task behavior.
- Bound retries. Retry only transient errors, with backoff, deadlines, and a terminal inspection path.
- Separate workloads. Long document jobs, quick notifications, mailbox ingestion, and reconciliation need independent capacity and timeouts.
- Reconcile external truth. Scheduled checks detect missing webhooks, incomplete outbox publication, unsettled debits, and stalled cases.
- Measure correction. Track document field corrections, status overrides, notification failures, disputed decisions, and reopened cases.
The original project reported producing a KYP document in under five minutes. Treat that as a historical outcome from one workload—not a current guarantee. Define service targets from document size, queue capacity, provider latency, review requirements, and measured percentiles.
10Implementation sketch
An idempotent document worker
The worker records extraction identity and confidence before creating a summary draft. Low-confidence or contradictory fields become review tasks rather than guessed values.
def process_policy_document(document_id: str, event_id: str) -> None:
document = documents.claim(
document_id=document_id,
event_id=event_id,
allowed_states={"queued", "retryable"},
)
if document is None:
return
source = secure_objects.open_verified(
document.object_key,
checksum=document.checksum,
)
extraction = document_ai.extract(
source,
schema_version=document.schema_version,
)
validated = validators.check(
extraction.fields,
source_pages=extraction.citations,
)
review_fields = [
field for field in validated
if field.confidence < field.review_threshold
or field.has_conflict
]
draft = summaries.create_from_validated_fields(
fields=validated,
require_source_citations=True,
)
documents.finish(
document_id=document.id,
extraction=validated.redacted(),
summary_draft=draft,
next_state="review_required",
review_fields=review_fields,
){
"event_id": "evt_01J...",
"event_type": "case.status_changed",
"occurred_at": "2026-07-29T10:30:00Z",
"aggregate": {
"type": "claim_case",
"id": "case_01J...",
"version": 17
},
"transition": {
"from": "insurer_query_received",
"to": "response_under_review",
"reason_code": "documents_uploaded"
},
"actor": {
"type": "operator",
"id": "user_01J..."
}
}11Before launch
A case-platform checklist
- Define states and owners. Every claim, application, mandate, debit, document, task, and review state has allowed transitions and an accountable actor.
- Test transaction boundaries. Database commits, outbox publication, external calls, callbacks, and retries cannot create missing or duplicate effects.
- Reconcile every provider. Detect missing notifications, inconsistent statuses, duplicate messages, and unsettled money movement.
- Evaluate document fields. Use representative policies and field-level accuracy, confidence, citation, and reviewer-correction metrics.
- Exercise access and retention. Test roles, revocation, document exports, audit trails, deletion schedules, and support access.
- Keep people in the decision. Sensitive determinations have review evidence, override paths, explanations, and appeal or correction processes.
12Working vocabulary
Glossary
- Case
- The durable aggregate containing participants, state, tasks, documents, deadlines, events, and audit history for one customer journey.
- Domain event
- A versioned record that a meaningful business transition occurred.
- Transactional outbox
- A pattern that stores event intent in the same database transaction as a state change, then publishes it asynchronously.
- Mandate
- An authorised recurring-payment instruction with its own registration, activation, change, and cancellation lifecycle.
- Reconciliation
- Comparing internal records with authoritative external reports or events and resolving differences.
- KYP
- Know Your Policy: a concise, reviewable explanation derived from an insurance policy and linked back to source evidence.
- Confidence threshold
- A field-specific boundary below which automated output is routed to review rather than accepted.
- Idempotent task
- A task that can receive the same intended operation again without creating duplicate business effects.
13Sources and further reading
References
- Building a Claims & Financing Engine from the Ground Up
Abhishek Choudhury
Original project article, published February 2025. - NACH: High Volume Repetitive Payment Solution
National Payments Corporation of India
An overview of NACH transactions and mandate management. - Django signals
Django Software Foundation
Signal behavior and the maintainability warning for implicit coupling. - Celery tasks
Celery Project
Task delivery, idempotency, timeouts, and worker behavior. - Azure Document Intelligence documentation
Microsoft
Current product terminology, capabilities, versions, and lifecycle. - Transparency note for Document Intelligence
Microsoft
Responsible-use considerations for the document-processing service.



