S
sai
Guest
"Design the claims experience" is a deceptively broad prompt. A carrier's claims platform spans intake, fraud detection, estimating, payments, subrogation, and correspondence — hours of material. In a 45-minute interview, the real skill isn't covering everything; it's scoping hard, picking the two flows that matter, and designing them end to end. I chose filing a claim (first notice of loss, or FNOL) and the adjuster work queue.
I start by writing the requirements down so the interviewer and I agree on scope. Functionally: let a policyholder file a claim and upload damage photos and documents; process those into derived artifacts (thumbnails for fast review, an input for an ML damage-estimate model, OCR'd text from documents, a virus scan); score and prioritize open claims into each adjuster's work queue; and support mobile and web. Non-functionally: high availability, durability (never lose a claim or a photo), an auditable trail for compliance, eventual consistency, horizontal scalability, and low latency for adjuster productivity. Durability and auditability quietly drive most of the design.
Figure 1 — The two flows: claim intake / write path (top) and the precomputed adjuster work queue / read path (bottom).
The key decision is to keep large media off my own servers. When a policyholder files, the app calls a claims-intake microservice through a load balancer. The service does two cheap things: it writes a claim metadata row (claimID, policyID, lossDate, docLink, status, timestamp) to a SQL store, and it returns a pre-signed S3 URL with a short expiry. The client then uploads the damage photos and documents directly to S3 — my services never handle the bytes. I deliberately avoid putting the media into a message queue; a batch of high-resolution photos would blow up queue memory.
Raw uploads aren't useful until they're processed. I trigger this with change data capture: the insert into the metadata table fires a CDC event that fans work out to a pool of processing workers. Each worker pulls the media from S3 and produces the derived artifacts — thumbnails, an ML damage-estimate input, OCR text, a virus scan — writing the results back to S3 and recording the new links in the table. The intake tier itself is sharded by a hash key (~100 shards) and fronted by load balancers, so it scales horizontally and stays stateless.
Ranking every adjuster's worklist on each dashboard load is too slow, so I precompute. A Scoring Service ranks open claims by severity, SLA urgency, complexity, and fraud signal, and an async job runs near-real-time to produce, per adjuster and skill queue, a Top-K prioritized list. The Queue Generation Service stores these lists in a NoSQL key-value store, keyed by (adjuster, queue).
When an adjuster opens the dashboard, we don't rank anything live: we return their precomputed worklist through the load balancer. Reads stay fast, the queue stays current enough under eventual consistency, and the expensive scoring happens off the request path — for example, adjuster "sai" opens the auto physical-damage queue and immediately sees the highest-priority open claims.
My first pass leaves room to sharpen a few decisions, and these are the ones that land:
In system design, scoping is the skill. Two flows designed cleanly — direct-to-S3 uploads, CDC-triggered processing, and a precomputed work queue — beat ten boxes drawn without depth. That focus is what carries an interview, and it is exactly how you'd build the real platform.
1. Amazon S3 User Guide, "Sharing objects with presigned URLs" — https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html
2. Debezium documentation (change data capture) — https://debezium.io/documentation/
3. Martin Fowler, "Audit Log," Patterns of Enterprise Application Architecture — https://martinfowler.com/eaaDev/AuditLog.html
AI Disclosure: AI tools were used for research assistance, reference gathering, and editorial support. The author reviewed, verified, and approved the final content.
Framing the requirements
I start by writing the requirements down so the interviewer and I agree on scope. Functionally: let a policyholder file a claim and upload damage photos and documents; process those into derived artifacts (thumbnails for fast review, an input for an ML damage-estimate model, OCR'd text from documents, a virus scan); score and prioritize open claims into each adjuster's work queue; and support mobile and web. Non-functionally: high availability, durability (never lose a claim or a photo), an auditable trail for compliance, eventual consistency, horizontal scalability, and low latency for adjuster productivity. Durability and auditability quietly drive most of the design.
Figure 1 — The two flows: claim intake / write path (top) and the precomputed adjuster work queue / read path (bottom).
Flow 1 — Filing a claim (FNOL)
The key decision is to keep large media off my own servers. When a policyholder files, the app calls a claims-intake microservice through a load balancer. The service does two cheap things: it writes a claim metadata row (claimID, policyID, lossDate, docLink, status, timestamp) to a SQL store, and it returns a pre-signed S3 URL with a short expiry. The client then uploads the damage photos and documents directly to S3 — my services never handle the bytes. I deliberately avoid putting the media into a message queue; a batch of high-resolution photos would blow up queue memory.
Raw uploads aren't useful until they're processed. I trigger this with change data capture: the insert into the metadata table fires a CDC event that fans work out to a pool of processing workers. Each worker pulls the media from S3 and produces the derived artifacts — thumbnails, an ML damage-estimate input, OCR text, a virus scan — writing the results back to S3 and recording the new links in the table. The intake tier itself is sharded by a hash key (~100 shards) and fronted by load balancers, so it scales horizontally and stays stateless.
user work queue
Ranking every adjuster's worklist on each dashboard load is too slow, so I precompute. A Scoring Service ranks open claims by severity, SLA urgency, complexity, and fraud signal, and an async job runs near-real-time to produce, per adjuster and skill queue, a Top-K prioritized list. The Queue Generation Service stores these lists in a NoSQL key-value store, keyed by (adjuster, queue).
When an adjuster opens the dashboard, we don't rank anything live: we return their precomputed worklist through the load balancer. Reads stay fast, the queue stays current enough under eventual consistency, and the expensive scoring happens off the request path — for example, adjuster "sai" opens the auto physical-damage queue and immediately sees the highest-priority open claims.
What an interviewer wants to hear
My first pass leaves room to sharpen a few decisions, and these are the ones that land:
The meta-lesson
In system design, scoping is the skill. Two flows designed cleanly — direct-to-S3 uploads, CDC-triggered processing, and a precomputed work queue — beat ten boxes drawn without depth. That focus is what carries an interview, and it is exactly how you'd build the real platform.
References
1. Amazon S3 User Guide, "Sharing objects with presigned URLs" — https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html
2. Debezium documentation (change data capture) — https://debezium.io/documentation/
3. Martin Fowler, "Audit Log," Patterns of Enterprise Application Architecture — https://martinfowler.com/eaaDev/AuditLog.html
AI Disclosure: AI tools were used for research assistance, reference gathering, and editorial support. The author reviewed, verified, and approved the final content.