Skip to content

feat(billing): add creditGrant idempotent method + source field on entries#3662

Merged
PierreBrisorgueil merged 2 commits into
masterfrom
feat-billing-credit-grant
May 11, 2026
Merged

feat(billing): add creditGrant idempotent method + source field on entries#3662
PierreBrisorgueil merged 2 commits into
masterfrom
feat-billing-credit-grant

Conversation

@PierreBrisorgueil
Copy link
Copy Markdown
Contributor

Summary

  • Adds creditGrant(orgId, amount, source) to BillingExtraBalanceRepository — mirrors creditPack 2-step pattern (getOrCreate → idempotency-guarded push) but uses a synthetic refId (source-orgId) instead of stripeSessionId, enabling non-Stripe grants (e.g. free tier signup)
  • Adds source enum field (signup_grant | adjustment) to Mongoose LedgerEntrySchema + Zod LedgerEntry schema (mirrors all 3 per feedback_enum_all_schemas)
  • Adds ExtraBalanceCreditGrant Zod input schema (no stripeSessionId required)
  • Adds sparse index on {ledger.refId, ledger.source} for grant idempotency lookups
  • Backward compat: creditPack unchanged — Stripe topup entries omit source field

Part of N2 Free Tier Grant

Task 2 of 6. Depends on: Task 1 (#3661 merged) — signupGrant/oneShot config fields on Free plan.
Next: Task 3 — BillingSignupGrantService + signup hook.

Test plan

  • billing.extraBalance.unit.tests.js — 14 new tests: creditGrant idempotency (duplicate returns applied:false + reason:duplicate_grant), step-1 upsert, step-2 no-upsert, refId filter shape, invalid orgId guard, zero/negative/empty-source guards; ExtraBalanceCreditGrant schema: valid no-stripeSessionId, valid sources, rejects 0 amount, rejects invalid orgId, rejects unknown source
  • All 1418 unit tests pass
  • Pre-existing perf integration test failures pre-date this PR ($sortArray requires MongoDB 5.2+, not available in CI)

…tries

Adds creditGrant(orgId, amount, source) to BillingExtraBalanceRepository —
mirrors creditPack's 2-step pattern but uses a synthetic refId (source-orgId)
for idempotency instead of stripeSessionId. Adds source enum field to
LedgerEntrySchema + ExtraBalanceCreditGrant Zod schema for input validation.
Copilot AI review requested due to automatic review settings May 11, 2026 18:44
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Warning

Rate limit exceeded

@PierreBrisorgueil has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 59 minutes and 35 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2914fe16-691d-4660-87a5-e04f34ab0293

📥 Commits

Reviewing files that changed from the base of the PR and between dd4ec25 and be14a9e.

📒 Files selected for processing (4)
  • modules/billing/models/billing.extraBalance.model.mongoose.js
  • modules/billing/models/billing.extraBalance.schema.js
  • modules/billing/repositories/billing.extraBalance.repository.js
  • modules/billing/tests/billing.extraBalance.unit.tests.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-billing-credit-grant

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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.43%. Comparing base (5a113f9) to head (be14a9e).
⚠️ Report is 2 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3662      +/-   ##
==========================================
+ Coverage   89.21%   89.43%   +0.21%     
==========================================
  Files         137      137              
  Lines        4683     4714      +31     
  Branches     1455     1466      +11     
==========================================
+ Hits         4178     4216      +38     
+ Misses        393      389       -4     
+ Partials      112      109       -3     
Flag Coverage Δ
integration 59.43% <23.07%> (-0.14%) ⬇️
unit 64.82% <100.00%> (+0.38%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5a113f9...be14a9e. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Adds support in the billing “extra balance” ledger for non-Stripe credit grants (e.g. free-tier signup grants) with idempotent application semantics, plus schema/index support to tag ledger entries with a source.

Changes:

  • Added BillingExtraBalanceRepository.creditGrant(orgId, amount, source) implementing a 2-step get-or-create + idempotent ledger push.
  • Extended the ExtraBalance ledger entry schemas (Mongoose + Zod) with a source enum and introduced an ExtraBalanceCreditGrant Zod input schema.
  • Added a sparse compound index on ledger.refId + ledger.source and expanded unit tests for the new grant behavior and schema.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
modules/billing/repositories/billing.extraBalance.repository.js Adds creditGrant() repository method and exports it.
modules/billing/models/billing.extraBalance.schema.js Adds GrantSource + source on ledger entries and ExtraBalanceCreditGrant schema.
modules/billing/models/billing.extraBalance.model.mongoose.js Adds source field to LedgerEntrySchema and adds an index on ledger.refId/ledger.source.
modules/billing/tests/billing.extraBalance.unit.tests.js Adds unit tests for creditGrant behavior and ExtraBalanceCreditGrant schema validation.

Comment thread modules/billing/repositories/billing.extraBalance.repository.js
Comment thread modules/billing/models/billing.extraBalance.model.mongoose.js Outdated
Comment thread modules/billing/models/billing.extraBalance.schema.js Outdated
…ents

- creditGrant now validates source via Zod (ExtraBalanceCreditGrant.parse) before write —
  findOneAndUpdate does not run validators so the explicit parse is necessary
- Add test for Zod throw on invalid source enum value
- Fix index comment: $ne predicate does not use tight index bounds (noted actual benefit)
- Fix GrantSource/LedgerEntry comments: creditCompensation does NOT set source; source
  is exclusively set by creditGrant and future grant methods
@PierreBrisorgueil PierreBrisorgueil merged commit 41e7bd9 into master May 11, 2026
7 checks passed
@PierreBrisorgueil PierreBrisorgueil deleted the feat-billing-credit-grant branch May 11, 2026 19:07
@PierreBrisorgueil
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

✅ 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.

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