Skip to content

Commit f80698a

Browse files
committed
extract billing webhook from billing module + deleteWorkspace if PENDING_CREATION workspace has deactivated sub
1 parent 83f28f1 commit f80698a

File tree

26 files changed

+105
-44
lines changed

26 files changed

+105
-44
lines changed

packages/twenty-server/src/engine/core-modules/billing/billing.controller.ts renamed to packages/twenty-server/src/engine/core-modules/billing-webhook/billing-webhook.controller.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ import {
1515
import { Response } from 'express';
1616
import Stripe from 'stripe';
1717

18+
import { BillingWebhookAlertService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-alert.service';
19+
import { BillingWebhookCustomerService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-customer.service';
20+
import { BillingWebhookEntitlementService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-entitlement.service';
21+
import { BillingWebhookInvoiceService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-invoice.service';
22+
import { BillingWebhookPriceService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-price.service';
23+
import { BillingWebhookProductService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-product.service';
24+
import { BillingWebhookSubscriptionService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-subscription.service';
1825
import {
1926
BillingException,
2027
BillingExceptionCode,
@@ -23,19 +30,12 @@ import { BillingWebhookEvent } from 'src/engine/core-modules/billing/enums/billi
2330
import { BillingRestApiExceptionFilter } from 'src/engine/core-modules/billing/filters/billing-api-exception.filter';
2431
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
2532
import { StripeWebhookService } from 'src/engine/core-modules/billing/stripe/services/stripe-webhook.service';
26-
import { BillingWebhookAlertService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-alert.service';
27-
import { BillingWebhookCustomerService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-customer.service';
28-
import { BillingWebhookEntitlementService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-entitlement.service';
29-
import { BillingWebhookInvoiceService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-invoice.service';
30-
import { BillingWebhookPriceService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-price.service';
31-
import { BillingWebhookProductService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-product.service';
32-
import { BillingWebhookSubscriptionService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-subscription.service';
3333
import { PublicEndpointGuard } from 'src/engine/guards/public-endpoint.guard';
3434

3535
@Controller()
3636
@UseFilters(BillingRestApiExceptionFilter)
37-
export class BillingController {
38-
protected readonly logger = new Logger(BillingController.name);
37+
export class BillingWebhookController {
38+
protected readonly logger = new Logger(BillingWebhookController.name);
3939

4040
constructor(
4141
private readonly stripeWebhookService: StripeWebhookService,
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { Module } from '@nestjs/common';
2+
import { TypeOrmModule } from '@nestjs/typeorm';
3+
4+
import { BillingWebhookController } from 'src/engine/core-modules/billing-webhook/billing-webhook.controller';
5+
import { BillingWebhookAlertService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-alert.service';
6+
import { BillingWebhookCustomerService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-customer.service';
7+
import { BillingWebhookEntitlementService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-entitlement.service';
8+
import { BillingWebhookInvoiceService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-invoice.service';
9+
import { BillingWebhookPriceService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-price.service';
10+
import { BillingWebhookProductService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-product.service';
11+
import { BillingWebhookSubscriptionService } from 'src/engine/core-modules/billing-webhook/services/billing-webhook-subscription.service';
12+
import { BillingModule } from 'src/engine/core-modules/billing/billing.module';
13+
import { BillingCustomer } from 'src/engine/core-modules/billing/entities/billing-customer.entity';
14+
import { BillingEntitlement } from 'src/engine/core-modules/billing/entities/billing-entitlement.entity';
15+
import { BillingMeter } from 'src/engine/core-modules/billing/entities/billing-meter.entity';
16+
import { BillingPrice } from 'src/engine/core-modules/billing/entities/billing-price.entity';
17+
import { BillingProduct } from 'src/engine/core-modules/billing/entities/billing-product.entity';
18+
import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity';
19+
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
20+
import { StripeModule } from 'src/engine/core-modules/billing/stripe/stripe.module';
21+
import { DomainManagerModule } from 'src/engine/core-modules/domain-manager/domain-manager.module';
22+
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
23+
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
24+
import { MessageQueueModule } from 'src/engine/core-modules/message-queue/message-queue.module';
25+
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
26+
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
27+
import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module';
28+
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
29+
30+
@Module({
31+
imports: [
32+
FeatureFlagModule,
33+
StripeModule,
34+
DomainManagerModule,
35+
MessageQueueModule,
36+
PermissionsModule,
37+
WorkspaceModule,
38+
BillingModule,
39+
TypeOrmModule.forFeature(
40+
[
41+
BillingSubscription,
42+
BillingSubscriptionItem,
43+
BillingCustomer,
44+
BillingProduct,
45+
BillingPrice,
46+
BillingMeter,
47+
BillingEntitlement,
48+
Workspace,
49+
UserWorkspace,
50+
FeatureFlag,
51+
],
52+
'core',
53+
),
54+
],
55+
controllers: [BillingWebhookController],
56+
providers: [
57+
BillingWebhookProductService,
58+
BillingWebhookPriceService,
59+
BillingWebhookAlertService,
60+
BillingWebhookInvoiceService,
61+
BillingWebhookCustomerService,
62+
BillingWebhookSubscriptionService,
63+
BillingWebhookEntitlementService,
64+
],
65+
})
66+
export class BillingWebhookModule {}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ import { InjectRepository } from '@nestjs/typeorm';
66
import Stripe from 'stripe';
77
import { Repository } from 'typeorm';
88

9+
import { transformStripeEntitlementUpdatedEventToDatabaseEntitlement } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-entitlement-updated-event-to-database-entitlement.util';
910
import {
1011
BillingException,
1112
BillingExceptionCode,
1213
} from 'src/engine/core-modules/billing/billing.exception';
1314
import { BillingCustomer } from 'src/engine/core-modules/billing/entities/billing-customer.entity';
1415
import { BillingEntitlement } from 'src/engine/core-modules/billing/entities/billing-entitlement.entity';
15-
import { transformStripeEntitlementUpdatedEventToDatabaseEntitlement } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-entitlement-updated-event-to-database-entitlement.util';
16+
1617
@Injectable()
1718
export class BillingWebhookEntitlementService {
1819
constructor(
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { InjectRepository } from '@nestjs/typeorm';
66
import Stripe from 'stripe';
77
import { Repository } from 'typeorm';
88

9+
import { transformStripePriceEventToDatabasePrice } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-price-event-to-database-price.util';
910
import {
1011
BillingException,
1112
BillingExceptionCode,
@@ -15,7 +16,6 @@ import { BillingPrice } from 'src/engine/core-modules/billing/entities/billing-p
1516
import { BillingProduct } from 'src/engine/core-modules/billing/entities/billing-product.entity';
1617
import { StripeBillingMeterService } from 'src/engine/core-modules/billing/stripe/services/stripe-billing-meter.service';
1718
import { transformStripeMeterToDatabaseMeter } from 'src/engine/core-modules/billing/utils/transform-stripe-meter-to-database-meter.util';
18-
import { transformStripePriceEventToDatabasePrice } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-price-event-to-database-price.util';
1919

2020
@Injectable()
2121
export class BillingWebhookPriceService {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import { InjectRepository } from '@nestjs/typeorm';
66
import Stripe from 'stripe';
77
import { Repository } from 'typeorm';
88

9+
import { transformStripeProductEventToDatabaseProduct } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-product-event-to-database-product.util';
910
import { BillingProduct } from 'src/engine/core-modules/billing/entities/billing-product.entity';
1011
import { isStripeValidProductMetadata } from 'src/engine/core-modules/billing/utils/is-stripe-valid-product-metadata.util';
11-
import { transformStripeProductEventToDatabaseProduct } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-product-event-to-database-product.util';
1212
@Injectable()
1313
export class BillingWebhookProductService {
1414
protected readonly logger = new Logger(BillingWebhookProductService.name);
Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,29 @@ import { isDefined } from 'twenty-shared/utils';
88
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
99
import { In, Repository } from 'typeorm';
1010

11+
import { getDeletedStripeSubscriptionItemIdsFromStripeSubscriptionEvent } from 'src/engine/core-modules/billing-webhook/utils/get-deleted-stripe-subscription-item-ids-from-stripe-subscription-event.util';
12+
import { transformStripeSubscriptionEventToDatabaseCustomer } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-subscription-event-to-database-customer.util';
13+
import { transformStripeSubscriptionEventToDatabaseSubscriptionItem } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-subscription-event-to-database-subscription-item.util';
14+
import { transformStripeSubscriptionEventToDatabaseSubscription } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-subscription-event-to-database-subscription.util';
1115
import { BillingCustomer } from 'src/engine/core-modules/billing/entities/billing-customer.entity';
1216
import { BillingSubscriptionItem } from 'src/engine/core-modules/billing/entities/billing-subscription-item.entity';
1317
import { BillingSubscription } from 'src/engine/core-modules/billing/entities/billing-subscription.entity';
1418
import { SubscriptionStatus } from 'src/engine/core-modules/billing/enums/billing-subscription-status.enum';
1519
import { BillingWebhookEvent } from 'src/engine/core-modules/billing/enums/billing-webhook-events.enum';
1620
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
1721
import { StripeCustomerService } from 'src/engine/core-modules/billing/stripe/services/stripe-customer.service';
18-
import { getDeletedStripeSubscriptionItemIdsFromStripeSubscriptionEvent } from 'src/engine/core-modules/billing/webhooks/utils/get-deleted-stripe-subscription-item-ids-from-stripe-subscription-event.util';
19-
import { transformStripeSubscriptionEventToDatabaseCustomer } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-subscription-event-to-database-customer.util';
20-
import { transformStripeSubscriptionEventToDatabaseSubscriptionItem } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-subscription-event-to-database-subscription-item.util';
21-
import { transformStripeSubscriptionEventToDatabaseSubscription } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-subscription-event-to-database-subscription.util';
22-
import { FeatureFlag } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
2322
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
2423
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
2524
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
25+
import { WorkspaceService } from 'src/engine/core-modules/workspace/services/workspace.service';
2626
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
2727
import {
2828
CleanWorkspaceDeletionWarningUserVarsJob,
2929
CleanWorkspaceDeletionWarningUserVarsJobData,
3030
} from 'src/engine/workspace-manager/workspace-cleaner/jobs/clean-workspace-deletion-warning-user-vars.job';
3131

3232
@Injectable()
33+
// eslint-disable-next-line @nx/workspace-inject-workspace-repository
3334
export class BillingWebhookSubscriptionService {
3435
protected readonly logger = new Logger(
3536
BillingWebhookSubscriptionService.name,
@@ -47,8 +48,7 @@ export class BillingWebhookSubscriptionService {
4748
@InjectRepository(BillingCustomer, 'core')
4849
private readonly billingCustomerRepository: Repository<BillingCustomer>,
4950
private readonly billingSubscriptionService: BillingSubscriptionService,
50-
@InjectRepository(FeatureFlag, 'core')
51-
private readonly featureFlagRepository: Repository<FeatureFlag>,
51+
private readonly workspaceService: WorkspaceService,
5252
) {}
5353

5454
async processStripeEvent(
@@ -115,6 +115,13 @@ export class BillingWebhookSubscriptionService {
115115
});
116116
}
117117

118+
if (
119+
this.shouldSuspendWorkspace(data) &&
120+
workspace.activationStatus == WorkspaceActivationStatus.PENDING_CREATION
121+
) {
122+
await this.workspaceService.deleteWorkspace(workspace.id);
123+
}
124+
118125
if (
119126
!this.shouldSuspendWorkspace(data) &&
120127
workspace.activationStatus == WorkspaceActivationStatus.SUSPENDED
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import {
22
mockStripeSubscriptionUpdatedEventWithDeletedItem,
33
mockStripeSubscriptionUpdatedEventWithoutUpdatedItem,
44
mockStripeSubscriptionUpdatedEventWithUpdatedItemOnly,
5-
} from 'src/engine/core-modules/billing/webhooks/__mocks__/stripe-subscription-updated-events';
6-
import { getDeletedStripeSubscriptionItemIdsFromStripeSubscriptionEvent } from 'src/engine/core-modules/billing/webhooks/utils/get-deleted-stripe-subscription-item-ids-from-stripe-subscription-event.util';
5+
} from 'src/engine/core-modules/billing-webhook/__mocks__/stripe-subscription-updated-events';
6+
import { getDeletedStripeSubscriptionItemIdsFromStripeSubscriptionEvent } from 'src/engine/core-modules/billing-webhook/utils/get-deleted-stripe-subscription-item-ids-from-stripe-subscription-event.util';
77

88
describe('getDeletedStripeSubscriptionItemIdsFromStripeSubscriptionEvent', () => {
99
it('should return an empty array if subscription items are not updated', () => {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import Stripe from 'stripe';
44

5+
import { transformStripeEntitlementUpdatedEventToDatabaseEntitlement } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-entitlement-updated-event-to-database-entitlement.util';
56
import { BillingEntitlementKey } from 'src/engine/core-modules/billing/enums/billing-entitlement-key.enum';
6-
import { transformStripeEntitlementUpdatedEventToDatabaseEntitlement } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-entitlement-updated-event-to-database-entitlement.util';
77

88
describe('transformStripeEntitlementUpdatedEventToDatabaseEntitlement', () => {
99
it('should return the SSO key with true value', () => {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/* @license Enterprise */
22

3+
import { transformStripePriceEventToDatabasePrice } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-price-event-to-database-price.util';
34
import { BillingPriceBillingScheme } from 'src/engine/core-modules/billing/enums/billing-price-billing-scheme.enum';
45
import { BillingPriceTaxBehavior } from 'src/engine/core-modules/billing/enums/billing-price-tax-behavior.enum';
56
import { BillingPriceTiersMode } from 'src/engine/core-modules/billing/enums/billing-price-tiers-mode.enum';
67
import { BillingPriceType } from 'src/engine/core-modules/billing/enums/billing-price-type.enum';
78
import { SubscriptionInterval } from 'src/engine/core-modules/billing/enums/billing-subscription-interval.enum';
89
import { BillingUsageType } from 'src/engine/core-modules/billing/enums/billing-usage-type.enum';
9-
import { transformStripePriceEventToDatabasePrice } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-price-event-to-database-price.util';
1010

1111
describe('transformStripePriceEventToDatabasePrice', () => {
1212
const createMockPriceData = (overrides = {}) => ({
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import Stripe from 'stripe';
44

5-
import { transformStripeProductEventToDatabaseProduct } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-product-event-to-database-product.util';
5+
import { transformStripeProductEventToDatabaseProduct } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-product-event-to-database-product.util';
66

77
describe('transformStripeProductEventToDatabaseProduct', () => {
88
it('should return the correct data', () => {
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* @license Enterprise */
22

3-
import { transformStripeSubscriptionEventToDatabaseCustomer } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-subscription-event-to-database-customer.util';
3+
import { transformStripeSubscriptionEventToDatabaseCustomer } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-subscription-event-to-database-customer.util';
4+
45
describe('transformStripeSubscriptionEventToDatabaseCustomer', () => {
56
const mockWorkspaceId = 'workspace_123';
67
const mockTimestamp = 1672531200; // 2023-01-01 00:00:00 UTC
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* @license Enterprise */
22

3+
import { transformStripeSubscriptionEventToDatabaseSubscription } from 'src/engine/core-modules/billing-webhook/utils/transform-stripe-subscription-event-to-database-subscription.util';
34
import { BillingSubscriptionCollectionMethod } from 'src/engine/core-modules/billing/enums/billing-subscription-collection-method.enum';
45
import { SubscriptionStatus } from 'src/engine/core-modules/billing/enums/billing-subscription-status.enum';
5-
import { transformStripeSubscriptionEventToDatabaseSubscription } from 'src/engine/core-modules/billing/webhooks/utils/transform-stripe-subscription-event-to-database-subscription.util';
66

77
describe('transformStripeSubscriptionEventToDatabaseSubscription', () => {
88
const mockWorkspaceId = 'workspace-123';

0 commit comments

Comments
 (0)