Skip to content

Conversation

@sean-brydon
Copy link
Member

@sean-brydon sean-brydon commented Jan 19, 2026

Part 2 of monthly proration feature.

Adds monthly proration billing processing that works on top of the seat tracking infrastructure.

Dependency chain:

Testing locally

  1. Setup trigger.dev locally and run their --analyze command
  2. Ensure you have yarn stripe:listen running
  3. Enable the monthly-proration feature flag
  4. Create a new user
  5. Create a team
  6. Switch to annual plan (You will need to create an upsell price in stripe)
  7. Add X users to the team
  8. Remove X users from the team
  9. Manually trigger the proration task from the trigger.dev dashboard

emrysal pushed a commit that referenced this pull request Jan 19, 2026
Part 1 of monthly proration feature.

Adds seat change tracking infrastructure with operationId for idempotency.

**Dependency chain:**
- This PR (seat tracking)
- PR #27002  depends on this
Base automatically changed from feat/monthly-proration-seat-tracking to main January 19, 2026 13:56
sean-brydon and others added 2 commits January 19, 2026 14:29
Add seat change logging infrastructure with operationId for idempotency.
This PR adds the foundation for monthly proration billing by tracking
seat additions and removals, gated behind the monthly-proration feature flag.

- Add operationId field to SeatChangeLog for idempotency
- Update SeatChangeLogRepository to support upsert with operationId
- Add feature flag guard in SeatChangeTrackingService
- Integrate seat tracking in team member invites
- Integrate seat tracking in bulk user deletions
- Integrate seat tracking in team service operations
- Integrate seat tracking in DSYNC user creation

When monthly-proration feature flag is disabled, seat logging is skipped
and behavior remains unchanged.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add monthly proration billing processing that works on top of the seat
tracking infrastructure. This PR implements the core proration logic,
webhook handlers, and integration with Stripe billing.

- Enhance MonthlyProrationService to process seat change logs
- Add payment webhook handlers (invoice.payment_succeeded, invoice.payment_failed)
- Update subscription webhook to sync billing period on renewals
- Update TeamBillingService to skip real-time updates when proration enabled
- Enhance StripeBillingService with proration capabilities
- Add Tasker enhancements for processing queues
- Update team creation/upgrade routes

Depends on: feat/monthly-proration-seat-tracking

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@sean-brydon sean-brydon force-pushed the feat/monthly-proration-processing branch from fb62dea to 1917746 Compare January 19, 2026 14:29
@github-actions
Copy link
Contributor

Devin AI is resolving merge conflicts

This PR has merge conflicts with the main branch. A Devin session has been created to automatically resolve them.

View Devin Session

Devin will:

  1. Merge the latest main into this branch
  2. Resolve any conflicts intelligently
  3. Run lint/type checks to ensure validity
  4. Push the resolved changes

If you prefer to resolve conflicts manually, you can close the Devin session and handle it yourself.

devin-ai-integration bot and others added 3 commits January 20, 2026 09:45
Resolved conflicts in:
- packages/features/ee/billing/service/billingProvider/IBillingProviderService.ts
- packages/features/ee/billing/service/billingProvider/StripeBillingService.ts

Both branches added independent methods to the billing interface:
- PR branch: voidInvoice, getPaymentIntentFailureReason, hasDefaultPaymentMethod
- main branch: createSubscriptionUsageRecord

All methods from both branches have been preserved.

Co-Authored-By: unknown <>
@sean-brydon sean-brydon marked this pull request as ready for review January 20, 2026 09:53
@graphite-app graphite-app bot added core area: core, team members only consumer labels Jan 20, 2026
@graphite-app graphite-app bot requested review from a team and removed request for a team January 20, 2026 09:53
Copy link
Contributor

@cubic-dev-ai cubic-dev-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.

No issues found across 27 files

eunjae-lee
eunjae-lee previously approved these changes Jan 21, 2026
Copy link
Contributor

@eunjae-lee eunjae-lee left a comment

Choose a reason for hiding this comment

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

looks good to go !


const { billingPeriod, pricePerSeat, paidSeats } = extractBillingDataFromStripeSubscription(subscription);

const teamBilling = await prisma.teamBilling.findUnique({
Copy link
Contributor

Choose a reason for hiding this comment

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

perhaps we use a repository here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm actually going to make this blocking since we don't need to rush this out.

Copy link
Contributor

@joeauyeung joeauyeung left a comment

Choose a reason for hiding this comment

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

Tested this out and it's working as expected.

I think we should ensure that we don't call prisma directly in any handlers so I'm making that a blocking comment before merging.


const { billingPeriod, pricePerSeat, paidSeats } = extractBillingDataFromStripeSubscription(subscription);

const teamBilling = await prisma.teamBilling.findUnique({
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm actually going to make this blocking since we don't need to rush this out.

@github-actions github-actions bot marked this pull request as draft January 21, 2026 18:15
joeauyeung
joeauyeung previously approved these changes Jan 21, 2026
Copy link
Contributor

@joeauyeung joeauyeung left a comment

Choose a reason for hiding this comment

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

Chatted with @sean-brydon about some feedback on ensuring we're checking the feature flag properly at every entry point into Cal.

Great job!

@sean-brydon sean-brydon marked this pull request as ready for review January 21, 2026 19:07
Copy link
Contributor

@cubic-dev-ai cubic-dev-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.

No issues found across 31 files

joeauyeung
joeauyeung previously approved these changes Jan 21, 2026
@sean-brydon sean-brydon enabled auto-merge (squash) January 21, 2026 19:55
@github-actions
Copy link
Contributor

github-actions bot commented Jan 21, 2026

E2E results are ready!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants