# TODO: Mastercom sandbox queue sync — unbounded growth

Filed 2026-08-10 after investigating why the Chargeback Management dashboard showed
48,000+ cases and climbing. **Deliberately not fixed yet** — see "Current decision"
below. This doc exists so the fix isn't forgotten, not because anything is broken.

## Root cause

`DisputeCore.Workers.MastercomQueueSyncWorker` runs every 30 minutes
(`config/config.exs:205`, `*/30 * * * *`) and creates a local `chargeback_cases` row
for every claim it finds in Mastercom's `AcquirerFirstCBUnworked` sandbox queue that it
hasn't synced before (dedup by `mastercom_claim_id` — this part works correctly, see
`sync_claim/1`).

The problem isn't the dedup logic. It's what's being synced *from*: Mastercard's public
sandbox queue is shared, synthetic test data, not scoped to our own merchants. Confirmed
by direct DB query on 2026-08-10:

- `merchants` table: **1** real row ("Test Risk Merchant Store").
- `chargeback_cases`: **48,692** rows, **47,579 distinct `merchant_mid`** values — i.e.
  almost every synced case has a MID that's never been seen before and doesn't belong to
  any merchant in our system.
- Growth is accelerating, not steady: 1 case on 2026-08-07 (day it started), 2,486 on
  2026-08-08, 19,087 on 2026-08-09, 27,118 on 2026-08-10 (partial day at time of
  measurement).

Since the sandbox queue is a shared pool other developers/tenants also hit, and Mastercard
keeps seeding it with fresh synthetic claims, `AcquirerFirstCBUnworked` never runs dry —
the worker will keep finding "new" (to us) claim IDs and creating cases for them
indefinitely, at whatever rate the sandbox generates them.

## Current decision (2026-08-10)

Left running as-is, on purpose — currently being used to load-test the rest of the
system (dashboard, analytics, table performance) against a large, continuously growing
`chargeback_cases` table. The ~48,691 rows already created are **not** to be cleaned up.
Table-load performance was fixed separately (pagination + bounded queries — see the
Disputes-module perf work landed alongside this doc) so growth here no longer means an
unbounded page load; it was that fix, not this one, that was actually urgent.

## When revisiting this

Two independent remediation options, either or both:

1. **Filter by known merchant.** In `MastercomQueueSyncWorker.sync_claim/1`
   (`apps/dispute_core/lib/dispute_core/workers/mastercom_queue_sync_worker.ex`), only
   call `fetch_and_create/1` when `claim["merchantId"]` matches a real row in
   `merchants`. Keeps the sync flow intact for cases that are actually ours; stops
   ingesting the rest of the sandbox's shared test pool as if it were real Mercury
   chargeback volume.

2. **Pause or throttle the cron.** Remove/adjust the
   `{"*/30 * * * *", DisputeCore.Workers.MastercomQueueSyncWorker, args: %{}}` entry in
   `config/config.exs:205` — e.g. disable it outright in non-prod, or move to a much
   longer interval, once the load-testing purpose above is done.

Either change is small and isolated. Worth doing before this environment is used for
anything other than load-testing, since a demo/UAT session showing tens of thousands of
chargebacks against MIDs nobody recognizes is confusing at best.
