Skip to content

fix(distributions): resume partial runs from persisted allocation plan - #1346

Merged
thlpkee20-wq merged 3 commits into
RevoraOrg:masterfrom
Oluwasegun6921:fix/issue-1303-fix-distributions-resuming-a-partial-run
Oct 22, 2026
Merged

thlpkee20-wq merged 3 commits into
RevoraOrg:masterfrom
Oluwasegun6921:fix/issue-1303-fix-distributions-resuming-a-partial-run

Conversation

@Oluwasegun6921

Copy link
Copy Markdown
Contributor

Overview

This PR fixes a correctness bug in distributeWithBatch: when resuming a partially completed distribution run, the engine refetched balances and recomputed every investor's share from the new balances, then inserted payouts only for investors that did not already have one. Old and new payouts therefore came from different proration bases, so the sum of payouts could drift from run.total_amount, and a holder who arrived between the first attempt and the resume could receive a payout for a period they did not hold.

The fix persists the computed allocation when the run is created, executes that persisted plan on resume instead of recomputing, and asserts the payout total against the run total on completion.

Related Issue

Changes

🗄️ Schema

  • [ADD] src/db/migrations/044_create_distribution_allocations.sql
    • New distribution_allocations table storing the planned (run_id, investor_id, amount) allocation for each distribution run.
    • Unique constraint on (run_id, investor_id) so a plan can be written exactly once per investor per run.

⚙️ Distribution Engine

  • [MODIFY] src/services/distributionEngine.ts
    • Persist the computed allocation when a run is created, so the proration basis is frozen at run creation time.
    • On resume of a non-completed run, load the persisted plan and execute it instead of refetching balances and recomputing payouts.
    • Return a 409 when a non-completed run has no persisted plan, rather than silently recomputing from fresh balances.
    • After completion, assert sum(payouts) == run.total_amount using Decimal; on mismatch, mark the run failed and log the discrepancy.

🧪 Tests

  • [MODIFY] src/services/distributionEngine.test.ts
    • Crash-after-batch-1 then resume with changed balances: final payouts match the original plan and sum to the run total.
    • A new holder added before resume receives no payout.
    • Regression test that fails on master for the recompute-on-resume behavior.

Verification Results

npm test -- src/services/distributionEngine.test.ts
✅ distributionEngine tests passed (including new crash-resume and regression cases)
Acceptance Criteria Status
Crash after batch 1, change balances, resume: final payouts equal original plan and sum equals run total ✅ Persisted plan executed on resume; Decimal total assertion on completion
A new holder added before resume receives no payout ✅ Resume executes persisted plan only; new holders are absent from it
Tests in src/services/distributionEngine.test.ts, plus a regression test that fails on master ✅ Added crash-resume, new-holder, and regression coverage
CI stays green ✅ Type-check and test suite pass

Closes #1303

@drips-wave

drips-wave Bot commented Oct 20, 2026

Copy link
Copy Markdown

@Oluwasegun6921 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Oluwasegun6921
Oluwasegun6921 force-pushed the fix/issue-1303-fix-distributions-resuming-a-partial-run branch from b7268e4 to 902ef37 Compare October 22, 2026 06:52
Oluwasegun6921 and others added 2 commits October 22, 2026 10:13
Strips the payload this branch picked up (deleted api.js, truncated eslint.config.js, unhooked package.json). No functional change to the branch's own work.
@thlpkee20-wq
thlpkee20-wq merged commit 10b2523 into RevoraOrg:master Oct 22, 2026
1 check passed
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.

fix(distributions): resuming a partial run recomputes shares from fresh balances, so the sum of payouts no longer equals the run total

2 participants