MCPcopy Index your code
hub / github.com/CodebuffAI/codebuff / handleSubscribe

Function handleSubscribe

packages/billing/src/subscription.ts:629–700  ·  view source on GitHub ↗
(params: {
  userId: string
  stripeSubscription: Stripe.Subscription
  logger: Logger
})

Source from the content-addressed store, hash-verified

627 * All operations run inside an advisory-locked transaction.
628 */
629export async function handleSubscribe(params: {
630 userId: string
631 stripeSubscription: Stripe.Subscription
632 logger: Logger
633}): Promise<void> {
634 const { userId, stripeSubscription, logger } = params
635 const newResetDate = new Date(stripeSubscription.current_period_end * 1000)
636
637 const { result: didMigrate } = await withAdvisoryLockTransaction({
638 callback: async (tx) => {
639 // Idempotency: check if credits were already migrated for this subscription.
640 // We use the credit_ledger instead of the subscription table because
641 // handleSubscriptionUpdated may upsert the subscription row before
642 // invoice.paid fires, which would cause this check to skip migration.
643 const migrationOpId = `subscribe-migrate-${stripeSubscription.id}`
644 const existingMigration = await tx
645 .select({ operation_id: schema.creditLedger.operation_id })
646 .from(schema.creditLedger)
647 .where(eq(schema.creditLedger.operation_id, migrationOpId))
648 .limit(1)
649
650 if (existingMigration.length > 0) {
651 logger.info(
652 { userId, subscriptionId: stripeSubscription.id },
653 'Credits already migrated — skipping handleSubscribe',
654 )
655 return false
656 }
657
658 // Move next_quota_reset to align with Stripe billing period
659 await tx
660 .update(schema.user)
661 .set({ next_quota_reset: newResetDate })
662 .where(eq(schema.user.id, userId))
663
664 // Migrate unused credits so nothing is lost
665 await migrateUnusedCredits({
666 tx,
667 userId,
668 subscriptionId: stripeSubscription.id,
669 expiresAt: newResetDate,
670 logger,
671 })
672
673 return true
674 },
675 lockKey: `user:${userId}`,
676 context: { userId, subscriptionId: stripeSubscription.id },
677 logger,
678 })
679
680 if (didMigrate) {
681 trackEvent({
682 event: AnalyticsEvent.SUBSCRIPTION_CREATED,
683 userId,
684 properties: {
685 subscriptionId: stripeSubscription.id,
686 newResetDate: newResetDate.toISOString(),

Callers 1

Calls 5

trackEventFunction · 0.90
migrateUnusedCreditsFunction · 0.85
fromMethod · 0.80
setMethod · 0.80

Tested by

no test coverage detected