Skip to content

ENG-181: Deal-related and fee-related cash event integration#253

Merged
Connorbelez merged 2 commits intomainfrom
eng-181
Mar 22, 2026
Merged

ENG-181: Deal-related and fee-related cash event integration#253
Connorbelez merged 2 commits intomainfrom
eng-181

Conversation

@Connorbelez
Copy link
Copy Markdown
Owner

@Connorbelez Connorbelez commented Mar 22, 2026

Wire 4 deal/fee cash events through the posting pipeline

  • postDealBuyerFundsReceived (CASH_RECEIVED → TRUST_CASH/CASH_CLEARING)
  • postDealSellerPayout (LENDER_PAYOUT_SENT → LENDER_PAYABLE/TRUST_CASH)
  • postLockingFeeReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)
  • postCommitmentDepositReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)

Also fixes CREDIT_NORMAL_FAMILIES to include CASH_CLEARING and UNAPPLIED_CASH — these are liabilities (credit-normal) not assets, which corrects balance computation polarity for all future entries.

Changes

  • Adds 4 new integration functions in integrations.ts with proper idempotency keys and metadata
  • Expands CASH_RECEIVED family map to accept CASH_CLEARING and UNAPPLIED_CASH as credit accounts
  • Adds dealId field to journal entries schema with corresponding index
  • Includes comprehensive test coverage for all functions including idempotency and error handling
  • Corrects account normal balance classifications for proper accounting semantics

Summary by CodeRabbit

  • New Features

    • Added cash posting operations for deal flows: buyer funds received, seller payouts, locking fees, and commitment deposits.
    • Cash ledger entries can now be associated with a dealId for improved tracing.
  • Behavior

    • Expanded allowed credit account families for received cash to accept clearing accounts in addition to previous options.
  • Tests

    • Added comprehensive integration and idempotency tests plus error-handling coverage for deal postings.
  • Bug Fixes

    • Fixed test pre-seeded cash balance conditions.

@linear
Copy link
Copy Markdown

linear bot commented Mar 22, 2026

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @Connorbelez, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 22, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 81b9cab8-78d0-43f8-8122-ee54da9834cc

📥 Commits

Reviewing files that changed from the base of the PR and between 89d823b and 6dc9f44.

📒 Files selected for processing (8)
  • convex/payments/cashLedger/__tests__/controlSubaccounts.test.ts
  • convex/payments/cashLedger/__tests__/dealCashEvents.test.ts
  • convex/payments/cashLedger/__tests__/entryTypes.test.ts
  • convex/payments/cashLedger/integrations.ts
  • convex/payments/cashLedger/postEntry.ts
  • convex/payments/cashLedger/types.ts
  • convex/payments/cashLedger/validators.ts
  • convex/schema.ts

📝 Walkthrough

Walkthrough

Adds four deal- and fee-related cash-posting mutations with tests, persists optional dealId on cash journal entries (plus index), and expands allowed credit families for CASH_RECEIVED.

Changes

Cohort / File(s) Summary
New Tests
convex/payments/cashLedger/__tests__/dealCashEvents.test.ts
End-to-end tests for new deal/fee posting helpers, idempotency, family map expansion, and error cases.
Test Adjustments
convex/payments/cashLedger/__tests__/controlSubaccounts.test.ts, convex/payments/cashLedger/__tests__/entryTypes.test.ts
Changed seeded UNAPPLIED_CASH account setup to use cumulativeCredits instead of cumulativeDebits.
New Posting Helpers
convex/payments/cashLedger/integrations.ts
Added postDealBuyerFundsReceived, postDealSellerPayout, postLockingFeeReceived, postCommitmentDepositReceived — validate entities, get/create accounts, post entries with deterministic idempotency keys and metadata.
Entry persistence & API
convex/payments/cashLedger/postEntry.ts, convex/payments/cashLedger/validators.ts
PostCashEntryInput and validator accept optional dealId; persistEntry writes dealId into journal entry.
Types & Families
convex/payments/cashLedger/types.ts
Expanded CASH_RECEIVED.credit allowed families to include CASH_CLEARING; added CASH_CLEARING/UNAPPLIED_CASH to CREDIT_NORMAL_FAMILIES.
Schema
convex/schema.ts
Added optional dealId field to cash_ledger_journal_entries and a secondary index by_deal on ["dealId", "entryType"].

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant Integrations as Integrations.postDealBuyerFundsReceived
    participant Accounts as CashAccountService
    participant PostEntry as postCashEntryInternal
    participant Journal as CashLedgerJournal

    Caller->>Integrations: call(dealId, amount, source)
    Integrations->>Accounts: getOrCreateCashAccount(TRUST_CASH, mortgageId)
    Accounts-->>Integrations: trustAccount
    Integrations->>Accounts: getOrCreateCashAccount(CASH_CLEARING, mortgageId)
    Accounts-->>Integrations: clearingAccount
    Integrations->>PostEntry: post(CASH_RECEIVED, debit:trust, credit:clearing, idempotencyKey:dealId, metadata:{buyerId,sellerId,dealId})
    PostEntry->>Journal: persist(entry with dealId)
    Journal-->>PostEntry: persistedEntry
    PostEntry-->>Integrations: success
    Integrations-->>Caller: return(createdEntry)
Loading
sequenceDiagram
    participant Caller
    participant Integrations as Integrations.postDealSellerPayout
    participant Accounts as CashAccountService
    participant PostEntry as postCashEntryInternal
    participant Journal as CashLedgerJournal

    Caller->>Integrations: call(dealId, lenderId, amount, source)
    Integrations->>Accounts: getOrCreateCashAccount(LENDER_PAYABLE, lenderId)
    Accounts-->>Integrations: lenderPayable
    Integrations->>Accounts: getOrCreateCashAccount(TRUST_CASH, mortgageId)
    Accounts-->>Integrations: trustAccount
    Integrations->>PostEntry: post(LENDER_PAYOUT_SENT, debit:lenderPayable, credit:trust, idempotencyKey:dealId+lenderId, metadata:{sellerId,buyerId,dealId})
    PostEntry->>Journal: persist(entry with dealId)
    Journal-->>PostEntry: persistedEntry
    PostEntry-->>Integrations: success
    Integrations-->>Caller: return(createdEntry)
Loading
sequenceDiagram
    participant Caller
    participant Integrations as Integrations.postLockingFeeReceived
    participant Accounts as CashAccountService
    participant PostEntry as postCashEntryInternal
    participant Journal as CashLedgerJournal

    Caller->>Integrations: call(feeId, mortgageId, amount, dealId?, source)
    Integrations->>Accounts: getOrCreateCashAccount(TRUST_CASH, mortgageId)
    Accounts-->>Integrations: trustAccount
    Integrations->>Accounts: getOrCreateCashAccount(UNAPPLIED_CASH, mortgageId)
    Accounts-->>Integrations: unappliedAccount
    Integrations->>PostEntry: post(CASH_RECEIVED, debit:trust, credit:unapplied, idempotencyKey:feeId (+dealId?), metadata:{feeType,feeId,dealId?})
    PostEntry->>Journal: persist(entry with dealId)
    Journal-->>PostEntry: persistedEntry
    PostEntry-->>Integrations: success
    Integrations-->>Caller: return(createdEntry)
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 I hopped into ledgers, nibbling code lines bright,
Posting buyer funds by day and seller payouts by night,
Fees tucked in neat, dealIds snug and tight,
Idempotent keys keep duplicates from sight,
A rabbit's ledger dance — everything's right! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically identifies the main change: integration of deal-related and fee-related cash event functions into the posting pipeline.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch eng-181

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Owner Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@Connorbelez Connorbelez marked this pull request as ready for review March 22, 2026 20:21
Copilot AI review requested due to automatic review settings March 22, 2026 20:21
Copy link
Copy Markdown

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connorbelez has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Wires new deal-related and fee-related cash events into the cash-ledger posting pipeline, and updates accounting semantics so CASH_CLEARING / UNAPPLIED_CASH are treated as credit-normal (liability) families. Also extends cash ledger journal entries to optionally associate entries with a deal for downstream reporting/querying.

Changes:

  • Add new cash-ledger integration helpers for deal buyer funds, deal seller payouts, locking fees, and commitment deposits.
  • Update cash ledger type constraints and balance polarity (CREDIT_NORMAL_FAMILIES, CASH_ENTRY_TYPE_FAMILY_MAP) to treat CASH_CLEARING and UNAPPLIED_CASH as credit-normal and allow them in CASH_RECEIVED postings.
  • Extend cash ledger journal entry schema + mutation args to include optional dealId, with a new index; add/adjust tests accordingly.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
convex/schema.ts Adds dealId field to cash ledger journal entries and indexes by deal.
convex/payments/cashLedger/validators.ts Extends postCashEntry args validator to accept optional dealId.
convex/payments/cashLedger/types.ts Expands CASH_RECEIVED family constraints and updates credit-normal families.
convex/payments/cashLedger/postEntry.ts Persists dealId onto journal entries and threads it through the input type.
convex/payments/cashLedger/integrations.ts Adds 4 new integration functions for deal/fee cash events.
convex/payments/cashLedger/tests/entryTypes.test.ts Updates tests to reflect UNAPPLIED_CASH being credit-normal.
convex/payments/cashLedger/tests/dealCashEvents.test.ts Adds comprehensive tests for new deal/fee integrations (including idempotency + errors).
convex/payments/cashLedger/tests/controlSubaccounts.test.ts Adjusts setup to pre-fund UNAPPLIED_CASH correctly under new polarity rules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread convex/payments/cashLedger/integrations.ts
Comment thread convex/payments/cashLedger/integrations.ts
Copy link
Copy Markdown
Owner Author

@coderabbitai please review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 22, 2026

@Connorbelez Sure! I'll start reviewing PR #253 now.


🧠 Learnings used
Learnt from: Connorbelez
Repo: Connorbelez/tanstackTemplate PR: 5
File: specs/governed-transitions/chunks/chunk-01-schema-machine/context.md:209-213
Timestamp: 2026-03-13T03:17:28.559Z
Learning: In the Connorbelez/tanstackTemplate repository, do not flag .md files for markdown formatting/linting issues (e.g., MD040 fenced code block language). Only reference .md files (specs, PRDs, design docs) when they reveal architectural drift or implementation inconsistencies against actual code.

Learnt from: CR
Repo: Connorbelez/tanstackTemplate PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-16T16:49:07.666Z
Learning: After completing a major unit of work, run `coderabbit review --plain` to get a code review summary and check for potential issues or improvements

Learnt from: CR
Repo: Connorbelez/tanstackTemplate PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-16T06:17:10.192Z
Learning: After completing a major unit of work, run `coderabbit review --plain` to get a code review summary and check for potential issues or improvements

Learnt from: CR
Repo: Connorbelez/tanstackTemplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-21T18:28:26.681Z
Learning: After completing a major unit of work, run `coderabbit review --plain` to get a code review summary and check for potential issues or improvements
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Connorbelez and others added 2 commits March 22, 2026 19:40
Wire 4 deal/fee cash events through the posting pipeline:
- postDealBuyerFundsReceived (CASH_RECEIVED → TRUST_CASH/CASH_CLEARING)
- postDealSellerPayout (LENDER_PAYOUT_SENT → LENDER_PAYABLE/TRUST_CASH)
- postLockingFeeReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)
- postCommitmentDepositReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)

Also fixes CREDIT_NORMAL_FAMILIES to include CASH_CLEARING and
UNAPPLIED_CASH — these are liabilities (credit-normal) not assets,
which corrects balance computation polarity for all future entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s-mortgage collisions

postLockingFeeReceived and postCommitmentDepositReceived used plain-string
feeId/depositId as the sole idempotency discriminant. Since these are not
globally-unique Convex IDs, reusing the same identifier across mortgages
would cause cross-mortgage idempotency collisions. Now includes mortgageId
(and dealId when present) in the key, matching the scoping pattern used by
the other deal integration functions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Connorbelez Connorbelez merged commit f5cc8d2 into main Mar 22, 2026
0 of 3 checks passed
Connorbelez added a commit that referenced this pull request Mar 22, 2026
…255)

ENG-181: Deal-related and fee-related cash event integration (#253)

## Wire 4 deal/fee cash events through the posting pipeline

- postDealBuyerFundsReceived (CASH_RECEIVED → TRUST_CASH/CASH_CLEARING)
- postDealSellerPayout (LENDER_PAYOUT_SENT → LENDER_PAYABLE/TRUST_CASH)
- postLockingFeeReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)
- postCommitmentDepositReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)

Also fixes CREDIT_NORMAL_FAMILIES to include CASH_CLEARING and UNAPPLIED_CASH — these are liabilities (credit-normal) not assets, which corrects balance computation polarity for all future entries.

### Changes

