@reorderjs/reorder 1.0.7 → 1.1.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/.medusa/server/e2e/auth.setup.js +26 -0
- package/.medusa/server/e2e/cancellation-retention.spec.js +133 -0
- package/.medusa/server/e2e/pages/CancellationCaseDetailPage.js +69 -0
- package/.medusa/server/e2e/pages/CancellationsListPage.js +34 -0
- package/.medusa/server/e2e/pages/PlanFormPage.js +89 -0
- package/.medusa/server/e2e/pages/RenewalDetailPage.js +101 -0
- package/.medusa/server/e2e/pages/SubscriptionDetailPage.js +102 -0
- package/.medusa/server/e2e/plans-offers.spec.js +96 -0
- package/.medusa/server/e2e/renewal-force.spec.js +154 -0
- package/.medusa/server/e2e/seed.setup.js +80 -0
- package/.medusa/server/e2e/subscription-status.spec.js +109 -0
- package/.medusa/server/e2e/subscriptions-list.spec.js +84 -0
- package/.medusa/server/playwright.config.js +37 -0
- package/.medusa/server/scripts/reset-subscriptions-test-data.js +279 -0
- package/.medusa/server/scripts/seed-subscriptions-test-data.js +2425 -0
- package/.medusa/server/scripts/wipe-test-data.js +44 -0
- package/.medusa/server/src/admin/index.js +13142 -11709
- package/.medusa/server/src/admin/index.mjs +13136 -11703
- package/.medusa/server/src/admin/types/activity-log.js +2 -1
- package/.medusa/server/src/admin/types/analytics.js +2 -1
- package/.medusa/server/src/api/admin/cancellations/validators.js +2 -2
- package/.medusa/server/src/api/admin/dunning/validators.js +2 -2
- package/.medusa/server/src/api/admin/renewals/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscription-analytics/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscription-logs/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscription-offers/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscription-settings/validators.js +2 -2
- package/.medusa/server/src/api/admin/subscriptions/[id]/payment-method/route.js +19 -0
- package/.medusa/server/src/api/admin/subscriptions/[id]/payment-methods/route.js +10 -0
- package/.medusa/server/src/api/admin/subscriptions/middlewares.js +8 -1
- package/.medusa/server/src/api/admin/subscriptions/utils.js +5 -1
- package/.medusa/server/src/api/admin/subscriptions/validators.js +7 -3
- package/.medusa/server/src/api/store/customers/me/subscriptions/[id]/payment-method/route.js +26 -0
- package/.medusa/server/src/api/store/customers/me/subscriptions/[id]/payment-methods/route.js +15 -0
- package/.medusa/server/src/api/store/customers/me/subscriptions/middlewares.js +8 -1
- package/.medusa/server/src/api/store/customers/me/subscriptions/utils.js +72 -1
- package/.medusa/server/src/api/store/customers/me/subscriptions/validators.js +7 -3
- package/.medusa/server/src/api/store/products/validators.js +2 -2
- package/.medusa/server/src/modules/activity-log/__tests__/create-subscription-log-event.spec.js +257 -0
- package/.medusa/server/src/modules/activity-log/__tests__/normalize-log-event.spec.js +231 -0
- package/.medusa/server/src/modules/activity-log/migrations/Migration20260524220933.js +16 -0
- package/.medusa/server/src/modules/activity-log/migrations/Migration20260524225625.js +16 -0
- package/.medusa/server/src/modules/activity-log/migrations/Migration20260818120000.js +16 -0
- package/.medusa/server/src/modules/activity-log/types/index.js +4 -1
- package/.medusa/server/src/modules/activity-log/utils/admin-query.js +15 -1
- package/.medusa/server/src/modules/analytics/__tests__/admin-query.spec.js +560 -0
- package/.medusa/server/src/modules/analytics/index.js +2 -2
- package/.medusa/server/src/modules/analytics/utils/admin-query.js +157 -5
- package/.medusa/server/src/modules/plan-offer/__tests__/service.spec.js +94 -0
- package/.medusa/server/src/modules/renewal/__tests__/service.spec.js +89 -0
- package/.medusa/server/src/modules/settings/__tests__/normalize-settings.spec.js +86 -0
- package/.medusa/server/src/modules/settings/__tests__/service.spec.js +124 -0
- package/.medusa/server/src/modules/subscription/__tests__/payment-methods.spec.js +186 -0
- package/.medusa/server/src/modules/subscription/__tests__/service.spec.js +124 -0
- package/.medusa/server/src/modules/subscription/utils/admin-query.js +196 -14
- package/.medusa/server/src/modules/subscription/utils/payment-methods.js +146 -0
- package/.medusa/server/src/subscription-flows/create-subscription-from-cart.js +55 -2
- package/.medusa/server/src/workflows/__tests__/cancel-subscription.spec.js +20 -0
- package/.medusa/server/src/workflows/__tests__/pause-subscription.spec.js +20 -0
- package/.medusa/server/src/workflows/__tests__/update-subscription-shipping-address.spec.js +49 -0
- package/.medusa/server/src/workflows/cancel-subscription.js +21 -1
- package/.medusa/server/src/workflows/index.js +6 -2
- package/.medusa/server/src/workflows/pause-subscription.js +21 -1
- package/.medusa/server/src/workflows/steps/rebuild-analytics-daily-snapshots.js +33 -10
- package/.medusa/server/src/workflows/steps/update-subscription-payment-method.js +110 -0
- package/.medusa/server/src/workflows/steps/validate-subscription-cart.js +7 -22
- package/.medusa/server/src/workflows/update-subscription-payment-method.js +65 -0
- package/.medusa/server/src/workflows/utils/analytics-incremental.js +1 -1
- package/README.md +89 -36
- package/package.json +25 -23
|
@@ -0,0 +1,2425 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = seedSubscriptionsTestData;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const activity_log_1 = require("../src/modules/activity-log");
|
|
6
|
+
const analytics_1 = require("../src/modules/analytics");
|
|
7
|
+
const constants_1 = require("../src/modules/analytics/constants");
|
|
8
|
+
const types_1 = require("../src/modules/activity-log/types");
|
|
9
|
+
const cancellation_1 = require("../src/modules/cancellation");
|
|
10
|
+
const types_2 = require("../src/modules/cancellation/types");
|
|
11
|
+
const dunning_1 = require("../src/modules/dunning");
|
|
12
|
+
const types_3 = require("../src/modules/dunning/types");
|
|
13
|
+
const plan_offer_1 = require("../src/modules/plan-offer");
|
|
14
|
+
const types_4 = require("../src/modules/plan-offer/types");
|
|
15
|
+
const renewal_1 = require("../src/modules/renewal");
|
|
16
|
+
const types_5 = require("../src/modules/renewal/types");
|
|
17
|
+
const subscription_1 = require("../src/modules/subscription");
|
|
18
|
+
const types_6 = require("../src/modules/subscription/types");
|
|
19
|
+
const settings_1 = require("../src/modules/settings");
|
|
20
|
+
const types_7 = require("../src/modules/settings/types");
|
|
21
|
+
const FIXED_TIME = new Date("2026-04-15T10:00:00.000Z");
|
|
22
|
+
const IDS = {
|
|
23
|
+
planOfferSuccess: "po_seed_subscriptions_success",
|
|
24
|
+
planOfferBlocked: "po_seed_subscriptions_blocked",
|
|
25
|
+
subSuccess: "sub_seed_subscriptions_success",
|
|
26
|
+
subPaused: "sub_seed_subscriptions_paused",
|
|
27
|
+
subCancelEffective: "sub_seed_subscriptions_cancel_effective",
|
|
28
|
+
subApprovalPending: "sub_seed_subscriptions_approval_pending",
|
|
29
|
+
subPolicyBlocked: "sub_seed_subscriptions_policy_blocked",
|
|
30
|
+
subFailedHistory: "sub_seed_subscriptions_failed_history",
|
|
31
|
+
subDunningRetryScheduled: "sub_seed_dunning_retry_scheduled",
|
|
32
|
+
subDunningAwaitingManual: "sub_seed_dunning_awaiting_manual",
|
|
33
|
+
subDunningRecovered: "sub_seed_dunning_recovered",
|
|
34
|
+
subDunningUnrecovered: "sub_seed_dunning_unrecovered",
|
|
35
|
+
subDunningManualOverride: "sub_seed_dunning_manual_override",
|
|
36
|
+
subCancellationOpenBilling: "sub_seed_cancellation_open_billing",
|
|
37
|
+
subCancellationRetainedDiscount: "sub_seed_cancellation_retained_discount",
|
|
38
|
+
subCancellationPaused: "sub_seed_cancellation_paused",
|
|
39
|
+
subCancellationCanceledImmediate: "sub_seed_cancellation_canceled_immediate",
|
|
40
|
+
subCancellationCanceledEndCycle: "sub_seed_cancellation_canceled_end_cycle",
|
|
41
|
+
subCancellationOpenPrice: "sub_seed_cancellation_open_price",
|
|
42
|
+
subCancellationOpenPaused: "sub_seed_cancellation_open_paused",
|
|
43
|
+
subAnalyticsBiMonthly: "sub_seed_analytics_bimonthly",
|
|
44
|
+
cycleSuccess: "re_seed_subscriptions_success",
|
|
45
|
+
cyclePaused: "re_seed_subscriptions_paused",
|
|
46
|
+
cycleCancelEffective: "re_seed_subscriptions_cancel_effective",
|
|
47
|
+
cycleApprovalPending: "re_seed_subscriptions_approval_pending",
|
|
48
|
+
cyclePolicyBlocked: "re_seed_subscriptions_policy_blocked",
|
|
49
|
+
cycleFailedHistory: "re_seed_subscriptions_failed_history",
|
|
50
|
+
cycleDunningRetryScheduled: "re_seed_dunning_retry_scheduled",
|
|
51
|
+
cycleDunningAwaitingManual: "re_seed_dunning_awaiting_manual",
|
|
52
|
+
cycleDunningRecovered: "re_seed_dunning_recovered",
|
|
53
|
+
cycleDunningUnrecovered: "re_seed_dunning_unrecovered",
|
|
54
|
+
cycleDunningManualOverride: "re_seed_dunning_manual_override",
|
|
55
|
+
cycleCancellationOpenBilling: "re_seed_cancellation_open_billing",
|
|
56
|
+
cycleCancellationRetainedDiscount: "re_seed_cancellation_retained_discount",
|
|
57
|
+
cycleCancellationPaused: "re_seed_cancellation_paused",
|
|
58
|
+
cycleCancellationCanceledImmediate: "re_seed_cancellation_canceled_immediate",
|
|
59
|
+
cycleCancellationCanceledEndCycle: "re_seed_cancellation_canceled_end_cycle",
|
|
60
|
+
cycleCancellationOpenPrice: "re_seed_cancellation_open_price",
|
|
61
|
+
cycleCancellationOpenPaused: "re_seed_cancellation_open_paused",
|
|
62
|
+
attemptFailedHistory: "rea_seed_subscriptions_failed_history",
|
|
63
|
+
dunningRetryScheduled: "dc_seed_dunning_retry_scheduled",
|
|
64
|
+
dunningAwaitingManual: "dc_seed_dunning_awaiting_manual",
|
|
65
|
+
dunningRecovered: "dc_seed_dunning_recovered",
|
|
66
|
+
dunningUnrecovered: "dc_seed_dunning_unrecovered",
|
|
67
|
+
dunningManualOverride: "dc_seed_dunning_manual_override",
|
|
68
|
+
dunningCancellationOpenBilling: "dc_seed_cancellation_open_billing",
|
|
69
|
+
dunningAttemptAwaitingManual: "da_seed_dunning_awaiting_manual_1",
|
|
70
|
+
dunningAttemptRecoveredFailed: "da_seed_dunning_recovered_1",
|
|
71
|
+
dunningAttemptRecoveredSucceeded: "da_seed_dunning_recovered_2",
|
|
72
|
+
dunningAttemptUnrecoveredOne: "da_seed_dunning_unrecovered_1",
|
|
73
|
+
dunningAttemptUnrecoveredTwo: "da_seed_dunning_unrecovered_2",
|
|
74
|
+
dunningAttemptUnrecoveredThree: "da_seed_dunning_unrecovered_3",
|
|
75
|
+
dunningAttemptManualOverride: "da_seed_dunning_manual_override_1",
|
|
76
|
+
cancellationOpenBilling: "cc_seed_cancellation_open_billing",
|
|
77
|
+
cancellationRetainedDiscount: "cc_seed_cancellation_retained_discount",
|
|
78
|
+
cancellationPaused: "cc_seed_cancellation_paused",
|
|
79
|
+
cancellationCanceledImmediate: "cc_seed_cancellation_canceled_immediate",
|
|
80
|
+
cancellationCanceledEndCycle: "cc_seed_cancellation_canceled_end_cycle",
|
|
81
|
+
cancellationOpenPrice: "cc_seed_cancellation_open_price",
|
|
82
|
+
cancellationOpenPaused: "cc_seed_cancellation_open_paused",
|
|
83
|
+
retentionDiscountRetained: "roe_seed_cancellation_discount_retained",
|
|
84
|
+
retentionPauseApplied: "roe_seed_cancellation_pause_applied",
|
|
85
|
+
logSubscriptionPaused: "slog_seed_subscription_paused",
|
|
86
|
+
logRenewalSucceeded: "slog_seed_renewal_succeeded",
|
|
87
|
+
logDunningRecovered: "slog_seed_dunning_recovered",
|
|
88
|
+
settingsGlobal: "set_seed_subscriptions_global",
|
|
89
|
+
};
|
|
90
|
+
function addDays(date, days) {
|
|
91
|
+
const copy = new Date(date);
|
|
92
|
+
copy.setUTCDate(copy.getUTCDate() + days);
|
|
93
|
+
return copy;
|
|
94
|
+
}
|
|
95
|
+
function buildSeedCustomerDefinition(input) {
|
|
96
|
+
return {
|
|
97
|
+
...input,
|
|
98
|
+
email: `${input.reference.toLowerCase()}@example.com`,
|
|
99
|
+
full_name: `QA ${input.reference}`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function ensureSeedCustomers(container, definitions) {
|
|
103
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
104
|
+
const customerModule = container.resolve(utils_1.Modules.CUSTOMER);
|
|
105
|
+
const customerDefinitions = definitions.map(buildSeedCustomerDefinition);
|
|
106
|
+
const emailToDefinition = new Map(customerDefinitions.map((definition) => [definition.email, definition]));
|
|
107
|
+
const { data: existingCustomers } = await query.graph({
|
|
108
|
+
entity: "customer",
|
|
109
|
+
fields: ["id", "email"],
|
|
110
|
+
filters: {
|
|
111
|
+
email: customerDefinitions.map((definition) => definition.email),
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
const customerMap = new Map();
|
|
115
|
+
for (const customer of (existingCustomers ?? [])) {
|
|
116
|
+
const definition = emailToDefinition.get(customer.email);
|
|
117
|
+
if (!definition) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
customerMap.set(definition.key, {
|
|
121
|
+
id: customer.id,
|
|
122
|
+
email: definition.email,
|
|
123
|
+
full_name: definition.full_name,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const missingDefinitions = customerDefinitions.filter((definition) => !customerMap.has(definition.key));
|
|
127
|
+
if (missingDefinitions.length) {
|
|
128
|
+
const result = await customerModule.createCustomers(missingDefinitions.map((definition) => ({
|
|
129
|
+
email: definition.email,
|
|
130
|
+
first_name: "QA",
|
|
131
|
+
last_name: definition.reference,
|
|
132
|
+
metadata: {
|
|
133
|
+
seed_namespace: "subscriptions-test-data",
|
|
134
|
+
seed_key: definition.key,
|
|
135
|
+
seed_reference: definition.reference,
|
|
136
|
+
},
|
|
137
|
+
})));
|
|
138
|
+
for (const customer of result) {
|
|
139
|
+
const definition = emailToDefinition.get(customer.email);
|
|
140
|
+
if (!definition) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
customerMap.set(definition.key, {
|
|
144
|
+
id: customer.id,
|
|
145
|
+
email: definition.email,
|
|
146
|
+
full_name: definition.full_name,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return customerMap;
|
|
151
|
+
}
|
|
152
|
+
async function listProductsWithVariants(container) {
|
|
153
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
154
|
+
const { data } = await query.graph({
|
|
155
|
+
entity: "product",
|
|
156
|
+
fields: ["id", "title", "variants.id", "variants.title", "variants.sku"],
|
|
157
|
+
});
|
|
158
|
+
return data.filter((product) => product.variants?.length);
|
|
159
|
+
}
|
|
160
|
+
async function listPlanOfferTargets(container) {
|
|
161
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
162
|
+
const { data } = await query.graph({
|
|
163
|
+
entity: "plan_offer",
|
|
164
|
+
fields: ["id", "product_id", "variant_id", "scope"],
|
|
165
|
+
});
|
|
166
|
+
return data;
|
|
167
|
+
}
|
|
168
|
+
function pickSeedTargets(products, offers) {
|
|
169
|
+
const offeredProductIds = new Set(offers.map((offer) => offer.product_id));
|
|
170
|
+
const candidates = products
|
|
171
|
+
.filter((product) => !offeredProductIds.has(product.id))
|
|
172
|
+
.map((product) => {
|
|
173
|
+
const variant = product.variants?.[0];
|
|
174
|
+
if (!variant) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
product_id: product.id,
|
|
179
|
+
product_title: product.title,
|
|
180
|
+
variant_id: variant.id,
|
|
181
|
+
variant_title: variant.title,
|
|
182
|
+
sku: variant.sku ?? null,
|
|
183
|
+
};
|
|
184
|
+
})
|
|
185
|
+
.filter(Boolean);
|
|
186
|
+
if (candidates.length < 2) {
|
|
187
|
+
throw new Error("Seed requires at least two products with variants that don't already have plan offers.");
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
success: candidates[0],
|
|
191
|
+
blocked: candidates[1],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function buildSubscriptionRecord(input) {
|
|
195
|
+
return {
|
|
196
|
+
id: input.id,
|
|
197
|
+
reference: input.reference,
|
|
198
|
+
status: input.status,
|
|
199
|
+
customer_id: input.customer.id,
|
|
200
|
+
cart_id: input.cart_id === undefined ? null : input.cart_id,
|
|
201
|
+
product_id: input.target.product_id,
|
|
202
|
+
variant_id: input.target.variant_id,
|
|
203
|
+
frequency_interval: input.frequency_interval,
|
|
204
|
+
frequency_value: input.frequency_value,
|
|
205
|
+
started_at: addDays(FIXED_TIME, -30),
|
|
206
|
+
next_renewal_at: input.next_renewal_at,
|
|
207
|
+
last_renewal_at: null,
|
|
208
|
+
paused_at: input.paused_at === undefined ? null : input.paused_at,
|
|
209
|
+
cancelled_at: input.cancelled_at === undefined ? null : input.cancelled_at,
|
|
210
|
+
cancel_effective_at: input.cancel_effective_at === undefined
|
|
211
|
+
? null
|
|
212
|
+
: input.cancel_effective_at,
|
|
213
|
+
skip_next_cycle: input.skip_next_cycle,
|
|
214
|
+
is_trial: false,
|
|
215
|
+
trial_ends_at: null,
|
|
216
|
+
customer_snapshot: {
|
|
217
|
+
email: input.customer.email,
|
|
218
|
+
full_name: input.customer.full_name,
|
|
219
|
+
},
|
|
220
|
+
product_snapshot: {
|
|
221
|
+
product_id: input.target.product_id,
|
|
222
|
+
product_title: input.target.product_title,
|
|
223
|
+
variant_id: input.target.variant_id,
|
|
224
|
+
variant_title: input.target.variant_title,
|
|
225
|
+
sku: input.target.sku,
|
|
226
|
+
},
|
|
227
|
+
pricing_snapshot: {
|
|
228
|
+
discount_type: "percentage",
|
|
229
|
+
discount_value: 10,
|
|
230
|
+
label: "10% off QA seed",
|
|
231
|
+
},
|
|
232
|
+
shipping_address: {
|
|
233
|
+
first_name: "QA",
|
|
234
|
+
last_name: "Tester",
|
|
235
|
+
company: null,
|
|
236
|
+
address_1: "Seed Street 1",
|
|
237
|
+
address_2: null,
|
|
238
|
+
city: "Warsaw",
|
|
239
|
+
postal_code: "00-001",
|
|
240
|
+
province: "Mazowieckie",
|
|
241
|
+
country_code: "PL",
|
|
242
|
+
phone: "+48111111111",
|
|
243
|
+
},
|
|
244
|
+
payment_context: {
|
|
245
|
+
payment_provider_id: input.payment_provider_id ?? "pp_system_default",
|
|
246
|
+
source_payment_collection_id: null,
|
|
247
|
+
source_payment_session_id: null,
|
|
248
|
+
payment_method_reference: null,
|
|
249
|
+
customer_payment_reference: null,
|
|
250
|
+
},
|
|
251
|
+
pending_update_data: input.pending_update_data === undefined
|
|
252
|
+
? null
|
|
253
|
+
: input.pending_update_data,
|
|
254
|
+
metadata: {
|
|
255
|
+
seed_namespace: "subscriptions-test-data",
|
|
256
|
+
seed_reference: input.reference,
|
|
257
|
+
},
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
async function resolveSeedOrderContext(container) {
|
|
261
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
262
|
+
const [{ data: storeData }, { data: regionData }] = await Promise.all([
|
|
263
|
+
query.graph({
|
|
264
|
+
entity: "store",
|
|
265
|
+
fields: ["id", "default_sales_channel_id"],
|
|
266
|
+
}),
|
|
267
|
+
query.graph({
|
|
268
|
+
entity: "region",
|
|
269
|
+
fields: ["id", "currency_code"],
|
|
270
|
+
}),
|
|
271
|
+
]);
|
|
272
|
+
const store = storeData?.[0];
|
|
273
|
+
const region = regionData?.[0];
|
|
274
|
+
if (!store?.default_sales_channel_id) {
|
|
275
|
+
throw new Error("Seed requires a store with default_sales_channel_id to create linked orders.");
|
|
276
|
+
}
|
|
277
|
+
if (!region?.id || !region.currency_code) {
|
|
278
|
+
throw new Error("Seed requires at least one region to create linked orders.");
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
region_id: region.id,
|
|
282
|
+
sales_channel_id: store.default_sales_channel_id,
|
|
283
|
+
currency_code: region.currency_code,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
async function listSeededSubscriptions(container, subscriptionIds) {
|
|
287
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
288
|
+
const { data } = await query.graph({
|
|
289
|
+
entity: "subscription",
|
|
290
|
+
fields: [
|
|
291
|
+
"id",
|
|
292
|
+
"reference",
|
|
293
|
+
"customer_id",
|
|
294
|
+
"product_id",
|
|
295
|
+
"variant_id",
|
|
296
|
+
"customer_snapshot",
|
|
297
|
+
"product_snapshot",
|
|
298
|
+
"shipping_address",
|
|
299
|
+
],
|
|
300
|
+
filters: {
|
|
301
|
+
id: subscriptionIds,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
return data;
|
|
305
|
+
}
|
|
306
|
+
async function ensureInitialSubscriptionOrders(container, subscriptions, orderContext) {
|
|
307
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
308
|
+
const link = container.resolve(utils_1.ContainerRegistrationKeys.LINK);
|
|
309
|
+
const initialOrderIds = new Map();
|
|
310
|
+
const { data } = await query.graph({
|
|
311
|
+
entity: "subscription_order",
|
|
312
|
+
fields: ["subscription.id", "order.id", "order.metadata"],
|
|
313
|
+
filters: {
|
|
314
|
+
subscription_id: subscriptions.map((subscription) => subscription.id),
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
for (const record of (data ?? [])) {
|
|
318
|
+
const subscriptionId = record.subscription?.id;
|
|
319
|
+
const orderId = record.order?.id;
|
|
320
|
+
const role = record.order?.metadata?.seed_order_role;
|
|
321
|
+
if (!subscriptionId || !orderId || role !== "initial") {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
initialOrderIds.set(subscriptionId, orderId);
|
|
325
|
+
}
|
|
326
|
+
for (const subscription of subscriptions) {
|
|
327
|
+
if (initialOrderIds.has(subscription.id)) {
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
const order = await createSeedOrder(container, {
|
|
331
|
+
orderContext,
|
|
332
|
+
subscription,
|
|
333
|
+
role: "initial",
|
|
334
|
+
scenario: subscription.reference.toLowerCase(),
|
|
335
|
+
});
|
|
336
|
+
await link.create({
|
|
337
|
+
[subscription_1.SUBSCRIPTION_MODULE]: {
|
|
338
|
+
subscription_id: subscription.id,
|
|
339
|
+
},
|
|
340
|
+
[utils_1.Modules.ORDER]: {
|
|
341
|
+
order_id: order.id,
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
initialOrderIds.set(subscription.id, order.id);
|
|
345
|
+
}
|
|
346
|
+
return initialOrderIds;
|
|
347
|
+
}
|
|
348
|
+
async function ensureRenewalOrders(container, subscriptions, scenarios, orderContext) {
|
|
349
|
+
const query = container.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
350
|
+
const link = container.resolve(utils_1.ContainerRegistrationKeys.LINK);
|
|
351
|
+
const pgConnection = container.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
|
|
352
|
+
const subscriptionById = new Map(subscriptions.map((sub) => [sub.id, sub]));
|
|
353
|
+
const renewalOrderIds = new Map();
|
|
354
|
+
const { data } = await query.graph({
|
|
355
|
+
entity: "renewal_cycle",
|
|
356
|
+
fields: ["id", "generated_order_id"],
|
|
357
|
+
filters: {
|
|
358
|
+
id: scenarios.map((scenario) => scenario.cycle_id),
|
|
359
|
+
},
|
|
360
|
+
});
|
|
361
|
+
for (const record of (data ?? [])) {
|
|
362
|
+
if (!record.id || !record.generated_order_id) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
renewalOrderIds.set(record.id, record.generated_order_id);
|
|
366
|
+
}
|
|
367
|
+
// On re-runs, upsertRenewalCycle resets generated_order_id to null, so the
|
|
368
|
+
// generated_order_id check above finds nothing. Check the link table directly
|
|
369
|
+
// (table name: renewal_renewal_cycle_order_order) to detect any
|
|
370
|
+
// renewal_cycle -> order links from a previous run.
|
|
371
|
+
//
|
|
372
|
+
// Two sub-cases:
|
|
373
|
+
// a) The linked order still exists → reuse it (skip order + link creation).
|
|
374
|
+
// b) The linked order was deleted → dismiss the stale link so we can
|
|
375
|
+
// re-create the order and a fresh link without hitting "Cannot create
|
|
376
|
+
// multiple links".
|
|
377
|
+
const unlinkedCycleIds = scenarios
|
|
378
|
+
.filter((s) => !renewalOrderIds.has(s.cycle_id))
|
|
379
|
+
.map((s) => s.cycle_id);
|
|
380
|
+
if (unlinkedCycleIds.length > 0) {
|
|
381
|
+
const existingRenewalLinks = await pgConnection("renewal_renewal_cycle_order_order")
|
|
382
|
+
.select("renewal_cycle_id", "order_id")
|
|
383
|
+
.whereIn("renewal_cycle_id", unlinkedCycleIds)
|
|
384
|
+
.whereNull("deleted_at");
|
|
385
|
+
for (const linkRecord of existingRenewalLinks) {
|
|
386
|
+
const cycleId = linkRecord.renewal_cycle_id;
|
|
387
|
+
const orderId = linkRecord.order_id;
|
|
388
|
+
const liveOrder = await pgConnection("order")
|
|
389
|
+
.select("id")
|
|
390
|
+
.where("id", orderId)
|
|
391
|
+
.whereNull("deleted_at")
|
|
392
|
+
.limit(1);
|
|
393
|
+
if (liveOrder.length > 0) {
|
|
394
|
+
// Order still exists – reuse it
|
|
395
|
+
renewalOrderIds.set(cycleId, orderId);
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
// Order was deleted – dismiss the stale link so a new one can be created
|
|
399
|
+
await link.dismiss({
|
|
400
|
+
[renewal_1.RENEWAL_MODULE]: { renewal_cycle_id: cycleId },
|
|
401
|
+
[utils_1.Modules.ORDER]: { order_id: orderId },
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
for (const scenario of scenarios) {
|
|
407
|
+
if (renewalOrderIds.has(scenario.cycle_id)) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
const existingSeedOrders = await pgConnection("order")
|
|
411
|
+
.select("id")
|
|
412
|
+
.whereRaw("metadata->>'seed_namespace' = ? and metadata->>'seed_order_role' = ? and metadata->>'seed_renewal_cycle_id' = ?", ["subscriptions-test-data", "renewal", scenario.cycle_id]);
|
|
413
|
+
const existingSeedOrderId = existingSeedOrders[0]?.id;
|
|
414
|
+
if (existingSeedOrderId) {
|
|
415
|
+
renewalOrderIds.set(scenario.cycle_id, existingSeedOrderId);
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
const subscription = subscriptionById.get(scenario.subscription_id);
|
|
419
|
+
if (!subscription) {
|
|
420
|
+
throw new Error(`Seed couldn't resolve subscription '${scenario.subscription_id}' for renewal order creation.`);
|
|
421
|
+
}
|
|
422
|
+
const order = await createSeedOrder(container, {
|
|
423
|
+
orderContext,
|
|
424
|
+
subscription,
|
|
425
|
+
role: "renewal",
|
|
426
|
+
scenario: scenario.scenario,
|
|
427
|
+
renewal_cycle_id: scenario.cycle_id,
|
|
428
|
+
});
|
|
429
|
+
await link.create([
|
|
430
|
+
{
|
|
431
|
+
[renewal_1.RENEWAL_MODULE]: {
|
|
432
|
+
renewal_cycle_id: scenario.cycle_id,
|
|
433
|
+
},
|
|
434
|
+
[utils_1.Modules.ORDER]: {
|
|
435
|
+
order_id: order.id,
|
|
436
|
+
},
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
[subscription_1.SUBSCRIPTION_MODULE]: {
|
|
440
|
+
subscription_id: subscription.id,
|
|
441
|
+
},
|
|
442
|
+
[utils_1.Modules.ORDER]: {
|
|
443
|
+
order_id: order.id,
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
]);
|
|
447
|
+
renewalOrderIds.set(scenario.cycle_id, order.id);
|
|
448
|
+
}
|
|
449
|
+
return renewalOrderIds;
|
|
450
|
+
}
|
|
451
|
+
async function createSeedOrder(container, input) {
|
|
452
|
+
const orderModule = container.resolve(utils_1.Modules.ORDER);
|
|
453
|
+
const customerEmail = input.subscription.customer_snapshot?.email;
|
|
454
|
+
if (!customerEmail) {
|
|
455
|
+
throw new Error(`Seed subscription '${input.subscription.id}' is missing customer email required for order creation.`);
|
|
456
|
+
}
|
|
457
|
+
const shippingAddress = buildSeedOrderShippingAddress(input.subscription.shipping_address);
|
|
458
|
+
return await orderModule.createOrders({
|
|
459
|
+
region_id: input.orderContext.region_id,
|
|
460
|
+
sales_channel_id: input.orderContext.sales_channel_id,
|
|
461
|
+
customer_id: input.subscription.customer_id,
|
|
462
|
+
email: customerEmail,
|
|
463
|
+
currency_code: input.orderContext.currency_code,
|
|
464
|
+
shipping_address: shippingAddress,
|
|
465
|
+
items: [
|
|
466
|
+
{
|
|
467
|
+
title: input.subscription.product_snapshot?.variant_title ??
|
|
468
|
+
"Seeded subscription item",
|
|
469
|
+
quantity: 1,
|
|
470
|
+
product_id: input.subscription.product_id,
|
|
471
|
+
product_title: input.subscription.product_snapshot?.product_title ??
|
|
472
|
+
"Seeded product",
|
|
473
|
+
variant_id: input.subscription.variant_id,
|
|
474
|
+
variant_title: input.subscription.product_snapshot?.variant_title ??
|
|
475
|
+
"Default variant",
|
|
476
|
+
variant_sku: input.subscription.product_snapshot?.sku ?? undefined,
|
|
477
|
+
unit_price: 10,
|
|
478
|
+
requires_shipping: true,
|
|
479
|
+
is_discountable: true,
|
|
480
|
+
metadata: {
|
|
481
|
+
seed_namespace: "subscriptions-test-data",
|
|
482
|
+
seed_order_role: input.role,
|
|
483
|
+
seed_subscription_id: input.subscription.id,
|
|
484
|
+
},
|
|
485
|
+
},
|
|
486
|
+
],
|
|
487
|
+
metadata: {
|
|
488
|
+
seed_namespace: "subscriptions-test-data",
|
|
489
|
+
seed_order_role: input.role,
|
|
490
|
+
seed_subscription_id: input.subscription.id,
|
|
491
|
+
seed_reference: input.subscription.reference,
|
|
492
|
+
seed_scenario: input.scenario,
|
|
493
|
+
...(input.renewal_cycle_id
|
|
494
|
+
? {
|
|
495
|
+
seed_renewal_cycle_id: input.renewal_cycle_id,
|
|
496
|
+
}
|
|
497
|
+
: {}),
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
function buildSeedOrderShippingAddress(shippingAddress) {
|
|
502
|
+
const value = shippingAddress ?? {};
|
|
503
|
+
return {
|
|
504
|
+
first_name: typeof value.first_name === "string" ? value.first_name : "QA",
|
|
505
|
+
last_name: typeof value.last_name === "string" ? value.last_name : "Tester",
|
|
506
|
+
company: typeof value.company === "string" ? value.company : undefined,
|
|
507
|
+
address_1: typeof value.address_1 === "string" ? value.address_1 : "Seed Street 1",
|
|
508
|
+
address_2: typeof value.address_2 === "string" ? value.address_2 : undefined,
|
|
509
|
+
city: typeof value.city === "string" ? value.city : "Warsaw",
|
|
510
|
+
postal_code: typeof value.postal_code === "string" ? value.postal_code : "00-001",
|
|
511
|
+
province: typeof value.province === "string" ? value.province : undefined,
|
|
512
|
+
country_code: typeof value.country_code === "string" ? value.country_code : "PL",
|
|
513
|
+
phone: typeof value.phone === "string" ? value.phone : undefined,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
async function upsertPlanOffer(service, input) {
|
|
517
|
+
try {
|
|
518
|
+
await service.retrievePlanOffer(String(input.id));
|
|
519
|
+
return await service.updatePlanOffers(input);
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
return await service.createPlanOffers(input);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
async function upsertSubscription(service, input) {
|
|
526
|
+
try {
|
|
527
|
+
await service.retrieveSubscription(String(input.id));
|
|
528
|
+
return await service.updateSubscriptions(input);
|
|
529
|
+
}
|
|
530
|
+
catch {
|
|
531
|
+
return await service.createSubscriptions(input);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
async function upsertRenewalCycle(service, input) {
|
|
535
|
+
try {
|
|
536
|
+
await service.retrieveRenewalCycle(String(input.id));
|
|
537
|
+
return await service.updateRenewalCycles(input);
|
|
538
|
+
}
|
|
539
|
+
catch {
|
|
540
|
+
return await service.createRenewalCycles(input);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
async function upsertRenewalAttempt(service, input) {
|
|
544
|
+
try {
|
|
545
|
+
await service.retrieveRenewalAttempt(String(input.id));
|
|
546
|
+
return await service.updateRenewalAttempts(input);
|
|
547
|
+
}
|
|
548
|
+
catch {
|
|
549
|
+
return await service.createRenewalAttempts(input);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
async function upsertDunningCase(service, input) {
|
|
553
|
+
try {
|
|
554
|
+
await service.retrieveDunningCase(String(input.id));
|
|
555
|
+
return await service.updateDunningCases(input);
|
|
556
|
+
}
|
|
557
|
+
catch {
|
|
558
|
+
return await service.createDunningCases(input);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
async function upsertDunningAttempt(service, input) {
|
|
562
|
+
try {
|
|
563
|
+
await service.retrieveDunningAttempt(String(input.id));
|
|
564
|
+
return await service.updateDunningAttempts(input);
|
|
565
|
+
}
|
|
566
|
+
catch {
|
|
567
|
+
return await service.createDunningAttempts(input);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
async function upsertCancellationCase(service, input) {
|
|
571
|
+
try {
|
|
572
|
+
await service.retrieveCancellationCase(String(input.id));
|
|
573
|
+
return await service.updateCancellationCases(input);
|
|
574
|
+
}
|
|
575
|
+
catch {
|
|
576
|
+
return await service.createCancellationCases(input);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
async function upsertRetentionOfferEvent(service, input) {
|
|
580
|
+
try {
|
|
581
|
+
await service.retrieveRetentionOfferEvent(String(input.id));
|
|
582
|
+
return await service.updateRetentionOfferEvents(input);
|
|
583
|
+
}
|
|
584
|
+
catch {
|
|
585
|
+
return await service.createRetentionOfferEvents(input);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
async function upsertSubscriptionLog(service, input) {
|
|
589
|
+
try {
|
|
590
|
+
await service.retrieveSubscriptionLog(String(input.id));
|
|
591
|
+
return await service.updateSubscriptionLogs(input);
|
|
592
|
+
}
|
|
593
|
+
catch {
|
|
594
|
+
return await service.createSubscriptionLogs(input);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
async function upsertSubscriptionMetricsDaily(service, input) {
|
|
598
|
+
try {
|
|
599
|
+
await service.retrieveSubscriptionMetricsDaily(String(input.id));
|
|
600
|
+
return await service.updateSubscriptionMetricsDailies(input);
|
|
601
|
+
}
|
|
602
|
+
catch {
|
|
603
|
+
return await service.createSubscriptionMetricsDailies(input);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
async function upsertSubscriptionSettings(service, input) {
|
|
607
|
+
const [existing] = (await service.listSubscriptionSettings({
|
|
608
|
+
settings_key: "global",
|
|
609
|
+
}));
|
|
610
|
+
if (existing) {
|
|
611
|
+
return await service.updateSubscriptionSettings({
|
|
612
|
+
id: existing.id,
|
|
613
|
+
...input,
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
return await service.createSubscriptionSettings(input);
|
|
617
|
+
}
|
|
618
|
+
function buildAnalyticsSnapshotId(subscriptionId, date) {
|
|
619
|
+
return `smd_seed_${subscriptionId}_${date}`;
|
|
620
|
+
}
|
|
621
|
+
function buildAnalyticsSnapshotRecord(input) {
|
|
622
|
+
return {
|
|
623
|
+
id: buildAnalyticsSnapshotId(input.subscription_id, input.metric_date),
|
|
624
|
+
metric_date: new Date(`${input.metric_date}T00:00:00.000Z`),
|
|
625
|
+
subscription_id: input.subscription_id,
|
|
626
|
+
customer_id: input.customer_id,
|
|
627
|
+
product_id: input.product_id,
|
|
628
|
+
variant_id: input.variant_id,
|
|
629
|
+
status: input.status,
|
|
630
|
+
frequency_interval: input.frequency_interval,
|
|
631
|
+
frequency_value: input.frequency_value,
|
|
632
|
+
currency_code: input.currency_code,
|
|
633
|
+
is_active: input.active_subscriptions_count === 1,
|
|
634
|
+
active_subscriptions_count: input.active_subscriptions_count,
|
|
635
|
+
mrr_amount: input.mrr_amount,
|
|
636
|
+
churned_subscriptions_count: input.churned_subscriptions_count,
|
|
637
|
+
churn_reason_category: input.churn_reason_category,
|
|
638
|
+
source_snapshot: {
|
|
639
|
+
source: "seed-script",
|
|
640
|
+
scenario: input.scenario,
|
|
641
|
+
revenue_source: input.mrr_amount === null ? "seeded-unavailable" : "seeded-fixed-value",
|
|
642
|
+
},
|
|
643
|
+
metadata: {
|
|
644
|
+
seed_namespace: "subscriptions-test-data",
|
|
645
|
+
seed_scenario: input.scenario,
|
|
646
|
+
metrics_version: constants_1.ANALYTICS_METRICS_VERSION,
|
|
647
|
+
},
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
function buildRetrySchedule(input) {
|
|
651
|
+
return {
|
|
652
|
+
strategy: "fixed_intervals",
|
|
653
|
+
intervals: input?.intervals ?? [1440, 4320, 10080],
|
|
654
|
+
timezone: "UTC",
|
|
655
|
+
source: input?.source ?? "default_policy",
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
function formatSummary(rows) {
|
|
659
|
+
return rows
|
|
660
|
+
.map((row) => {
|
|
661
|
+
const cyclePart = row.renewal_cycle_id
|
|
662
|
+
? ` renewal=${row.renewal_cycle_id}`
|
|
663
|
+
: "";
|
|
664
|
+
const dunningPart = row.dunning_case_id
|
|
665
|
+
? ` dunning=${row.dunning_case_id}`
|
|
666
|
+
: "";
|
|
667
|
+
const cancellationPart = row.cancellation_case_id
|
|
668
|
+
? ` cancellation=${row.cancellation_case_id}`
|
|
669
|
+
: "";
|
|
670
|
+
return `- ${row.scenario}: subscription=${row.subscription_reference}${cyclePart}${dunningPart}${cancellationPart} | ${row.notes}`;
|
|
671
|
+
})
|
|
672
|
+
.join("\n");
|
|
673
|
+
}
|
|
674
|
+
async function seedSubscriptionsTestData({ container, }) {
|
|
675
|
+
const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
|
|
676
|
+
const planOfferModule = container.resolve(plan_offer_1.PLAN_OFFER_MODULE);
|
|
677
|
+
const subscriptionModule = container.resolve(subscription_1.SUBSCRIPTION_MODULE);
|
|
678
|
+
const renewalModule = container.resolve(renewal_1.RENEWAL_MODULE);
|
|
679
|
+
const dunningModule = container.resolve(dunning_1.DUNNING_MODULE);
|
|
680
|
+
const cancellationModule = container.resolve(cancellation_1.CANCELLATION_MODULE);
|
|
681
|
+
const activityLogModule = container.resolve(activity_log_1.ACTIVITY_LOG_MODULE);
|
|
682
|
+
const analyticsModule = container.resolve(analytics_1.ANALYTICS_MODULE);
|
|
683
|
+
const settingsModule = container.resolve(settings_1.SETTINGS_MODULE);
|
|
684
|
+
const [existingSettings] = (await settingsModule.listSubscriptionSettings({
|
|
685
|
+
settings_key: "global",
|
|
686
|
+
}));
|
|
687
|
+
const shouldSeedSettings = !existingSettings ||
|
|
688
|
+
existingSettings.metadata?.seed_namespace === "subscriptions-test-data";
|
|
689
|
+
if (!shouldSeedSettings) {
|
|
690
|
+
logger.warn("[subscriptions-test-data] Skipping SubscriptionSettings seed because a non-seeded global singleton already exists.");
|
|
691
|
+
}
|
|
692
|
+
logger.info("[subscriptions-test-data] Resolving products and existing offers");
|
|
693
|
+
const products = await listProductsWithVariants(container);
|
|
694
|
+
const offers = await listPlanOfferTargets(container);
|
|
695
|
+
const targets = pickSeedTargets(products, offers);
|
|
696
|
+
const customerMap = await ensureSeedCustomers(container, [
|
|
697
|
+
{ key: IDS.subSuccess, reference: "SUB-QA-REN-SUCCESS" },
|
|
698
|
+
{ key: IDS.subPaused, reference: "SUB-QA-REN-PAUSED" },
|
|
699
|
+
{ key: IDS.subCancelEffective, reference: "SUB-QA-REN-CANCEL-EFFECTIVE" },
|
|
700
|
+
{ key: IDS.subApprovalPending, reference: "SUB-QA-REN-APPROVAL-PENDING" },
|
|
701
|
+
{ key: IDS.subPolicyBlocked, reference: "SUB-QA-REN-POLICY-BLOCKED" },
|
|
702
|
+
{ key: IDS.subFailedHistory, reference: "SUB-QA-REN-FAILED-HISTORY" },
|
|
703
|
+
{
|
|
704
|
+
key: IDS.subDunningRetryScheduled,
|
|
705
|
+
reference: "SUB-QA-DUN-RETRY-SCHEDULED",
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
key: IDS.subDunningAwaitingManual,
|
|
709
|
+
reference: "SUB-QA-DUN-AWAITING-MANUAL",
|
|
710
|
+
},
|
|
711
|
+
{ key: IDS.subDunningRecovered, reference: "SUB-QA-DUN-RECOVERED" },
|
|
712
|
+
{ key: IDS.subDunningUnrecovered, reference: "SUB-QA-DUN-UNRECOVERED" },
|
|
713
|
+
{
|
|
714
|
+
key: IDS.subDunningManualOverride,
|
|
715
|
+
reference: "SUB-QA-DUN-MANUAL-OVERRIDE",
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
key: IDS.subCancellationOpenBilling,
|
|
719
|
+
reference: "SUB-QA-CAN-OPEN-BILLING",
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
key: IDS.subCancellationRetainedDiscount,
|
|
723
|
+
reference: "SUB-QA-CAN-RETAINED-DISCOUNT",
|
|
724
|
+
},
|
|
725
|
+
{ key: IDS.subCancellationPaused, reference: "SUB-QA-CAN-PAUSED" },
|
|
726
|
+
{
|
|
727
|
+
key: IDS.subCancellationCanceledImmediate,
|
|
728
|
+
reference: "SUB-QA-CAN-CANCELED-IMMEDIATE",
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
key: IDS.subCancellationCanceledEndCycle,
|
|
732
|
+
reference: "SUB-QA-CAN-CANCELED-END-CYCLE",
|
|
733
|
+
},
|
|
734
|
+
{ key: IDS.subCancellationOpenPrice, reference: "SUB-QA-CAN-OPEN-PRICE" },
|
|
735
|
+
{
|
|
736
|
+
key: IDS.subCancellationOpenPaused,
|
|
737
|
+
reference: "SUB-QA-CAN-OPEN-PAUSED-SUB",
|
|
738
|
+
},
|
|
739
|
+
{ key: IDS.subAnalyticsBiMonthly, reference: "SUB-QA-ANL-BI-MONTHLY" },
|
|
740
|
+
]);
|
|
741
|
+
const getSeedCustomer = (key) => {
|
|
742
|
+
const customer = customerMap.get(key);
|
|
743
|
+
if (!customer) {
|
|
744
|
+
throw new Error(`Seed customer missing for ${key}`);
|
|
745
|
+
}
|
|
746
|
+
return customer;
|
|
747
|
+
};
|
|
748
|
+
logger.info(`[subscriptions-test-data] Using success target ${targets.success.product_id}/${targets.success.variant_id} and blocked target ${targets.blocked.product_id}/${targets.blocked.variant_id}`);
|
|
749
|
+
await upsertPlanOffer(planOfferModule, {
|
|
750
|
+
id: IDS.planOfferSuccess,
|
|
751
|
+
name: "QA Subscriptions Success Offer",
|
|
752
|
+
scope: types_4.PlanOfferScope.VARIANT,
|
|
753
|
+
product_id: targets.success.product_id,
|
|
754
|
+
variant_id: targets.success.variant_id,
|
|
755
|
+
is_enabled: true,
|
|
756
|
+
allowed_frequencies: [
|
|
757
|
+
{
|
|
758
|
+
interval: types_4.PlanOfferFrequencyInterval.MONTH,
|
|
759
|
+
value: 1,
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
interval: types_4.PlanOfferFrequencyInterval.MONTH,
|
|
763
|
+
value: 2,
|
|
764
|
+
},
|
|
765
|
+
],
|
|
766
|
+
frequency_intervals: [types_4.PlanOfferFrequencyInterval.MONTH],
|
|
767
|
+
discount_per_frequency: [],
|
|
768
|
+
rules: {
|
|
769
|
+
minimum_cycles: 1,
|
|
770
|
+
trial_enabled: false,
|
|
771
|
+
trial_days: null,
|
|
772
|
+
stacking_policy: types_4.PlanOfferStackingPolicy.ALLOWED,
|
|
773
|
+
},
|
|
774
|
+
metadata: {
|
|
775
|
+
seed_namespace: "subscriptions-test-data",
|
|
776
|
+
scenario: "renewals-success",
|
|
777
|
+
},
|
|
778
|
+
});
|
|
779
|
+
if (shouldSeedSettings) {
|
|
780
|
+
await upsertSubscriptionSettings(settingsModule, {
|
|
781
|
+
id: existingSettings?.id ?? IDS.settingsGlobal,
|
|
782
|
+
settings_key: "global",
|
|
783
|
+
default_trial_days: 14,
|
|
784
|
+
dunning_retry_intervals: [60, 180, 720],
|
|
785
|
+
max_dunning_attempts: 3,
|
|
786
|
+
default_renewal_behavior: types_7.SubscriptionRenewalBehavior.REQUIRE_REVIEW_FOR_PENDING_CHANGES,
|
|
787
|
+
default_cancellation_behavior: types_7.SubscriptionCancellationBehavior.ALLOW_DIRECT_CANCELLATION,
|
|
788
|
+
version: 1,
|
|
789
|
+
updated_by: "qa-seed",
|
|
790
|
+
metadata: {
|
|
791
|
+
seed_namespace: "subscriptions-test-data",
|
|
792
|
+
scenario: "settings-global-defaults",
|
|
793
|
+
audit_log: [
|
|
794
|
+
{
|
|
795
|
+
action: "update_settings",
|
|
796
|
+
who: "qa-seed",
|
|
797
|
+
when: FIXED_TIME.toISOString(),
|
|
798
|
+
reason: "seed_settings_defaults",
|
|
799
|
+
previous_version: 0,
|
|
800
|
+
next_version: 1,
|
|
801
|
+
change_summary: [
|
|
802
|
+
{
|
|
803
|
+
field: "default_trial_days",
|
|
804
|
+
from: 0,
|
|
805
|
+
to: 14,
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
field: "dunning_retry_intervals",
|
|
809
|
+
from: [1440, 4320, 10080],
|
|
810
|
+
to: [60, 180, 720],
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
field: "default_renewal_behavior",
|
|
814
|
+
from: types_7.SubscriptionRenewalBehavior.PROCESS_IMMEDIATELY,
|
|
815
|
+
to: types_7.SubscriptionRenewalBehavior.REQUIRE_REVIEW_FOR_PENDING_CHANGES,
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
field: "default_cancellation_behavior",
|
|
819
|
+
from: types_7.SubscriptionCancellationBehavior.RECOMMEND_RETENTION_FIRST,
|
|
820
|
+
to: types_7.SubscriptionCancellationBehavior.ALLOW_DIRECT_CANCELLATION,
|
|
821
|
+
},
|
|
822
|
+
],
|
|
823
|
+
},
|
|
824
|
+
],
|
|
825
|
+
last_update: {
|
|
826
|
+
action: "update_settings",
|
|
827
|
+
who: "qa-seed",
|
|
828
|
+
when: FIXED_TIME.toISOString(),
|
|
829
|
+
reason: "seed_settings_defaults",
|
|
830
|
+
previous_version: 0,
|
|
831
|
+
next_version: 1,
|
|
832
|
+
change_summary: [
|
|
833
|
+
{
|
|
834
|
+
field: "default_trial_days",
|
|
835
|
+
from: 0,
|
|
836
|
+
to: 14,
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
field: "dunning_retry_intervals",
|
|
840
|
+
from: [1440, 4320, 10080],
|
|
841
|
+
to: [60, 180, 720],
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
field: "default_renewal_behavior",
|
|
845
|
+
from: types_7.SubscriptionRenewalBehavior.PROCESS_IMMEDIATELY,
|
|
846
|
+
to: types_7.SubscriptionRenewalBehavior.REQUIRE_REVIEW_FOR_PENDING_CHANGES,
|
|
847
|
+
},
|
|
848
|
+
{
|
|
849
|
+
field: "default_cancellation_behavior",
|
|
850
|
+
from: types_7.SubscriptionCancellationBehavior.RECOMMEND_RETENTION_FIRST,
|
|
851
|
+
to: types_7.SubscriptionCancellationBehavior.ALLOW_DIRECT_CANCELLATION,
|
|
852
|
+
},
|
|
853
|
+
],
|
|
854
|
+
},
|
|
855
|
+
},
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
await upsertPlanOffer(planOfferModule, {
|
|
859
|
+
id: IDS.planOfferBlocked,
|
|
860
|
+
name: "QA Subscriptions Blocked Offer",
|
|
861
|
+
scope: types_4.PlanOfferScope.VARIANT,
|
|
862
|
+
product_id: targets.blocked.product_id,
|
|
863
|
+
variant_id: targets.blocked.variant_id,
|
|
864
|
+
is_enabled: true,
|
|
865
|
+
allowed_frequencies: [
|
|
866
|
+
{
|
|
867
|
+
interval: types_4.PlanOfferFrequencyInterval.MONTH,
|
|
868
|
+
value: 1,
|
|
869
|
+
},
|
|
870
|
+
],
|
|
871
|
+
frequency_intervals: [types_4.PlanOfferFrequencyInterval.MONTH],
|
|
872
|
+
discount_per_frequency: [],
|
|
873
|
+
rules: {
|
|
874
|
+
minimum_cycles: 1,
|
|
875
|
+
trial_enabled: false,
|
|
876
|
+
trial_days: null,
|
|
877
|
+
stacking_policy: types_4.PlanOfferStackingPolicy.ALLOWED,
|
|
878
|
+
},
|
|
879
|
+
metadata: {
|
|
880
|
+
seed_namespace: "subscriptions-test-data",
|
|
881
|
+
scenario: "renewals-policy-blocked",
|
|
882
|
+
},
|
|
883
|
+
});
|
|
884
|
+
const successScheduledFor = addDays(FIXED_TIME, 2);
|
|
885
|
+
const pausedScheduledFor = addDays(FIXED_TIME, 3);
|
|
886
|
+
const cancelScheduledFor = addDays(FIXED_TIME, 4);
|
|
887
|
+
const approvalScheduledFor = addDays(FIXED_TIME, 5);
|
|
888
|
+
const policyBlockedScheduledFor = addDays(FIXED_TIME, 6);
|
|
889
|
+
const failedHistoryScheduledFor = addDays(FIXED_TIME, -2);
|
|
890
|
+
const dunningRetryScheduledAt = addDays(FIXED_TIME, -1);
|
|
891
|
+
const dunningAwaitingManualAt = addDays(FIXED_TIME, -3);
|
|
892
|
+
const dunningRecoveredAt = addDays(FIXED_TIME, -7);
|
|
893
|
+
const dunningUnrecoveredAt = addDays(FIXED_TIME, -10);
|
|
894
|
+
const dunningManualOverrideAt = addDays(FIXED_TIME, -4);
|
|
895
|
+
const cancellationOpenBillingAt = addDays(FIXED_TIME, 7);
|
|
896
|
+
const cancellationRetainedDiscountAt = addDays(FIXED_TIME, 8);
|
|
897
|
+
const cancellationPausedAt = addDays(FIXED_TIME, 9);
|
|
898
|
+
const cancellationCanceledImmediateAt = addDays(FIXED_TIME, 10);
|
|
899
|
+
const cancellationCanceledEndCycleAt = addDays(FIXED_TIME, 12);
|
|
900
|
+
const cancellationOpenPriceAt = addDays(FIXED_TIME, 13);
|
|
901
|
+
const cancellationOpenPausedAt = addDays(FIXED_TIME, 14);
|
|
902
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
903
|
+
id: IDS.subSuccess,
|
|
904
|
+
reference: "SUB-QA-REN-SUCCESS",
|
|
905
|
+
customer: getSeedCustomer(IDS.subSuccess),
|
|
906
|
+
target: targets.success,
|
|
907
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
908
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
909
|
+
frequency_value: 1,
|
|
910
|
+
next_renewal_at: successScheduledFor,
|
|
911
|
+
skip_next_cycle: true,
|
|
912
|
+
}));
|
|
913
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
914
|
+
id: IDS.subPaused,
|
|
915
|
+
reference: "SUB-QA-REN-PAUSED",
|
|
916
|
+
customer: getSeedCustomer(IDS.subPaused),
|
|
917
|
+
target: targets.success,
|
|
918
|
+
status: types_6.SubscriptionStatus.PAUSED,
|
|
919
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
920
|
+
frequency_value: 1,
|
|
921
|
+
next_renewal_at: pausedScheduledFor,
|
|
922
|
+
skip_next_cycle: true,
|
|
923
|
+
paused_at: addDays(FIXED_TIME, -1),
|
|
924
|
+
}));
|
|
925
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
926
|
+
id: IDS.subCancelEffective,
|
|
927
|
+
reference: "SUB-QA-REN-CANCEL-EFFECTIVE",
|
|
928
|
+
customer: getSeedCustomer(IDS.subCancelEffective),
|
|
929
|
+
target: targets.success,
|
|
930
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
931
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
932
|
+
frequency_value: 1,
|
|
933
|
+
next_renewal_at: cancelScheduledFor,
|
|
934
|
+
skip_next_cycle: true,
|
|
935
|
+
cancel_effective_at: addDays(cancelScheduledFor, -1),
|
|
936
|
+
}));
|
|
937
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
938
|
+
id: IDS.subApprovalPending,
|
|
939
|
+
reference: "SUB-QA-REN-APPROVAL-PENDING",
|
|
940
|
+
customer: getSeedCustomer(IDS.subApprovalPending),
|
|
941
|
+
target: targets.success,
|
|
942
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
943
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
944
|
+
frequency_value: 1,
|
|
945
|
+
next_renewal_at: approvalScheduledFor,
|
|
946
|
+
skip_next_cycle: true,
|
|
947
|
+
pending_update_data: {
|
|
948
|
+
variant_id: targets.success.variant_id,
|
|
949
|
+
variant_title: targets.success.variant_title,
|
|
950
|
+
sku: targets.success.sku,
|
|
951
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
952
|
+
frequency_value: 2,
|
|
953
|
+
effective_at: null,
|
|
954
|
+
requested_at: FIXED_TIME.toISOString(),
|
|
955
|
+
requested_by: "qa-seed",
|
|
956
|
+
},
|
|
957
|
+
}));
|
|
958
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
959
|
+
id: IDS.subPolicyBlocked,
|
|
960
|
+
reference: "SUB-QA-REN-POLICY-BLOCKED",
|
|
961
|
+
customer: getSeedCustomer(IDS.subPolicyBlocked),
|
|
962
|
+
target: targets.blocked,
|
|
963
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
964
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
965
|
+
frequency_value: 1,
|
|
966
|
+
next_renewal_at: policyBlockedScheduledFor,
|
|
967
|
+
skip_next_cycle: true,
|
|
968
|
+
pending_update_data: {
|
|
969
|
+
variant_id: targets.blocked.variant_id,
|
|
970
|
+
variant_title: targets.blocked.variant_title,
|
|
971
|
+
sku: targets.blocked.sku,
|
|
972
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
973
|
+
frequency_value: 2,
|
|
974
|
+
effective_at: null,
|
|
975
|
+
requested_at: FIXED_TIME.toISOString(),
|
|
976
|
+
requested_by: "qa-seed",
|
|
977
|
+
},
|
|
978
|
+
}));
|
|
979
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
980
|
+
id: IDS.subFailedHistory,
|
|
981
|
+
reference: "SUB-QA-REN-FAILED-HISTORY",
|
|
982
|
+
customer: getSeedCustomer(IDS.subFailedHistory),
|
|
983
|
+
target: targets.success,
|
|
984
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
985
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
986
|
+
frequency_value: 1,
|
|
987
|
+
next_renewal_at: failedHistoryScheduledFor,
|
|
988
|
+
skip_next_cycle: false,
|
|
989
|
+
cart_id: null,
|
|
990
|
+
}));
|
|
991
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
992
|
+
id: IDS.subDunningRetryScheduled,
|
|
993
|
+
reference: "SUB-QA-DUN-RETRY-SCHEDULED",
|
|
994
|
+
customer: getSeedCustomer(IDS.subDunningRetryScheduled),
|
|
995
|
+
target: targets.success,
|
|
996
|
+
status: types_6.SubscriptionStatus.PAST_DUE,
|
|
997
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
998
|
+
frequency_value: 1,
|
|
999
|
+
next_renewal_at: addDays(FIXED_TIME, 1),
|
|
1000
|
+
skip_next_cycle: false,
|
|
1001
|
+
cart_id: "cart_seed_dunning_retry_scheduled",
|
|
1002
|
+
payment_provider_id: "pp_stripe_stripe",
|
|
1003
|
+
}));
|
|
1004
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1005
|
+
id: IDS.subCancellationOpenBilling,
|
|
1006
|
+
reference: "SUB-QA-CAN-OPEN-BILLING",
|
|
1007
|
+
customer: getSeedCustomer(IDS.subCancellationOpenBilling),
|
|
1008
|
+
target: targets.success,
|
|
1009
|
+
status: types_6.SubscriptionStatus.PAST_DUE,
|
|
1010
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1011
|
+
frequency_value: 1,
|
|
1012
|
+
next_renewal_at: cancellationOpenBillingAt,
|
|
1013
|
+
skip_next_cycle: false,
|
|
1014
|
+
cart_id: "cart_seed_cancellation_open_billing",
|
|
1015
|
+
payment_provider_id: "pp_stripe_stripe",
|
|
1016
|
+
}));
|
|
1017
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1018
|
+
id: IDS.subCancellationRetainedDiscount,
|
|
1019
|
+
reference: "SUB-QA-CAN-RETAINED-DISCOUNT",
|
|
1020
|
+
customer: getSeedCustomer(IDS.subCancellationRetainedDiscount),
|
|
1021
|
+
target: targets.success,
|
|
1022
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
1023
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1024
|
+
frequency_value: 1,
|
|
1025
|
+
next_renewal_at: cancellationRetainedDiscountAt,
|
|
1026
|
+
skip_next_cycle: false,
|
|
1027
|
+
cart_id: "cart_seed_cancellation_retained_discount",
|
|
1028
|
+
}));
|
|
1029
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1030
|
+
id: IDS.subCancellationPaused,
|
|
1031
|
+
reference: "SUB-QA-CAN-PAUSED",
|
|
1032
|
+
customer: getSeedCustomer(IDS.subCancellationPaused),
|
|
1033
|
+
target: targets.success,
|
|
1034
|
+
status: types_6.SubscriptionStatus.PAUSED,
|
|
1035
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1036
|
+
frequency_value: 1,
|
|
1037
|
+
next_renewal_at: cancellationPausedAt,
|
|
1038
|
+
skip_next_cycle: false,
|
|
1039
|
+
paused_at: addDays(FIXED_TIME, -2),
|
|
1040
|
+
cart_id: "cart_seed_cancellation_paused",
|
|
1041
|
+
}));
|
|
1042
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1043
|
+
id: IDS.subCancellationCanceledImmediate,
|
|
1044
|
+
reference: "SUB-QA-CAN-CANCELED-IMMEDIATE",
|
|
1045
|
+
customer: getSeedCustomer(IDS.subCancellationCanceledImmediate),
|
|
1046
|
+
target: targets.blocked,
|
|
1047
|
+
status: types_6.SubscriptionStatus.CANCELLED,
|
|
1048
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1049
|
+
frequency_value: 1,
|
|
1050
|
+
next_renewal_at: null,
|
|
1051
|
+
skip_next_cycle: false,
|
|
1052
|
+
cancelled_at: FIXED_TIME,
|
|
1053
|
+
cancel_effective_at: FIXED_TIME,
|
|
1054
|
+
cart_id: "cart_seed_cancellation_canceled_immediate",
|
|
1055
|
+
}));
|
|
1056
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1057
|
+
id: IDS.subCancellationCanceledEndCycle,
|
|
1058
|
+
reference: "SUB-QA-CAN-CANCELED-END-CYCLE",
|
|
1059
|
+
customer: getSeedCustomer(IDS.subCancellationCanceledEndCycle),
|
|
1060
|
+
target: targets.blocked,
|
|
1061
|
+
status: types_6.SubscriptionStatus.CANCELLED,
|
|
1062
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1063
|
+
frequency_value: 1,
|
|
1064
|
+
next_renewal_at: null,
|
|
1065
|
+
skip_next_cycle: false,
|
|
1066
|
+
cancelled_at: FIXED_TIME,
|
|
1067
|
+
cancel_effective_at: cancellationCanceledEndCycleAt,
|
|
1068
|
+
cart_id: "cart_seed_cancellation_canceled_end_cycle",
|
|
1069
|
+
}));
|
|
1070
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1071
|
+
id: IDS.subCancellationOpenPrice,
|
|
1072
|
+
reference: "SUB-QA-CAN-OPEN-PRICE",
|
|
1073
|
+
customer: getSeedCustomer(IDS.subCancellationOpenPrice),
|
|
1074
|
+
target: targets.success,
|
|
1075
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
1076
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1077
|
+
frequency_value: 1,
|
|
1078
|
+
next_renewal_at: cancellationOpenPriceAt,
|
|
1079
|
+
skip_next_cycle: false,
|
|
1080
|
+
cart_id: "cart_seed_cancellation_open_price",
|
|
1081
|
+
}));
|
|
1082
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1083
|
+
id: IDS.subCancellationOpenPaused,
|
|
1084
|
+
reference: "SUB-QA-CAN-OPEN-PAUSED-SUB",
|
|
1085
|
+
customer: getSeedCustomer(IDS.subCancellationOpenPaused),
|
|
1086
|
+
target: targets.success,
|
|
1087
|
+
status: types_6.SubscriptionStatus.PAUSED,
|
|
1088
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1089
|
+
frequency_value: 1,
|
|
1090
|
+
next_renewal_at: cancellationOpenPausedAt,
|
|
1091
|
+
skip_next_cycle: false,
|
|
1092
|
+
paused_at: addDays(FIXED_TIME, -5),
|
|
1093
|
+
cart_id: "cart_seed_cancellation_open_paused",
|
|
1094
|
+
}));
|
|
1095
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1096
|
+
id: IDS.subDunningAwaitingManual,
|
|
1097
|
+
reference: "SUB-QA-DUN-AWAITING-MANUAL",
|
|
1098
|
+
customer: getSeedCustomer(IDS.subDunningAwaitingManual),
|
|
1099
|
+
target: targets.success,
|
|
1100
|
+
status: types_6.SubscriptionStatus.PAST_DUE,
|
|
1101
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1102
|
+
frequency_value: 1,
|
|
1103
|
+
next_renewal_at: addDays(FIXED_TIME, 2),
|
|
1104
|
+
skip_next_cycle: false,
|
|
1105
|
+
cart_id: "cart_seed_dunning_awaiting_manual",
|
|
1106
|
+
payment_provider_id: "pp_stripe_stripe",
|
|
1107
|
+
}));
|
|
1108
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1109
|
+
id: IDS.subDunningRecovered,
|
|
1110
|
+
reference: "SUB-QA-DUN-RECOVERED",
|
|
1111
|
+
customer: getSeedCustomer(IDS.subDunningRecovered),
|
|
1112
|
+
target: targets.success,
|
|
1113
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
1114
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1115
|
+
frequency_value: 1,
|
|
1116
|
+
next_renewal_at: addDays(FIXED_TIME, 14),
|
|
1117
|
+
skip_next_cycle: false,
|
|
1118
|
+
cart_id: "cart_seed_dunning_recovered",
|
|
1119
|
+
payment_provider_id: "pp_adyen_adyen",
|
|
1120
|
+
}));
|
|
1121
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1122
|
+
id: IDS.subDunningUnrecovered,
|
|
1123
|
+
reference: "SUB-QA-DUN-UNRECOVERED",
|
|
1124
|
+
customer: getSeedCustomer(IDS.subDunningUnrecovered),
|
|
1125
|
+
target: targets.success,
|
|
1126
|
+
status: types_6.SubscriptionStatus.PAST_DUE,
|
|
1127
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1128
|
+
frequency_value: 1,
|
|
1129
|
+
next_renewal_at: addDays(FIXED_TIME, -1),
|
|
1130
|
+
skip_next_cycle: false,
|
|
1131
|
+
cart_id: "cart_seed_dunning_unrecovered",
|
|
1132
|
+
payment_provider_id: "pp_paypal_paypal",
|
|
1133
|
+
}));
|
|
1134
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1135
|
+
id: IDS.subDunningManualOverride,
|
|
1136
|
+
reference: "SUB-QA-DUN-MANUAL-OVERRIDE",
|
|
1137
|
+
customer: getSeedCustomer(IDS.subDunningManualOverride),
|
|
1138
|
+
target: targets.success,
|
|
1139
|
+
status: types_6.SubscriptionStatus.PAST_DUE,
|
|
1140
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1141
|
+
frequency_value: 1,
|
|
1142
|
+
next_renewal_at: addDays(FIXED_TIME, 3),
|
|
1143
|
+
skip_next_cycle: false,
|
|
1144
|
+
cart_id: "cart_seed_dunning_manual_override",
|
|
1145
|
+
payment_provider_id: "pp_stripe_stripe",
|
|
1146
|
+
}));
|
|
1147
|
+
await upsertSubscription(subscriptionModule, buildSubscriptionRecord({
|
|
1148
|
+
id: IDS.subAnalyticsBiMonthly,
|
|
1149
|
+
reference: "SUB-QA-ANL-BI-MONTHLY",
|
|
1150
|
+
customer: getSeedCustomer(IDS.subAnalyticsBiMonthly),
|
|
1151
|
+
target: targets.success,
|
|
1152
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
1153
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
1154
|
+
frequency_value: 2,
|
|
1155
|
+
next_renewal_at: addDays(FIXED_TIME, 18),
|
|
1156
|
+
skip_next_cycle: false,
|
|
1157
|
+
cart_id: "cart_seed_analytics_bimonthly",
|
|
1158
|
+
}));
|
|
1159
|
+
const orderContext = await resolveSeedOrderContext(container);
|
|
1160
|
+
const seededSubscriptions = await listSeededSubscriptions(container, [
|
|
1161
|
+
IDS.subSuccess,
|
|
1162
|
+
IDS.subPaused,
|
|
1163
|
+
IDS.subCancelEffective,
|
|
1164
|
+
IDS.subApprovalPending,
|
|
1165
|
+
IDS.subPolicyBlocked,
|
|
1166
|
+
IDS.subFailedHistory,
|
|
1167
|
+
IDS.subDunningRetryScheduled,
|
|
1168
|
+
IDS.subDunningAwaitingManual,
|
|
1169
|
+
IDS.subDunningRecovered,
|
|
1170
|
+
IDS.subDunningUnrecovered,
|
|
1171
|
+
IDS.subDunningManualOverride,
|
|
1172
|
+
IDS.subCancellationOpenBilling,
|
|
1173
|
+
IDS.subCancellationRetainedDiscount,
|
|
1174
|
+
IDS.subCancellationPaused,
|
|
1175
|
+
IDS.subCancellationCanceledImmediate,
|
|
1176
|
+
IDS.subCancellationCanceledEndCycle,
|
|
1177
|
+
IDS.subCancellationOpenPrice,
|
|
1178
|
+
IDS.subCancellationOpenPaused,
|
|
1179
|
+
IDS.subAnalyticsBiMonthly,
|
|
1180
|
+
]);
|
|
1181
|
+
await ensureInitialSubscriptionOrders(container, seededSubscriptions, orderContext);
|
|
1182
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1183
|
+
id: IDS.cycleSuccess,
|
|
1184
|
+
subscription_id: IDS.subSuccess,
|
|
1185
|
+
scheduled_for: successScheduledFor,
|
|
1186
|
+
processed_at: null,
|
|
1187
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1188
|
+
approval_required: false,
|
|
1189
|
+
approval_status: null,
|
|
1190
|
+
approval_decided_at: null,
|
|
1191
|
+
approval_decided_by: null,
|
|
1192
|
+
approval_reason: null,
|
|
1193
|
+
generated_order_id: null,
|
|
1194
|
+
applied_pending_update_data: null,
|
|
1195
|
+
last_error: null,
|
|
1196
|
+
attempt_count: 0,
|
|
1197
|
+
metadata: {
|
|
1198
|
+
seed_namespace: "subscriptions-test-data",
|
|
1199
|
+
scenario: "renewal-success",
|
|
1200
|
+
},
|
|
1201
|
+
});
|
|
1202
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1203
|
+
id: IDS.cycleCancellationOpenBilling,
|
|
1204
|
+
subscription_id: IDS.subCancellationOpenBilling,
|
|
1205
|
+
scheduled_for: cancellationOpenBillingAt,
|
|
1206
|
+
processed_at: addDays(FIXED_TIME, -1),
|
|
1207
|
+
status: types_5.RenewalCycleStatus.FAILED,
|
|
1208
|
+
approval_required: false,
|
|
1209
|
+
approval_status: null,
|
|
1210
|
+
approval_decided_at: null,
|
|
1211
|
+
approval_decided_by: null,
|
|
1212
|
+
approval_reason: null,
|
|
1213
|
+
generated_order_id: null,
|
|
1214
|
+
applied_pending_update_data: null,
|
|
1215
|
+
last_error: "Payment-qualified billing failure before retention handling.",
|
|
1216
|
+
attempt_count: 1,
|
|
1217
|
+
metadata: {
|
|
1218
|
+
seed_namespace: "subscriptions-test-data",
|
|
1219
|
+
scenario: "cancellation-open-billing",
|
|
1220
|
+
},
|
|
1221
|
+
});
|
|
1222
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1223
|
+
id: IDS.cycleCancellationRetainedDiscount,
|
|
1224
|
+
subscription_id: IDS.subCancellationRetainedDiscount,
|
|
1225
|
+
scheduled_for: cancellationRetainedDiscountAt,
|
|
1226
|
+
processed_at: null,
|
|
1227
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1228
|
+
approval_required: false,
|
|
1229
|
+
approval_status: null,
|
|
1230
|
+
approval_decided_at: null,
|
|
1231
|
+
approval_decided_by: null,
|
|
1232
|
+
approval_reason: null,
|
|
1233
|
+
generated_order_id: null,
|
|
1234
|
+
applied_pending_update_data: null,
|
|
1235
|
+
last_error: null,
|
|
1236
|
+
attempt_count: 0,
|
|
1237
|
+
metadata: {
|
|
1238
|
+
seed_namespace: "subscriptions-test-data",
|
|
1239
|
+
scenario: "cancellation-retained-discount",
|
|
1240
|
+
},
|
|
1241
|
+
});
|
|
1242
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1243
|
+
id: IDS.cycleCancellationPaused,
|
|
1244
|
+
subscription_id: IDS.subCancellationPaused,
|
|
1245
|
+
scheduled_for: cancellationPausedAt,
|
|
1246
|
+
processed_at: null,
|
|
1247
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1248
|
+
approval_required: false,
|
|
1249
|
+
approval_status: null,
|
|
1250
|
+
approval_decided_at: null,
|
|
1251
|
+
approval_decided_by: null,
|
|
1252
|
+
approval_reason: null,
|
|
1253
|
+
generated_order_id: null,
|
|
1254
|
+
applied_pending_update_data: null,
|
|
1255
|
+
last_error: null,
|
|
1256
|
+
attempt_count: 0,
|
|
1257
|
+
metadata: {
|
|
1258
|
+
seed_namespace: "subscriptions-test-data",
|
|
1259
|
+
scenario: "cancellation-paused",
|
|
1260
|
+
},
|
|
1261
|
+
});
|
|
1262
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1263
|
+
id: IDS.cycleCancellationCanceledImmediate,
|
|
1264
|
+
subscription_id: IDS.subCancellationCanceledImmediate,
|
|
1265
|
+
scheduled_for: cancellationCanceledImmediateAt,
|
|
1266
|
+
processed_at: null,
|
|
1267
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1268
|
+
approval_required: false,
|
|
1269
|
+
approval_status: null,
|
|
1270
|
+
approval_decided_at: null,
|
|
1271
|
+
approval_decided_by: null,
|
|
1272
|
+
approval_reason: null,
|
|
1273
|
+
generated_order_id: null,
|
|
1274
|
+
applied_pending_update_data: null,
|
|
1275
|
+
last_error: null,
|
|
1276
|
+
attempt_count: 0,
|
|
1277
|
+
metadata: {
|
|
1278
|
+
seed_namespace: "subscriptions-test-data",
|
|
1279
|
+
scenario: "cancellation-canceled-immediate",
|
|
1280
|
+
},
|
|
1281
|
+
});
|
|
1282
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1283
|
+
id: IDS.cycleCancellationCanceledEndCycle,
|
|
1284
|
+
subscription_id: IDS.subCancellationCanceledEndCycle,
|
|
1285
|
+
scheduled_for: cancellationCanceledEndCycleAt,
|
|
1286
|
+
processed_at: null,
|
|
1287
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1288
|
+
approval_required: false,
|
|
1289
|
+
approval_status: null,
|
|
1290
|
+
approval_decided_at: null,
|
|
1291
|
+
approval_decided_by: null,
|
|
1292
|
+
approval_reason: null,
|
|
1293
|
+
generated_order_id: null,
|
|
1294
|
+
applied_pending_update_data: null,
|
|
1295
|
+
last_error: null,
|
|
1296
|
+
attempt_count: 0,
|
|
1297
|
+
metadata: {
|
|
1298
|
+
seed_namespace: "subscriptions-test-data",
|
|
1299
|
+
scenario: "cancellation-canceled-end-cycle",
|
|
1300
|
+
},
|
|
1301
|
+
});
|
|
1302
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1303
|
+
id: IDS.cycleCancellationOpenPrice,
|
|
1304
|
+
subscription_id: IDS.subCancellationOpenPrice,
|
|
1305
|
+
scheduled_for: cancellationOpenPriceAt,
|
|
1306
|
+
processed_at: null,
|
|
1307
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1308
|
+
approval_required: false,
|
|
1309
|
+
approval_status: null,
|
|
1310
|
+
approval_decided_at: null,
|
|
1311
|
+
approval_decided_by: null,
|
|
1312
|
+
approval_reason: null,
|
|
1313
|
+
generated_order_id: null,
|
|
1314
|
+
applied_pending_update_data: null,
|
|
1315
|
+
last_error: null,
|
|
1316
|
+
attempt_count: 0,
|
|
1317
|
+
metadata: {
|
|
1318
|
+
seed_namespace: "subscriptions-test-data",
|
|
1319
|
+
scenario: "cancellation-open-price",
|
|
1320
|
+
},
|
|
1321
|
+
});
|
|
1322
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1323
|
+
id: IDS.cycleCancellationOpenPaused,
|
|
1324
|
+
subscription_id: IDS.subCancellationOpenPaused,
|
|
1325
|
+
scheduled_for: cancellationOpenPausedAt,
|
|
1326
|
+
processed_at: null,
|
|
1327
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1328
|
+
approval_required: false,
|
|
1329
|
+
approval_status: null,
|
|
1330
|
+
approval_decided_at: null,
|
|
1331
|
+
approval_decided_by: null,
|
|
1332
|
+
approval_reason: null,
|
|
1333
|
+
generated_order_id: null,
|
|
1334
|
+
applied_pending_update_data: null,
|
|
1335
|
+
last_error: null,
|
|
1336
|
+
attempt_count: 0,
|
|
1337
|
+
metadata: {
|
|
1338
|
+
seed_namespace: "subscriptions-test-data",
|
|
1339
|
+
scenario: "cancellation-open-paused-sub",
|
|
1340
|
+
},
|
|
1341
|
+
});
|
|
1342
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1343
|
+
id: IDS.cyclePaused,
|
|
1344
|
+
subscription_id: IDS.subPaused,
|
|
1345
|
+
scheduled_for: pausedScheduledFor,
|
|
1346
|
+
processed_at: null,
|
|
1347
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1348
|
+
approval_required: false,
|
|
1349
|
+
approval_status: null,
|
|
1350
|
+
approval_decided_at: null,
|
|
1351
|
+
approval_decided_by: null,
|
|
1352
|
+
approval_reason: null,
|
|
1353
|
+
generated_order_id: null,
|
|
1354
|
+
applied_pending_update_data: null,
|
|
1355
|
+
last_error: null,
|
|
1356
|
+
attempt_count: 0,
|
|
1357
|
+
metadata: {
|
|
1358
|
+
seed_namespace: "subscriptions-test-data",
|
|
1359
|
+
scenario: "renewal-paused-block",
|
|
1360
|
+
},
|
|
1361
|
+
});
|
|
1362
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1363
|
+
id: IDS.cycleCancelEffective,
|
|
1364
|
+
subscription_id: IDS.subCancelEffective,
|
|
1365
|
+
scheduled_for: cancelScheduledFor,
|
|
1366
|
+
processed_at: null,
|
|
1367
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1368
|
+
approval_required: false,
|
|
1369
|
+
approval_status: null,
|
|
1370
|
+
approval_decided_at: null,
|
|
1371
|
+
approval_decided_by: null,
|
|
1372
|
+
approval_reason: null,
|
|
1373
|
+
generated_order_id: null,
|
|
1374
|
+
applied_pending_update_data: null,
|
|
1375
|
+
last_error: null,
|
|
1376
|
+
attempt_count: 0,
|
|
1377
|
+
metadata: {
|
|
1378
|
+
seed_namespace: "subscriptions-test-data",
|
|
1379
|
+
scenario: "renewal-cancel-effective-block",
|
|
1380
|
+
},
|
|
1381
|
+
});
|
|
1382
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1383
|
+
id: IDS.cycleApprovalPending,
|
|
1384
|
+
subscription_id: IDS.subApprovalPending,
|
|
1385
|
+
scheduled_for: approvalScheduledFor,
|
|
1386
|
+
processed_at: null,
|
|
1387
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1388
|
+
approval_required: true,
|
|
1389
|
+
approval_status: types_5.RenewalApprovalStatus.PENDING,
|
|
1390
|
+
approval_decided_at: null,
|
|
1391
|
+
approval_decided_by: null,
|
|
1392
|
+
approval_reason: null,
|
|
1393
|
+
generated_order_id: null,
|
|
1394
|
+
applied_pending_update_data: null,
|
|
1395
|
+
last_error: null,
|
|
1396
|
+
attempt_count: 0,
|
|
1397
|
+
metadata: {
|
|
1398
|
+
seed_namespace: "subscriptions-test-data",
|
|
1399
|
+
scenario: "renewal-approval-pending",
|
|
1400
|
+
},
|
|
1401
|
+
});
|
|
1402
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1403
|
+
id: IDS.cyclePolicyBlocked,
|
|
1404
|
+
subscription_id: IDS.subPolicyBlocked,
|
|
1405
|
+
scheduled_for: policyBlockedScheduledFor,
|
|
1406
|
+
processed_at: null,
|
|
1407
|
+
status: types_5.RenewalCycleStatus.SCHEDULED,
|
|
1408
|
+
approval_required: true,
|
|
1409
|
+
approval_status: types_5.RenewalApprovalStatus.PENDING,
|
|
1410
|
+
approval_decided_at: null,
|
|
1411
|
+
approval_decided_by: null,
|
|
1412
|
+
approval_reason: null,
|
|
1413
|
+
generated_order_id: null,
|
|
1414
|
+
applied_pending_update_data: null,
|
|
1415
|
+
last_error: null,
|
|
1416
|
+
attempt_count: 0,
|
|
1417
|
+
metadata: {
|
|
1418
|
+
seed_namespace: "subscriptions-test-data",
|
|
1419
|
+
scenario: "renewal-offer-policy-blocked",
|
|
1420
|
+
},
|
|
1421
|
+
});
|
|
1422
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1423
|
+
id: IDS.cycleFailedHistory,
|
|
1424
|
+
subscription_id: IDS.subFailedHistory,
|
|
1425
|
+
scheduled_for: failedHistoryScheduledFor,
|
|
1426
|
+
processed_at: addDays(FIXED_TIME, -1),
|
|
1427
|
+
status: types_5.RenewalCycleStatus.FAILED,
|
|
1428
|
+
approval_required: false,
|
|
1429
|
+
approval_status: null,
|
|
1430
|
+
approval_decided_at: null,
|
|
1431
|
+
approval_decided_by: null,
|
|
1432
|
+
approval_reason: null,
|
|
1433
|
+
generated_order_id: null,
|
|
1434
|
+
applied_pending_update_data: null,
|
|
1435
|
+
last_error: "Subscription is missing 'cart_id' required for renewal order creation",
|
|
1436
|
+
attempt_count: 1,
|
|
1437
|
+
metadata: {
|
|
1438
|
+
seed_namespace: "subscriptions-test-data",
|
|
1439
|
+
scenario: "renewal-failed-history",
|
|
1440
|
+
},
|
|
1441
|
+
});
|
|
1442
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1443
|
+
id: IDS.cycleDunningRetryScheduled,
|
|
1444
|
+
subscription_id: IDS.subDunningRetryScheduled,
|
|
1445
|
+
scheduled_for: dunningRetryScheduledAt,
|
|
1446
|
+
processed_at: addDays(FIXED_TIME, -1),
|
|
1447
|
+
status: types_5.RenewalCycleStatus.FAILED,
|
|
1448
|
+
approval_required: false,
|
|
1449
|
+
approval_status: null,
|
|
1450
|
+
approval_decided_at: null,
|
|
1451
|
+
approval_decided_by: null,
|
|
1452
|
+
approval_reason: null,
|
|
1453
|
+
generated_order_id: null,
|
|
1454
|
+
applied_pending_update_data: null,
|
|
1455
|
+
last_error: "Card declined during payment authorization",
|
|
1456
|
+
attempt_count: 1,
|
|
1457
|
+
metadata: {
|
|
1458
|
+
seed_namespace: "subscriptions-test-data",
|
|
1459
|
+
scenario: "dunning-retry-scheduled",
|
|
1460
|
+
},
|
|
1461
|
+
});
|
|
1462
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1463
|
+
id: IDS.cycleDunningAwaitingManual,
|
|
1464
|
+
subscription_id: IDS.subDunningAwaitingManual,
|
|
1465
|
+
scheduled_for: dunningAwaitingManualAt,
|
|
1466
|
+
processed_at: addDays(FIXED_TIME, -3),
|
|
1467
|
+
status: types_5.RenewalCycleStatus.FAILED,
|
|
1468
|
+
approval_required: false,
|
|
1469
|
+
approval_status: null,
|
|
1470
|
+
approval_decided_at: null,
|
|
1471
|
+
approval_decided_by: null,
|
|
1472
|
+
approval_reason: null,
|
|
1473
|
+
generated_order_id: null,
|
|
1474
|
+
applied_pending_update_data: null,
|
|
1475
|
+
last_error: "Payment requires additional customer authentication",
|
|
1476
|
+
attempt_count: 1,
|
|
1477
|
+
metadata: {
|
|
1478
|
+
seed_namespace: "subscriptions-test-data",
|
|
1479
|
+
scenario: "dunning-awaiting-manual",
|
|
1480
|
+
},
|
|
1481
|
+
});
|
|
1482
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1483
|
+
id: IDS.cycleDunningRecovered,
|
|
1484
|
+
subscription_id: IDS.subDunningRecovered,
|
|
1485
|
+
scheduled_for: dunningRecoveredAt,
|
|
1486
|
+
processed_at: addDays(FIXED_TIME, -7),
|
|
1487
|
+
status: types_5.RenewalCycleStatus.FAILED,
|
|
1488
|
+
approval_required: false,
|
|
1489
|
+
approval_status: null,
|
|
1490
|
+
approval_decided_at: null,
|
|
1491
|
+
approval_decided_by: null,
|
|
1492
|
+
approval_reason: null,
|
|
1493
|
+
generated_order_id: null,
|
|
1494
|
+
applied_pending_update_data: null,
|
|
1495
|
+
last_error: "Initial payment authorization failed before recovery",
|
|
1496
|
+
attempt_count: 1,
|
|
1497
|
+
metadata: {
|
|
1498
|
+
seed_namespace: "subscriptions-test-data",
|
|
1499
|
+
scenario: "dunning-recovered",
|
|
1500
|
+
},
|
|
1501
|
+
});
|
|
1502
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1503
|
+
id: IDS.cycleDunningUnrecovered,
|
|
1504
|
+
subscription_id: IDS.subDunningUnrecovered,
|
|
1505
|
+
scheduled_for: dunningUnrecoveredAt,
|
|
1506
|
+
processed_at: addDays(FIXED_TIME, -10),
|
|
1507
|
+
status: types_5.RenewalCycleStatus.FAILED,
|
|
1508
|
+
approval_required: false,
|
|
1509
|
+
approval_status: null,
|
|
1510
|
+
approval_decided_at: null,
|
|
1511
|
+
approval_decided_by: null,
|
|
1512
|
+
approval_reason: null,
|
|
1513
|
+
generated_order_id: null,
|
|
1514
|
+
applied_pending_update_data: null,
|
|
1515
|
+
last_error: "Payment method expired and recovery attempts were exhausted",
|
|
1516
|
+
attempt_count: 3,
|
|
1517
|
+
metadata: {
|
|
1518
|
+
seed_namespace: "subscriptions-test-data",
|
|
1519
|
+
scenario: "dunning-unrecovered",
|
|
1520
|
+
},
|
|
1521
|
+
});
|
|
1522
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1523
|
+
id: IDS.cycleDunningManualOverride,
|
|
1524
|
+
subscription_id: IDS.subDunningManualOverride,
|
|
1525
|
+
scheduled_for: dunningManualOverrideAt,
|
|
1526
|
+
processed_at: addDays(FIXED_TIME, -4),
|
|
1527
|
+
status: types_5.RenewalCycleStatus.FAILED,
|
|
1528
|
+
approval_required: false,
|
|
1529
|
+
approval_status: null,
|
|
1530
|
+
approval_decided_at: null,
|
|
1531
|
+
approval_decided_by: null,
|
|
1532
|
+
approval_reason: null,
|
|
1533
|
+
generated_order_id: null,
|
|
1534
|
+
applied_pending_update_data: null,
|
|
1535
|
+
last_error: "Retry schedule was manually overridden after repeated soft declines",
|
|
1536
|
+
attempt_count: 1,
|
|
1537
|
+
metadata: {
|
|
1538
|
+
seed_namespace: "subscriptions-test-data",
|
|
1539
|
+
scenario: "dunning-manual-override",
|
|
1540
|
+
},
|
|
1541
|
+
});
|
|
1542
|
+
const renewalOrderIds = await ensureRenewalOrders(container, seededSubscriptions, [
|
|
1543
|
+
{
|
|
1544
|
+
cycle_id: IDS.cycleCancellationOpenBilling,
|
|
1545
|
+
subscription_id: IDS.subCancellationOpenBilling,
|
|
1546
|
+
scenario: "cancellation-open-billing",
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
cycle_id: IDS.cycleDunningRetryScheduled,
|
|
1550
|
+
subscription_id: IDS.subDunningRetryScheduled,
|
|
1551
|
+
scenario: "dunning-retry-scheduled",
|
|
1552
|
+
},
|
|
1553
|
+
{
|
|
1554
|
+
cycle_id: IDS.cycleDunningAwaitingManual,
|
|
1555
|
+
subscription_id: IDS.subDunningAwaitingManual,
|
|
1556
|
+
scenario: "dunning-awaiting-manual",
|
|
1557
|
+
},
|
|
1558
|
+
{
|
|
1559
|
+
cycle_id: IDS.cycleDunningRecovered,
|
|
1560
|
+
subscription_id: IDS.subDunningRecovered,
|
|
1561
|
+
scenario: "dunning-recovered",
|
|
1562
|
+
},
|
|
1563
|
+
{
|
|
1564
|
+
cycle_id: IDS.cycleDunningUnrecovered,
|
|
1565
|
+
subscription_id: IDS.subDunningUnrecovered,
|
|
1566
|
+
scenario: "dunning-unrecovered",
|
|
1567
|
+
},
|
|
1568
|
+
{
|
|
1569
|
+
cycle_id: IDS.cycleDunningManualOverride,
|
|
1570
|
+
subscription_id: IDS.subDunningManualOverride,
|
|
1571
|
+
scenario: "dunning-manual-override",
|
|
1572
|
+
},
|
|
1573
|
+
], orderContext);
|
|
1574
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1575
|
+
id: IDS.cycleCancellationOpenBilling,
|
|
1576
|
+
generated_order_id: renewalOrderIds.get(IDS.cycleCancellationOpenBilling) ?? null,
|
|
1577
|
+
});
|
|
1578
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1579
|
+
id: IDS.cycleDunningRetryScheduled,
|
|
1580
|
+
generated_order_id: renewalOrderIds.get(IDS.cycleDunningRetryScheduled) ?? null,
|
|
1581
|
+
});
|
|
1582
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1583
|
+
id: IDS.cycleDunningAwaitingManual,
|
|
1584
|
+
generated_order_id: renewalOrderIds.get(IDS.cycleDunningAwaitingManual) ?? null,
|
|
1585
|
+
});
|
|
1586
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1587
|
+
id: IDS.cycleDunningRecovered,
|
|
1588
|
+
generated_order_id: renewalOrderIds.get(IDS.cycleDunningRecovered) ?? null,
|
|
1589
|
+
});
|
|
1590
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1591
|
+
id: IDS.cycleDunningUnrecovered,
|
|
1592
|
+
generated_order_id: renewalOrderIds.get(IDS.cycleDunningUnrecovered) ?? null,
|
|
1593
|
+
});
|
|
1594
|
+
await upsertRenewalCycle(renewalModule, {
|
|
1595
|
+
id: IDS.cycleDunningManualOverride,
|
|
1596
|
+
generated_order_id: renewalOrderIds.get(IDS.cycleDunningManualOverride) ?? null,
|
|
1597
|
+
});
|
|
1598
|
+
await upsertRenewalAttempt(renewalModule, {
|
|
1599
|
+
id: IDS.attemptFailedHistory,
|
|
1600
|
+
renewal_cycle_id: IDS.cycleFailedHistory,
|
|
1601
|
+
attempt_no: 1,
|
|
1602
|
+
started_at: addDays(FIXED_TIME, -1),
|
|
1603
|
+
finished_at: addDays(FIXED_TIME, -1),
|
|
1604
|
+
status: types_5.RenewalAttemptStatus.FAILED,
|
|
1605
|
+
error_code: "renewal_failed",
|
|
1606
|
+
error_message: "Subscription is missing 'cart_id' required for renewal order creation",
|
|
1607
|
+
payment_reference: null,
|
|
1608
|
+
order_id: null,
|
|
1609
|
+
metadata: {
|
|
1610
|
+
seed_namespace: "subscriptions-test-data",
|
|
1611
|
+
scenario: "renewal-failed-history",
|
|
1612
|
+
},
|
|
1613
|
+
});
|
|
1614
|
+
await upsertDunningCase(dunningModule, {
|
|
1615
|
+
id: IDS.dunningRetryScheduled,
|
|
1616
|
+
subscription_id: IDS.subDunningRetryScheduled,
|
|
1617
|
+
renewal_cycle_id: IDS.cycleDunningRetryScheduled,
|
|
1618
|
+
renewal_order_id: renewalOrderIds.get(IDS.cycleDunningRetryScheduled) ?? null,
|
|
1619
|
+
status: types_3.DunningCaseStatus.RETRY_SCHEDULED,
|
|
1620
|
+
attempt_count: 0,
|
|
1621
|
+
max_attempts: 3,
|
|
1622
|
+
retry_schedule: buildRetrySchedule(),
|
|
1623
|
+
next_retry_at: addDays(FIXED_TIME, 1),
|
|
1624
|
+
last_payment_error_code: "card_declined",
|
|
1625
|
+
last_payment_error_message: "Issuer declined the renewal authorization attempt.",
|
|
1626
|
+
last_attempt_at: null,
|
|
1627
|
+
recovered_at: null,
|
|
1628
|
+
closed_at: null,
|
|
1629
|
+
recovery_reason: null,
|
|
1630
|
+
metadata: {
|
|
1631
|
+
seed_namespace: "subscriptions-test-data",
|
|
1632
|
+
scenario: "dunning-retry-scheduled",
|
|
1633
|
+
qa_focus: ["queue", "filters", "retry-now"],
|
|
1634
|
+
},
|
|
1635
|
+
});
|
|
1636
|
+
await upsertDunningCase(dunningModule, {
|
|
1637
|
+
id: IDS.dunningCancellationOpenBilling,
|
|
1638
|
+
subscription_id: IDS.subCancellationOpenBilling,
|
|
1639
|
+
renewal_cycle_id: IDS.cycleCancellationOpenBilling,
|
|
1640
|
+
renewal_order_id: renewalOrderIds.get(IDS.cycleCancellationOpenBilling) ?? null,
|
|
1641
|
+
status: types_3.DunningCaseStatus.RETRY_SCHEDULED,
|
|
1642
|
+
attempt_count: 1,
|
|
1643
|
+
max_attempts: 3,
|
|
1644
|
+
retry_schedule: buildRetrySchedule(),
|
|
1645
|
+
next_retry_at: addDays(FIXED_TIME, 1),
|
|
1646
|
+
last_payment_error_code: "card_declined",
|
|
1647
|
+
last_payment_error_message: "Billing issue is active while the operator evaluates retention.",
|
|
1648
|
+
last_attempt_at: FIXED_TIME,
|
|
1649
|
+
recovered_at: null,
|
|
1650
|
+
closed_at: null,
|
|
1651
|
+
recovery_reason: null,
|
|
1652
|
+
metadata: {
|
|
1653
|
+
seed_namespace: "subscriptions-test-data",
|
|
1654
|
+
scenario: "cancellation-open-billing",
|
|
1655
|
+
qa_focus: ["cancellation-detail", "linked-dunning"],
|
|
1656
|
+
},
|
|
1657
|
+
});
|
|
1658
|
+
await upsertDunningCase(dunningModule, {
|
|
1659
|
+
id: IDS.dunningAwaitingManual,
|
|
1660
|
+
subscription_id: IDS.subDunningAwaitingManual,
|
|
1661
|
+
renewal_cycle_id: IDS.cycleDunningAwaitingManual,
|
|
1662
|
+
renewal_order_id: renewalOrderIds.get(IDS.cycleDunningAwaitingManual) ?? null,
|
|
1663
|
+
status: types_3.DunningCaseStatus.AWAITING_MANUAL_RESOLUTION,
|
|
1664
|
+
attempt_count: 1,
|
|
1665
|
+
max_attempts: 3,
|
|
1666
|
+
retry_schedule: buildRetrySchedule(),
|
|
1667
|
+
next_retry_at: null,
|
|
1668
|
+
last_payment_error_code: "requires_more",
|
|
1669
|
+
last_payment_error_message: "Customer action is required before another retry can succeed.",
|
|
1670
|
+
last_attempt_at: addDays(FIXED_TIME, -2),
|
|
1671
|
+
recovered_at: null,
|
|
1672
|
+
closed_at: null,
|
|
1673
|
+
recovery_reason: null,
|
|
1674
|
+
metadata: {
|
|
1675
|
+
seed_namespace: "subscriptions-test-data",
|
|
1676
|
+
scenario: "dunning-awaiting-manual",
|
|
1677
|
+
qa_focus: ["detail", "mark-recovered", "mark-unrecovered"],
|
|
1678
|
+
},
|
|
1679
|
+
});
|
|
1680
|
+
await upsertDunningCase(dunningModule, {
|
|
1681
|
+
id: IDS.dunningRecovered,
|
|
1682
|
+
subscription_id: IDS.subDunningRecovered,
|
|
1683
|
+
renewal_cycle_id: IDS.cycleDunningRecovered,
|
|
1684
|
+
renewal_order_id: renewalOrderIds.get(IDS.cycleDunningRecovered) ?? null,
|
|
1685
|
+
status: types_3.DunningCaseStatus.RECOVERED,
|
|
1686
|
+
attempt_count: 1,
|
|
1687
|
+
max_attempts: 3,
|
|
1688
|
+
retry_schedule: buildRetrySchedule(),
|
|
1689
|
+
next_retry_at: null,
|
|
1690
|
+
last_payment_error_code: null,
|
|
1691
|
+
last_payment_error_message: null,
|
|
1692
|
+
last_attempt_at: addDays(FIXED_TIME, -6),
|
|
1693
|
+
recovered_at: addDays(FIXED_TIME, -6),
|
|
1694
|
+
closed_at: addDays(FIXED_TIME, -6),
|
|
1695
|
+
recovery_reason: "automatic_retry_succeeded",
|
|
1696
|
+
metadata: {
|
|
1697
|
+
seed_namespace: "subscriptions-test-data",
|
|
1698
|
+
scenario: "dunning-recovered",
|
|
1699
|
+
qa_focus: ["history", "detail", "terminal-state"],
|
|
1700
|
+
},
|
|
1701
|
+
});
|
|
1702
|
+
await upsertDunningCase(dunningModule, {
|
|
1703
|
+
id: IDS.dunningUnrecovered,
|
|
1704
|
+
subscription_id: IDS.subDunningUnrecovered,
|
|
1705
|
+
renewal_cycle_id: IDS.cycleDunningUnrecovered,
|
|
1706
|
+
renewal_order_id: renewalOrderIds.get(IDS.cycleDunningUnrecovered) ?? null,
|
|
1707
|
+
status: types_3.DunningCaseStatus.UNRECOVERED,
|
|
1708
|
+
attempt_count: 3,
|
|
1709
|
+
max_attempts: 3,
|
|
1710
|
+
retry_schedule: buildRetrySchedule(),
|
|
1711
|
+
next_retry_at: null,
|
|
1712
|
+
last_payment_error_code: "expired_card",
|
|
1713
|
+
last_payment_error_message: "The saved payment method expired and recovery attempts were exhausted.",
|
|
1714
|
+
last_attempt_at: addDays(FIXED_TIME, -8),
|
|
1715
|
+
recovered_at: null,
|
|
1716
|
+
closed_at: addDays(FIXED_TIME, -8),
|
|
1717
|
+
recovery_reason: "max_attempts_exceeded",
|
|
1718
|
+
metadata: {
|
|
1719
|
+
seed_namespace: "subscriptions-test-data",
|
|
1720
|
+
scenario: "dunning-unrecovered",
|
|
1721
|
+
qa_focus: ["history", "filters", "terminal-state"],
|
|
1722
|
+
},
|
|
1723
|
+
});
|
|
1724
|
+
await upsertDunningCase(dunningModule, {
|
|
1725
|
+
id: IDS.dunningManualOverride,
|
|
1726
|
+
subscription_id: IDS.subDunningManualOverride,
|
|
1727
|
+
renewal_cycle_id: IDS.cycleDunningManualOverride,
|
|
1728
|
+
renewal_order_id: renewalOrderIds.get(IDS.cycleDunningManualOverride) ?? null,
|
|
1729
|
+
status: types_3.DunningCaseStatus.RETRY_SCHEDULED,
|
|
1730
|
+
attempt_count: 1,
|
|
1731
|
+
max_attempts: 4,
|
|
1732
|
+
retry_schedule: buildRetrySchedule({
|
|
1733
|
+
intervals: [720, 1440, 2880, 5760],
|
|
1734
|
+
source: "manual_override",
|
|
1735
|
+
}),
|
|
1736
|
+
next_retry_at: addDays(FIXED_TIME, 2),
|
|
1737
|
+
last_payment_error_code: "insufficient_funds",
|
|
1738
|
+
last_payment_error_message: "Soft decline after a manual retry schedule override.",
|
|
1739
|
+
last_attempt_at: addDays(FIXED_TIME, -3),
|
|
1740
|
+
recovered_at: null,
|
|
1741
|
+
closed_at: null,
|
|
1742
|
+
recovery_reason: null,
|
|
1743
|
+
metadata: {
|
|
1744
|
+
seed_namespace: "subscriptions-test-data",
|
|
1745
|
+
scenario: "dunning-manual-override",
|
|
1746
|
+
qa_focus: ["schedule-override", "filters", "detail"],
|
|
1747
|
+
},
|
|
1748
|
+
});
|
|
1749
|
+
await upsertDunningAttempt(dunningModule, {
|
|
1750
|
+
id: IDS.dunningAttemptAwaitingManual,
|
|
1751
|
+
dunning_case_id: IDS.dunningAwaitingManual,
|
|
1752
|
+
attempt_no: 1,
|
|
1753
|
+
started_at: addDays(FIXED_TIME, -2),
|
|
1754
|
+
finished_at: addDays(FIXED_TIME, -2),
|
|
1755
|
+
status: types_3.DunningAttemptStatus.FAILED,
|
|
1756
|
+
error_code: "requires_more",
|
|
1757
|
+
error_message: "3DS authentication is required before another payment attempt.",
|
|
1758
|
+
payment_reference: "pay_seed_dunning_awaiting_manual_1",
|
|
1759
|
+
metadata: {
|
|
1760
|
+
seed_namespace: "subscriptions-test-data",
|
|
1761
|
+
scenario: "dunning-awaiting-manual",
|
|
1762
|
+
},
|
|
1763
|
+
});
|
|
1764
|
+
await upsertCancellationCase(cancellationModule, {
|
|
1765
|
+
id: IDS.cancellationOpenBilling,
|
|
1766
|
+
subscription_id: IDS.subCancellationOpenBilling,
|
|
1767
|
+
status: types_2.CancellationCaseStatus.EVALUATING_RETENTION,
|
|
1768
|
+
reason: "Customer reports billing problems and wants to stop unless billing is stabilized.",
|
|
1769
|
+
reason_category: types_2.CancellationReasonCategory.BILLING,
|
|
1770
|
+
notes: "Use to validate active case detail with linked dunning summary.",
|
|
1771
|
+
final_outcome: null,
|
|
1772
|
+
finalized_at: null,
|
|
1773
|
+
finalized_by: null,
|
|
1774
|
+
cancellation_effective_at: null,
|
|
1775
|
+
metadata: {
|
|
1776
|
+
seed_namespace: "subscriptions-test-data",
|
|
1777
|
+
scenario: "cancellation-open-billing",
|
|
1778
|
+
},
|
|
1779
|
+
});
|
|
1780
|
+
await upsertCancellationCase(cancellationModule, {
|
|
1781
|
+
id: IDS.cancellationRetainedDiscount,
|
|
1782
|
+
subscription_id: IDS.subCancellationRetainedDiscount,
|
|
1783
|
+
status: types_2.CancellationCaseStatus.RETAINED,
|
|
1784
|
+
reason: "Customer said the current price is too high.",
|
|
1785
|
+
reason_category: types_2.CancellationReasonCategory.PRICE,
|
|
1786
|
+
notes: "Use to validate retained detail, timeline, and discount-offer filtering.",
|
|
1787
|
+
final_outcome: types_2.CancellationFinalOutcome.RETAINED,
|
|
1788
|
+
finalized_at: FIXED_TIME,
|
|
1789
|
+
finalized_by: "qa-seed",
|
|
1790
|
+
cancellation_effective_at: null,
|
|
1791
|
+
metadata: {
|
|
1792
|
+
seed_namespace: "subscriptions-test-data",
|
|
1793
|
+
scenario: "cancellation-retained-discount",
|
|
1794
|
+
manual_actions: [
|
|
1795
|
+
{
|
|
1796
|
+
action: "apply_offer",
|
|
1797
|
+
who: "qa-seed",
|
|
1798
|
+
when: FIXED_TIME.toISOString(),
|
|
1799
|
+
why: "Customer accepted a temporary discount.",
|
|
1800
|
+
data: {
|
|
1801
|
+
offer_type: "discount_offer",
|
|
1802
|
+
},
|
|
1803
|
+
},
|
|
1804
|
+
],
|
|
1805
|
+
},
|
|
1806
|
+
});
|
|
1807
|
+
await upsertCancellationCase(cancellationModule, {
|
|
1808
|
+
id: IDS.cancellationPaused,
|
|
1809
|
+
subscription_id: IDS.subCancellationPaused,
|
|
1810
|
+
status: types_2.CancellationCaseStatus.PAUSED,
|
|
1811
|
+
reason: "Customer asked for a temporary pause instead of canceling.",
|
|
1812
|
+
reason_category: types_2.CancellationReasonCategory.TEMPORARY_PAUSE,
|
|
1813
|
+
notes: "Use to validate pause as retention outcome.",
|
|
1814
|
+
final_outcome: types_2.CancellationFinalOutcome.PAUSED,
|
|
1815
|
+
finalized_at: addDays(FIXED_TIME, -2),
|
|
1816
|
+
finalized_by: "qa-seed",
|
|
1817
|
+
cancellation_effective_at: null,
|
|
1818
|
+
metadata: {
|
|
1819
|
+
seed_namespace: "subscriptions-test-data",
|
|
1820
|
+
scenario: "cancellation-paused",
|
|
1821
|
+
},
|
|
1822
|
+
});
|
|
1823
|
+
await upsertCancellationCase(cancellationModule, {
|
|
1824
|
+
id: IDS.cancellationCanceledImmediate,
|
|
1825
|
+
subscription_id: IDS.subCancellationCanceledImmediate,
|
|
1826
|
+
status: types_2.CancellationCaseStatus.CANCELED,
|
|
1827
|
+
reason: "Customer switched to another provider and requested immediate cancel.",
|
|
1828
|
+
reason_category: types_2.CancellationReasonCategory.SWITCHED_COMPETITOR,
|
|
1829
|
+
notes: "Use to compare immediate cancel semantics on detail.",
|
|
1830
|
+
final_outcome: types_2.CancellationFinalOutcome.CANCELED,
|
|
1831
|
+
finalized_at: FIXED_TIME,
|
|
1832
|
+
finalized_by: "qa-seed",
|
|
1833
|
+
cancellation_effective_at: FIXED_TIME,
|
|
1834
|
+
metadata: {
|
|
1835
|
+
seed_namespace: "subscriptions-test-data",
|
|
1836
|
+
scenario: "cancellation-canceled-immediate",
|
|
1837
|
+
final_cancellation: {
|
|
1838
|
+
effective_at: "immediately",
|
|
1839
|
+
},
|
|
1840
|
+
},
|
|
1841
|
+
});
|
|
1842
|
+
await upsertCancellationCase(cancellationModule, {
|
|
1843
|
+
id: IDS.cancellationCanceledEndCycle,
|
|
1844
|
+
subscription_id: IDS.subCancellationCanceledEndCycle,
|
|
1845
|
+
status: types_2.CancellationCaseStatus.CANCELED,
|
|
1846
|
+
reason: "Customer wants cancellation at the end of the current cycle.",
|
|
1847
|
+
reason_category: types_2.CancellationReasonCategory.OTHER,
|
|
1848
|
+
notes: "Use to compare end-of-cycle cancellation semantics.",
|
|
1849
|
+
final_outcome: types_2.CancellationFinalOutcome.CANCELED,
|
|
1850
|
+
finalized_at: FIXED_TIME,
|
|
1851
|
+
finalized_by: "qa-seed",
|
|
1852
|
+
cancellation_effective_at: cancellationCanceledEndCycleAt,
|
|
1853
|
+
metadata: {
|
|
1854
|
+
seed_namespace: "subscriptions-test-data",
|
|
1855
|
+
scenario: "cancellation-canceled-end-cycle",
|
|
1856
|
+
final_cancellation: {
|
|
1857
|
+
effective_at: "end_of_cycle",
|
|
1858
|
+
},
|
|
1859
|
+
},
|
|
1860
|
+
});
|
|
1861
|
+
await upsertCancellationCase(cancellationModule, {
|
|
1862
|
+
id: IDS.cancellationOpenPrice,
|
|
1863
|
+
subscription_id: IDS.subCancellationOpenPrice,
|
|
1864
|
+
status: types_2.CancellationCaseStatus.REQUESTED,
|
|
1865
|
+
reason: "Customer is considering cancellation because the price feels too high.",
|
|
1866
|
+
reason_category: types_2.CancellationReasonCategory.PRICE,
|
|
1867
|
+
notes: "Use to validate an open price-driven cancellation case before any offer is applied.",
|
|
1868
|
+
final_outcome: null,
|
|
1869
|
+
finalized_at: null,
|
|
1870
|
+
finalized_by: null,
|
|
1871
|
+
cancellation_effective_at: null,
|
|
1872
|
+
metadata: {
|
|
1873
|
+
seed_namespace: "subscriptions-test-data",
|
|
1874
|
+
scenario: "cancellation-open-price",
|
|
1875
|
+
},
|
|
1876
|
+
});
|
|
1877
|
+
await upsertCancellationCase(cancellationModule, {
|
|
1878
|
+
id: IDS.cancellationOpenPaused,
|
|
1879
|
+
subscription_id: IDS.subCancellationOpenPaused,
|
|
1880
|
+
status: types_2.CancellationCaseStatus.REQUESTED,
|
|
1881
|
+
reason: "Paused customer may still want final cancellation after the break.",
|
|
1882
|
+
reason_category: types_2.CancellationReasonCategory.OTHER,
|
|
1883
|
+
notes: "Use to validate an active case on an already paused subscription.",
|
|
1884
|
+
final_outcome: null,
|
|
1885
|
+
finalized_at: null,
|
|
1886
|
+
finalized_by: null,
|
|
1887
|
+
cancellation_effective_at: null,
|
|
1888
|
+
metadata: {
|
|
1889
|
+
seed_namespace: "subscriptions-test-data",
|
|
1890
|
+
scenario: "cancellation-open-paused-sub",
|
|
1891
|
+
},
|
|
1892
|
+
});
|
|
1893
|
+
await upsertRetentionOfferEvent(cancellationModule, {
|
|
1894
|
+
id: IDS.retentionDiscountRetained,
|
|
1895
|
+
cancellation_case_id: IDS.cancellationRetainedDiscount,
|
|
1896
|
+
offer_type: types_2.RetentionOfferType.DISCOUNT_OFFER,
|
|
1897
|
+
offer_payload: {
|
|
1898
|
+
discount_offer: {
|
|
1899
|
+
discount_type: "percentage",
|
|
1900
|
+
discount_value: 15,
|
|
1901
|
+
duration_cycles: 2,
|
|
1902
|
+
note: "QA seed retention discount",
|
|
1903
|
+
},
|
|
1904
|
+
},
|
|
1905
|
+
decision_status: types_2.RetentionOfferDecisionStatus.APPLIED,
|
|
1906
|
+
decision_reason: "Customer accepted a temporary 15% retention discount.",
|
|
1907
|
+
decided_at: FIXED_TIME,
|
|
1908
|
+
decided_by: "qa-seed",
|
|
1909
|
+
applied_at: FIXED_TIME,
|
|
1910
|
+
metadata: {
|
|
1911
|
+
seed_namespace: "subscriptions-test-data",
|
|
1912
|
+
scenario: "cancellation-retained-discount",
|
|
1913
|
+
},
|
|
1914
|
+
});
|
|
1915
|
+
await upsertRetentionOfferEvent(cancellationModule, {
|
|
1916
|
+
id: IDS.retentionPauseApplied,
|
|
1917
|
+
cancellation_case_id: IDS.cancellationPaused,
|
|
1918
|
+
offer_type: types_2.RetentionOfferType.PAUSE_OFFER,
|
|
1919
|
+
offer_payload: {
|
|
1920
|
+
pause_offer: {
|
|
1921
|
+
pause_cycles: 2,
|
|
1922
|
+
resume_at: null,
|
|
1923
|
+
note: "QA seed pause offer",
|
|
1924
|
+
},
|
|
1925
|
+
},
|
|
1926
|
+
decision_status: types_2.RetentionOfferDecisionStatus.APPLIED,
|
|
1927
|
+
decision_reason: "Customer accepted a two-cycle pause.",
|
|
1928
|
+
decided_at: addDays(FIXED_TIME, -2),
|
|
1929
|
+
decided_by: "qa-seed",
|
|
1930
|
+
applied_at: addDays(FIXED_TIME, -2),
|
|
1931
|
+
metadata: {
|
|
1932
|
+
seed_namespace: "subscriptions-test-data",
|
|
1933
|
+
scenario: "cancellation-paused",
|
|
1934
|
+
},
|
|
1935
|
+
});
|
|
1936
|
+
await upsertDunningAttempt(dunningModule, {
|
|
1937
|
+
id: IDS.dunningAttemptRecoveredFailed,
|
|
1938
|
+
dunning_case_id: IDS.dunningRecovered,
|
|
1939
|
+
attempt_no: 1,
|
|
1940
|
+
started_at: addDays(FIXED_TIME, -7),
|
|
1941
|
+
finished_at: addDays(FIXED_TIME, -7),
|
|
1942
|
+
status: types_3.DunningAttemptStatus.FAILED,
|
|
1943
|
+
error_code: "authentication_required",
|
|
1944
|
+
error_message: "Initial recovery attempt required customer authentication.",
|
|
1945
|
+
payment_reference: "pay_seed_dunning_recovered_1",
|
|
1946
|
+
metadata: {
|
|
1947
|
+
seed_namespace: "subscriptions-test-data",
|
|
1948
|
+
scenario: "dunning-recovered",
|
|
1949
|
+
},
|
|
1950
|
+
});
|
|
1951
|
+
await upsertDunningAttempt(dunningModule, {
|
|
1952
|
+
id: IDS.dunningAttemptRecoveredSucceeded,
|
|
1953
|
+
dunning_case_id: IDS.dunningRecovered,
|
|
1954
|
+
attempt_no: 2,
|
|
1955
|
+
started_at: addDays(FIXED_TIME, -6),
|
|
1956
|
+
finished_at: addDays(FIXED_TIME, -6),
|
|
1957
|
+
status: types_3.DunningAttemptStatus.SUCCEEDED,
|
|
1958
|
+
error_code: null,
|
|
1959
|
+
error_message: null,
|
|
1960
|
+
payment_reference: "pay_seed_dunning_recovered_2",
|
|
1961
|
+
metadata: {
|
|
1962
|
+
seed_namespace: "subscriptions-test-data",
|
|
1963
|
+
scenario: "dunning-recovered",
|
|
1964
|
+
},
|
|
1965
|
+
});
|
|
1966
|
+
await upsertDunningAttempt(dunningModule, {
|
|
1967
|
+
id: IDS.dunningAttemptUnrecoveredOne,
|
|
1968
|
+
dunning_case_id: IDS.dunningUnrecovered,
|
|
1969
|
+
attempt_no: 1,
|
|
1970
|
+
started_at: addDays(FIXED_TIME, -10),
|
|
1971
|
+
finished_at: addDays(FIXED_TIME, -10),
|
|
1972
|
+
status: types_3.DunningAttemptStatus.FAILED,
|
|
1973
|
+
error_code: "expired_card",
|
|
1974
|
+
error_message: "Retry failed because the stored card was already expired.",
|
|
1975
|
+
payment_reference: "pay_seed_dunning_unrecovered_1",
|
|
1976
|
+
metadata: {
|
|
1977
|
+
seed_namespace: "subscriptions-test-data",
|
|
1978
|
+
scenario: "dunning-unrecovered",
|
|
1979
|
+
},
|
|
1980
|
+
});
|
|
1981
|
+
await upsertDunningAttempt(dunningModule, {
|
|
1982
|
+
id: IDS.dunningAttemptUnrecoveredTwo,
|
|
1983
|
+
dunning_case_id: IDS.dunningUnrecovered,
|
|
1984
|
+
attempt_no: 2,
|
|
1985
|
+
started_at: addDays(FIXED_TIME, -9),
|
|
1986
|
+
finished_at: addDays(FIXED_TIME, -9),
|
|
1987
|
+
status: types_3.DunningAttemptStatus.FAILED,
|
|
1988
|
+
error_code: "expired_card",
|
|
1989
|
+
error_message: "Second retry failed with the same expired payment method.",
|
|
1990
|
+
payment_reference: "pay_seed_dunning_unrecovered_2",
|
|
1991
|
+
metadata: {
|
|
1992
|
+
seed_namespace: "subscriptions-test-data",
|
|
1993
|
+
scenario: "dunning-unrecovered",
|
|
1994
|
+
},
|
|
1995
|
+
});
|
|
1996
|
+
await upsertDunningAttempt(dunningModule, {
|
|
1997
|
+
id: IDS.dunningAttemptUnrecoveredThree,
|
|
1998
|
+
dunning_case_id: IDS.dunningUnrecovered,
|
|
1999
|
+
attempt_no: 3,
|
|
2000
|
+
started_at: addDays(FIXED_TIME, -8),
|
|
2001
|
+
finished_at: addDays(FIXED_TIME, -8),
|
|
2002
|
+
status: types_3.DunningAttemptStatus.FAILED,
|
|
2003
|
+
error_code: "expired_card",
|
|
2004
|
+
error_message: "Final retry failed and the case was closed as unrecovered.",
|
|
2005
|
+
payment_reference: "pay_seed_dunning_unrecovered_3",
|
|
2006
|
+
metadata: {
|
|
2007
|
+
seed_namespace: "subscriptions-test-data",
|
|
2008
|
+
scenario: "dunning-unrecovered",
|
|
2009
|
+
},
|
|
2010
|
+
});
|
|
2011
|
+
await upsertDunningAttempt(dunningModule, {
|
|
2012
|
+
id: IDS.dunningAttemptManualOverride,
|
|
2013
|
+
dunning_case_id: IDS.dunningManualOverride,
|
|
2014
|
+
attempt_no: 1,
|
|
2015
|
+
started_at: addDays(FIXED_TIME, -3),
|
|
2016
|
+
finished_at: addDays(FIXED_TIME, -3),
|
|
2017
|
+
status: types_3.DunningAttemptStatus.FAILED,
|
|
2018
|
+
error_code: "insufficient_funds",
|
|
2019
|
+
error_message: "Retry failed due to insufficient funds before a manual override was applied.",
|
|
2020
|
+
payment_reference: "pay_seed_dunning_manual_override_1",
|
|
2021
|
+
metadata: {
|
|
2022
|
+
seed_namespace: "subscriptions-test-data",
|
|
2023
|
+
scenario: "dunning-manual-override",
|
|
2024
|
+
manual_override_reason: "Customer requested more time before next retry.",
|
|
2025
|
+
},
|
|
2026
|
+
});
|
|
2027
|
+
await upsertSubscriptionLog(activityLogModule, {
|
|
2028
|
+
id: IDS.logSubscriptionPaused,
|
|
2029
|
+
subscription_id: IDS.subPaused,
|
|
2030
|
+
customer_id: getSeedCustomer(IDS.subPaused).id,
|
|
2031
|
+
event_type: types_1.ActivityLogEventType.SUBSCRIPTION_PAUSED,
|
|
2032
|
+
actor_type: types_1.ActivityLogActorType.USER,
|
|
2033
|
+
actor_id: "qa-seed-admin",
|
|
2034
|
+
subscription_reference: "SUB-QA-REN-PAUSED",
|
|
2035
|
+
customer_name: "QA SUB-QA-REN-PAUSED",
|
|
2036
|
+
product_title: targets.success.product_title,
|
|
2037
|
+
variant_title: targets.success.variant_title,
|
|
2038
|
+
reason: "Seeded admin pause event for timeline and detail verification.",
|
|
2039
|
+
dedupe_key: "seed:activity-log:subscription-paused",
|
|
2040
|
+
previous_state: {
|
|
2041
|
+
status: "active",
|
|
2042
|
+
paused_at: null,
|
|
2043
|
+
},
|
|
2044
|
+
new_state: {
|
|
2045
|
+
status: "paused",
|
|
2046
|
+
paused_at: addDays(FIXED_TIME, -1).toISOString(),
|
|
2047
|
+
},
|
|
2048
|
+
changed_fields: [
|
|
2049
|
+
{
|
|
2050
|
+
field: "status",
|
|
2051
|
+
before: "active",
|
|
2052
|
+
after: "paused",
|
|
2053
|
+
},
|
|
2054
|
+
{
|
|
2055
|
+
field: "paused_at",
|
|
2056
|
+
before: null,
|
|
2057
|
+
after: addDays(FIXED_TIME, -1).toISOString(),
|
|
2058
|
+
},
|
|
2059
|
+
],
|
|
2060
|
+
metadata: {
|
|
2061
|
+
source: "seed-script",
|
|
2062
|
+
seed_namespace: "subscriptions-test-data",
|
|
2063
|
+
},
|
|
2064
|
+
});
|
|
2065
|
+
await upsertSubscriptionLog(activityLogModule, {
|
|
2066
|
+
id: IDS.logRenewalSucceeded,
|
|
2067
|
+
subscription_id: IDS.subSuccess,
|
|
2068
|
+
customer_id: getSeedCustomer(IDS.subSuccess).id,
|
|
2069
|
+
event_type: types_1.ActivityLogEventType.RENEWAL_SUCCEEDED,
|
|
2070
|
+
actor_type: types_1.ActivityLogActorType.SCHEDULER,
|
|
2071
|
+
actor_id: null,
|
|
2072
|
+
subscription_reference: "SUB-QA-REN-SUCCESS",
|
|
2073
|
+
customer_name: "QA SUB-QA-REN-SUCCESS",
|
|
2074
|
+
product_title: targets.success.product_title,
|
|
2075
|
+
variant_title: targets.success.variant_title,
|
|
2076
|
+
reason: null,
|
|
2077
|
+
dedupe_key: "seed:activity-log:renewal-succeeded",
|
|
2078
|
+
previous_state: {
|
|
2079
|
+
status: "scheduled",
|
|
2080
|
+
processed_at: null,
|
|
2081
|
+
},
|
|
2082
|
+
new_state: {
|
|
2083
|
+
status: "succeeded",
|
|
2084
|
+
processed_at: FIXED_TIME.toISOString(),
|
|
2085
|
+
},
|
|
2086
|
+
changed_fields: [
|
|
2087
|
+
{
|
|
2088
|
+
field: "status",
|
|
2089
|
+
before: "scheduled",
|
|
2090
|
+
after: "succeeded",
|
|
2091
|
+
},
|
|
2092
|
+
{
|
|
2093
|
+
field: "processed_at",
|
|
2094
|
+
before: null,
|
|
2095
|
+
after: FIXED_TIME.toISOString(),
|
|
2096
|
+
},
|
|
2097
|
+
],
|
|
2098
|
+
metadata: {
|
|
2099
|
+
source: "seed-script",
|
|
2100
|
+
seed_namespace: "subscriptions-test-data",
|
|
2101
|
+
renewal_cycle_id: IDS.cycleSuccess,
|
|
2102
|
+
scheduled_for: successScheduledFor.toISOString(),
|
|
2103
|
+
},
|
|
2104
|
+
});
|
|
2105
|
+
await upsertSubscriptionLog(activityLogModule, {
|
|
2106
|
+
id: IDS.logDunningRecovered,
|
|
2107
|
+
subscription_id: IDS.subDunningRecovered,
|
|
2108
|
+
customer_id: getSeedCustomer(IDS.subDunningRecovered).id,
|
|
2109
|
+
event_type: types_1.ActivityLogEventType.DUNNING_RECOVERED,
|
|
2110
|
+
actor_type: types_1.ActivityLogActorType.SYSTEM,
|
|
2111
|
+
actor_id: "qa-seed-system",
|
|
2112
|
+
subscription_reference: "SUB-QA-DUN-RECOVERED",
|
|
2113
|
+
customer_name: "QA SUB-QA-DUN-RECOVERED",
|
|
2114
|
+
product_title: targets.success.product_title,
|
|
2115
|
+
variant_title: targets.success.variant_title,
|
|
2116
|
+
reason: "Seeded recovery event to validate system-originated activity-log rows.",
|
|
2117
|
+
dedupe_key: "seed:activity-log:dunning-recovered",
|
|
2118
|
+
previous_state: {
|
|
2119
|
+
status: "retry_scheduled",
|
|
2120
|
+
attempt_count: 1,
|
|
2121
|
+
},
|
|
2122
|
+
new_state: {
|
|
2123
|
+
status: "recovered",
|
|
2124
|
+
attempt_count: 2,
|
|
2125
|
+
},
|
|
2126
|
+
changed_fields: [
|
|
2127
|
+
{
|
|
2128
|
+
field: "status",
|
|
2129
|
+
before: "retry_scheduled",
|
|
2130
|
+
after: "recovered",
|
|
2131
|
+
},
|
|
2132
|
+
{
|
|
2133
|
+
field: "attempt_count",
|
|
2134
|
+
before: 1,
|
|
2135
|
+
after: 2,
|
|
2136
|
+
},
|
|
2137
|
+
],
|
|
2138
|
+
metadata: {
|
|
2139
|
+
source: "seed-script",
|
|
2140
|
+
seed_namespace: "subscriptions-test-data",
|
|
2141
|
+
dunning_case_id: IDS.dunningRecovered,
|
|
2142
|
+
reason_code: "automatic_retry_succeeded",
|
|
2143
|
+
},
|
|
2144
|
+
});
|
|
2145
|
+
const analyticsDates = [
|
|
2146
|
+
"2026-04-06",
|
|
2147
|
+
"2026-04-07",
|
|
2148
|
+
"2026-04-08",
|
|
2149
|
+
"2026-04-09",
|
|
2150
|
+
"2026-04-10",
|
|
2151
|
+
"2026-04-11",
|
|
2152
|
+
"2026-04-12",
|
|
2153
|
+
"2026-04-13",
|
|
2154
|
+
"2026-04-14",
|
|
2155
|
+
"2026-04-15",
|
|
2156
|
+
];
|
|
2157
|
+
for (const date of analyticsDates) {
|
|
2158
|
+
const successMrr = date === "2026-04-12" ? 260 : 120;
|
|
2159
|
+
await upsertSubscriptionMetricsDaily(analyticsModule, buildAnalyticsSnapshotRecord({
|
|
2160
|
+
subscription_id: IDS.subSuccess,
|
|
2161
|
+
metric_date: date,
|
|
2162
|
+
customer_id: getSeedCustomer(IDS.subSuccess).id,
|
|
2163
|
+
product_id: targets.success.product_id,
|
|
2164
|
+
variant_id: targets.success.variant_id,
|
|
2165
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
2166
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
2167
|
+
frequency_value: 1,
|
|
2168
|
+
currency_code: "USD",
|
|
2169
|
+
active_subscriptions_count: 1,
|
|
2170
|
+
mrr_amount: successMrr,
|
|
2171
|
+
churned_subscriptions_count: 0,
|
|
2172
|
+
churn_reason_category: null,
|
|
2173
|
+
scenario: "analytics-active-monthly-baseline",
|
|
2174
|
+
}));
|
|
2175
|
+
await upsertSubscriptionMetricsDaily(analyticsModule, buildAnalyticsSnapshotRecord({
|
|
2176
|
+
subscription_id: IDS.subAnalyticsBiMonthly,
|
|
2177
|
+
metric_date: date,
|
|
2178
|
+
customer_id: getSeedCustomer(IDS.subAnalyticsBiMonthly).id,
|
|
2179
|
+
product_id: targets.success.product_id,
|
|
2180
|
+
variant_id: targets.success.variant_id,
|
|
2181
|
+
status: types_6.SubscriptionStatus.ACTIVE,
|
|
2182
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
2183
|
+
frequency_value: 2,
|
|
2184
|
+
currency_code: "USD",
|
|
2185
|
+
active_subscriptions_count: 1,
|
|
2186
|
+
mrr_amount: 45,
|
|
2187
|
+
churned_subscriptions_count: 0,
|
|
2188
|
+
churn_reason_category: null,
|
|
2189
|
+
scenario: "analytics-active-bimonthly-comparison",
|
|
2190
|
+
}));
|
|
2191
|
+
await upsertSubscriptionMetricsDaily(analyticsModule, buildAnalyticsSnapshotRecord({
|
|
2192
|
+
subscription_id: IDS.subPaused,
|
|
2193
|
+
metric_date: date,
|
|
2194
|
+
customer_id: getSeedCustomer(IDS.subPaused).id,
|
|
2195
|
+
product_id: targets.success.product_id,
|
|
2196
|
+
variant_id: targets.success.variant_id,
|
|
2197
|
+
status: types_6.SubscriptionStatus.PAUSED,
|
|
2198
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
2199
|
+
frequency_value: 1,
|
|
2200
|
+
currency_code: null,
|
|
2201
|
+
active_subscriptions_count: 0,
|
|
2202
|
+
mrr_amount: null,
|
|
2203
|
+
churned_subscriptions_count: 0,
|
|
2204
|
+
churn_reason_category: null,
|
|
2205
|
+
scenario: "analytics-status-segmentation-paused",
|
|
2206
|
+
}));
|
|
2207
|
+
await upsertSubscriptionMetricsDaily(analyticsModule, buildAnalyticsSnapshotRecord({
|
|
2208
|
+
subscription_id: IDS.subDunningRetryScheduled,
|
|
2209
|
+
metric_date: date,
|
|
2210
|
+
customer_id: getSeedCustomer(IDS.subDunningRetryScheduled).id,
|
|
2211
|
+
product_id: targets.success.product_id,
|
|
2212
|
+
variant_id: targets.success.variant_id,
|
|
2213
|
+
status: types_6.SubscriptionStatus.PAST_DUE,
|
|
2214
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
2215
|
+
frequency_value: 1,
|
|
2216
|
+
currency_code: null,
|
|
2217
|
+
active_subscriptions_count: 0,
|
|
2218
|
+
mrr_amount: null,
|
|
2219
|
+
churned_subscriptions_count: 0,
|
|
2220
|
+
churn_reason_category: null,
|
|
2221
|
+
scenario: "analytics-status-segmentation-past-due",
|
|
2222
|
+
}));
|
|
2223
|
+
await upsertSubscriptionMetricsDaily(analyticsModule, buildAnalyticsSnapshotRecord({
|
|
2224
|
+
subscription_id: IDS.subCancellationCanceledImmediate,
|
|
2225
|
+
metric_date: date,
|
|
2226
|
+
customer_id: getSeedCustomer(IDS.subCancellationCanceledImmediate).id,
|
|
2227
|
+
product_id: targets.blocked.product_id,
|
|
2228
|
+
variant_id: targets.blocked.variant_id,
|
|
2229
|
+
status: types_6.SubscriptionStatus.CANCELLED,
|
|
2230
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
2231
|
+
frequency_value: 1,
|
|
2232
|
+
currency_code: null,
|
|
2233
|
+
active_subscriptions_count: 0,
|
|
2234
|
+
mrr_amount: null,
|
|
2235
|
+
churned_subscriptions_count: date === "2026-04-10" ? 1 : 0,
|
|
2236
|
+
churn_reason_category: date === "2026-04-10" ? types_2.CancellationReasonCategory.BILLING : null,
|
|
2237
|
+
scenario: "analytics-churn-billing",
|
|
2238
|
+
}));
|
|
2239
|
+
await upsertSubscriptionMetricsDaily(analyticsModule, buildAnalyticsSnapshotRecord({
|
|
2240
|
+
subscription_id: IDS.subCancellationCanceledEndCycle,
|
|
2241
|
+
metric_date: date,
|
|
2242
|
+
customer_id: getSeedCustomer(IDS.subCancellationCanceledEndCycle).id,
|
|
2243
|
+
product_id: targets.blocked.product_id,
|
|
2244
|
+
variant_id: targets.blocked.variant_id,
|
|
2245
|
+
status: types_6.SubscriptionStatus.CANCELLED,
|
|
2246
|
+
frequency_interval: types_6.SubscriptionFrequencyInterval.MONTH,
|
|
2247
|
+
frequency_value: 1,
|
|
2248
|
+
currency_code: null,
|
|
2249
|
+
active_subscriptions_count: 0,
|
|
2250
|
+
mrr_amount: null,
|
|
2251
|
+
churned_subscriptions_count: date === "2026-04-14" ? 1 : 0,
|
|
2252
|
+
churn_reason_category: date === "2026-04-14" ? types_2.CancellationReasonCategory.PRICE : null,
|
|
2253
|
+
scenario: "analytics-churn-price",
|
|
2254
|
+
}));
|
|
2255
|
+
}
|
|
2256
|
+
const summary = [
|
|
2257
|
+
...(shouldSeedSettings
|
|
2258
|
+
? [
|
|
2259
|
+
{
|
|
2260
|
+
scenario: "Settings global defaults",
|
|
2261
|
+
subscription_reference: "GLOBAL",
|
|
2262
|
+
notes: "Use Settings > Subscription Settings to inspect a persisted singleton with trial_days=14, retry intervals [60,180,720], renewal review-by-default, and direct-cancel default.",
|
|
2263
|
+
},
|
|
2264
|
+
]
|
|
2265
|
+
: []),
|
|
2266
|
+
{
|
|
2267
|
+
scenario: "Renewal success without approval",
|
|
2268
|
+
subscription_reference: "SUB-QA-REN-SUCCESS",
|
|
2269
|
+
renewal_cycle_id: IDS.cycleSuccess,
|
|
2270
|
+
notes: "Active subscription with skip_next_cycle=true and a seeded linked order. Use Force renewal for a clean success path.",
|
|
2271
|
+
},
|
|
2272
|
+
{
|
|
2273
|
+
scenario: "Paused subscription block",
|
|
2274
|
+
subscription_reference: "SUB-QA-REN-PAUSED",
|
|
2275
|
+
renewal_cycle_id: IDS.cyclePaused,
|
|
2276
|
+
notes: "Use to verify that renewal respects paused subscription state.",
|
|
2277
|
+
},
|
|
2278
|
+
{
|
|
2279
|
+
scenario: "Cancel effective block",
|
|
2280
|
+
subscription_reference: "SUB-QA-REN-CANCEL-EFFECTIVE",
|
|
2281
|
+
renewal_cycle_id: IDS.cycleCancelEffective,
|
|
2282
|
+
notes: "Use to verify that renewal is blocked when cancel_effective_at is already in effect.",
|
|
2283
|
+
},
|
|
2284
|
+
{
|
|
2285
|
+
scenario: "Approval pending",
|
|
2286
|
+
subscription_reference: "SUB-QA-REN-APPROVAL-PENDING",
|
|
2287
|
+
renewal_cycle_id: IDS.cycleApprovalPending,
|
|
2288
|
+
notes: "Use Approve changes or Reject changes from Admin detail. Approved path should later succeed on Force renewal.",
|
|
2289
|
+
},
|
|
2290
|
+
{
|
|
2291
|
+
scenario: "Offer policy blocked after approval",
|
|
2292
|
+
subscription_reference: "SUB-QA-REN-POLICY-BLOCKED",
|
|
2293
|
+
renewal_cycle_id: IDS.cyclePolicyBlocked,
|
|
2294
|
+
notes: "Approve changes first, then Force renewal. Execution should be blocked by active plan-offer policy.",
|
|
2295
|
+
},
|
|
2296
|
+
{
|
|
2297
|
+
scenario: "Failed history / retry view",
|
|
2298
|
+
subscription_reference: "SUB-QA-REN-FAILED-HISTORY",
|
|
2299
|
+
renewal_cycle_id: IDS.cycleFailedHistory,
|
|
2300
|
+
notes: "Use to inspect failed attempt history and failed cycle UI states.",
|
|
2301
|
+
},
|
|
2302
|
+
{
|
|
2303
|
+
scenario: "Dunning retry scheduled queue item",
|
|
2304
|
+
subscription_reference: "SUB-QA-DUN-RETRY-SCHEDULED",
|
|
2305
|
+
renewal_cycle_id: IDS.cycleDunningRetryScheduled,
|
|
2306
|
+
dunning_case_id: IDS.dunningRetryScheduled,
|
|
2307
|
+
notes: "Use on Subscriptions > Dunning for queue filters, due retry visibility, and Retry now.",
|
|
2308
|
+
},
|
|
2309
|
+
{
|
|
2310
|
+
scenario: "Dunning awaiting manual resolution",
|
|
2311
|
+
subscription_reference: "SUB-QA-DUN-AWAITING-MANUAL",
|
|
2312
|
+
renewal_cycle_id: IDS.cycleDunningAwaitingManual,
|
|
2313
|
+
dunning_case_id: IDS.dunningAwaitingManual,
|
|
2314
|
+
notes: "Use on detail page to review failed timeline and test Mark recovered / Mark unrecovered.",
|
|
2315
|
+
},
|
|
2316
|
+
{
|
|
2317
|
+
scenario: "Dunning recovered history",
|
|
2318
|
+
subscription_reference: "SUB-QA-DUN-RECOVERED",
|
|
2319
|
+
renewal_cycle_id: IDS.cycleDunningRecovered,
|
|
2320
|
+
dunning_case_id: IDS.dunningRecovered,
|
|
2321
|
+
notes: "Use to inspect a completed recovery with failed + successful attempts in the timeline.",
|
|
2322
|
+
},
|
|
2323
|
+
{
|
|
2324
|
+
scenario: "Dunning unrecovered history",
|
|
2325
|
+
subscription_reference: "SUB-QA-DUN-UNRECOVERED",
|
|
2326
|
+
renewal_cycle_id: IDS.cycleDunningUnrecovered,
|
|
2327
|
+
dunning_case_id: IDS.dunningUnrecovered,
|
|
2328
|
+
notes: "Use to inspect max-attempt exhaustion, terminal unrecovered state, and filters by provider/error code.",
|
|
2329
|
+
},
|
|
2330
|
+
{
|
|
2331
|
+
scenario: "Dunning manual schedule override",
|
|
2332
|
+
subscription_reference: "SUB-QA-DUN-MANUAL-OVERRIDE",
|
|
2333
|
+
renewal_cycle_id: IDS.cycleDunningManualOverride,
|
|
2334
|
+
dunning_case_id: IDS.dunningManualOverride,
|
|
2335
|
+
notes: "Use to inspect a case with manual_override retry schedule and test the retry schedule drawer.",
|
|
2336
|
+
},
|
|
2337
|
+
{
|
|
2338
|
+
scenario: "Cancellation open case with linked dunning",
|
|
2339
|
+
subscription_reference: "SUB-QA-CAN-OPEN-BILLING",
|
|
2340
|
+
renewal_cycle_id: IDS.cycleCancellationOpenBilling,
|
|
2341
|
+
dunning_case_id: IDS.dunningCancellationOpenBilling,
|
|
2342
|
+
cancellation_case_id: IDS.cancellationOpenBilling,
|
|
2343
|
+
notes: "Use on Subscriptions > Cancellation & Retention to inspect an active case with billing reason, linked dunning summary, and pause-oriented recommendation.",
|
|
2344
|
+
},
|
|
2345
|
+
{
|
|
2346
|
+
scenario: "Cancellation retained after discount offer",
|
|
2347
|
+
subscription_reference: "SUB-QA-CAN-RETAINED-DISCOUNT",
|
|
2348
|
+
renewal_cycle_id: IDS.cycleCancellationRetainedDiscount,
|
|
2349
|
+
cancellation_case_id: IDS.cancellationRetainedDiscount,
|
|
2350
|
+
notes: "Use to validate retained detail, offer history, final timeline, and filters by outcome and discount offer type.",
|
|
2351
|
+
},
|
|
2352
|
+
{
|
|
2353
|
+
scenario: "Cancellation paused after pause offer",
|
|
2354
|
+
subscription_reference: "SUB-QA-CAN-PAUSED",
|
|
2355
|
+
renewal_cycle_id: IDS.cycleCancellationPaused,
|
|
2356
|
+
cancellation_case_id: IDS.cancellationPaused,
|
|
2357
|
+
notes: "Use to validate pause as a retention outcome and compare subscription paused state with case final outcome.",
|
|
2358
|
+
},
|
|
2359
|
+
{
|
|
2360
|
+
scenario: "Cancellation finalized immediately",
|
|
2361
|
+
subscription_reference: "SUB-QA-CAN-CANCELED-IMMEDIATE",
|
|
2362
|
+
renewal_cycle_id: IDS.cycleCancellationCanceledImmediate,
|
|
2363
|
+
cancellation_case_id: IDS.cancellationCanceledImmediate,
|
|
2364
|
+
notes: "Use to inspect immediate final cancel, cancel_effective_at, and cleared renewal eligibility semantics.",
|
|
2365
|
+
},
|
|
2366
|
+
{
|
|
2367
|
+
scenario: "Cancellation finalized at end of cycle",
|
|
2368
|
+
subscription_reference: "SUB-QA-CAN-CANCELED-END-CYCLE",
|
|
2369
|
+
renewal_cycle_id: IDS.cycleCancellationCanceledEndCycle,
|
|
2370
|
+
cancellation_case_id: IDS.cancellationCanceledEndCycle,
|
|
2371
|
+
notes: "Use to compare end-of-cycle final cancel against immediate cancel on the detail page.",
|
|
2372
|
+
},
|
|
2373
|
+
{
|
|
2374
|
+
scenario: "Cancellation open case with price reason",
|
|
2375
|
+
subscription_reference: "SUB-QA-CAN-OPEN-PRICE",
|
|
2376
|
+
renewal_cycle_id: IDS.cycleCancellationOpenPrice,
|
|
2377
|
+
cancellation_case_id: IDS.cancellationOpenPrice,
|
|
2378
|
+
notes: "Use to validate an open price-driven cancellation case before any retention action is applied.",
|
|
2379
|
+
},
|
|
2380
|
+
{
|
|
2381
|
+
scenario: "Cancellation open case for paused subscription",
|
|
2382
|
+
subscription_reference: "SUB-QA-CAN-OPEN-PAUSED-SUB",
|
|
2383
|
+
renewal_cycle_id: IDS.cycleCancellationOpenPaused,
|
|
2384
|
+
cancellation_case_id: IDS.cancellationOpenPaused,
|
|
2385
|
+
notes: "Use to validate cancellation detail and decision-making when the subscription is already paused.",
|
|
2386
|
+
},
|
|
2387
|
+
{
|
|
2388
|
+
scenario: "Activity Log: admin subscription pause",
|
|
2389
|
+
subscription_reference: "SUB-QA-REN-PAUSED",
|
|
2390
|
+
notes: "Use on global Activity Log and subscription timeline to verify a user-triggered subscription event with before/after state.",
|
|
2391
|
+
},
|
|
2392
|
+
{
|
|
2393
|
+
scenario: "Activity Log: scheduler renewal success",
|
|
2394
|
+
subscription_reference: "SUB-QA-REN-SUCCESS",
|
|
2395
|
+
renewal_cycle_id: IDS.cycleSuccess,
|
|
2396
|
+
notes: "Use to verify scheduler actor rendering and a compact renewal success payload in list, detail, and timeline.",
|
|
2397
|
+
},
|
|
2398
|
+
{
|
|
2399
|
+
scenario: "Activity Log: system dunning recovery",
|
|
2400
|
+
subscription_reference: "SUB-QA-DUN-RECOVERED",
|
|
2401
|
+
renewal_cycle_id: IDS.cycleDunningRecovered,
|
|
2402
|
+
dunning_case_id: IDS.dunningRecovered,
|
|
2403
|
+
notes: "Use to verify system-originated actor rendering and cross-domain dunning recovery context in the Activity Log.",
|
|
2404
|
+
},
|
|
2405
|
+
{
|
|
2406
|
+
scenario: "Analytics overview baseline",
|
|
2407
|
+
subscription_reference: "SUB-QA-REN-SUCCESS",
|
|
2408
|
+
notes: "Use on Subscriptions > Analytics for 2026-04-06..2026-04-15. Baseline active monthly MRR plus one intentional spike on 2026-04-12.",
|
|
2409
|
+
},
|
|
2410
|
+
{
|
|
2411
|
+
scenario: "Analytics frequency comparison",
|
|
2412
|
+
subscription_reference: "SUB-QA-ANL-BI-MONTHLY",
|
|
2413
|
+
notes: "Use frequency filter month:2 to isolate a dedicated bi-monthly active subscription with deterministic USD contribution.",
|
|
2414
|
+
},
|
|
2415
|
+
{
|
|
2416
|
+
scenario: "Analytics churn windows",
|
|
2417
|
+
subscription_reference: "SUB-QA-CAN-CANCELED-IMMEDIATE",
|
|
2418
|
+
cancellation_case_id: IDS.cancellationCanceledImmediate,
|
|
2419
|
+
notes: "Use Analytics for 2026-04-10 and 2026-04-14 to inspect churn spikes and exports with billing vs price churn days.",
|
|
2420
|
+
},
|
|
2421
|
+
];
|
|
2422
|
+
logger.info("[subscriptions-test-data] Seed completed.");
|
|
2423
|
+
logger.info(`[subscriptions-test-data] Scenario summary:\n${formatSummary(summary)}`);
|
|
2424
|
+
}
|
|
2425
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VlZC1zdWJzY3JpcHRpb25zLXRlc3QtZGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NjcmlwdHMvc2VlZC1zdWJzY3JpcHRpb25zLXRlc3QtZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQXFnQ0EsNENBMDhEQztBQTk4RkQscURBQThFO0FBQzlFLDhEQUFpRTtBQUVqRSx3REFBMkQ7QUFDM0Qsa0VBQThFO0FBRTlFLDZEQUcwQztBQUMxQyw4REFBaUU7QUFFakUsNkRBTTBDO0FBQzFDLG9EQUF1RDtBQUV2RCx3REFJcUM7QUFDckMsMERBQTZEO0FBRTdELDJEQUl3QztBQUN4QyxvREFBdUQ7QUFFdkQsd0RBSXFDO0FBQ3JDLDhEQUFpRTtBQUVqRSw2REFHMEM7QUFDMUMsc0RBQXlEO0FBRXpELHlEQUdzQztBQXNHdEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQTtBQUV2RCxNQUFNLEdBQUcsR0FBRztJQUNWLGdCQUFnQixFQUFFLCtCQUErQjtJQUNqRCxnQkFBZ0IsRUFBRSwrQkFBK0I7SUFDakQsVUFBVSxFQUFFLGdDQUFnQztJQUM1QyxTQUFTLEVBQUUsK0JBQStCO0lBQzFDLGtCQUFrQixFQUFFLHlDQUF5QztJQUM3RCxrQkFBa0IsRUFBRSx5Q0FBeUM7SUFDN0QsZ0JBQWdCLEVBQUUsdUNBQXVDO0lBQ3pELGdCQUFnQixFQUFFLHVDQUF1QztJQUN6RCx3QkFBd0IsRUFBRSxrQ0FBa0M7SUFDNUQsd0JBQXdCLEVBQUUsa0NBQWtDO0lBQzVELG1CQUFtQixFQUFFLDRCQUE0QjtJQUNqRCxxQkFBcUIsRUFBRSw4QkFBOEI7SUFDckQsd0JBQXdCLEVBQUUsa0NBQWtDO0lBQzVELDBCQUEwQixFQUFFLG9DQUFvQztJQUNoRSwrQkFBK0IsRUFBRSx5Q0FBeUM7SUFDMUUscUJBQXFCLEVBQUUsOEJBQThCO0lBQ3JELGdDQUFnQyxFQUFFLDBDQUEwQztJQUM1RSwrQkFB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
|