@carlonicora/nestjs-neo4jsonapi 7.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap/app.module.factory.d.ts.map +1 -1
- package/dist/bootstrap/app.module.factory.js +1 -0
- package/dist/bootstrap/app.module.factory.js.map +1 -1
- package/dist/bootstrap/bootstrap.options.d.ts +20 -0
- package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
- package/dist/common/decorators/audit.decorator.d.ts +3 -0
- package/dist/common/decorators/audit.decorator.d.ts.map +1 -1
- package/dist/common/decorators/audit.decorator.js +15 -2
- package/dist/common/decorators/audit.decorator.js.map +1 -1
- package/dist/common/decorators/cache-invalidate.decorator.d.ts.map +1 -1
- package/dist/common/decorators/cache-invalidate.decorator.js +3 -11
- package/dist/common/decorators/cache-invalidate.decorator.js.map +1 -1
- package/dist/common/decorators/handler-wrapper.d.ts +13 -0
- package/dist/common/decorators/handler-wrapper.d.ts.map +1 -0
- package/dist/common/decorators/handler-wrapper.js +25 -0
- package/dist/common/decorators/handler-wrapper.js.map +1 -0
- package/dist/common/decorators/validate-id.decorator.d.ts.map +1 -1
- package/dist/common/decorators/validate-id.decorator.js +3 -11
- package/dist/common/decorators/validate-id.decorator.js.map +1 -1
- package/dist/core/email/templates/en/cardExpiring.hbs +28 -0
- package/dist/core/email/templates/en/paymentFailure.hbs +4 -0
- package/dist/foundations/ai-connection/controllers/ai-connection.controller.d.ts +2 -1
- package/dist/foundations/ai-connection/controllers/ai-connection.controller.d.ts.map +1 -1
- package/dist/foundations/ai-connection/controllers/ai-connection.controller.js +5 -4
- package/dist/foundations/ai-connection/controllers/ai-connection.controller.js.map +1 -1
- package/dist/foundations/analytics/controllers/analytics.admin.controller.d.ts +2 -1
- package/dist/foundations/analytics/controllers/analytics.admin.controller.d.ts.map +1 -1
- package/dist/foundations/analytics/controllers/analytics.admin.controller.js +5 -4
- package/dist/foundations/analytics/controllers/analytics.admin.controller.js.map +1 -1
- package/dist/foundations/billing/billing.module.d.ts +26 -0
- package/dist/foundations/billing/billing.module.d.ts.map +1 -0
- package/dist/foundations/billing/billing.module.js +74 -0
- package/dist/foundations/billing/billing.module.js.map +1 -0
- package/dist/foundations/billing/cron/billing-lifecycle.cron.d.ts +16 -0
- package/dist/foundations/billing/cron/billing-lifecycle.cron.d.ts.map +1 -0
- package/dist/foundations/billing/cron/billing-lifecycle.cron.js +52 -0
- package/dist/foundations/billing/cron/billing-lifecycle.cron.js.map +1 -0
- package/dist/foundations/billing/index.d.ts +7 -0
- package/dist/foundations/billing/index.d.ts.map +1 -0
- package/dist/foundations/billing/index.js +28 -0
- package/dist/foundations/billing/index.js.map +1 -0
- package/dist/foundations/billing/interfaces/billing.config.interface.d.ts +71 -0
- package/dist/foundations/billing/interfaces/billing.config.interface.d.ts.map +1 -0
- package/dist/foundations/billing/interfaces/billing.config.interface.js +41 -0
- package/dist/foundations/billing/interfaces/billing.config.interface.js.map +1 -0
- package/dist/foundations/billing/processors/billing-email.jobs.d.ts +127 -0
- package/dist/foundations/billing/processors/billing-email.jobs.d.ts.map +1 -0
- package/dist/foundations/billing/processors/billing-email.jobs.js +196 -0
- package/dist/foundations/billing/processors/billing-email.jobs.js.map +1 -0
- package/dist/foundations/billing/processors/billing-email.processor.d.ts +33 -0
- package/dist/foundations/billing/processors/billing-email.processor.d.ts.map +1 -0
- package/dist/foundations/billing/processors/billing-email.processor.js +95 -0
- package/dist/foundations/billing/processors/billing-email.processor.js.map +1 -0
- package/dist/foundations/billing/services/card-expiry-warning.service.d.ts +58 -0
- package/dist/foundations/billing/services/card-expiry-warning.service.d.ts.map +1 -0
- package/dist/foundations/billing/services/card-expiry-warning.service.js +90 -0
- package/dist/foundations/billing/services/card-expiry-warning.service.js.map +1 -0
- package/dist/foundations/company/repositories/company.repository.d.ts +2 -0
- package/dist/foundations/company/repositories/company.repository.d.ts.map +1 -1
- package/dist/foundations/company/repositories/company.repository.js +2 -2
- package/dist/foundations/company/repositories/company.repository.js.map +1 -1
- package/dist/foundations/foundations.modules.d.ts +3 -0
- package/dist/foundations/foundations.modules.d.ts.map +1 -1
- package/dist/foundations/foundations.modules.js +3 -1
- package/dist/foundations/foundations.modules.js.map +1 -1
- package/dist/foundations/handbook/controllers/handbook.controller.d.ts +1 -1
- package/dist/foundations/handbook/controllers/handbook.controller.d.ts.map +1 -1
- package/dist/foundations/handbook/controllers/handbook.controller.js +5 -4
- package/dist/foundations/handbook/controllers/handbook.controller.js.map +1 -1
- package/dist/foundations/index.d.ts +1 -0
- package/dist/foundations/index.d.ts.map +1 -1
- package/dist/foundations/index.js +1 -0
- package/dist/foundations/index.js.map +1 -1
- package/dist/foundations/notification/controllers/notification.controller.d.ts.map +1 -1
- package/dist/foundations/notification/controllers/notification.controller.js +0 -1
- package/dist/foundations/notification/controllers/notification.controller.js.map +1 -1
- package/dist/foundations/role/controllers/role.controller.d.ts +1 -1
- package/dist/foundations/role/controllers/role.controller.d.ts.map +1 -1
- package/dist/foundations/role/controllers/role.controller.js +4 -3
- package/dist/foundations/role/controllers/role.controller.js.map +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon-code-checkout.controller.d.ts +2 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon-code-checkout.controller.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon-code-checkout.controller.js +5 -6
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon-code-checkout.controller.js.map +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon-code.controller.d.ts +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon-code.controller.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon-code.controller.js +5 -4
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon-code.controller.js.map +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon.controller.d.ts +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon.controller.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon.controller.js +5 -4
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon.controller.js.map +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon.public.controller.d.ts +1 -0
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon.public.controller.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon.public.controller.js +4 -0
- package/dist/foundations/stripe-coupon/controllers/stripe-coupon.public.controller.js.map +1 -1
- package/dist/foundations/stripe-coupon/dtos/stripe-coupon-code.automatic.query.dto.d.ts +8 -0
- package/dist/foundations/stripe-coupon/dtos/stripe-coupon-code.automatic.query.dto.d.ts.map +1 -0
- package/dist/foundations/stripe-coupon/dtos/stripe-coupon-code.automatic.query.dto.js +25 -0
- package/dist/foundations/stripe-coupon/dtos/stripe-coupon-code.automatic.query.dto.js.map +1 -0
- package/dist/foundations/stripe-coupon/entities/stripe-coupon-code.js +1 -1
- package/dist/foundations/stripe-coupon/entities/stripe-coupon-code.js.map +1 -1
- package/dist/foundations/stripe-coupon/entities/stripe-coupon-offer.d.ts +5 -0
- package/dist/foundations/stripe-coupon/entities/stripe-coupon-offer.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/entities/stripe-coupon-offer.js.map +1 -1
- package/dist/foundations/stripe-coupon/entities/stripe-coupon.d.ts +25 -2
- package/dist/foundations/stripe-coupon/entities/stripe-coupon.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/entities/stripe-coupon.js +1 -1
- package/dist/foundations/stripe-coupon/entities/stripe-coupon.js.map +1 -1
- package/dist/foundations/stripe-coupon/index.d.ts +1 -0
- package/dist/foundations/stripe-coupon/index.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/index.js +1 -0
- package/dist/foundations/stripe-coupon/index.js.map +1 -1
- package/dist/foundations/stripe-coupon/services/stripe-coupon-api.service.d.ts +5 -8
- package/dist/foundations/stripe-coupon/services/stripe-coupon-api.service.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/services/stripe-coupon-api.service.js +9 -9
- package/dist/foundations/stripe-coupon/services/stripe-coupon-api.service.js.map +1 -1
- package/dist/foundations/stripe-coupon/services/stripe-coupon-offer.service.js.map +1 -1
- package/dist/foundations/stripe-coupon/services/stripe-coupon.service.d.ts +36 -3
- package/dist/foundations/stripe-coupon/services/stripe-coupon.service.d.ts.map +1 -1
- package/dist/foundations/stripe-coupon/services/stripe-coupon.service.js +69 -33
- package/dist/foundations/stripe-coupon/services/stripe-coupon.service.js.map +1 -1
- package/dist/foundations/stripe-customer/services/stripe-customer-api.service.d.ts +17 -0
- package/dist/foundations/stripe-customer/services/stripe-customer-api.service.d.ts.map +1 -1
- package/dist/foundations/stripe-customer/services/stripe-customer-api.service.js +40 -0
- package/dist/foundations/stripe-customer/services/stripe-customer-api.service.js.map +1 -1
- package/dist/foundations/stripe-invoice/entities/stripe-invoice.entity.d.ts +1 -1
- package/dist/foundations/stripe-invoice/entities/stripe-invoice.entity.d.ts.map +1 -1
- package/dist/foundations/stripe-invoice/serialisers/stripe-invoice.serialiser.js +2 -2
- package/dist/foundations/stripe-invoice/serialisers/stripe-invoice.serialiser.js.map +1 -1
- package/dist/foundations/stripe-invoice/services/stripe-invoice-api.service.d.ts +13 -0
- package/dist/foundations/stripe-invoice/services/stripe-invoice-api.service.d.ts.map +1 -1
- package/dist/foundations/stripe-invoice/services/stripe-invoice-api.service.js +21 -0
- package/dist/foundations/stripe-invoice/services/stripe-invoice-api.service.js.map +1 -1
- package/dist/foundations/stripe-subscription/controllers/stripe-subscription.controller.d.ts +1 -3
- package/dist/foundations/stripe-subscription/controllers/stripe-subscription.controller.d.ts.map +1 -1
- package/dist/foundations/stripe-subscription/controllers/stripe-subscription.controller.js +5 -38
- package/dist/foundations/stripe-subscription/controllers/stripe-subscription.controller.js.map +1 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.d.ts +60 -0
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.d.ts.map +1 -0
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.discount.d.ts +1 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.discount.d.ts.map +1 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.js +61 -0
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.js.map +1 -0
- package/dist/foundations/stripe-subscription/index.d.ts +1 -4
- package/dist/foundations/stripe-subscription/index.d.ts.map +1 -1
- package/dist/foundations/stripe-subscription/index.js +4 -8
- package/dist/foundations/stripe-subscription/index.js.map +1 -1
- package/dist/foundations/stripe-subscription/repositories/stripe-subscription.repository.d.ts +93 -165
- package/dist/foundations/stripe-subscription/repositories/stripe-subscription.repository.d.ts.map +1 -1
- package/dist/foundations/stripe-subscription/repositories/stripe-subscription.repository.js +206 -274
- package/dist/foundations/stripe-subscription/repositories/stripe-subscription.repository.js.map +1 -1
- package/dist/foundations/stripe-subscription/services/stripe-subscription-admin.service.d.ts +34 -36
- package/dist/foundations/stripe-subscription/services/stripe-subscription-admin.service.d.ts.map +1 -1
- package/dist/foundations/stripe-subscription/services/stripe-subscription-admin.service.js +20 -72
- package/dist/foundations/stripe-subscription/services/stripe-subscription-admin.service.js.map +1 -1
- package/dist/foundations/stripe-subscription/services/stripe-subscription-api.service.d.ts +1 -29
- package/dist/foundations/stripe-subscription/services/stripe-subscription-api.service.d.ts.map +1 -1
- package/dist/foundations/stripe-subscription/services/stripe-subscription-api.service.js +1 -53
- package/dist/foundations/stripe-subscription/services/stripe-subscription-api.service.js.map +1 -1
- package/dist/foundations/stripe-subscription/stripe-subscription.module.d.ts +3 -3
- package/dist/foundations/stripe-subscription/stripe-subscription.module.d.ts.map +1 -1
- package/dist/foundations/stripe-subscription/stripe-subscription.module.js +8 -7
- package/dist/foundations/stripe-subscription/stripe-subscription.module.js.map +1 -1
- package/dist/foundations/stripe-usage/entities/stripe-usage-record.entity.d.ts +1 -1
- package/dist/foundations/stripe-usage/entities/stripe-usage-record.entity.d.ts.map +1 -1
- package/dist/foundations/stripe-usage/serialisers/stripe-usage-record.serialiser.js +2 -2
- package/dist/foundations/stripe-usage/serialisers/stripe-usage-record.serialiser.js.map +1 -1
- package/dist/foundations/stripe-webhook/processors/stripe-webhook.processor.d.ts +6 -1
- package/dist/foundations/stripe-webhook/processors/stripe-webhook.processor.d.ts.map +1 -1
- package/dist/foundations/stripe-webhook/processors/stripe-webhook.processor.js +73 -15
- package/dist/foundations/stripe-webhook/processors/stripe-webhook.processor.js.map +1 -1
- package/dist/foundations/stripe-webhook/services/stripe-webhook-notification.service.d.ts +24 -2
- package/dist/foundations/stripe-webhook/services/stripe-webhook-notification.service.d.ts.map +1 -1
- package/dist/foundations/stripe-webhook/services/stripe-webhook-notification.service.js +88 -20
- package/dist/foundations/stripe-webhook/services/stripe-webhook-notification.service.js.map +1 -1
- package/package.json +1 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.entity.d.ts +0 -27
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.entity.d.ts.map +0 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.entity.js +0 -3
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.entity.js.map +0 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.map.d.ts +0 -8
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.map.d.ts.map +0 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.map.js +0 -30
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.map.js.map +0 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.model.d.ts +0 -4
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.model.d.ts.map +0 -1
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.model.js +0 -17
- package/dist/foundations/stripe-subscription/entities/stripe-subscription.model.js.map +0 -1
- package/dist/foundations/stripe-subscription/serialisers/stripe-subscription.serialiser.d.ts +0 -9
- package/dist/foundations/stripe-subscription/serialisers/stripe-subscription.serialiser.d.ts.map +0 -1
- package/dist/foundations/stripe-subscription/serialisers/stripe-subscription.serialiser.js +0 -59
- package/dist/foundations/stripe-subscription/serialisers/stripe-subscription.serialiser.js.map +0 -1
|
@@ -12,169 +12,131 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.StripeSubscriptionRepository = void 0;
|
|
13
13
|
const common_1 = require("@nestjs/common");
|
|
14
14
|
const crypto_1 = require("crypto");
|
|
15
|
-
const
|
|
16
|
-
const
|
|
15
|
+
const nestjs_cls_1 = require("nestjs-cls");
|
|
16
|
+
const abstract_repository_1 = require("../../../core/neo4j/abstracts/abstract.repository");
|
|
17
|
+
const neo4j_service_1 = require("../../../core/neo4j/services/neo4j.service");
|
|
18
|
+
const security_service_1 = require("../../../core/security/services/security.service");
|
|
19
|
+
const company_meta_1 = require("../../company/entities/company.meta");
|
|
17
20
|
const stripe_customer_meta_1 = require("../../stripe-customer/entities/stripe-customer.meta");
|
|
18
21
|
const stripe_price_meta_1 = require("../../stripe-price/entities/stripe-price.meta");
|
|
19
22
|
const stripe_product_meta_1 = require("../../stripe-product/entities/stripe-product.meta");
|
|
23
|
+
const user_meta_1 = require("../../user/entities/user.meta");
|
|
24
|
+
const stripe_subscription_1 = require("../entities/stripe-subscription");
|
|
20
25
|
const stripe_subscription_discount_1 = require("../entities/stripe-subscription.discount");
|
|
21
26
|
const stripe_subscription_meta_1 = require("../entities/stripe-subscription.meta");
|
|
22
|
-
const
|
|
27
|
+
const S = stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName;
|
|
28
|
+
/** Datetime fields `update()` can set or clear: undefined leaves, null clears. */
|
|
29
|
+
const CLEARABLE_DATETIME_FIELDS = ["canceledAt", "cardExpiryCheckedFor"];
|
|
23
30
|
/**
|
|
24
31
|
* StripeSubscriptionRepository
|
|
25
32
|
*
|
|
26
|
-
* Neo4j repository for
|
|
27
|
-
*
|
|
33
|
+
* Neo4j repository for StripeSubscription nodes:
|
|
34
|
+
* `(stripeSubscription)-[:BELONGS_TO]->(stripeCustomer)`, `-[:USES_PRICE]->(stripePrice)`,
|
|
35
|
+
* `-[:BELONGS_TO]->(company)` and `-[:CREATED_BY]->(user)`.
|
|
28
36
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* - Create and update operations with relationship management
|
|
33
|
-
* - Support for plan changes by updating price relationships
|
|
34
|
-
* - Sync operations for webhook data
|
|
35
|
-
* - Track trial periods, billing cycles, and cancellation status
|
|
36
|
-
* - Bulk cancel operations for customer deletion
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```typescript
|
|
40
|
-
* const subscription = await subscriptionRepository.create({
|
|
41
|
-
* stripeCustomerId: 'cust_123',
|
|
42
|
-
* priceId: 'price_456',
|
|
43
|
-
* stripeSubscriptionId: 'sub_stripe789',
|
|
44
|
-
* status: 'active',
|
|
45
|
-
* currentPeriodStart: new Date(),
|
|
46
|
-
* currentPeriodEnd: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
|
|
47
|
-
* cancelAtPeriodEnd: false,
|
|
48
|
-
* quantity: 1
|
|
49
|
-
* });
|
|
50
|
-
* ```
|
|
37
|
+
* Every read and every request-time write starts from `buildDefaultMatch()`, so a request is
|
|
38
|
+
* scoped to the caller's company. Jobs with no company in CLS (webhooks, crons, backfills)
|
|
39
|
+
* reach every company through the `$companyId IS NULL` branch.
|
|
51
40
|
*/
|
|
52
|
-
let StripeSubscriptionRepository = class StripeSubscriptionRepository {
|
|
53
|
-
constructor(neo4j) {
|
|
54
|
-
|
|
41
|
+
let StripeSubscriptionRepository = class StripeSubscriptionRepository extends abstract_repository_1.AbstractRepository {
|
|
42
|
+
constructor(neo4j, securityService, clsService) {
|
|
43
|
+
super(neo4j, securityService, clsService);
|
|
44
|
+
this.descriptor = stripe_subscription_1.StripeSubscriptionDescriptor;
|
|
55
45
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Initialize repository constraints
|
|
58
|
-
*
|
|
59
|
-
* Creates unique constraints and indexes on module initialization.
|
|
60
|
-
*/
|
|
46
|
+
/** The inherited id constraint and indexes, plus the unique Stripe subscription id. */
|
|
61
47
|
async onModuleInit() {
|
|
48
|
+
await super.onModuleInit();
|
|
62
49
|
await this.neo4j.writeOne({
|
|
63
|
-
query: `CREATE CONSTRAINT ${
|
|
64
|
-
});
|
|
65
|
-
await this.neo4j.writeOne({
|
|
66
|
-
query: `CREATE CONSTRAINT ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_stripeSubscriptionId IF NOT EXISTS FOR (${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}:${stripe_subscription_meta_1.stripeSubscriptionMeta.labelName}) REQUIRE ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}.stripeSubscriptionId IS UNIQUE`,
|
|
50
|
+
query: `CREATE CONSTRAINT ${S}_stripeSubscriptionId IF NOT EXISTS FOR (${S}:${stripe_subscription_meta_1.stripeSubscriptionMeta.labelName}) REQUIRE ${S}.stripeSubscriptionId IS UNIQUE`,
|
|
67
51
|
});
|
|
68
52
|
}
|
|
69
53
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* @param params - Query parameters
|
|
73
|
-
* @param params.stripeCustomerId - Stripe customer identifier (internal ID)
|
|
74
|
-
* @param params.status - Optional filter by subscription status
|
|
75
|
-
* @returns Array of subscriptions ordered by creation date descending
|
|
54
|
+
* The subscription with its company, customer, price, the price's product and its creator.
|
|
76
55
|
*/
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
WHERE 1=1 ${where}
|
|
90
|
-
RETURN ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}, ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_price_meta_1.stripePriceMeta.nodeName}, ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_price_meta_1.stripePriceMeta.nodeName}_${stripe_product_meta_1.stripeProductMeta.nodeName}
|
|
91
|
-
ORDER BY ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}.createdAt DESC
|
|
56
|
+
buildReturnStatement() {
|
|
57
|
+
return `
|
|
58
|
+
MATCH (${S})-[:BELONGS_TO]->(${S}_${company_meta_1.companyMeta.nodeName}:${company_meta_1.companyMeta.labelName})
|
|
59
|
+
MATCH (${S})-[:BELONGS_TO]->(${S}_stripeCustomer:${stripe_customer_meta_1.stripeCustomerMeta.labelName})
|
|
60
|
+
MATCH (${S})-[:USES_PRICE]->(${S}_stripePrice:${stripe_price_meta_1.stripePriceMeta.labelName})-[:BELONGS_TO]->(${S}_stripePrice_${stripe_product_meta_1.stripeProductMeta.nodeName}:${stripe_product_meta_1.stripeProductMeta.labelName})
|
|
61
|
+
OPTIONAL MATCH (${S})-[:CREATED_BY]->(${S}_createdBy:${user_meta_1.userMeta.labelName})
|
|
62
|
+
RETURN ${S},
|
|
63
|
+
${S}_${company_meta_1.companyMeta.nodeName},
|
|
64
|
+
${S}_stripeCustomer,
|
|
65
|
+
${S}_stripePrice,
|
|
66
|
+
${S}_stripePrice_${stripe_product_meta_1.stripeProductMeta.nodeName},
|
|
67
|
+
${S}_createdBy
|
|
92
68
|
`;
|
|
93
|
-
return this.neo4j.readMany(query);
|
|
94
69
|
}
|
|
95
70
|
/**
|
|
96
|
-
*
|
|
71
|
+
* The cron finders read across every company. Inside a request `buildDefaultMatch()` would
|
|
72
|
+
* scope them to the caller's company, so they refuse to run there.
|
|
73
|
+
*/
|
|
74
|
+
assertNoRequestCompany(method) {
|
|
75
|
+
if (this.clsService.get("companyId")) {
|
|
76
|
+
throw new Error(`StripeSubscriptionRepository.${method} is for the worker cron only, not for a request.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Subscriptions of a customer, newest first.
|
|
97
81
|
*
|
|
98
|
-
* @param params -
|
|
99
|
-
* @param params.
|
|
100
|
-
* @returns Subscription if found, null otherwise
|
|
82
|
+
* @param params.stripeCustomerId - internal StripeCustomer id
|
|
83
|
+
* @param params.status - optional status filter
|
|
101
84
|
*/
|
|
102
|
-
async
|
|
103
|
-
const query = this.neo4j.initQuery({ serialiser:
|
|
85
|
+
async findByStripeCustomerId(params) {
|
|
86
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model, fetchAll: true });
|
|
104
87
|
query.queryParams = {
|
|
105
|
-
|
|
88
|
+
...query.queryParams,
|
|
89
|
+
stripeCustomerId: params.stripeCustomerId,
|
|
90
|
+
...(params.status ? { status: params.status } : {}),
|
|
106
91
|
};
|
|
107
|
-
query.query
|
|
108
|
-
|
|
109
|
-
MATCH (${
|
|
110
|
-
|
|
92
|
+
query.query += `
|
|
93
|
+
${this.buildDefaultMatch()}
|
|
94
|
+
MATCH (${S})-[:BELONGS_TO]->(:${stripe_customer_meta_1.stripeCustomerMeta.labelName} {id: $stripeCustomerId})
|
|
95
|
+
${params.status ? `WHERE ${S}.status = $status` : ``}
|
|
96
|
+
WITH ${S}
|
|
97
|
+
${this.buildReturnStatement()}
|
|
98
|
+
ORDER BY ${S}.createdAt DESC
|
|
111
99
|
`;
|
|
112
|
-
return this.neo4j.
|
|
100
|
+
return this.neo4j.readMany(query);
|
|
113
101
|
}
|
|
114
102
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* Not company-scoped and not paginated: it serves system jobs that run outside a
|
|
118
|
-
* request (the discount backfill), never an endpoint. It matches the same
|
|
119
|
-
* customer and price path as {@link update}, so every row it returns can be updated.
|
|
120
|
-
*
|
|
121
|
-
* @returns All subscriptions ordered by creation date ascending
|
|
103
|
+
* Every subscription, oldest first. Not paginated: it serves system jobs that run outside a
|
|
104
|
+
* request (the discount backfill), never an endpoint.
|
|
122
105
|
*/
|
|
123
106
|
async findAll() {
|
|
124
|
-
const query = this.neo4j.initQuery({ serialiser:
|
|
107
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model, fetchAll: true });
|
|
125
108
|
query.query += `
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
ORDER BY ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}.createdAt ASC
|
|
109
|
+
${this.buildDefaultMatch()}
|
|
110
|
+
${this.buildReturnStatement()}
|
|
111
|
+
ORDER BY ${S}.createdAt ASC
|
|
130
112
|
`;
|
|
131
113
|
return this.neo4j.readMany(query);
|
|
132
114
|
}
|
|
133
|
-
/**
|
|
134
|
-
* Find subscription by Stripe subscription ID
|
|
135
|
-
*
|
|
136
|
-
* @param params - Query parameters
|
|
137
|
-
* @param params.stripeSubscriptionId - Stripe subscription ID
|
|
138
|
-
* @returns Subscription if found, null otherwise
|
|
139
|
-
*/
|
|
115
|
+
/** The subscription with this Stripe subscription id, or null. */
|
|
140
116
|
async findByStripeSubscriptionId(params) {
|
|
141
|
-
const query = this.neo4j.initQuery({ serialiser:
|
|
142
|
-
query.queryParams = {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
MATCH (${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}:${stripe_subscription_meta_1.stripeSubscriptionMeta.labelName} {stripeSubscriptionId: $stripeSubscriptionId})-[:BELONGS_TO]->(${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_customer_meta_1.stripeCustomerMeta.nodeName}:${stripe_customer_meta_1.stripeCustomerMeta.labelName})
|
|
147
|
-
MATCH (${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName})-[:USES_PRICE]->(${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_price_meta_1.stripePriceMeta.nodeName}:${stripe_price_meta_1.stripePriceMeta.labelName})-[:BELONGS_TO]->(${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_price_meta_1.stripePriceMeta.nodeName}_${stripe_product_meta_1.stripeProductMeta.nodeName}:${stripe_product_meta_1.stripeProductMeta.labelName})
|
|
148
|
-
RETURN ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}, ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_customer_meta_1.stripeCustomerMeta.nodeName}, ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_price_meta_1.stripePriceMeta.nodeName}, ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_price_meta_1.stripePriceMeta.nodeName}_${stripe_product_meta_1.stripeProductMeta.nodeName}
|
|
117
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model });
|
|
118
|
+
query.queryParams = { ...query.queryParams, searchValue: params.stripeSubscriptionId };
|
|
119
|
+
query.query += `
|
|
120
|
+
${this.buildDefaultMatch({ searchField: "stripeSubscriptionId" })}
|
|
121
|
+
${this.buildReturnStatement()}
|
|
149
122
|
`;
|
|
150
123
|
return this.neo4j.readOne(query);
|
|
151
124
|
}
|
|
152
125
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* Creates a Subscription node with BELONGS_TO relationship to StripeCustomer
|
|
156
|
-
* and USES_PRICE relationship to StripePrice.
|
|
157
|
-
*
|
|
158
|
-
* @param params - Creation parameters
|
|
159
|
-
* @param params.stripeCustomerId - Stripe customer ID to link to
|
|
160
|
-
* @param params.priceId - Price ID to link to
|
|
161
|
-
* @param params.stripeSubscriptionId - Stripe subscription ID
|
|
162
|
-
* @param params.stripeSubscriptionItemId - Optional Stripe subscription item ID
|
|
163
|
-
* @param params.status - Subscription status
|
|
164
|
-
* @param params.currentPeriodStart - Current billing period start date
|
|
165
|
-
* @param params.currentPeriodEnd - Current billing period end date
|
|
166
|
-
* @param params.cancelAtPeriodEnd - Whether subscription cancels at period end
|
|
167
|
-
* @param params.trialStart - Optional trial start date
|
|
168
|
-
* @param params.trialEnd - Optional trial end date
|
|
169
|
-
* @param params.quantity - Subscription quantity
|
|
170
|
-
* @returns Created Subscription
|
|
126
|
+
* Creates a subscription linked to its customer, its price, the caller's company and the
|
|
127
|
+
* caller. The customer and price ids are checked against the caller's company first.
|
|
171
128
|
*/
|
|
172
|
-
async
|
|
173
|
-
|
|
174
|
-
|
|
129
|
+
async createSubscription(params) {
|
|
130
|
+
await this.neo4j.validateRelatedNodes({
|
|
131
|
+
nodes: [
|
|
132
|
+
{ id: params.stripeCustomerId, label: stripe_customer_meta_1.stripeCustomerMeta.labelName },
|
|
133
|
+
{ id: params.priceId, label: stripe_price_meta_1.stripePriceMeta.labelName },
|
|
134
|
+
],
|
|
135
|
+
});
|
|
136
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model });
|
|
175
137
|
query.queryParams = {
|
|
176
138
|
...query.queryParams,
|
|
177
|
-
id:
|
|
139
|
+
id: (0, crypto_1.randomUUID)(),
|
|
178
140
|
stripeCustomerId: params.stripeCustomerId,
|
|
179
141
|
priceId: params.priceId,
|
|
180
142
|
stripeSubscriptionId: params.stripeSubscriptionId,
|
|
@@ -188,11 +150,12 @@ let StripeSubscriptionRepository = class StripeSubscriptionRepository {
|
|
|
188
150
|
quantity: params.quantity,
|
|
189
151
|
...(0, stripe_subscription_discount_1.discountQueryParams)(params.discount ?? null),
|
|
190
152
|
};
|
|
191
|
-
// Guarded: initQuery() binds
|
|
153
|
+
// Guarded: initQuery() binds `company` / `currentUser` only when CLS holds them; an
|
|
154
|
+
// unbound CREATE target would create an orphan node.
|
|
192
155
|
query.query += `
|
|
193
|
-
MATCH (
|
|
194
|
-
MATCH (
|
|
195
|
-
CREATE (${
|
|
156
|
+
MATCH (newStripeCustomer:${stripe_customer_meta_1.stripeCustomerMeta.labelName} {id: $stripeCustomerId})
|
|
157
|
+
MATCH (newStripePrice:${stripe_price_meta_1.stripePriceMeta.labelName} {id: $priceId})
|
|
158
|
+
CREATE (${S}:${stripe_subscription_meta_1.stripeSubscriptionMeta.labelName} {
|
|
196
159
|
id: $id,
|
|
197
160
|
stripeSubscriptionId: $stripeSubscriptionId,
|
|
198
161
|
stripeSubscriptionItemId: $stripeSubscriptionItemId,
|
|
@@ -212,213 +175,182 @@ let StripeSubscriptionRepository = class StripeSubscriptionRepository {
|
|
|
212
175
|
createdAt: datetime(),
|
|
213
176
|
updatedAt: datetime()
|
|
214
177
|
})
|
|
215
|
-
CREATE (${
|
|
216
|
-
CREATE (${
|
|
217
|
-
${query.queryParams.companyId ? `CREATE (${
|
|
218
|
-
${query.queryParams.currentUserId ? `CREATE (${
|
|
219
|
-
|
|
178
|
+
CREATE (${S})-[:BELONGS_TO]->(newStripeCustomer)
|
|
179
|
+
CREATE (${S})-[:USES_PRICE]->(newStripePrice)
|
|
180
|
+
${query.queryParams.companyId ? `CREATE (${S})-[:BELONGS_TO]->(${company_meta_1.companyMeta.nodeName})` : ``}
|
|
181
|
+
${query.queryParams.currentUserId ? `CREATE (${S})-[:CREATED_BY]->(currentUser)` : ``}
|
|
182
|
+
WITH ${S}
|
|
183
|
+
${this.buildReturnStatement()}
|
|
220
184
|
`;
|
|
221
185
|
return this.neo4j.writeOne(query);
|
|
222
186
|
}
|
|
223
187
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
* @param params - Update parameters
|
|
227
|
-
* @param params.id - Internal subscription ID
|
|
228
|
-
* @param params.status - Optional new status
|
|
229
|
-
* @param params.currentPeriodStart - Optional new period start
|
|
230
|
-
* @param params.currentPeriodEnd - Optional new period end
|
|
231
|
-
* @param params.cancelAtPeriodEnd - Optional cancel at period end flag
|
|
232
|
-
* @param params.canceledAt - Optional cancellation date (null to clear)
|
|
233
|
-
* @param params.trialStart - Optional trial start date
|
|
234
|
-
* @param params.trialEnd - Optional trial end date
|
|
235
|
-
* @param params.pausedAt - Optional pause date (null to clear)
|
|
236
|
-
* @param params.quantity - Optional new quantity
|
|
237
|
-
* @returns Updated Subscription
|
|
188
|
+
* Updates a subscription by internal id. For every optional field, undefined leaves the
|
|
189
|
+
* stored value and (where the type allows it) null clears it.
|
|
238
190
|
*/
|
|
239
191
|
async update(params) {
|
|
240
|
-
const query = this.neo4j.initQuery({ serialiser:
|
|
241
|
-
const setParams = [];
|
|
242
|
-
|
|
192
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model });
|
|
193
|
+
const setParams = [`${S}.updatedAt = datetime()`];
|
|
194
|
+
const values = {};
|
|
243
195
|
if (params.status !== undefined) {
|
|
244
|
-
setParams.push(`${
|
|
196
|
+
setParams.push(`${S}.status = $status`);
|
|
197
|
+
values.status = params.status;
|
|
245
198
|
}
|
|
246
199
|
if (params.currentPeriodStart !== undefined) {
|
|
247
|
-
setParams.push(`${
|
|
200
|
+
setParams.push(`${S}.currentPeriodStart = datetime($currentPeriodStart)`);
|
|
201
|
+
values.currentPeriodStart = params.currentPeriodStart.toISOString();
|
|
248
202
|
}
|
|
249
203
|
if (params.currentPeriodEnd !== undefined) {
|
|
250
|
-
setParams.push(`${
|
|
204
|
+
setParams.push(`${S}.currentPeriodEnd = datetime($currentPeriodEnd)`);
|
|
205
|
+
values.currentPeriodEnd = params.currentPeriodEnd.toISOString();
|
|
251
206
|
}
|
|
252
207
|
if (params.cancelAtPeriodEnd !== undefined) {
|
|
253
|
-
setParams.push(`${
|
|
254
|
-
|
|
255
|
-
if (params.canceledAt !== undefined) {
|
|
256
|
-
setParams.push(params.canceledAt === null
|
|
257
|
-
? `${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}.canceledAt = null`
|
|
258
|
-
: `${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}.canceledAt = datetime($canceledAt)`);
|
|
208
|
+
setParams.push(`${S}.cancelAtPeriodEnd = $cancelAtPeriodEnd`);
|
|
209
|
+
values.cancelAtPeriodEnd = params.cancelAtPeriodEnd;
|
|
259
210
|
}
|
|
260
211
|
if (params.trialStart !== undefined) {
|
|
261
|
-
setParams.push(`${
|
|
212
|
+
setParams.push(`${S}.trialStart = datetime($trialStart)`);
|
|
213
|
+
values.trialStart = params.trialStart.toISOString();
|
|
262
214
|
}
|
|
263
215
|
if (params.trialEnd !== undefined) {
|
|
264
|
-
setParams.push(`${
|
|
216
|
+
setParams.push(`${S}.trialEnd = datetime($trialEnd)`);
|
|
217
|
+
values.trialEnd = params.trialEnd.toISOString();
|
|
265
218
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
219
|
+
for (const field of CLEARABLE_DATETIME_FIELDS) {
|
|
220
|
+
const value = params[field];
|
|
221
|
+
if (value === undefined)
|
|
222
|
+
continue;
|
|
223
|
+
if (value === null) {
|
|
224
|
+
setParams.push(`${S}.${field} = null`);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
setParams.push(`${S}.${field} = datetime($${field})`);
|
|
228
|
+
values[field] = value.toISOString();
|
|
229
|
+
}
|
|
270
230
|
}
|
|
271
231
|
if (params.quantity !== undefined) {
|
|
272
|
-
setParams.push(`${
|
|
232
|
+
setParams.push(`${S}.quantity = $quantity`);
|
|
233
|
+
values.quantity = params.quantity;
|
|
273
234
|
}
|
|
274
235
|
// undefined leaves the stored discount as it is; null clears it.
|
|
275
236
|
if (params.discount !== undefined) {
|
|
276
|
-
setParams.push(`${
|
|
237
|
+
setParams.push(`${S}.discountPercentOff = $discountPercentOff`, `${S}.discountAmountOff = $discountAmountOff`, `${S}.discountCurrency = $discountCurrency`, `${S}.discountDuration = $discountDuration`, `${S}.discountDurationInMonths = $discountDurationInMonths`, `${S}.discountEnd = CASE WHEN $discountEnd IS NOT NULL THEN datetime($discountEnd) ELSE null END`);
|
|
238
|
+
Object.assign(values, (0, stripe_subscription_discount_1.discountQueryParams)(params.discount));
|
|
277
239
|
}
|
|
278
|
-
query.queryParams = {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
currentPeriodStart: params.currentPeriodStart?.toISOString(),
|
|
282
|
-
currentPeriodEnd: params.currentPeriodEnd?.toISOString(),
|
|
283
|
-
cancelAtPeriodEnd: params.cancelAtPeriodEnd,
|
|
284
|
-
canceledAt: params.canceledAt?.toISOString(),
|
|
285
|
-
trialStart: params.trialStart?.toISOString(),
|
|
286
|
-
trialEnd: params.trialEnd?.toISOString(),
|
|
287
|
-
pausedAt: params.pausedAt?.toISOString(),
|
|
288
|
-
quantity: params.quantity,
|
|
289
|
-
...(params.discount !== undefined ? (0, stripe_subscription_discount_1.discountQueryParams)(params.discount) : {}),
|
|
290
|
-
};
|
|
291
|
-
query.query = `
|
|
292
|
-
MATCH (${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}:${stripe_subscription_meta_1.stripeSubscriptionMeta.labelName} {id: $id})-[:BELONGS_TO]->(${stripe_customer_meta_1.stripeCustomerMeta.nodeName}:${stripe_customer_meta_1.stripeCustomerMeta.labelName})
|
|
293
|
-
MATCH (${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName})-[:USES_PRICE]->(${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_price_meta_1.stripePriceMeta.nodeName}:${stripe_price_meta_1.stripePriceMeta.labelName})-[:BELONGS_TO]->(${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}_${stripe_price_meta_1.stripePriceMeta.nodeName}_${stripe_product_meta_1.stripeProductMeta.nodeName}:${stripe_product_meta_1.stripeProductMeta.labelName})
|
|
240
|
+
query.queryParams = { ...query.queryParams, ...values, searchValue: params.id };
|
|
241
|
+
query.query += `
|
|
242
|
+
${this.buildDefaultMatch({ searchField: "id" })}
|
|
294
243
|
SET ${setParams.join(", ")}
|
|
295
|
-
|
|
244
|
+
WITH ${S}
|
|
245
|
+
${this.buildReturnStatement()}
|
|
296
246
|
`;
|
|
297
247
|
return this.neo4j.writeOne(query);
|
|
298
248
|
}
|
|
299
249
|
/**
|
|
300
|
-
*
|
|
250
|
+
* Updates a subscription by Stripe subscription id (webhook sync).
|
|
301
251
|
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
304
|
-
* @param params - Update parameters
|
|
305
|
-
* @param params.stripeSubscriptionId - Stripe subscription ID
|
|
306
|
-
* @param params.status - Optional new status
|
|
307
|
-
* @param params.currentPeriodStart - Optional new period start
|
|
308
|
-
* @param params.currentPeriodEnd - Optional new period end
|
|
309
|
-
* @param params.cancelAtPeriodEnd - Optional cancel at period end flag
|
|
310
|
-
* @param params.canceledAt - Optional cancellation date (null to clear)
|
|
311
|
-
* @param params.trialStart - Optional trial start date
|
|
312
|
-
* @param params.trialEnd - Optional trial end date
|
|
313
|
-
* @param params.pausedAt - Optional pause date (null to clear)
|
|
314
|
-
* @param params.quantity - Optional new quantity
|
|
315
|
-
* @returns Updated Subscription if found, null otherwise
|
|
252
|
+
* @returns the updated subscription, or null when none has this id
|
|
316
253
|
*/
|
|
317
254
|
async updateByStripeSubscriptionId(params) {
|
|
318
255
|
const existing = await this.findByStripeSubscriptionId({ stripeSubscriptionId: params.stripeSubscriptionId });
|
|
319
256
|
if (!existing)
|
|
320
257
|
return null;
|
|
321
|
-
return this.update({
|
|
322
|
-
id: existing.id,
|
|
323
|
-
...params,
|
|
324
|
-
});
|
|
258
|
+
return this.update({ id: existing.id, ...params });
|
|
325
259
|
}
|
|
326
260
|
/**
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
* Removes old USES_PRICE relationship and creates new one to different price.
|
|
330
|
-
*
|
|
331
|
-
* @param params - Update parameters
|
|
332
|
-
* @param params.id - Internal subscription ID
|
|
333
|
-
* @param params.newPriceId - New price ID to switch to
|
|
334
|
-
* @returns Updated Subscription with new price relationship
|
|
261
|
+
* Moves the subscription to another price (plan change). The price id is checked against
|
|
262
|
+
* the caller's company first.
|
|
335
263
|
*/
|
|
336
264
|
async updatePrice(params) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
};
|
|
342
|
-
query.query
|
|
343
|
-
|
|
344
|
-
MATCH (${
|
|
265
|
+
await this.neo4j.validateRelatedNodes({
|
|
266
|
+
nodes: [{ id: params.newPriceId, label: stripe_price_meta_1.stripePriceMeta.labelName }],
|
|
267
|
+
});
|
|
268
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model });
|
|
269
|
+
query.queryParams = { ...query.queryParams, searchValue: params.id, newPriceId: params.newPriceId };
|
|
270
|
+
query.query += `
|
|
271
|
+
${this.buildDefaultMatch({ searchField: "id" })}
|
|
272
|
+
MATCH (${S})-[oldRel:USES_PRICE]->(:${stripe_price_meta_1.stripePriceMeta.labelName})
|
|
345
273
|
DELETE oldRel
|
|
346
|
-
WITH ${
|
|
347
|
-
MATCH (
|
|
348
|
-
CREATE (${
|
|
349
|
-
SET ${
|
|
350
|
-
|
|
274
|
+
WITH ${S}
|
|
275
|
+
MATCH (newStripePrice:${stripe_price_meta_1.stripePriceMeta.labelName} {id: $newPriceId})
|
|
276
|
+
CREATE (${S})-[:USES_PRICE]->(newStripePrice)
|
|
277
|
+
SET ${S}.updatedAt = datetime()
|
|
278
|
+
WITH ${S}
|
|
279
|
+
${this.buildReturnStatement()}
|
|
351
280
|
`;
|
|
352
281
|
return this.neo4j.writeOne(query);
|
|
353
282
|
}
|
|
354
283
|
/**
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
* Performs a DETACH DELETE to remove the subscription and all relationships.
|
|
358
|
-
*
|
|
359
|
-
* @param params - Deletion parameters
|
|
360
|
-
* @param params.id - Internal subscription ID
|
|
361
|
-
* @returns Promise that resolves when deletion is complete
|
|
362
|
-
*/
|
|
363
|
-
async delete(params) {
|
|
364
|
-
const query = this.neo4j.initQuery();
|
|
365
|
-
query.queryParams = {
|
|
366
|
-
id: params.id,
|
|
367
|
-
};
|
|
368
|
-
query.query = `
|
|
369
|
-
MATCH (${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}:${stripe_subscription_meta_1.stripeSubscriptionMeta.labelName} {id: $id})
|
|
370
|
-
DETACH DELETE ${stripe_subscription_meta_1.stripeSubscriptionMeta.nodeName}
|
|
371
|
-
`;
|
|
372
|
-
await this.neo4j.writeOne(query);
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* Cancel all active subscriptions for a Stripe customer
|
|
376
|
-
*
|
|
377
|
-
* Bulk operation to cancel all active, trialing, or past_due subscriptions
|
|
378
|
-
* when a customer is deleted. Sets status to canceled and updates timestamps.
|
|
284
|
+
* Cancels every active, trialing or past_due subscription of a customer (customer deleted).
|
|
379
285
|
*
|
|
380
|
-
* @param params -
|
|
381
|
-
* @
|
|
382
|
-
* @returns Number of subscriptions canceled
|
|
286
|
+
* @param params.stripeCustomerId - Stripe customer id (cus_xxx)
|
|
287
|
+
* @returns number of subscriptions cancelled
|
|
383
288
|
*/
|
|
384
289
|
async cancelAllByStripeCustomerId(params) {
|
|
385
|
-
const query = this.neo4j.initQuery();
|
|
290
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model });
|
|
386
291
|
query.queryParams = {
|
|
292
|
+
...query.queryParams,
|
|
387
293
|
stripeCustomerId: params.stripeCustomerId,
|
|
388
294
|
canceledStatus: "canceled",
|
|
389
295
|
canceledAt: new Date().toISOString(),
|
|
390
296
|
};
|
|
391
|
-
query.query
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
${
|
|
397
|
-
${
|
|
398
|
-
|
|
297
|
+
query.query += `
|
|
298
|
+
${this.buildDefaultMatch()}
|
|
299
|
+
MATCH (${S})-[:BELONGS_TO]->(:${stripe_customer_meta_1.stripeCustomerMeta.labelName} {stripeCustomerId: $stripeCustomerId})
|
|
300
|
+
WHERE ${S}.status IN ['active', 'trialing', 'past_due']
|
|
301
|
+
SET ${S}.status = $canceledStatus,
|
|
302
|
+
${S}.canceledAt = datetime($canceledAt),
|
|
303
|
+
${S}.cancelAtPeriodEnd = false,
|
|
304
|
+
${S}.updatedAt = datetime()
|
|
305
|
+
WITH ${S}
|
|
306
|
+
${this.buildReturnStatement()}
|
|
399
307
|
`;
|
|
400
|
-
const
|
|
401
|
-
return
|
|
308
|
+
const cancelled = await this.neo4j.writeAndReturnMany(query);
|
|
309
|
+
return (cancelled ?? []).length;
|
|
402
310
|
}
|
|
403
311
|
/**
|
|
404
|
-
*
|
|
405
|
-
* Used for smart feature removal to check overlapping features
|
|
312
|
+
* Active or trialing subscriptions of a customer, newest first (smart feature removal).
|
|
406
313
|
*
|
|
407
|
-
* @param params -
|
|
408
|
-
* @param params.stripeCustomerId - Stripe customer ID (cus_xxx format)
|
|
409
|
-
* @returns Array of active subscriptions with price and product info
|
|
314
|
+
* @param params.stripeCustomerId - Stripe customer id (cus_xxx)
|
|
410
315
|
*/
|
|
411
316
|
async findActiveByStripeCustomerId(params) {
|
|
412
|
-
const query = this.neo4j.initQuery({ serialiser:
|
|
317
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model, fetchAll: true });
|
|
318
|
+
query.queryParams = { ...query.queryParams, stripeCustomerId: params.stripeCustomerId };
|
|
319
|
+
query.query += `
|
|
320
|
+
${this.buildDefaultMatch()}
|
|
321
|
+
MATCH (${S})-[:BELONGS_TO]->(:${stripe_customer_meta_1.stripeCustomerMeta.labelName} {stripeCustomerId: $stripeCustomerId})
|
|
322
|
+
WHERE ${S}.status IN ['active', 'trialing']
|
|
323
|
+
WITH ${S}
|
|
324
|
+
${this.buildReturnStatement()}
|
|
325
|
+
ORDER BY ${S}.createdAt DESC
|
|
326
|
+
`;
|
|
327
|
+
return this.neo4j.readMany(query);
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Worker cron only. Active recurring subscriptions renewing between `now` (excluded) and
|
|
331
|
+
* `before` (included), not cancelling, whose card has not been checked yet for this renewal.
|
|
332
|
+
*/
|
|
333
|
+
async findRenewalsForCardCheck(params) {
|
|
334
|
+
this.assertNoRequestCompany("findRenewalsForCardCheck");
|
|
335
|
+
const query = this.neo4j.initQuery({ serialiser: stripe_subscription_1.StripeSubscriptionDescriptor.model, fetchAll: true });
|
|
413
336
|
query.queryParams = {
|
|
414
|
-
|
|
337
|
+
...query.queryParams,
|
|
338
|
+
now: params.now.toISOString(),
|
|
339
|
+
before: params.before.toISOString(),
|
|
415
340
|
};
|
|
416
|
-
query.query
|
|
417
|
-
|
|
418
|
-
WHERE ${
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
341
|
+
query.query += `
|
|
342
|
+
${this.buildDefaultMatch()}
|
|
343
|
+
WHERE ${S}.status = "active"
|
|
344
|
+
AND ${S}.cancelAtPeriodEnd = false
|
|
345
|
+
AND ${S}.currentPeriodEnd > datetime($now)
|
|
346
|
+
AND ${S}.currentPeriodEnd <= datetime($before)
|
|
347
|
+
AND (${S}.cardExpiryCheckedFor IS NULL OR ${S}.cardExpiryCheckedFor <> ${S}.currentPeriodEnd)
|
|
348
|
+
AND EXISTS {
|
|
349
|
+
MATCH (${S})-[:USES_PRICE]->(recurringPrice:${stripe_price_meta_1.stripePriceMeta.labelName})
|
|
350
|
+
WHERE recurringPrice.priceType = "recurring"
|
|
351
|
+
}
|
|
352
|
+
${this.buildReturnStatement()}
|
|
353
|
+
ORDER BY ${S}.currentPeriodEnd ASC
|
|
422
354
|
`;
|
|
423
355
|
return this.neo4j.readMany(query);
|
|
424
356
|
}
|
|
@@ -426,6 +358,6 @@ let StripeSubscriptionRepository = class StripeSubscriptionRepository {
|
|
|
426
358
|
exports.StripeSubscriptionRepository = StripeSubscriptionRepository;
|
|
427
359
|
exports.StripeSubscriptionRepository = StripeSubscriptionRepository = __decorate([
|
|
428
360
|
(0, common_1.Injectable)(),
|
|
429
|
-
__metadata("design:paramtypes", [
|
|
361
|
+
__metadata("design:paramtypes", [neo4j_service_1.Neo4jService, security_service_1.SecurityService, nestjs_cls_1.ClsService])
|
|
430
362
|
], StripeSubscriptionRepository);
|
|
431
363
|
//# sourceMappingURL=stripe-subscription.repository.js.map
|