Skip to content

fix(funding): paginate transfer reconcile past the first 100 (dup-payout guard) - #71

Open
keithfawcett wants to merge 1 commit into
mainfrom
fix/funding-reconcile-pagination
Open

fix(funding): paginate transfer reconcile past the first 100 (dup-payout guard)#71
keithfawcett wants to merge 1 commit into
mainfrom
fix/funding-reconcile-pagination

Conversation

@keithfawcett

Copy link
Copy Markdown
Contributor

Problem (audit #12 — one isolated subfix)

reconcileIntent (funding transfer executor) listed only the first 100 transfers in a batch's transfer_group to decide whether an ambiguous transfer had actually landed. A batch with >100 transfers whose match sat on a later page looked absent → the intent was reset to pending and re-posted, sending a duplicate partner transfer.

Fix

Page through the whole transfer_group via has_more / starting_after, stopping early once our openpartner_transfer_intent_id metadata stamp is found. This is the isolated, Codex-tagged safe subfix of the funding-race cluster (#12); HOSTED_FUNDING_ENABLED stays off.

Tests

New case: an ambiguous intent whose landed transfer is on page 2 now reconciles (confirmed, no re-POST) and the listing is called twice. All 12 executor tests pass; typecheck clean.

Not in this PR

The rest of #12 (ambiguous-PI re-create search, release-vs-create guard, inbox claim-after-process) and #10 (direct-Connect transfer-before-commit restructure) are larger money-state-machine changes — see the notes on the tracking issue; recommended as a focused, staged effort.

🤖 Generated with Claude Code

…out guard)

reconcileIntent listed only the first 100 transfers in a batch's
transfer_group. A batch with >100 transfers whose match sits on a later page
looked "absent", so the intent was reset to pending and RE-POSTED — a
duplicate partner transfer. Follow has_more to exhaustion (stop early on
match). Isolated, Codex-tagged safe subfix of the funding-race set (#12);
the flag stays off.

Test: an ambiguous intent whose landed transfer is on page 2 now reconciles
(confirmed, no re-POST) and the listing pages twice.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
it('reconcile pages past the first 100 transfers to find the match (no duplicate re-POST)', async () => {
const partnerId = await seedPartner();
const commissionIds = await seedCommissions(partnerId, 1, '50.00');
const batch = await fundedBatch(partnerId, commissionIds, 5000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant