@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
|
@@ -2,80 +2,80 @@
|
|
|
2
2
|
// Keep in sync with DB CHECK constraints
|
|
3
3
|
|
|
4
4
|
export const UserStatus = {
|
|
5
|
-
//
|
|
5
|
+
// Anonymous user
|
|
6
6
|
ANONYMOUS: 'anonymous',
|
|
7
|
-
//
|
|
7
|
+
// Registered user
|
|
8
8
|
REGISTERED: 'registered',
|
|
9
|
-
//
|
|
9
|
+
// Frozen by admin intervention
|
|
10
10
|
FROZEN: 'frozen',
|
|
11
|
-
//
|
|
11
|
+
// Soft-deleted user data that must not be reused
|
|
12
12
|
DELETED: 'deleted',
|
|
13
13
|
} as const;
|
|
14
14
|
|
|
15
15
|
export 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
|
} as const;
|
|
27
27
|
|
|
28
28
|
export const OrderStatus = {
|
|
29
|
-
//
|
|
29
|
+
// Initial state
|
|
30
30
|
CREATED: 'created',
|
|
31
|
-
//
|
|
31
|
+
// Intermediate state, awaiting payment; may be triggered by a payment failure event
|
|
32
32
|
PENDING_UNPAID: 'pending_unpaid',
|
|
33
|
-
//
|
|
33
|
+
// Intermediate or final state; payment succeeded and may later become refunded or canceled
|
|
34
34
|
SUCCESS: 'success',
|
|
35
|
-
//
|
|
35
|
+
// Intermediate or final state; checkout or payment failed and may later become refunded or canceled
|
|
36
36
|
FAILED: 'failed',
|
|
37
|
-
//
|
|
37
|
+
// Final state, refunded
|
|
38
38
|
REFUNDED: 'refunded',
|
|
39
|
-
//
|
|
39
|
+
// Final state, canceled
|
|
40
40
|
CANCELED: 'canceled',
|
|
41
41
|
} as const;
|
|
42
42
|
|
|
43
43
|
export const TransactionType = {
|
|
44
|
-
//
|
|
44
|
+
// Subscription order
|
|
45
45
|
SUBSCRIPTION: 'subscription',
|
|
46
|
-
//
|
|
46
|
+
// One-time payment order
|
|
47
47
|
ONE_TIME: 'one_time',
|
|
48
48
|
} as const;
|
|
49
49
|
|
|
50
50
|
export const CreditType = {
|
|
51
|
-
//
|
|
51
|
+
// Subscription credits
|
|
52
52
|
PAID: 'paid',
|
|
53
|
-
//
|
|
53
|
+
// One-time paid credits
|
|
54
54
|
ONE_TIME_PAID: 'one_time_paid',
|
|
55
|
-
//
|
|
55
|
+
// Free credits
|
|
56
56
|
FREE: 'free',
|
|
57
57
|
} as const;
|
|
58
58
|
|
|
59
59
|
export const OperationType = {
|
|
60
|
-
//
|
|
60
|
+
// System-granted credits
|
|
61
61
|
SYS_GIFT: 'system_gift',
|
|
62
|
-
//
|
|
62
|
+
// User credit consumption
|
|
63
63
|
CONSUME: 'consume',
|
|
64
|
-
//
|
|
64
|
+
// User credit recharge
|
|
65
65
|
RECHARGE: 'recharge',
|
|
66
|
-
//
|
|
66
|
+
// Admin credit freeze
|
|
67
67
|
FREEZE: 'freeze',
|
|
68
|
-
//
|
|
68
|
+
// Admin credit unfreeze
|
|
69
69
|
UNFREEZE: 'unfreeze',
|
|
70
|
-
//
|
|
70
|
+
// Admin credit increase
|
|
71
71
|
ADJUST_INCREASE: 'adjust_increase',
|
|
72
|
-
//
|
|
72
|
+
// Admin credit decrease
|
|
73
73
|
ADJUST_DECREASE: 'adjust_decrease',
|
|
74
|
-
//
|
|
74
|
+
// Credit purge triggered by an event or expiration
|
|
75
75
|
PURGE: 'purge',
|
|
76
76
|
} as const;
|
|
77
77
|
|
|
78
|
-
//
|
|
78
|
+
// Payment provider types
|
|
79
79
|
export const PaySupplier = {
|
|
80
80
|
STRIPE: 'Stripe',
|
|
81
81
|
APPLE: 'Apple',
|
|
@@ -83,18 +83,18 @@ export const PaySupplier = {
|
|
|
83
83
|
} as const;
|
|
84
84
|
|
|
85
85
|
export const BillingReason = {
|
|
86
|
-
//
|
|
86
|
+
// Initial subscription
|
|
87
87
|
SUBSCRIPTION_CREATE: 'subscription_create',
|
|
88
|
-
//
|
|
88
|
+
// Subscription renewal
|
|
89
89
|
SUBSCRIPTION_CYCLE: 'subscription_cycle',
|
|
90
90
|
} as const;
|
|
91
91
|
|
|
92
92
|
export const PaymentStatus = {
|
|
93
|
-
//
|
|
93
|
+
// Paid
|
|
94
94
|
PAID: 'paid',
|
|
95
|
-
//
|
|
95
|
+
// Pending payment
|
|
96
96
|
UN_PAID: 'un_paid',
|
|
97
|
-
//
|
|
97
|
+
// No payment required
|
|
98
98
|
NO_PAYMENT_REQUIRED: 'no_payment_required',
|
|
99
99
|
} as const;
|
|
100
100
|
|
|
@@ -300,7 +300,7 @@ export class CreditService {
|
|
|
300
300
|
this.ensureNonNegative(normalized, 'initializeCredit');
|
|
301
301
|
const client = checkAndFallbackWithNonTCClient(tx);
|
|
302
302
|
|
|
303
|
-
//
|
|
303
|
+
// Use upsert semantics to share initialization logic for anonymous users and anonymous-to-registered upgrades.
|
|
304
304
|
const credit = await client.credit.upsert({
|
|
305
305
|
where: {
|
|
306
306
|
userId: init.userId
|
|
@@ -636,7 +636,7 @@ export class CreditService {
|
|
|
636
636
|
data: updateData as Prisma.CreditUpdateInput,
|
|
637
637
|
});
|
|
638
638
|
|
|
639
|
-
//
|
|
639
|
+
// Always write an audit entry, even when the credit change is zero.
|
|
640
640
|
const usage = await this.recordCreditAuditLog(client, userId, OperationType.PURGE, normalizedDeduction, { feature: reason, operationReferId })
|
|
641
641
|
|
|
642
642
|
return { credit, usage };
|
|
@@ -43,7 +43,7 @@ export class TransactionService {
|
|
|
43
43
|
orderId: data.orderId,
|
|
44
44
|
orderStatus: data.orderStatus || OrderStatus.CREATED,
|
|
45
45
|
paymentStatus: data.paymentStatus || PaymentStatus.UN_PAID,
|
|
46
|
-
orderExpiredAt: data.orderExpiredAt || new Date(Date.now() + 30 * 60 * 1000), //
|
|
46
|
+
orderExpiredAt: data.orderExpiredAt || new Date(Date.now() + 30 * 60 * 1000), // Default expiration: 30 minutes
|
|
47
47
|
paySupplier: data.paySupplier,
|
|
48
48
|
payTransactionId: data.payTransactionId,
|
|
49
49
|
paySubscriptionId: data.paySubscriptionId,
|
|
@@ -83,7 +83,7 @@ export class UserService {
|
|
|
83
83
|
async findByClerkUserId(clerkUserId: string, tx?: Prisma.TransactionClient): Promise<User | null> {
|
|
84
84
|
const client = checkAndFallbackWithNonTCClient(tx);
|
|
85
85
|
|
|
86
|
-
// DB
|
|
86
|
+
// Partial DB indexes match this status filter, so findUnique is valid here.
|
|
87
87
|
return await client.user.findUnique({
|
|
88
88
|
where: {
|
|
89
89
|
clerkUserId,
|
|
@@ -183,7 +183,7 @@ export class UserService {
|
|
|
183
183
|
return { users, total };
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
//
|
|
186
|
+
// Create anonymous users in bulk
|
|
187
187
|
async createBatchAnonymousUsers(
|
|
188
188
|
fingerprintIds: string[],
|
|
189
189
|
tx?: Prisma.TransactionClient
|
|
@@ -292,7 +292,7 @@ async function handleInvoicePaid(invoice: Stripe.Invoice) {
|
|
|
292
292
|
});
|
|
293
293
|
|
|
294
294
|
if (isInitialPayment) {
|
|
295
|
-
//
|
|
295
|
+
// check
|
|
296
296
|
const nonActiveSubscription = await subscriptionService.getNonActiveSubscription(userId);
|
|
297
297
|
if (!nonActiveSubscription) {
|
|
298
298
|
throw new Error(`Subscription status is ACTIVE for user ${userId}, forbidden to re-active!`);
|
|
@@ -324,7 +324,7 @@ async function handleInvoicePaid(invoice: Stripe.Invoice) {
|
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
if (isRenewal) {
|
|
327
|
-
//
|
|
327
|
+
// must query it's subscription db record
|
|
328
328
|
const subscription = await subscriptionService.findByPaySubscriptionId(subscriptionId);
|
|
329
329
|
if (!subscription) {
|
|
330
330
|
throw new Error(`Subscription not found for renewal: ${subscriptionId}`);
|
|
@@ -337,8 +337,8 @@ async function handleInvoicePaid(invoice: Stripe.Invoice) {
|
|
|
337
337
|
}
|
|
338
338
|
|
|
339
339
|
// Get credits from current price configuration (handles plan upgrades/downgrades)
|
|
340
|
-
//
|
|
341
|
-
//
|
|
340
|
+
// 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
|
|
341
|
+
// No error occurs here as long as the configuration is correct!
|
|
342
342
|
const creditsForRenewal = subscription.priceId
|
|
343
343
|
? getCreditsFromPriceId(subscription.priceId)
|
|
344
344
|
: subscription.creditsAllocated;
|
|
@@ -467,7 +467,7 @@ async function handleInvoicePaymentFailed(invoice: Stripe.Invoice) {
|
|
|
467
467
|
const subscriptionId = parentDetails.subscription;
|
|
468
468
|
const subscriptionMetadata = parentDetails.metadata || {};
|
|
469
469
|
|
|
470
|
-
//
|
|
470
|
+
// PaymentIntentId
|
|
471
471
|
const paymentIntentId = await fetchPaymentId(invoice.id)
|
|
472
472
|
|
|
473
473
|
console.log('Invoice payment failed event key-info:', {
|