@windrun-huaiin/backend-core 30.0.0 → 31.0.1
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/README.md +95 -0
- package/dist/app/api/user/anonymous/init/fingerprint-only-route.d.ts +8 -0
- package/dist/app/api/user/anonymous/init/fingerprint-only-route.d.ts.map +1 -0
- package/dist/app/api/user/anonymous/init/fingerprint-only-route.js +20 -0
- package/dist/app/api/user/anonymous/init/fingerprint-only-route.mjs +18 -0
- package/dist/app/api/user/anonymous/init/route-shared.d.ts +10 -0
- package/dist/app/api/user/anonymous/init/route-shared.d.ts.map +1 -0
- package/dist/app/api/user/anonymous/init/route-shared.js +557 -0
- package/dist/app/api/user/anonymous/init/route-shared.mjs +555 -0
- package/dist/app/api/user/anonymous/init/route.d.ts +3 -3
- package/dist/app/api/user/anonymous/init/route.d.ts.map +1 -1
- package/dist/app/api/user/anonymous/init/route.js +6 -554
- package/dist/app/api/user/anonymous/init/route.mjs +7 -555
- package/dist/app/api/webhook/clerk/user/route.js +16 -16
- package/dist/app/api/webhook/clerk/user/route.mjs +16 -16
- package/dist/auth/auth-utils.d.ts +8 -23
- package/dist/auth/auth-utils.d.ts.map +1 -1
- package/dist/auth/auth-utils.js +8 -20
- package/dist/auth/auth-utils.mjs +8 -20
- package/dist/lib/money-price-config.d.ts +28 -28
- package/dist/lib/money-price-config.js +31 -31
- package/dist/lib/money-price-config.mjs +31 -31
- package/dist/lib/stripe-config.js +3 -3
- package/dist/lib/stripe-config.mjs +3 -3
- package/dist/prisma/prisma-transaction-util.js +1 -1
- package/dist/prisma/prisma-transaction-util.mjs +1 -1
- package/dist/prisma/prisma.d.ts.map +1 -1
- package/dist/prisma/prisma.js +18 -19
- package/dist/prisma/prisma.mjs +18 -19
- package/dist/services/aggregate/billing.aggregate.service.js +6 -6
- package/dist/services/aggregate/billing.aggregate.service.mjs +6 -6
- package/dist/services/aggregate/user.aggregate.service.d.ts +9 -9
- package/dist/services/aggregate/user.aggregate.service.js +16 -16
- package/dist/services/aggregate/user.aggregate.service.mjs +16 -16
- package/dist/services/database/constants.js +34 -34
- package/dist/services/database/constants.mjs +34 -34
- package/dist/services/database/credit.service.js +2 -2
- package/dist/services/database/credit.service.mjs +2 -2
- package/dist/services/database/transaction.service.js +1 -1
- package/dist/services/database/transaction.service.mjs +1 -1
- package/dist/services/database/user.service.js +2 -2
- package/dist/services/database/user.service.mjs +2 -2
- package/dist/services/stripe/webhook-handler.js +5 -5
- package/dist/services/stripe/webhook-handler.mjs +5 -5
- package/package.json +18 -6
- package/src/app/api/user/anonymous/init/fingerprint-only-route.ts +14 -0
- package/src/app/api/user/anonymous/init/route-shared.ts +710 -0
- package/src/app/api/user/anonymous/init/route.ts +7 -712
- package/src/app/api/webhook/clerk/user/route.ts +17 -17
- package/src/auth/auth-utils.ts +8 -23
- package/src/lib/money-price-config.ts +31 -32
- package/src/lib/stripe-config.ts +3 -3
- package/src/prisma/prisma-transaction-util.ts +1 -1
- package/src/prisma/prisma.ts +18 -19
- package/src/services/aggregate/billing.aggregate.service.ts +7 -7
- package/src/services/aggregate/user.aggregate.service.ts +16 -16
- package/src/services/database/constants.ts +34 -34
- package/src/services/database/credit.service.ts +2 -2
- package/src/services/database/transaction.service.ts +1 -1
- package/src/services/database/user.service.ts +2 -2
- package/src/services/stripe/webhook-handler.ts +5 -5
|
@@ -3,91 +3,91 @@
|
|
|
3
3
|
// Database Field Enums
|
|
4
4
|
// Keep in sync with DB CHECK constraints
|
|
5
5
|
const UserStatus = {
|
|
6
|
-
//
|
|
6
|
+
// Anonymous user
|
|
7
7
|
ANONYMOUS: 'anonymous',
|
|
8
|
-
//
|
|
8
|
+
// Registered user
|
|
9
9
|
REGISTERED: 'registered',
|
|
10
|
-
//
|
|
10
|
+
// Frozen by admin intervention
|
|
11
11
|
FROZEN: 'frozen',
|
|
12
|
-
//
|
|
12
|
+
// Soft-deleted user data that must not be reused
|
|
13
13
|
DELETED: 'deleted',
|
|
14
14
|
};
|
|
15
15
|
const SubscriptionStatus = {
|
|
16
|
-
//
|
|
16
|
+
// Initial or post-cancellation state
|
|
17
17
|
INCOMPLETE: 'incomplete',
|
|
18
|
-
//
|
|
18
|
+
// Trial subscription period
|
|
19
19
|
TRIALING: 'trialing',
|
|
20
|
-
//
|
|
20
|
+
// Active subscription
|
|
21
21
|
ACTIVE: 'active',
|
|
22
|
-
//
|
|
22
|
+
// Past-due subscription
|
|
23
23
|
PAST_DUE: 'past_due',
|
|
24
|
-
//
|
|
24
|
+
// Canceled subscription
|
|
25
25
|
CANCELED: 'canceled',
|
|
26
26
|
};
|
|
27
27
|
const OrderStatus = {
|
|
28
|
-
//
|
|
28
|
+
// Initial state
|
|
29
29
|
CREATED: 'created',
|
|
30
|
-
//
|
|
30
|
+
// Intermediate state, awaiting payment; may be triggered by a payment failure event
|
|
31
31
|
PENDING_UNPAID: 'pending_unpaid',
|
|
32
|
-
//
|
|
32
|
+
// Intermediate or final state; payment succeeded and may later become refunded or canceled
|
|
33
33
|
SUCCESS: 'success',
|
|
34
|
-
//
|
|
34
|
+
// Intermediate or final state; checkout or payment failed and may later become refunded or canceled
|
|
35
35
|
FAILED: 'failed',
|
|
36
|
-
//
|
|
36
|
+
// Final state, refunded
|
|
37
37
|
REFUNDED: 'refunded',
|
|
38
|
-
//
|
|
38
|
+
// Final state, canceled
|
|
39
39
|
CANCELED: 'canceled',
|
|
40
40
|
};
|
|
41
41
|
const TransactionType = {
|
|
42
|
-
//
|
|
42
|
+
// Subscription order
|
|
43
43
|
SUBSCRIPTION: 'subscription',
|
|
44
|
-
//
|
|
44
|
+
// One-time payment order
|
|
45
45
|
ONE_TIME: 'one_time',
|
|
46
46
|
};
|
|
47
47
|
const CreditType = {
|
|
48
|
-
//
|
|
48
|
+
// Subscription credits
|
|
49
49
|
PAID: 'paid',
|
|
50
|
-
//
|
|
50
|
+
// One-time paid credits
|
|
51
51
|
ONE_TIME_PAID: 'one_time_paid',
|
|
52
|
-
//
|
|
52
|
+
// Free credits
|
|
53
53
|
FREE: 'free',
|
|
54
54
|
};
|
|
55
55
|
const OperationType = {
|
|
56
|
-
//
|
|
56
|
+
// System-granted credits
|
|
57
57
|
SYS_GIFT: 'system_gift',
|
|
58
|
-
//
|
|
58
|
+
// User credit consumption
|
|
59
59
|
CONSUME: 'consume',
|
|
60
|
-
//
|
|
60
|
+
// User credit recharge
|
|
61
61
|
RECHARGE: 'recharge',
|
|
62
|
-
//
|
|
62
|
+
// Admin credit freeze
|
|
63
63
|
FREEZE: 'freeze',
|
|
64
|
-
//
|
|
64
|
+
// Admin credit unfreeze
|
|
65
65
|
UNFREEZE: 'unfreeze',
|
|
66
|
-
//
|
|
66
|
+
// Admin credit increase
|
|
67
67
|
ADJUST_INCREASE: 'adjust_increase',
|
|
68
|
-
//
|
|
68
|
+
// Admin credit decrease
|
|
69
69
|
ADJUST_DECREASE: 'adjust_decrease',
|
|
70
|
-
//
|
|
70
|
+
// Credit purge triggered by an event or expiration
|
|
71
71
|
PURGE: 'purge',
|
|
72
72
|
};
|
|
73
|
-
//
|
|
73
|
+
// Payment provider types
|
|
74
74
|
const PaySupplier = {
|
|
75
75
|
STRIPE: 'Stripe',
|
|
76
76
|
APPLE: 'Apple',
|
|
77
77
|
PAYPAL: 'Paypal',
|
|
78
78
|
};
|
|
79
79
|
const BillingReason = {
|
|
80
|
-
//
|
|
80
|
+
// Initial subscription
|
|
81
81
|
SUBSCRIPTION_CREATE: 'subscription_create',
|
|
82
|
-
//
|
|
82
|
+
// Subscription renewal
|
|
83
83
|
SUBSCRIPTION_CYCLE: 'subscription_cycle',
|
|
84
84
|
};
|
|
85
85
|
const PaymentStatus = {
|
|
86
|
-
//
|
|
86
|
+
// Paid
|
|
87
87
|
PAID: 'paid',
|
|
88
|
-
//
|
|
88
|
+
// Pending payment
|
|
89
89
|
UN_PAID: 'un_paid',
|
|
90
|
-
//
|
|
90
|
+
// No payment required
|
|
91
91
|
NO_PAYMENT_REQUIRED: 'no_payment_required',
|
|
92
92
|
};
|
|
93
93
|
// Validation Functions
|
|
@@ -1,91 +1,91 @@
|
|
|
1
1
|
// Database Field Enums
|
|
2
2
|
// Keep in sync with DB CHECK constraints
|
|
3
3
|
const UserStatus = {
|
|
4
|
-
//
|
|
4
|
+
// Anonymous user
|
|
5
5
|
ANONYMOUS: 'anonymous',
|
|
6
|
-
//
|
|
6
|
+
// Registered user
|
|
7
7
|
REGISTERED: 'registered',
|
|
8
|
-
//
|
|
8
|
+
// Frozen by admin intervention
|
|
9
9
|
FROZEN: 'frozen',
|
|
10
|
-
//
|
|
10
|
+
// Soft-deleted user data that must not be reused
|
|
11
11
|
DELETED: 'deleted',
|
|
12
12
|
};
|
|
13
13
|
const SubscriptionStatus = {
|
|
14
|
-
//
|
|
14
|
+
// Initial or post-cancellation state
|
|
15
15
|
INCOMPLETE: 'incomplete',
|
|
16
|
-
//
|
|
16
|
+
// Trial subscription period
|
|
17
17
|
TRIALING: 'trialing',
|
|
18
|
-
//
|
|
18
|
+
// Active subscription
|
|
19
19
|
ACTIVE: 'active',
|
|
20
|
-
//
|
|
20
|
+
// Past-due subscription
|
|
21
21
|
PAST_DUE: 'past_due',
|
|
22
|
-
//
|
|
22
|
+
// Canceled subscription
|
|
23
23
|
CANCELED: 'canceled',
|
|
24
24
|
};
|
|
25
25
|
const OrderStatus = {
|
|
26
|
-
//
|
|
26
|
+
// Initial state
|
|
27
27
|
CREATED: 'created',
|
|
28
|
-
//
|
|
28
|
+
// Intermediate state, awaiting payment; may be triggered by a payment failure event
|
|
29
29
|
PENDING_UNPAID: 'pending_unpaid',
|
|
30
|
-
//
|
|
30
|
+
// Intermediate or final state; payment succeeded and may later become refunded or canceled
|
|
31
31
|
SUCCESS: 'success',
|
|
32
|
-
//
|
|
32
|
+
// Intermediate or final state; checkout or payment failed and may later become refunded or canceled
|
|
33
33
|
FAILED: 'failed',
|
|
34
|
-
//
|
|
34
|
+
// Final state, refunded
|
|
35
35
|
REFUNDED: 'refunded',
|
|
36
|
-
//
|
|
36
|
+
// Final state, canceled
|
|
37
37
|
CANCELED: 'canceled',
|
|
38
38
|
};
|
|
39
39
|
const TransactionType = {
|
|
40
|
-
//
|
|
40
|
+
// Subscription order
|
|
41
41
|
SUBSCRIPTION: 'subscription',
|
|
42
|
-
//
|
|
42
|
+
// One-time payment order
|
|
43
43
|
ONE_TIME: 'one_time',
|
|
44
44
|
};
|
|
45
45
|
const CreditType = {
|
|
46
|
-
//
|
|
46
|
+
// Subscription credits
|
|
47
47
|
PAID: 'paid',
|
|
48
|
-
//
|
|
48
|
+
// One-time paid credits
|
|
49
49
|
ONE_TIME_PAID: 'one_time_paid',
|
|
50
|
-
//
|
|
50
|
+
// Free credits
|
|
51
51
|
FREE: 'free',
|
|
52
52
|
};
|
|
53
53
|
const OperationType = {
|
|
54
|
-
//
|
|
54
|
+
// System-granted credits
|
|
55
55
|
SYS_GIFT: 'system_gift',
|
|
56
|
-
//
|
|
56
|
+
// User credit consumption
|
|
57
57
|
CONSUME: 'consume',
|
|
58
|
-
//
|
|
58
|
+
// User credit recharge
|
|
59
59
|
RECHARGE: 'recharge',
|
|
60
|
-
//
|
|
60
|
+
// Admin credit freeze
|
|
61
61
|
FREEZE: 'freeze',
|
|
62
|
-
//
|
|
62
|
+
// Admin credit unfreeze
|
|
63
63
|
UNFREEZE: 'unfreeze',
|
|
64
|
-
//
|
|
64
|
+
// Admin credit increase
|
|
65
65
|
ADJUST_INCREASE: 'adjust_increase',
|
|
66
|
-
//
|
|
66
|
+
// Admin credit decrease
|
|
67
67
|
ADJUST_DECREASE: 'adjust_decrease',
|
|
68
|
-
//
|
|
68
|
+
// Credit purge triggered by an event or expiration
|
|
69
69
|
PURGE: 'purge',
|
|
70
70
|
};
|
|
71
|
-
//
|
|
71
|
+
// Payment provider types
|
|
72
72
|
const PaySupplier = {
|
|
73
73
|
STRIPE: 'Stripe',
|
|
74
74
|
APPLE: 'Apple',
|
|
75
75
|
PAYPAL: 'Paypal',
|
|
76
76
|
};
|
|
77
77
|
const BillingReason = {
|
|
78
|
-
//
|
|
78
|
+
// Initial subscription
|
|
79
79
|
SUBSCRIPTION_CREATE: 'subscription_create',
|
|
80
|
-
//
|
|
80
|
+
// Subscription renewal
|
|
81
81
|
SUBSCRIPTION_CYCLE: 'subscription_cycle',
|
|
82
82
|
};
|
|
83
83
|
const PaymentStatus = {
|
|
84
|
-
//
|
|
84
|
+
// Paid
|
|
85
85
|
PAID: 'paid',
|
|
86
|
-
//
|
|
86
|
+
// Pending payment
|
|
87
87
|
UN_PAID: 'un_paid',
|
|
88
|
-
//
|
|
88
|
+
// No payment required
|
|
89
89
|
NO_PAYMENT_REQUIRED: 'no_payment_required',
|
|
90
90
|
};
|
|
91
91
|
// Validation Functions
|
|
@@ -208,7 +208,7 @@ class CreditService {
|
|
|
208
208
|
const normalized = this.normalizeAmounts({ free: init.creditsChange });
|
|
209
209
|
this.ensureNonNegative(normalized, 'initializeCredit');
|
|
210
210
|
const client = prisma.checkAndFallbackWithNonTCClient(tx);
|
|
211
|
-
//
|
|
211
|
+
// Use upsert semantics to share initialization logic for anonymous users and anonymous-to-registered upgrades.
|
|
212
212
|
const credit = yield client.credit.upsert({
|
|
213
213
|
where: {
|
|
214
214
|
userId: init.userId
|
|
@@ -430,7 +430,7 @@ class CreditService {
|
|
|
430
430
|
where: { userId },
|
|
431
431
|
data: updateData,
|
|
432
432
|
});
|
|
433
|
-
//
|
|
433
|
+
// Always write an audit entry, even when the credit change is zero.
|
|
434
434
|
const usage = yield this.recordCreditAuditLog(client, userId, constants.OperationType.PURGE, normalizedDeduction, { feature: reason, operationReferId });
|
|
435
435
|
return { credit, usage };
|
|
436
436
|
});
|
|
@@ -206,7 +206,7 @@ class CreditService {
|
|
|
206
206
|
const normalized = this.normalizeAmounts({ free: init.creditsChange });
|
|
207
207
|
this.ensureNonNegative(normalized, 'initializeCredit');
|
|
208
208
|
const client = checkAndFallbackWithNonTCClient(tx);
|
|
209
|
-
//
|
|
209
|
+
// Use upsert semantics to share initialization logic for anonymous users and anonymous-to-registered upgrades.
|
|
210
210
|
const credit = yield client.credit.upsert({
|
|
211
211
|
where: {
|
|
212
212
|
userId: init.userId
|
|
@@ -428,7 +428,7 @@ class CreditService {
|
|
|
428
428
|
where: { userId },
|
|
429
429
|
data: updateData,
|
|
430
430
|
});
|
|
431
|
-
//
|
|
431
|
+
// Always write an audit entry, even when the credit change is zero.
|
|
432
432
|
const usage = yield this.recordCreditAuditLog(client, userId, OperationType.PURGE, normalizedDeduction, { feature: reason, operationReferId });
|
|
433
433
|
return { credit, usage };
|
|
434
434
|
});
|
|
@@ -16,7 +16,7 @@ class TransactionService {
|
|
|
16
16
|
orderId: data.orderId,
|
|
17
17
|
orderStatus: data.orderStatus || constants.OrderStatus.CREATED,
|
|
18
18
|
paymentStatus: data.paymentStatus || constants.PaymentStatus.UN_PAID,
|
|
19
|
-
orderExpiredAt: data.orderExpiredAt || new Date(Date.now() + 30 * 60 * 1000), //
|
|
19
|
+
orderExpiredAt: data.orderExpiredAt || new Date(Date.now() + 30 * 60 * 1000), // Default expiration: 30 minutes
|
|
20
20
|
paySupplier: data.paySupplier,
|
|
21
21
|
payTransactionId: data.payTransactionId,
|
|
22
22
|
paySubscriptionId: data.paySubscriptionId,
|
|
@@ -14,7 +14,7 @@ class TransactionService {
|
|
|
14
14
|
orderId: data.orderId,
|
|
15
15
|
orderStatus: data.orderStatus || OrderStatus.CREATED,
|
|
16
16
|
paymentStatus: data.paymentStatus || PaymentStatus.UN_PAID,
|
|
17
|
-
orderExpiredAt: data.orderExpiredAt || new Date(Date.now() + 30 * 60 * 1000), //
|
|
17
|
+
orderExpiredAt: data.orderExpiredAt || new Date(Date.now() + 30 * 60 * 1000), // Default expiration: 30 minutes
|
|
18
18
|
paySupplier: data.paySupplier,
|
|
19
19
|
payTransactionId: data.payTransactionId,
|
|
20
20
|
paySubscriptionId: data.paySubscriptionId,
|
|
@@ -63,7 +63,7 @@ class UserService {
|
|
|
63
63
|
findByClerkUserId(clerkUserId, tx) {
|
|
64
64
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
65
65
|
const client = prisma.checkAndFallbackWithNonTCClient(tx);
|
|
66
|
-
// DB
|
|
66
|
+
// Partial DB indexes match this status filter, so findUnique is valid here.
|
|
67
67
|
return yield client.user.findUnique({
|
|
68
68
|
where: {
|
|
69
69
|
clerkUserId,
|
|
@@ -137,7 +137,7 @@ class UserService {
|
|
|
137
137
|
return { users, total };
|
|
138
138
|
});
|
|
139
139
|
}
|
|
140
|
-
//
|
|
140
|
+
// Create anonymous users in bulk
|
|
141
141
|
createBatchAnonymousUsers(fingerprintIds, tx) {
|
|
142
142
|
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
143
143
|
const client = prisma.checkAndFallbackWithNonTCClient(tx);
|
|
@@ -61,7 +61,7 @@ class UserService {
|
|
|
61
61
|
findByClerkUserId(clerkUserId, tx) {
|
|
62
62
|
return __awaiter(this, void 0, void 0, function* () {
|
|
63
63
|
const client = checkAndFallbackWithNonTCClient(tx);
|
|
64
|
-
// DB
|
|
64
|
+
// Partial DB indexes match this status filter, so findUnique is valid here.
|
|
65
65
|
return yield client.user.findUnique({
|
|
66
66
|
where: {
|
|
67
67
|
clerkUserId,
|
|
@@ -135,7 +135,7 @@ class UserService {
|
|
|
135
135
|
return { users, total };
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
|
-
//
|
|
138
|
+
// Create anonymous users in bulk
|
|
139
139
|
createBatchAnonymousUsers(fingerprintIds, tx) {
|
|
140
140
|
return __awaiter(this, void 0, void 0, function* () {
|
|
141
141
|
const client = checkAndFallbackWithNonTCClient(tx);
|
|
@@ -236,7 +236,7 @@ function handleInvoicePaid(invoice) {
|
|
|
236
236
|
periodEnd: utils.viewLocalTime(subPeriodEnd),
|
|
237
237
|
});
|
|
238
238
|
if (isInitialPayment) {
|
|
239
|
-
//
|
|
239
|
+
// check
|
|
240
240
|
const nonActiveSubscription = yield subscription_service.subscriptionService.getNonActiveSubscription(userId);
|
|
241
241
|
if (!nonActiveSubscription) {
|
|
242
242
|
throw new Error(`Subscription status is ACTIVE for user ${userId}, forbidden to re-active!`);
|
|
@@ -263,7 +263,7 @@ function handleInvoicePaid(invoice) {
|
|
|
263
263
|
return;
|
|
264
264
|
}
|
|
265
265
|
if (isRenewal) {
|
|
266
|
-
//
|
|
266
|
+
// must query it's subscription db record
|
|
267
267
|
const subscription = yield subscription_service.subscriptionService.findByPaySubscriptionId(subscriptionId);
|
|
268
268
|
if (!subscription) {
|
|
269
269
|
throw new Error(`Subscription not found for renewal: ${subscriptionId}`);
|
|
@@ -274,8 +274,8 @@ function handleInvoicePaid(invoice) {
|
|
|
274
274
|
throw new Error(`Renewal invoice ${invoice.id} already processed as ${existingOrder.orderId}, skipping.`);
|
|
275
275
|
}
|
|
276
276
|
// Get credits from current price configuration (handles plan upgrades/downgrades)
|
|
277
|
-
//
|
|
278
|
-
//
|
|
277
|
+
// Prefer values from configuration; fall back to the previous cycle value if unavailable. Manual remediation will be applied later if issues occur, prioritizing functional availability
|
|
278
|
+
// No error occurs here as long as the configuration is correct!
|
|
279
279
|
const creditsForRenewal = subscription.priceId
|
|
280
280
|
? moneyPriceConfig.getCreditsFromPriceId(subscription.priceId)
|
|
281
281
|
: subscription.creditsAllocated;
|
|
@@ -386,7 +386,7 @@ function handleInvoicePaymentFailed(invoice) {
|
|
|
386
386
|
}
|
|
387
387
|
const subscriptionId = parentDetails.subscription;
|
|
388
388
|
const subscriptionMetadata = parentDetails.metadata || {};
|
|
389
|
-
//
|
|
389
|
+
// PaymentIntentId
|
|
390
390
|
const paymentIntentId = yield stripeConfig.fetchPaymentId(invoice.id);
|
|
391
391
|
console.log('Invoice payment failed event key-info:', {
|
|
392
392
|
invoiceId: invoice.id,
|
|
@@ -234,7 +234,7 @@ function handleInvoicePaid(invoice) {
|
|
|
234
234
|
periodEnd: viewLocalTime(subPeriodEnd),
|
|
235
235
|
});
|
|
236
236
|
if (isInitialPayment) {
|
|
237
|
-
//
|
|
237
|
+
// check
|
|
238
238
|
const nonActiveSubscription = yield subscriptionService.getNonActiveSubscription(userId);
|
|
239
239
|
if (!nonActiveSubscription) {
|
|
240
240
|
throw new Error(`Subscription status is ACTIVE for user ${userId}, forbidden to re-active!`);
|
|
@@ -261,7 +261,7 @@ function handleInvoicePaid(invoice) {
|
|
|
261
261
|
return;
|
|
262
262
|
}
|
|
263
263
|
if (isRenewal) {
|
|
264
|
-
//
|
|
264
|
+
// must query it's subscription db record
|
|
265
265
|
const subscription = yield subscriptionService.findByPaySubscriptionId(subscriptionId);
|
|
266
266
|
if (!subscription) {
|
|
267
267
|
throw new Error(`Subscription not found for renewal: ${subscriptionId}`);
|
|
@@ -272,8 +272,8 @@ function handleInvoicePaid(invoice) {
|
|
|
272
272
|
throw new Error(`Renewal invoice ${invoice.id} already processed as ${existingOrder.orderId}, skipping.`);
|
|
273
273
|
}
|
|
274
274
|
// Get credits from current price configuration (handles plan upgrades/downgrades)
|
|
275
|
-
//
|
|
276
|
-
//
|
|
275
|
+
// Prefer values from configuration; fall back to the previous cycle value if unavailable. Manual remediation will be applied later if issues occur, prioritizing functional availability
|
|
276
|
+
// No error occurs here as long as the configuration is correct!
|
|
277
277
|
const creditsForRenewal = subscription.priceId
|
|
278
278
|
? getCreditsFromPriceId(subscription.priceId)
|
|
279
279
|
: subscription.creditsAllocated;
|
|
@@ -384,7 +384,7 @@ function handleInvoicePaymentFailed(invoice) {
|
|
|
384
384
|
}
|
|
385
385
|
const subscriptionId = parentDetails.subscription;
|
|
386
386
|
const subscriptionMetadata = parentDetails.metadata || {};
|
|
387
|
-
//
|
|
387
|
+
// PaymentIntentId
|
|
388
388
|
const paymentIntentId = yield fetchPaymentId(invoice.id);
|
|
389
389
|
console.log('Invoice payment failed event key-info:', {
|
|
390
390
|
invoiceId: invoice.id,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windrun-huaiin/backend-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "31.0.1",
|
|
4
4
|
"description": "Shared backend primitives: Prisma schema/client, database services, routing helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -107,6 +107,11 @@
|
|
|
107
107
|
"import": "./dist/app/api/user/anonymous/init/route.mjs",
|
|
108
108
|
"require": "./dist/app/api/user/anonymous/init/route.js"
|
|
109
109
|
},
|
|
110
|
+
"./app/api/user/anonymous/init/fingerprint-only-route": {
|
|
111
|
+
"types": "./dist/app/api/user/anonymous/init/fingerprint-only-route.d.ts",
|
|
112
|
+
"import": "./dist/app/api/user/anonymous/init/fingerprint-only-route.mjs",
|
|
113
|
+
"require": "./dist/app/api/user/anonymous/init/fingerprint-only-route.js"
|
|
114
|
+
},
|
|
110
115
|
"./app/api/user/credit-overview/route": {
|
|
111
116
|
"types": "./dist/app/api/user/credit-overview/route.d.ts",
|
|
112
117
|
"import": "./dist/app/api/user/credit-overview/route.mjs",
|
|
@@ -139,7 +144,7 @@
|
|
|
139
144
|
"LICENSE"
|
|
140
145
|
],
|
|
141
146
|
"dependencies": {
|
|
142
|
-
"@clerk/nextjs": "^7.
|
|
147
|
+
"@clerk/nextjs": "^7.3.3",
|
|
143
148
|
"@upstash/redis": "^1.34.0",
|
|
144
149
|
"@upstash/qstash": "^2.7.0",
|
|
145
150
|
"@upstash/lock": "^0.2.1",
|
|
@@ -148,9 +153,9 @@
|
|
|
148
153
|
"svix": "^1.86.0",
|
|
149
154
|
"tslib": "^2.8.1",
|
|
150
155
|
"zod": "^4.3.6",
|
|
151
|
-
"@windrun-huaiin/
|
|
152
|
-
"@windrun-huaiin/
|
|
153
|
-
"@windrun-huaiin/
|
|
156
|
+
"@windrun-huaiin/lib": "^31.0.2",
|
|
157
|
+
"@windrun-huaiin/contracts": "^31.0.0",
|
|
158
|
+
"@windrun-huaiin/third-ui": "^31.3.1"
|
|
154
159
|
},
|
|
155
160
|
"devDependencies": {
|
|
156
161
|
"@rollup/plugin-alias": "^5.1.1",
|
|
@@ -163,7 +168,7 @@
|
|
|
163
168
|
},
|
|
164
169
|
"peerDependencies": {
|
|
165
170
|
"@windrun-huaiin/contracts": ">=22.0.0",
|
|
166
|
-
"@clerk/nextjs": "^7.
|
|
171
|
+
"@clerk/nextjs": "^7.3.3",
|
|
167
172
|
"@prisma/client": "^7.8.0",
|
|
168
173
|
"next": "16.1.6",
|
|
169
174
|
"stripe": "22.0.2",
|
|
@@ -172,6 +177,13 @@
|
|
|
172
177
|
"publishConfig": {
|
|
173
178
|
"access": "public"
|
|
174
179
|
},
|
|
180
|
+
"author": "windrun-huaiin",
|
|
181
|
+
"homepage": "https://d8ger.com",
|
|
182
|
+
"repository": {
|
|
183
|
+
"type": "git",
|
|
184
|
+
"url": "git+https://github.com/caofanCPU/next-ai-build.git",
|
|
185
|
+
"directory": "packages/backend-core"
|
|
186
|
+
},
|
|
175
187
|
"scripts": {
|
|
176
188
|
"build": "rm -rf dist && rollup -c rollup.config.mjs",
|
|
177
189
|
"build:prod": "rm -rf dist && rollup -c rollup.config.mjs",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { handleFingerprintRequest } from './route-shared';
|
|
2
|
+
import type { NextRequest } from 'next/server';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fingerprint-only anonymous user initialization API.
|
|
6
|
+
* Use this route in apps that do not install or configure Clerk.
|
|
7
|
+
* POST /api/user/anonymous/init
|
|
8
|
+
*/
|
|
9
|
+
export async function POST(request: NextRequest) {
|
|
10
|
+
return handleFingerprintRequest(request, {
|
|
11
|
+
createIfNotExists: true,
|
|
12
|
+
getAuthIdentity: async () => null,
|
|
13
|
+
});
|
|
14
|
+
}
|