Skip to content

feat(billing): record affiliate commission in billing history - #4278

Merged
baktun14 merged 11 commits into
mainfrom
feat/billing-affiliate-commission-type
Nov 11, 2026
Merged

baktun14 merged 11 commits into
mainfrom
feat/billing-affiliate-commission-type

Conversation

@baktun14

@baktun14 baktun14 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Why

Part of CON-1191. Affiliate commission is paid as Console credit, and it has to show up in the affiliate's billing history like any other credit. This PR adds the transaction type and the storage; the next one grants the commission.

Merges after #4277. It targets main so CI runs; until #4277 merges, the diff also shows the PRs below it.

What

  • stripe_transactions gets the affiliate_commission type and a source_transaction_id column pointing at the referred user's payment (migration 0128). A partial unique index allows at most one commission per payment. If the referred user's account is deleted, the commission row stays on the affiliate's ledger and its source becomes null.
  • The migration adds the enum value in a statement of its own, and nothing else in it uses that value.
  • Repository methods to create a commission row and find it by its source payment (with a row lock).
  • Billing history (API schema, http-sdk type, deploy-web table) and the credits-added Slack message label it "Affiliate commission" and show it as a credit.
  • Only payment_intent rows count as a purchase, so a commission can never trigger the first-purchase bonus.

Testing

Repository integration specs (create, find, lock, unique violation, deleting the referred user), plus BillingView and Slack message specs. Mutation score on changed lines: API 100%, deploy-web 100%.

Screenshots

Billing history with test data: a commission credit, a commission fully taken back after a refund, a card payment and a coupon.

Billing history with affiliate commission rows

@baktun14
baktun14 requested a review from a team as a code owner October 8, 2026 13:14

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

This review includes 35 billable files and costs up to $8.75.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Or wait 16 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

Commits

Reviewing files that changed from the base of the PR and between d9c0882 and 5a0bd9f.