- Adds 4 new integration functions in `integrations.ts` with proper idempotency keys and metadata
- Expands CASH_RECEIVED family map to accept CASH_CLEARING and UNAPPLIED_CASH as credit accounts
- Adds dealId field to journal entries schema with corresponding index
- Includes comprehensive test coverage for all functions including idempotency and error handling
- Corrects account normal balance classifications for proper accounting semantics

## Summary by Sourcery

Bug Fixes:
- Fix runtime crash in obligation settlement dispersal caused by missing paymentFrequency argument in servicing fee calculation.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added cash posting functions for deal-related transactions: buyer funds received, seller payouts, locking fees, and commitment deposits.
  * Added support for associating cash ledger entries with specific deals for better transaction tracking.

* **Tests**
  * Comprehensive test coverage for new cash posting functions, including idempotency and error handling scenarios.

* **Bug Fixes**
  * Corrected cash account balance preconditions in existing tests.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

ENG-224: Pass paymentFrequency to calculateServicingFee

ENG-152 added paymentFrequency as a required third parameter but the
caller in calculateServicingSplit was not updated, causing a runtime
crash on any obligation settlement triggering dispersal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Connorbelez added a commit that referenced this pull request Apr 20, 2026
## Wire 4 deal/fee cash events through the posting pipeline

- postDealBuyerFundsReceived (CASH_RECEIVED → TRUST_CASH/CASH_CLEARING)
- postDealSellerPayout (LENDER_PAYOUT_SENT → LENDER_PAYABLE/TRUST_CASH)
- postLockingFeeReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)
- postCommitmentDepositReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)

Also fixes CREDIT_NORMAL_FAMILIES to include CASH_CLEARING and UNAPPLIED_CASH — these are liabilities (credit-normal) not assets, which corrects balance computation polarity for all future entries.

### Changes

- Adds 4 new integration functions in `integrations.ts` with proper idempotency keys and metadata
- Expands CASH_RECEIVED family map to accept CASH_CLEARING and UNAPPLIED_CASH as credit accounts
- Adds dealId field to journal entries schema with corresponding index
- Includes comprehensive test coverage for all functions including idempotency and error handling
- Corrects account normal balance classifications for proper accounting semantics

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added cash posting functions for deal-related transactions: buyer funds received, seller payouts, locking fees, and commitment deposits.
  * Added support for associating cash ledger entries with specific deals for better transaction tracking.

* **Tests**
  * Comprehensive test coverage for new cash posting functions, including idempotency and error handling scenarios.

* **Bug Fixes**
  * Corrected cash account balance preconditions in existing tests.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Connorbelez added a commit that referenced this pull request Apr 20, 2026
…255)

ENG-181: Deal-related and fee-related cash event integration (#253)

## Wire 4 deal/fee cash events through the posting pipeline

- postDealBuyerFundsReceived (CASH_RECEIVED → TRUST_CASH/CASH_CLEARING)
- postDealSellerPayout (LENDER_PAYOUT_SENT → LENDER_PAYABLE/TRUST_CASH)
- postLockingFeeReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)
- postCommitmentDepositReceived (CASH_RECEIVED → TRUST_CASH/UNAPPLIED_CASH)

Also fixes CREDIT_NORMAL_FAMILIES to include CASH_CLEARING and UNAPPLIED_CASH — these are liabilities (credit-normal) not assets, which corrects balance computation polarity for all future entries.

### Changes

- Adds 4 new integration functions in `integrations.ts` with proper idempotency keys and metadata
- Expands CASH_RECEIVED family map to accept CASH_CLEARING and UNAPPLIED_CASH as credit accounts
- Adds dealId field to journal entries schema with corresponding index
- Includes comprehensive test coverage for all functions including idempotency and error handling
- Corrects account normal balance classifications for proper accounting semantics

## Summary by Sourcery

Bug Fixes:
- Fix runtime crash in obligation settlement dispersal caused by missing paymentFrequency argument in servicing fee calculation.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added cash posting functions for deal-related transactions: buyer funds received, seller payouts, locking fees, and commitment deposits.
  * Added support for associating cash ledger entries with specific deals for better transaction tracking.

* **Tests**
  * Comprehensive test coverage for new cash posting functions, including idempotency and error handling scenarios.

* **Bug Fixes**
  * Corrected cash account balance preconditions in existing tests.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

ENG-224: Pass paymentFrequency to calculateServicingFee

ENG-152 added paymentFrequency as a required third parameter but the
caller in calculateServicingSplit was not updated, causing a runtime
crash on any obligation settlement triggering dispersal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

2 participants