Repository navigation
[HARD][FINANCE] Implement an immutable double-entry ledger for all balance movements #81
Copy link
Copy link
Closed
Labels
GrantFox OSSIssue tracked in GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignCampaign: Official CampaignOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Campaign: Official Campaign | FWC26
Description
Overview
Introduce an immutable double-entry accounting ledger as the source of truth for ChainMove wallet, investment, repayment, payout, fee, and adjustment balances.
Problem
The application currently updates denormalized fields such as User.availableBalance and writes a general transaction record. A partial failure, manual update, or future code path can cause the cached balance and transaction history to disagree. A finance platform needs balanced, auditable entries for every movement of value.
Scope
- Define ledger accounts for investor wallets, driver balances, pool escrow, platform clearing, revenue/fees, repayments receivable, payouts payable, and adjustment accounts.
- Add immutable journal and journal-entry models.
- Require every journal to contain balanced debit and credit totals.
- Create domain posting helpers for wallet funding, wallet debit, pool investment, down payment, repayment, refund, payout, fee, and administrative adjustment.
- Make journal creation idempotent using a domain event/reference key.
- Treat existing balance fields as cached projections, not the source of truth.
- Add a projection/rebuild service that can recompute balances from the ledger.
- Backfill legacy
Transactionrecords into journals through a dry-run migration.
Security and integrity requirements
- Posted journals cannot be edited or deleted; corrections use reversing entries.
- Administrative adjustments require an actor, reason, and audit event.
- Prevent a journal from posting if total debits and credits differ.
- Keep currency explicit on accounts and entries.
- Enforce transaction/session boundaries for journal and projection updates.
Suggested structure
models/LedgerAccount.tsmodels/LedgerJournal.tsmodels/LedgerEntry.tslib/ledger/posting.service.tslib/ledger/projection.service.tsscripts/migrations/backfill-ledger.ts
Test requirements
- balanced and unbalanced journal validation
- idempotent reposting of the same payment reference
- reversal entries
- concurrent wallet credits/debits
- projection rebuild from journal history
- failure rollback inside MongoDB transactions
- backfill dry run and resume behavior
- invariant test proving system-wide debits equal credits per currency
Acceptance criteria
- Every balance-changing workflow posts a balanced journal.
- Ledger entries are immutable after posting.
- Cached balances can be rebuilt and verified against the ledger.
- Duplicate provider/domain references cannot create duplicate value.
- Legacy transactions can be backfilled with a documented migration.
- Reconciliation command reports zero unexplained imbalance on seeded data.
-
npm run lint,npm run typecheck,npm run test, andnpm run buildpass.
Evidence required
- Sample balanced journals for at least five domain flows
- Rebuild/reconciliation command output
- Tests demonstrating rollback, reversal, and idempotency
Difficulty
Hard
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
GrantFox OSSIssue tracked in GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardIssue may be eligible for a GrantFox rewardOfficial CampaignCampaign: Official CampaignCampaign: Official CampaignOfficial Campaign | FWC26Campaign: Official Campaign | FWC26Campaign: Official Campaign | FWC26
Activity
edehvictor commentedon Aug 22, 2026
Hi maintainers!
I’d love to help out with this issue. I’ve checked the current codebase/documentation and know exactly what needs to be updated to make this clearer. I will ensure everything aligns perfectly with your existing contribution guidelines.
grantfox-oss commentedon Aug 26, 2026
🦊 GrantFox — @edehvictor has been assigned to this issue as part of the Third Campaign campaign!
Next steps:
Closes #81)Good luck! Track your progress on GrantFox.
feat(finance): implement immutable double-entry ledger (#81)
Merge pull request #230 from edehvictor/feature/immutable-ledger-81
grantfox-oss commentedon Aug 30, 2026
🎉 This issue has been marked as completed on GrantFox as part of the Third Campaign campaign!
@edehvictor's PR #230 was approved and merged by @Obiajulu-gif.
🏆 @edehvictor: You earned 40 FoxPoints for this contribution! Your current tier: Builder (1,122 total points). Track your full progress on GrantFox.
👏 Great work, @edehvictor! Keep contributing to Chainmove.