Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@steven-tey
Copy link
Collaborator

@steven-tey steven-tey commented Oct 27, 2025

Summary by CodeRabbit

  • New Features
    • Automatic payout creation when available balance exceeds the fixed reserve.
  • Improvements
    • More accurate tracking of processing vs processed payouts for calculation.
    • Reserve updated to a fixed amount for predictable withdrawals.
    • Withdrawal eligibility refined using the new balance computation.
    • Expanded logging to surface processing, processed totals and withdrawal amounts.

@vercel
Copy link
Contributor

vercel bot commented Oct 27, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
dub Ready Ready Preview Oct 27, 2025 6:35pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 27, 2025

Walkthrough

The withdrawal cron handler now uses prisma.payout.groupBy to compute sums by status, derives processingPayouts and processedPayouts, computes balanceToWithdraw = currentAvailableBalance - processedPayouts, uses a fixed reservedBalance = 50000, and creates a Stripe payout when balanceToWithdraw > reservedBalance, otherwise logs and returns early.

Changes

Cohort / File(s) Summary
Withdrawal Cron Handler Refactor
apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts
Replaced prisma.payout.aggregate with prisma.payout.groupBy to sum payouts by status; derive processingPayouts and processedPayouts with defaults; compute balanceToWithdraw = currentAvailableBalance - processedPayouts; set fixed reservedBalance = 50000; skip withdrawal when balanceToWithdraw <= reservedBalance (log with currencyFormatter); create Stripe payout and corresponding DB record when balanceToWithdraw > reservedBalance; expanded logging to include processing/processed totals and balanceToWithdraw.

Sequence Diagram(s)

sequenceDiagram
    participant Cron as Cron Trigger
    participant DB as Database (Prisma)
    participant Stripe as Stripe API
    participant Log as Logger

    Cron->>DB: Query currentAvailableBalance\nand groupBy payouts by status
    DB-->>Cron: Return balance, processingPayouts, processedPayouts

    Note over Cron: Compute balanceToWithdraw = currentAvailableBalance - processedPayouts
    Note over Cron: reservedBalance = 50000

    alt balanceToWithdraw <= reservedBalance
        Cron->>Log: Log skip with formatted currency and totals
        Cron-->>Cron: Return early
    else balanceToWithdraw > reservedBalance
        Cron->>Stripe: Create payout for balanceToWithdraw
        Stripe-->>Cron: Return payout confirmation
        Cron->>DB: Create payout record (store Stripe payout)
        DB-->>Cron: Confirm stored
        Cron->>Log: Log created payout details and totals
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify correctness of groupBy usage and handling of missing statuses/defaults.
  • Check arithmetic and intent of balanceToWithdraw = currentAvailableBalance - processedPayouts.
  • Confirm reservedBalance change to fixed 50000 is intended and unit-consistent.
  • Review Stripe payout creation and DB record creation for error handling and idempotency.

Possibly related PRs

Suggested reviewers

  • devkiran

Poem

🐰
Payouts sorted by status, neat and bright,
Reserves set steady through the night.
Balance trimmed and sent away,
The cron hops softly, saves the day.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The title "Fix withdrawal cron again" is related to the changeset, as the modifications are indeed focused on the withdrawal cron job. However, the title is vague and generic, using the broad term "Fix" without specifying what issue is being addressed or what the actual changes accomplish. While "withdrawal cron" correctly identifies the component, the lack of specificity about whether the fix addresses balance calculations, guard logic, payout creation, or another aspect means that someone scanning the repository history would not understand the nature or purpose of these changes from the title alone.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-withdrawal

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3ffabcf and 4ba9368.

📒 Files selected for processing (1)
  • apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts (1)
packages/prisma/index.ts (1)
  • prisma (3-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (5)
apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts (5)

20-31: LGTM: Query structure is sound.

The switch to groupBy correctly retrieves separate sums for "processing" and "processed" payouts that haven't been transferred to Stripe yet.


34-38: Good: Default values prevent undefined.

The ?? 0 defaults ensure both variables are always numeric, which addresses part of the previous review concern.


52-52: LGTM: Fixed reserved balance is clear.

The hardcoded $500 minimum balance is reasonable and well-documented.


53-57: Guard logic is sound, but depends on correct balance calculation.

The early return when balanceToWithdraw <= reservedBalance is appropriate and prevents unnecessary Stripe API calls. However, this relies on balanceToWithdraw being calculated correctly (see comment on lines 39-42).


59-66: Payout creation logic is correct, but amount may be wrong.

The Stripe payout creation and logging are implemented correctly. However, the payout amount depends on balanceToWithdraw being calculated correctly (see critical issue on lines 39-42). If processingPayouts aren't subtracted, this could create payouts for more than the actual available balance after accounting for all owed payouts.


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
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts (1)

53-58: Consider making the reserved balance configurable.

The reserved balance is currently hardcoded to $500. While this may be appropriate for the current scale, consider making this value configurable via an environment variable or database setting to allow easier adjustments without code changes as transaction volumes grow.

Example:

const reservedBalance = Number(process.env.STRIPE_RESERVED_BALANCE) || 50000; // keep at least $500 in the account
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dbb584a and 3ffabcf.

📒 Files selected for processing (1)
  • apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts (1)
packages/prisma/index.ts (1)
  • prisma (3-9)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (2)
apps/web/app/(ee)/api/cron/trigger-withdrawal/route.ts (2)

18-32: LGTM: groupBy query is well-structured.

The query correctly groups payouts by status and filters for those that haven't been transferred to Stripe yet (stripeTransferId: null), representing money owed to partners.


60-63: Verify hardcoded USD currency assumption.

The currency is hardcoded to "usd" for the payout creation. Ensure this aligns with your business requirements and that all Stripe accounts being used are USD-based. If you plan to support multiple currencies in the future, this will need to be refactored.

@steven-tey steven-tey merged commit 973ffbf into main Oct 27, 2025
7 of 8 checks passed
@steven-tey steven-tey deleted the fix-withdrawal branch October 27, 2025 18:39
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.

3 participants