Design a platform that ingests a monthly Medicaid claims snapshot with more than 200 million rows, enriches it, runs fixed-rule rules, supervised models, temporal statistics, and provider-beneficiary network analysis, then gives investigators a prioritized case queue. Every score must be reproducible and false positives are expensive.
A Lead Is Not a Verdict
Design a reproducible Medicaid fraud, waste, and abuse analytics platform over hundreds of millions of rows—without drowning investigators or turning anomalies into accusations.
The answer map
Do not memorize every box. Remember this path and rebuild the answer from it.
Understand the problem
Restate the goal in plain English. Name the one thing the system must never get wrong.
The first rule is simple: a risk score is only a lead for an investigator. It must never deny payment or declare fraud by itself. A human reviews the source claims and decides what happens next.
I need to know the batch deadline, how corrected claims arrive, how many cases investigators can handle, and which mistakes cost more: missed abuse or a needless review. For every run, I save the exact source files, code, rules, model, and settings. That saved version list lets us reproduce any score later.
Step 1 · Set the scope
Name the users, must-have features, speed and safety goals, and what is out of scope.
Scope a first release. State actors, functional requirements, service targets, and exclusions.
Data stewards load claim and provider data. Analysts and investigators review risk leads. Supervisors manage the limited case queue. Rule owners, compliance reviewers, operators, and auditors govern the system. Version one checks data quality, runs several detector types, groups related alerts into cases, assigns those cases, and exports the exact evidence behind a score. It learns only from cases that were actually reviewed and decided.
For this mock, a 250-million-row batch must publish within 36 hours after all inputs arrive. The case list should load in under one second for 95 out of 100 requests; an evidence page gets three seconds. We must reproduce a score for seven years. We are not blocking claims in real time, deciding criminal fraud, contacting providers, or building one identity graph across every state.
Data stewards, analysts, investigators, supervisors, rule/model owners, compliance, auditors, and platform SREs.
Snapshot ingest, quality/enrichment, rule/statistical/ML/graph detectors, composite receipts, lead grouping, queue, disposition.
Lead ≠ verdict. Time-safe features. Exact score replay. Corrections supersede. Source evidence preserved.
250M rows in 36 h, 99.5% batch success, UI p95 <1 s, evidence p95 <3 s, seven-year reproducibility.
Program isolation, FTI/PHI controls, least privilege, purpose binding, break-glass, signed exports.
Real-time claim denial, fraud expert review to settle disagreements, criminal referral automation, universal cross-state identity graph.
Step 2 · Do the useful math
Estimate only what changes the design. After each number, say why it matters.
Assume 250 million claim lines, 5,000 rows/second per worker, a 36-hour window, 1% raw flag rate, 500 investigators, and 20 cases per investigator per day. Quantify it.
At perfect utilization one worker needs 50,000 seconds, or 13.9 hours, to scan all rows—so throughput math alone says one worker fits 36 hours. With 50% effective duty cycle and 50% failure/headroom, the one-pass equivalent rounds up to two workers. That deceptively small result ignores joins, multiple detector passes, shuffle, skew, retries, and roughly four feature facts per row. In practice shuffle partitions number in the hundreds for parallel stages and skew isolation, not because raw scan bandwidth alone requires them.
The bigger constraint is decisions: 1% produces 2.5 million raw hits, while investigators can close only 10,000 cases/day. We need grouping, suppression, calibrated risk, diversity/coverage constraints, and a fixed intake budget. Optimizing detector recall without modeling human service capacity makes the queue unstable.
Batch throughput versus investigator service capacity
Steps 4–5 · APIs and data
Start with the few records the system cannot work without. Then add simple endpoints around them.
Show the data model and APIs. How do I rerun the exact score from six months ago?
I need four main records. A BatchManifest is the saved list of exact input files, row counts, code, rules, model, and settings used for one run. A ScoreReceipt explains one score and points back to its claim rows and feature values. A Lead groups related alerts into one case. A Disposition records what an investigator decided.
We never overwrite a published score. Corrected claims create a newer batch for future use while the old result remains explainable. Dates on feature records prevent a model from using information that arrived after the period being scored. APIs publish batches, search leads, open evidence, assign work, save decisions, and export a replay package.
Records and how we find them
| Record | Main key / retry key | Fields we never overwrite | How we find it |
|---|---|---|---|
BatchManifest | (program_id, batch_id) | source/partition digests, schemas, code/rule/model/graph manifests, seed | publication, replay, batch comparison |
CanonicalClaim | (program_id, claim_line_id, source_version) | service time, provider/member IDs, amounts, quality flags | partition by period; evidence by lead |
FeatureVector | (entity_id, as_of, feature_set_version) | values, windows, reference digests, quality score | model inference; audit by entity/time |
DetectorReceipt | (batch_id, entity_id, detector_id) | rule operands or model/graph score, version, calibration, evidence IDs | group by entity; reproduce score |
Lead | (program_id, lead_id, version) | entity set, score components, queue policy, rank reasons, supersession | queue by skill/status/priority |
CaseDisposition | (case_id, disposition_version) | investigator, evidence viewed, outcome, reason, maturity, supervisor | feedback/evaluation; appeals |
QueueLease | (queue_id, lead_id) | assignee, expires_at, version | atomic claim/renew/release |
Simple API
POST /v1/programs/{p}/batches manifest + source digests
POST /v1/batches/{id}/seal expected source control totals
POST /v1/batches/{id}/publish If-Match: COMPLETED
GET /v1/leads?queue=&status=&cursor= stable rank cursor + policy version
POST /v1/leads/{id}:claim Idempotency-Key + lease TTL
GET /v1/leads/{id}/evidence source rows + detector receipts
POST /v1/cases/{id}/dispositions If-Match: case_version
GET /v1/scores/{receipt_id}/reproduction manifest + operands + tolerances
POST /v1/batches/{id}:supersede corrected_source_manifestSteps 3 and 6 · Draw, then follow one request
Explain the system in a few parts. Then follow one real request from the user to the final result.
Walk through the end-to-end architecture. Which parts are batch, streaming, and transactional?
I would draw five parts: file intake, batch processing, detectors, case selection, and the investigator app. Intake checks file fingerprints, schemas, dates, row counts, and completeness. Batch workers turn the files into a standard table and isolate bad rows for review. Rule, statistics, model, and network detectors all read the same frozen batch.
The combiner keeps each detector’s evidence, then groups related claim alerts into one provider or member case. Because investigators can review only a fixed number, a queue policy chooses the strongest cases while preserving required policy cases and a small exploration sample. Publishing the batch also saves an event for the case index in the same database transaction. Investigator decisions become training labels only after supervisor review.
Make every score reproducible
A result is the write-once function of a frozen source set, code, features, models, graph view, and policy.
Deep dive on reproducibility. Reference tables are corrected, code dependencies move, and graph algorithms can be nondeterministic.
Every reference lookup is time-aware and locked to a source file fingerprint. “latest provider file” is forbidden in a published run. The container image and dependency lockfile are identified by a file fingerprint. Rule DSL compiles to a stored plan. Feature definitions include null/imputation and window semantics. Stable ordering, fixed seeds, fixed-rule reducers, and explicit tie-breaking control graph/model nondeterminism. Hardware/library differences are either constrained by the release version list or accepted within a documented numeric tolerance.
A replay mode reads the original version list in an isolated ID group and writes a comparison report, never replacing history. We cross-check input row counts, partition hashes, feature aggregates, detector hit counts, lead counts, and a sample of per-entity receipts. An auditor can reconstruct one lead without recomputing all 250M rows because its evidence package contains source row IDs, feature operands, rule traces, and model/graph version lists.
A claim gets a fraud-risk score of 82 today. Six months later an auditor asks why. The receipt lets us run the same claim through the same source files, rules, and model version and get 82 again.
score_receipt = {
batch_id, entity_id, source_row_ids[], feature_vector_digest,
rule_hits[{rule_version, operands}], model_scores[{model, calibrator}],
graph_scores[{projection, component, seed}], quality_penalty,
composite_policy_version, final_score, created_at
}Optimize investigative yield, not raw flags
Selection bias, duplicate hits, skill constraints, and finite case service rate belong in the algorithm.
Deep dive on false-positive controls and investigator queues. Labels are biased because investigators mostly reviewed the old model’s top scores.
I keep detector scores separate instead of collapsing them into an unexplained “fraud probability.” The combiner calibrates on adjudicated outcomes, but selection bias means observed labels are missing-not-at-random. We reserve a small random or stratified exploration sample, use inverse-propensity analysis where appropriate, and track label source and maturity. Unreviewed does not mean negative.
Queueing is a service-design problem: group duplicate claim hits into one coherent lead. Suppress known explained patterns. Respect open-case locks and investigator skills. Cap provider exposure. Reserve slots for high-severity policy rules and exploration. Then rank by expected recoverable value, harm, evidence strength, novelty, and age. Supervisors see why a case ranked, what was suppressed, and slice-level yield. Queue changes are policy versions, not hidden model tweaks.
One provider causes 500 similar alerts. Sending all 500 would fill the queue with one pattern. We group them into one case with examples, then reserve some investigator time for new patterns.
| Control | Failure it prevents |
|---|---|
| Episode/entity grouping | One pattern flooding hundreds of duplicate claim-line leads. |
| Open-case and known-explanation suppression | Re-investigating already resolved behavior. |
| Reserved exploration sample | Training only on yesterday’s model-selected positives. |
| Capacity and skill budget | An unstable queue whose arrival rate exceeds service rate. |
| Evidence/rank explanation | Opaque accusation and reviewer anchoring. |
What if it breaks?
Protect the correct data first. Then contain the problem, recover, and explain what users see.
Eligibility corrections arrive after publication and affect 8% of members. Half the investigators have already acted on leads. What do you do?
The input version list had a completeness freshness marker. If it was violated, the published batch is marked impaired but remains reproducible. I ingest the correction as a new source version, compute data-history impact for affected member/time partitions, and build superseding batch B42. We do not mutate scores under open cases.
For untouched leads, queue policy withdraws or replaces them with an explicit reason. For acted-on cases, we attach a material-change alert, recomputed evidence, and required supervisor acknowledgment. Downstream financial action needs its own cross-checking. The data steward receives a completeness incident. Future publication can require two-source control totals and an explicit waiver when the source misses its freshness marker.
What if timing gets messy?
Retries, delayed messages, and two updates at once are normal. State the rule that keeps one clear result.
A dominant clearinghouse creates a graph supernode. One partition runs for 18 hours while the rest finish. Network risk suddenly flags 40% of providers.
That is likely topology and compute skew, not a fraud epidemic. The graph view excludes or downweights known infrastructural hubs by typed edge semantics. It does not create a naive graph where any shared intermediary implies collusion. We monitor degree distributions and component growth before scoring. Heavy keys get salted partitions, two-stage aggregation, degree caps, and a dedicated skew lane.
I trip a detector-level circuit breaker when hit-rate or distribution shift exceeds bounds. Rules and other models can publish, but graph-derived leads stay shadowed until reviewed. A backfill runs on a corrected read-ready copy version. Score receipts make the change explicit. We never silently lower a threshold just to fit the deadline.
Keep it safe and running
Cover overload, security, monitoring, and disaster recovery in that order.
Cover idempotency, overload control, state isolation, security, monitoring, and DR.
Each stage key is (program,batch,input_partition_digest,stage_version). Write-once outputs and a commit version list make retries safe. Scheduler queues have per-program quotas, stage concurrency, retry budgets, straggler detection, and separate urgent/live versus historical backfill pools. Publication uses compare-and-set on batch state plus a database-backed event queue. Investigator assignment uses leases and optimistic versioning so two users cannot dispose one case concurrently.
State programs have separate object prefixes/accounts, keys, catalogs, serving indexes, and worker identities where contracts require. Access policy combines program, role, purpose, case assignment, and break-glass. FTI/PHI never enters metrics. Monitor input completeness, row quarantine, stage critical path, skew, cost, score drift, calibration, flags and confirmed yield by slice, queue age/capacity, overrides, audit export, and privileged access. Replicate version lists/objects, rebuild serving stores from published batches, and rehearse regional restore with RPO/RTO evidence.
Completeness freshness marker, row/control totals, quarantine rate, reference freshness, data history gaps.
Critical-path age, partition skew, retry/failed-job queue, cost per million rows, publish deadline, reproducibility mismatch.
Calibration, precision/yield, confirmed value, false-positive/appeal, drift, hit rate, fairness by policy-relevant slice.
Arrival/service rate, age, skill fragmentation, lease conflicts, duplicate/suppressed leads, exploration coverage.
Program-specific accounts/namespaces/keys/catalogs/indexes, access policy by role/purpose/case, FTI/PHI-redacted telemetry.
Write-once inputs and version lists replicated. Serving indexes rebuilt. Published batch pointer rolled back. Restore exercised.
Rollout and trade-offs
A credible production answer defines how it earns trust and how it retreats safely.
Rollout plan and the most important trade-off?
Start with data-quality reports. Then replay historical periods. Run rules/model/graph in shadow beside the old process. Show evidence to a small investigator cohort without changing queue rank. Canary queue policy with matched control investigators. Expand only when yield, reviewer time, subgroup fairness, recoverable value, reproducibility, and appeals stay within gates. Automatic adverse action remains out of scope.
The trade-off is detector recall versus constrained human attention and false accusation. A giant uncalibrated queue looks “sensitive” but wastes investigators and damages providers. I prefer an explicit capacity budget, diverse evidence, honest uncertainty, and exploration designed to learn about blind spots.
- Publish data-quality-only reports.
- Replay multiple historical periods with frozen labels and leakage tests.
- Shadow all detectors beside the existing workflow.
- Show evidence without changing investigator rank.
- Canary queue policy with matched control groups and supervisor review.
- Reserve random/stratified exploration to measure blind spots.
- Expand by detector/program only when yield, fairness, appeals, queue, and reproducibility pass.
- Keep adverse automatic action outside the system boundary.
One-minute spoken recap
Practice this synthesis until it sounds conversational rather than memorized.
One-minute summary.
I’ll connect frozen batch truth, explainable detector receipts, bounded queues, and safe correction.
Reference shelf
Definitions, traps, and the final checklist stay outside the timed mock.
- Adjudicated label
- An outcome reviewed under a defined policy, not merely an investigator click or unreviewed negative.
- Bitemporal reference
- A table tracking both real-world effective time and system-recorded time.
- Calibration
- Agreement between predicted probability and observed outcome frequency.
- Composite score
- A policy-governed combination of distinct detector evidence, not necessarily a fraud probability.
- Data-quality penalty
- Explicit reduction or abstention when source completeness makes a score less trustworthy.
- Feature leakage
- Using information unavailable at the historical decision time, producing unrealistically good evaluation.
- Graph projection
- A typed selection of nodes/edges built for a specific analysis; not every shared identifier belongs.
- Lead
- A reviewable evidence package suggesting investigation, not an adjudication.
- MNAR
- Missing not at random: labels are absent in a way related to the old selection process.
- Point-in-time feature
- A value computed using only information available as of a specified timestamp.
- Score receipt
- The versions, operands, evidence, and transformations needed to explain/reproduce one score.
- Straggler
- A slow partition or task that delays a whole distributed stage.
- Calling every outlier fraud.
- Counting unreviewed entities as negative training labels.
- Using current reference tables in a historical replay.
- Ranking 2.5M hits without modeling investigator service capacity.
- Building an untyped graph where shared clearinghouses imply collusion.
- Publishing aggregate precision while one provider or region collapses.
- Overwriting scores after a late source correction.
- Claiming exactly-once batch work instead of retry-safe stage commits.
- Mixing state-program PHI in shared caches, logs, or indexes.
- Letting a queue threshold drift outside version control.
- Measuring MAE/AUC without case yield, calibration, or business cost.
- Allowing investigators to see model score before a blinded quality study.
- Clarified actors, authority, business harm, and out-of-scope.
- Did correct BOTEC and named the variable that changes the architecture.
- Defined stable IDs, versions, access paths, and retry keys.
- Separated source of truth state from derived indexes and model output.
- Explained consistency, retries, overload control, and unknown outcomes.
- Revised the design after both failure injections.
- Covered customer isolation, secrets, least privilege, deletion, and audit.
- Named golden signals, domain quality metrics, rollout gates, and rollback.