Batch eligibility sweeps
Outcome
Pre-flight 270 sweeps run nightly (or ad-hoc) so the intake desk only sees coverage anomalies before a visit. Failed-row exceptions are triaged in the queue.
Prerequisites
eligibility.readto view,eligibility.updateto schedule.- A configured trading partner for the payers being swept.
When to use a sweep
| Scenario | Approach |
|---|---|
| Nightly pre-flight | Schedule a sweep for next 24-72 hours so intake sees anomalies pre-visit. |
| Ad-hoc reconciliation | Run a 14-day backward sweep when a payer reports a benefits change for a known population. |
| New facility onboarding | Single sweep across the next 30 days to seed the eligibility cache before go-live. |
Schedule a nightly sweep
Open the Sweeps tab → Schedules sub-tab → New schedule.
Name the schedule (e.g.
Nightly outpatient pre-check).Pick a cron preset (
Nightly 2 AM UTC) or enter a custom 5-field expression. The dialog shows the next fire time as you type.Choose the scope:
Field Notes Facility Leave on All facilitiesfor tenant-wide; otherwise pick one.Window relative to fire time from 0to 7for "next 7 days from when the cron fires".Payer filter Leave blank to target every active coverage on each member; paste comma-separated payer UUIDs to narrow. Submit. The schedule is hot-loaded by the supervisor; the next cron firing creates an
eligibility_sweep_runrow and dispatches the job to the per-tenant queue.
Interpret the exception queue
The detail page exposes two sub-tabs:
- All members — every roster member, including SUBMITTED / RECEIVED. Use for routine post-run review.
- Exceptions — only
FAILEDandSKIPPEDper-member rows. Each row carries afailure_reason:
failure_reason | Meaning | Fix |
|---|---|---|
No active coverage on the service date | Roster found a scheduled visit but no qualifying coverage | Have intake desk add the policy and re-run the sweep, or initiate the per-member 270 directly. |
| 270 transport errors (timeouts, payer 999 rejects, gateway auth) | Surface verbatim from the upstream eligibility-service failure | Check trading-partner credentials in /admin/trading-partners; check per-feed alert dashboards. |
Cancelled by operator | Row was QUEUED when run was cancelled | Re-run sweep with same scope to retry. |
Cancel a stuck run
Open the run detail page from
/eligibility?tab=sweepsby clicking the run name.If RUNNING, click Cancel sweep. This:
- Updates queued
sweep_run_memberrows toSKIPPEDwith reasonCancelled by operator. - Sets the parent run to
CANCELLEDwithcompleted_at = now(). - Does not revoke 270s already submitted upstream — those resolve
independently as
RECEIVEDonce the 271 lands.
- Updates queued
Re-run with a narrower window if the original scope was the cause.
Drain the queue during incident response
If an upstream payer is degraded and the supervisor is hammering their gateway:
- Pause the schedule in-place (Schedules sub-tab → pause icon) rather than deleting it. New runs stop without losing the configuration.
- Existing in-flight runs continue draining — cancel them via the detail page if they need to stop sooner.
Service-level expectations
- Roster query — backed by a two-step
service.service_event→member.coverage_policylookup. Indexes(member_id, service_date)(status, service_date)keep the first leg under 100 ms even on 100k-event tenants.
- Fan-out — serial per-tenant inside
runSweep; the supervisor's concurrency limit governs how many sweeps run simultaneously across tenants. Tune viaINGEST_QUEUE_CONCURRENCY. - Idempotency — re-firing the same
sweepRunIdafter a worker crash is safe — terminal-status runs early-exit, and the unique index on(sweep_run_id, member_id)rejects duplicate insertions.
Validation
| Check | Expected |
|---|---|
| Schedule next-fire countdown | Counts down |
| Run row created on cron fire | Yes |
| Exceptions tab | Surfaces FAILED + SKIPPED |
| Idempotent re-fire | No duplicate rows |
Caveats / follow-ups
- The handler skips members with no qualifying coverage rather than routing them to a "needs intake" queue. If you want a CSR queue fed from sweep exceptions, wire an event-bus consumer onto the exception list — not in scope today.
- No per-payer rate limits. If a payer publishes a daily 270 cap, throttle by narrowing the schedule scope (e.g. one schedule per facility) rather than a tenant-wide schedule.
- Re-running a sweep against only its FAILED rows is not surfaced — edit the original scope by date or facility and run-now.
Cross-references
- Real-time event stream — sweep events surface to operators here.
- Authorization workflow + 278 lifecycle for the related auth-side flow.