Files ignored due to path filters: 1

  • apps/api/test/functional/__snapshots__/docs.spec.ts.snap is excluded by !**/*.snap
Files selected for processing: 35

  • apps/api/drizzle/0128_affiliate_commission.sql
  • apps/api/drizzle/meta/0128_snapshot.json
  • apps/api/drizzle/meta/_journal.json
  • apps/api/src/affiliate/controllers/referral/referral.controller.ts
  • apps/api/src/affiliate/http-schemas/referral.schema.ts
  • apps/api/src/affiliate/index.ts
  • apps/api/src/affiliate/routes/referral/referral.router.ts
  • apps/api/src/affiliate/services/referral/referral.service.spec.ts
  • apps/api/src/affiliate/services/referral/referral.service.ts
  • apps/api/src/app/services/credits-added-slack-alert/credits-added-slack-message.spec.ts
  • apps/api/src/app/services/credits-added-slack-alert/credits-added-slack-message.ts
  • apps/api/src/billing/http-schemas/stripe.schema.ts
  • apps/api/src/billing/model-schemas/stripe-transaction/stripe-transaction.schema.ts
  • apps/api/src/billing/repositories/stripe-transaction/stripe-transaction.repository.integration.ts
  • apps/api/src/billing/repositories/stripe-transaction/stripe-transaction.repository.ts
  • apps/api/src/billing/services/activate-trial/trial-activation-instrumentation.service.spec.ts
  • apps/api/src/billing/services/activate-trial/trial-activation-instrumentation.service.ts
  • apps/api/src/billing/services/managed-user-wallet/managed-user-wallet.service.spec.ts
  • apps/api/src/billing/services/managed-user-wallet/managed-user-wallet.service.ts
  • apps/api/src/billing/services/stripe-transaction/stripe-transaction.service.spec.ts
  • apps/api/src/billing/services/wallet-initializer/wallet-initializer.service.spec.ts
  • apps/api/src/billing/services/wallet-initializer/wallet-initializer.service.ts
  • apps/api/src/routers/open-api-handlers.ts
  • apps/api/swagger/openapi.json
  • apps/api/test/functional/referral.spec.ts
  • apps/api/test/seeders/database-stripe-transaction.seeder.ts
  • apps/deploy-web/src/components/billing-usage/BillingView/BillingView.spec.tsx
  • apps/deploy-web/src/components/billing-usage/BillingView/BillingView.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.spec.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx
  • apps/deploy-web/src/queries/useReferralQuery.spec.tsx
  • apps/deploy-web/src/queries/useReferralQuery.ts
  • packages/console-api-types/src/operations.gen.ts
  • packages/console-api-types/src/schema.d.ts
  • packages/http-sdk/src/stripe/stripe.types.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@baktun14

Copy link
Copy Markdown
Contributor Author

@claude review

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Code review skipped — your organization's remaining monthly code review budget is too low to start another review, so this review was not started.

An organization admin can view or raise the monthly spending cap at claude.ai/admin-settings/usage, on the Claude Code Review row under Services. The cap resets at the start of the next billing period.

Once the cap resets or is raised, someone with write access to this repository can comment @claude review on this pull request to trigger a review.

@baktun14
baktun14 force-pushed the feat/billing-affiliate-commission-type branch from 78d73c9 to bd1213b Compare November 4, 2026 07:29
@baktun14
baktun14 force-pushed the feat/billing-referral-trial branch 2 times, most recently from 80eb401 to 1d9a57c Compare November 5, 2026 21:02
@baktun14
baktun14 force-pushed the feat/billing-affiliate-commission-type branch from bd1213b to 9e54cd2 Compare November 5, 2026 21:02
@baktun14
baktun14 force-pushed the feat/billing-referral-trial branch from 1d9a57c to b020646 Compare November 5, 2026 21:43
@baktun14
baktun14 force-pushed the feat/billing-affiliate-commission-type branch 2 times, most recently from 4de533a to a283986 Compare November 9, 2026 01:08
@baktun14
baktun14 force-pushed the feat/billing-referral-trial branch from b020646 to 10cb1a6 Compare November 9, 2026 01:08
@baktun14
baktun14 changed the base branch from feat/billing-referral-trial to main November 10, 2026 04:43
@baktun14
baktun14 force-pushed the feat/billing-affiliate-commission-type branch from a283986 to 7e24410 Compare November 10, 2026 04:43
@github-actions github-actions Bot added size: XL and removed size: M labels Nov 10, 2026
@baktun14
baktun14 force-pushed the feat/billing-affiliate-commission-type branch from 7e24410 to 3d06a3a Compare November 10, 2026 04:50
@codecov

codecov Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.48485% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 95.10%. Comparing base (d9c0882) to head (5a0bd9f).
⚠️ Report is 11 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...as/stripe-transaction/stripe-transaction.schema.ts 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4278      +/-   ##
==========================================
+ Coverage   94.89%   95.10%   +0.20%     
==========================================
  Files        2145     2077      -68     
  Lines       62324    60619    -1705     
  Branches    15578    15256     -322     
==========================================
- Hits        59143    57649    -1494     
+ Misses       2861     2665     -196     
+ Partials      320      305      -15     
Flag Coverage Δ *Carryforward flag
api 96.84% <97.87%> (+<0.01%) ⬆️
deploy-web 93.62% <100.00%> (+0.08%) ⬆️
log-collector ?
notifications 96.68% <ø> (ø)
provider-console 81.68% <ø> (ø) Carriedforward from d50dd71
provider-inventory ?
provider-proxy 95.18% <ø> (ø) Carriedforward from d50dd71
tx-signer 93.50% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...iliate/controllers/referral/referral.controller.ts 100.00% <100.00%> (ø)
...rc/affiliate/services/referral/referral.service.ts 100.00% <100.00%> (ø)
...s-added-slack-alert/credits-added-slack-message.ts 100.00% <100.00%> (ø)
...tripe-transaction/stripe-transaction.repository.ts 87.25% <100.00%> (+0.79%) ⬆️
...-trial/trial-activation-instrumentation.service.ts 100.00% <100.00%> (ø)
...managed-user-wallet/managed-user-wallet.service.ts 100.00% <100.00%> (ø)
...s/wallet-initializer/wallet-initializer.service.ts 100.00% <100.00%> (ø)
...mponents/billing-usage/BillingView/BillingView.tsx 100.00% <100.00%> (ø)
...ponents/onboarding-picker/OnboardingPickerPage.tsx 100.00% <100.00%> (ø)
apps/deploy-web/src/queries/useReferralQuery.ts 100.00% <100.00%> (ø)
... and 1 more

... and 94 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@baktun14
baktun14 added this pull request to the merge queue Nov 10, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Nov 10, 2026
@baktun14
baktun14 force-pushed the feat/billing-affiliate-commission-type branch from 3d06a3a to 92f853c Compare November 10, 2026 05:36
@baktun14
baktun14 added this pull request to the merge queue Nov 10, 2026
@baktun14
baktun14 removed this pull request from the merge queue due to a manual request Nov 10, 2026
Referred sign-ups now get the env-configured referral trial deployment
allowance instead of the standard trial amount, exposed via GET
/v1/referral and shown on the onboarding page.
Kills two surviving mutants from the stryker run: a zero-cents edge
case on the recorded referral trial amount, and a sign check on the
trial activation latency passed to instrumentation.
recordTrialGranted ran after the wallet was marked activatedAt, so a
failure there left the trial credits unrecorded while the retry
short-circuited on the already-activated wallet and reported success.
Granting on-chain, then recording the referral trial, then activating
means a failure anywhere leaves the wallet unactivated and the retry
replays the whole sequence.
A referred user briefly saw the default trial amount before the referral
query resolved and swapped in the referral amount.
Adds the `affiliate_commission` stripe_transactions type and a
source_transaction_id column so a future commission job can link a
grant back to the payment it was earned on, and plumbs the new type
through the API schema, http-sdk, billing history UI and the
credits-added Slack alert.

- add enum value + source_transaction_id (partial unique index) via
  migration 0075_affiliate_commission
- add StripeTransactionRepository.createAffiliateCommission,
  findAffiliateCommissionBySource(AndLock)
- regenerate the OpenAPI spec and console-api-types
… of blocking it

source_transaction_id defaulted to ON DELETE NO ACTION, so deleting a
referred user (which cascades to their payment row) would fail with an
FK violation once the affiliate's commission row referenced that
payment. The commission is the affiliate's ledger entry and must
survive account deletion with its source link severed, so the FK is
ON DELETE SET NULL instead.

0075_affiliate_commission is unreleased, so the migration and its
snapshot are updated in place rather than adding a new one.
"Refunded" on a commission row read as money returned to the affiliate,
when the commission was in fact taken back.
@baktun14
baktun14 force-pushed the feat/billing-affiliate-commission-type branch from 92f853c to d50dd71 Compare November 10, 2026 06:01
@github-actions github-actions Bot added size: L and removed size: XL labels Nov 10, 2026
@baktun14
baktun14 added this pull request to the merge queue Nov 11, 2026
Merged via the queue into main with commit 2986d42 Nov 11, 2026
84 of 85 checks passed
@baktun14
baktun14 deleted the feat/billing-affiliate-commission-type branch November 11, 2026 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant