Files
sean-brydonGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
f4abbb2de1 feat: refactor billing to strategy implemention (#27828)
* factory and statergie

* chore: use correct method of DI

* feat: add onchagne

* add logic to HWM stat

* add webhook resolver methods to each statergy

* move seat tracking + webhooks over to own statergy

* Move to factory base approach

* move logic to correct class

* rename create -> createByTeamId

* fix: remove debug `true ||` overrides from IS_STRIPE_ENABLED and IS_TEAM_BILLING_ENABLED

Remove accidentally committed debug overrides that short-circuited
IS_STRIPE_ENABLED and IS_TEAM_BILLING_ENABLED to always be true,
bypassing Stripe credential checks. This would break self-hosted
instances without Stripe configured.

Identified by cubic (https://cubic.dev)

Co-Authored-By: unknown <>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 13:11:36 -03:00

46 lines
1.5 KiB
TypeScript

export type SeatChangeType = "addition" | "removal" | "sync";
export interface SeatChangeContext {
teamId: number;
subscriptionId: string;
subscriptionItemId: string;
membershipCount: number;
changeType: SeatChangeType;
}
export interface StripeInvoiceData {
lines: {
data: Array<{
metadata?: Record<string, string | null | undefined> | null;
}>;
};
}
export interface ISeatBillingStrategy {
onSeatChange(context: SeatChangeContext): Promise<void>;
onInvoiceUpcoming(subscriptionId: string): Promise<{ applied: boolean }>;
onRenewalPaid(subscriptionId: string, periodStart: Date): Promise<{ reset: boolean }>;
onPaymentSucceeded(invoice: StripeInvoiceData): Promise<{ handled: boolean }>;
onPaymentFailed(invoice: StripeInvoiceData, reason: string): Promise<{ handled: boolean }>;
}
export abstract class BaseSeatBillingStrategy implements ISeatBillingStrategy {
abstract onSeatChange(context: SeatChangeContext): Promise<void>;
async onInvoiceUpcoming(_subscriptionId: string): Promise<{ applied: boolean }> {
return { applied: false };
}
async onRenewalPaid(_subscriptionId: string, _periodStart: Date): Promise<{ reset: boolean }> {
return { reset: false };
}
async onPaymentSucceeded(_invoice: StripeInvoiceData): Promise<{ handled: boolean }> {
return { handled: false };
}
async onPaymentFailed(_invoice: StripeInvoiceData, _reason: string): Promise<{ handled: boolean }> {
return { handled: false };
}
}