@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.
Files changed (61) hide show
  1. package/README.md +95 -0
  2. package/dist/app/api/user/anonymous/init/fingerprint-only-route.d.ts +8 -0
  3. package/dist/app/api/user/anonymous/init/fingerprint-only-route.d.ts.map +1 -0
  4. package/dist/app/api/user/anonymous/init/fingerprint-only-route.js +20 -0
  5. package/dist/app/api/user/anonymous/init/fingerprint-only-route.mjs +18 -0
  6. package/dist/app/api/user/anonymous/init/route-shared.d.ts +10 -0
  7. package/dist/app/api/user/anonymous/init/route-shared.d.ts.map +1 -0
  8. package/dist/app/api/user/anonymous/init/route-shared.js +557 -0
  9. package/dist/app/api/user/anonymous/init/route-shared.mjs +555 -0
  10. package/dist/app/api/user/anonymous/init/route.d.ts +3 -3
  11. package/dist/app/api/user/anonymous/init/route.d.ts.map +1 -1
  12. package/dist/app/api/user/anonymous/init/route.js +6 -554
  13. package/dist/app/api/user/anonymous/init/route.mjs +7 -555
  14. package/dist/app/api/webhook/clerk/user/route.js +16 -16
  15. package/dist/app/api/webhook/clerk/user/route.mjs +16 -16
  16. package/dist/auth/auth-utils.d.ts +8 -23
  17. package/dist/auth/auth-utils.d.ts.map +1 -1
  18. package/dist/auth/auth-utils.js +8 -20
  19. package/dist/auth/auth-utils.mjs +8 -20
  20. package/dist/lib/money-price-config.d.ts +28 -28
  21. package/dist/lib/money-price-config.js +31 -31
  22. package/dist/lib/money-price-config.mjs +31 -31
  23. package/dist/lib/stripe-config.js +3 -3
  24. package/dist/lib/stripe-config.mjs +3 -3
  25. package/dist/prisma/prisma-transaction-util.js +1 -1
  26. package/dist/prisma/prisma-transaction-util.mjs +1 -1
  27. package/dist/prisma/prisma.d.ts.map +1 -1
  28. package/dist/prisma/prisma.js +18 -19
  29. package/dist/prisma/prisma.mjs +18 -19
  30. package/dist/services/aggregate/billing.aggregate.service.js +6 -6
  31. package/dist/services/aggregate/billing.aggregate.service.mjs +6 -6
  32. package/dist/services/aggregate/user.aggregate.service.d.ts +9 -9
  33. package/dist/services/aggregate/user.aggregate.service.js +16 -16
  34. package/dist/services/aggregate/user.aggregate.service.mjs +16 -16
  35. package/dist/services/database/constants.js +34 -34
  36. package/dist/services/database/constants.mjs +34 -34
  37. package/dist/services/database/credit.service.js +2 -2
  38. package/dist/services/database/credit.service.mjs +2 -2
  39. package/dist/services/database/transaction.service.js +1 -1
  40. package/dist/services/database/transaction.service.mjs +1 -1
  41. package/dist/services/database/user.service.js +2 -2
  42. package/dist/services/database/user.service.mjs +2 -2
  43. package/dist/services/stripe/webhook-handler.js +5 -5
  44. package/dist/services/stripe/webhook-handler.mjs +5 -5
  45. package/package.json +18 -6
  46. package/src/app/api/user/anonymous/init/fingerprint-only-route.ts +14 -0
  47. package/src/app/api/user/anonymous/init/route-shared.ts +710 -0
  48. package/src/app/api/user/anonymous/init/route.ts +7 -712
  49. package/src/app/api/webhook/clerk/user/route.ts +17 -17
  50. package/src/auth/auth-utils.ts +8 -23
  51. package/src/lib/money-price-config.ts +31 -32
  52. package/src/lib/stripe-config.ts +3 -3
  53. package/src/prisma/prisma-transaction-util.ts +1 -1
  54. package/src/prisma/prisma.ts +18 -19
  55. package/src/services/aggregate/billing.aggregate.service.ts +7 -7
  56. package/src/services/aggregate/user.aggregate.service.ts +16 -16
  57. package/src/services/database/constants.ts +34 -34
  58. package/src/services/database/credit.service.ts +2 -2
  59. package/src/services/database/transaction.service.ts +1 -1
  60. package/src/services/database/user.service.ts +2 -2
  61. package/src/services/stripe/webhook-handler.ts +5 -5
@@ -60,7 +60,7 @@ const createCheckoutSession = (params, subscriptionData) => tslib.__awaiter(void
60
60
  }
61
61
  // One-time payment specific configuration
62
62
  if (isSubscriptionMode) {
63
- // 在这里注入订单元数据,以保证后续事件处理能根据订单去匹配处理,只能在订阅模式里设置数据,否则Stripe报错
63
+ // Attach order metadata for later event matching. Stripe only allows this in subscription mode.
64
64
  sessionParams.subscription_data = subscriptionData;
65
65
  }
66
66
  else {
@@ -89,7 +89,7 @@ const createCheckoutSession = (params, subscriptionData) => tslib.__awaiter(void
89
89
  throw error;
90
90
  }
91
91
  });
92
- // 根据发票ID去查支付ID
92
+ // Resolve the payment ID from an invoice ID.
93
93
  const fetchPaymentId = (invoiceId) => tslib.__awaiter(void 0, void 0, void 0, function* () {
94
94
  var _a, _b;
95
95
  const fullInvoice = yield getStripe().invoices.retrieve(invoiceId, {
@@ -147,7 +147,7 @@ const createOrGetCustomer = (params) => tslib.__awaiter(void 0, void 0, void 0,
147
147
  return stripeCustomer.id;
148
148
  }
149
149
  }
150
- // 创建新客户
150
+ // Create a new customer.
151
151
  const customerParams = {
152
152
  metadata: {
153
153
  user_id: userId,
@@ -58,7 +58,7 @@ const createCheckoutSession = (params, subscriptionData) => __awaiter(void 0, vo
58
58
  }
59
59
  // One-time payment specific configuration
60
60
  if (isSubscriptionMode) {
61
- // 在这里注入订单元数据,以保证后续事件处理能根据订单去匹配处理,只能在订阅模式里设置数据,否则Stripe报错
61
+ // Attach order metadata for later event matching. Stripe only allows this in subscription mode.
62
62
  sessionParams.subscription_data = subscriptionData;
63
63
  }
64
64
  else {
@@ -87,7 +87,7 @@ const createCheckoutSession = (params, subscriptionData) => __awaiter(void 0, vo
87
87
  throw error;
88
88
  }
89
89
  });
90
- // 根据发票ID去查支付ID
90
+ // Resolve the payment ID from an invoice ID.
91
91
  const fetchPaymentId = (invoiceId) => __awaiter(void 0, void 0, void 0, function* () {
92
92
  var _a, _b;
93
93
  const fullInvoice = yield getStripe().invoices.retrieve(invoiceId, {
@@ -145,7 +145,7 @@ const createOrGetCustomer = (params) => __awaiter(void 0, void 0, void 0, functi
145
145
  return stripeCustomer.id;
146
146
  }
147
147
  }
148
- // 创建新客户
148
+ // Create a new customer.
149
149
  const customerParams = {
150
150
  metadata: {
151
151
  user_id: userId,
@@ -3,7 +3,7 @@
3
3
  var tslib = require('tslib');
4
4
  var prisma = require('./prisma.js');
5
5
 
6
- // 事务工具类,回滚时打印回滚日志
6
+ // Transaction helper that logs rollback details on failure.
7
7
  function runInTransaction(fn, operationName) {
8
8
  return tslib.__awaiter(this, void 0, void 0, function* () {
9
9
  const start = Date.now();
@@ -1,7 +1,7 @@
1
1
  import { __awaiter } from 'tslib';
2
2
  import { getBackendCorePrisma } from './prisma.mjs';
3
3
 
4
- // 事务工具类,回滚时打印回滚日志
4
+ // Transaction helper that logs rollback details on failure.
5
5
  function runInTransaction(fn, operationName) {
6
6
  return __awaiter(this, void 0, void 0, function* () {
7
7
  const start = Date.now();
@@ -1 +1 @@
1
- {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/prisma/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,MAAM,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;AAClE,MAAM,MAAM,2BAA2B,GAAG;IAKxC,YAAY,EAAE,GAAG,CAAC;IAElB,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,WAAW,EAAE,GAAG,CAAC;IAEjB,iBAAiB,CAAC,EAAE,GAAG,CAAC;IAExB,SAAS,EAAE,GAAG,CAAC;IAEf,eAAe,CAAC,EAAE,GAAG,CAAC;IAEtB,IAAI,EAAE,GAAG,CAAC;IAEV,YAAY,EAAE,GAAG,CAAC;IAElB,MAAM,EAAE,GAAG,CAAC;IAEZ,WAAW,EAAE,GAAG,CAAC;IAEjB,cAAc,EAAE,GAAG,CAAC;IAEpB,UAAU,EAAE,GAAG,CAAC;IAEhB,MAAM,EAAE,GAAG,CAAC;CACb,CAAC;AA2CF,wBAAgB,kBAAkB,IAAI,KAAK,CAI1C;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,2BAA2B,EACzC,UAAU,SAAmE,GAC5E,2BAA2B,CAK7B;AAED,wBAAgB,oBAAoB,IAAI,uBAAuB,CAQ9D;AAID,eAAO,MAAM,MAAM,6BAIjB,CAAC;AAuFH,wBAAgB,+BAA+B,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,GAAG,uBAAuB,CAEjI"}
1
+ {"version":3,"file":"prisma.d.ts","sourceRoot":"","sources":["../../src/prisma/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEzD,MAAM,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;AAClE,MAAM,MAAM,2BAA2B,GAAG;IAKxC,YAAY,EAAE,GAAG,CAAC;IAElB,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,WAAW,EAAE,GAAG,CAAC;IAEjB,iBAAiB,CAAC,EAAE,GAAG,CAAC;IAExB,SAAS,EAAE,GAAG,CAAC;IAEf,eAAe,CAAC,EAAE,GAAG,CAAC;IAEtB,IAAI,EAAE,GAAG,CAAC;IAEV,YAAY,EAAE,GAAG,CAAC;IAElB,MAAM,EAAE,GAAG,CAAC;IAEZ,WAAW,EAAE,GAAG,CAAC;IAEjB,cAAc,EAAE,GAAG,CAAC;IAEpB,UAAU,EAAE,GAAG,CAAC;IAEhB,MAAM,EAAE,GAAG,CAAC;CACb,CAAC;AA2CF,wBAAgB,kBAAkB,IAAI,KAAK,CAI1C;AAED,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,2BAA2B,EACzC,UAAU,SAAmE,GAC5E,2BAA2B,CAK7B;AAED,wBAAgB,oBAAoB,IAAI,uBAAuB,CAQ9D;AAID,eAAO,MAAM,MAAM,6BAIjB,CAAC;AAsFH,wBAAgB,+BAA+B,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,GAAG,uBAAuB,CAEjI"}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const globalForPrisma = globalThis;
4
- // ==================== 日志配置 ====================
4
+ // ==================== Logging Configuration ====================
5
5
  const getLogConfig = () => {
6
6
  if (process.env.PRISMA_DEBUG === 'true') {
7
7
  return [
@@ -67,41 +67,40 @@ function registerDevelopmentQueryLogger(prismaClient, instanceId) {
67
67
  const listenerId = `listener_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
68
68
  globalForPrisma[ID_KEY] = listenerId;
69
69
  console.log(`Prisma Query Logger Registered | Listener ID: ${listenerId} | Instance ID: ${instanceId}`);
70
- // --- 自定义SQL拼接 ---
70
+ // --- Custom SQL interpolation ---
71
71
  const interpolate = (query, params) => {
72
- // 1. 【核心修改】:安全检查和参数解析
72
+ // 1. Validate and parse parameters safely.
73
73
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
74
  let parameters = [];
75
75
  try {
76
- // 尝试解析 params 字符串
77
- // 如果 params 是空字符串 "",或者不是有效的 JSON,这里会捕获错误
76
+ // Parse the params string. Empty strings or invalid JSON are handled by the catch block.
78
77
  parameters = params && params.length > 0 ? JSON.parse(params) : [];
79
78
  // eslint-disable-next-line unused-imports/no-unused-vars
80
79
  }
81
80
  catch (e) {
82
- // 如果无法解析,则直接返回原始查询,跳过替换
81
+ // If parsing fails, return the original query without interpolation.
83
82
  return query;
84
83
  }
85
- // 确保 parameters 是一个数组
84
+ // Ensure parameters is an array.
86
85
  if (!Array.isArray(parameters)) {
87
- console.warn('Prisma params解析结果不是数组,跳过参数替换。Result:', parameters);
86
+ console.warn('Prisma params did not parse to an array; skipping parameter interpolation. Result:', parameters);
88
87
  return query;
89
88
  }
90
- // 如果没有参数,直接返回查询
89
+ // If there are no parameters, return the query as-is.
91
90
  if (parameters.length === 0) {
92
91
  return query;
93
92
  }
94
- // 2. 将参数列表的值进行安全的字符串化处理
93
+ // 2. Safely stringify parameter values.
95
94
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
96
95
  const safeValues = parameters.map((p) => {
97
96
  if (p === null)
98
97
  return 'NULL';
99
- // 对字符串类型的值加上单引号并转义(这是SQL安全的关键)
98
+ // Quote and escape string values for readable SQL logging.
100
99
  if (typeof p === 'string')
101
100
  return `'${p.replace(/'/g, "''")}'`;
102
- return p; // 数字、布尔值等直接返回
101
+ return p; // Numbers, booleans, and similar values can be returned directly.
103
102
  });
104
- // 3. 循环替换 $1, $2, ...
103
+ // 3. Replace $1, $2, ... placeholders.
105
104
  let sql = query;
106
105
  for (let i = 0; i < safeValues.length; i++) {
107
106
  const placeholder = new RegExp('\\$' + (i + 1) + '(?!\\d)', 'g');
@@ -114,20 +113,20 @@ function registerDevelopmentQueryLogger(prismaClient, instanceId) {
114
113
  const slow = ms >= 200 ? '🐌 SLOW SQL ' : '🚀 SQL';
115
114
  const interpolatedSql = interpolate(event.query, event.params);
116
115
  const clean = interpolatedSql
117
- .replace(/"[^"]+"\./g, '') // "".
118
- .replace(/= '([^']+)'/g, `= '$1'`) // 已经替换成单引号,此处可以优化
119
- .replace(/"/g, ''); // 彻底灭双引号
116
+ .replace(/"[^"]+"\./g, '') // Remove "table". prefixes.
117
+ .replace(/= '([^']+)'/g, `= '$1'`) // Keep normalized quoted values.
118
+ .replace(/"/g, ''); // Remove remaining double quotes.
120
119
  console.log('─'.repeat(60));
121
120
  console.log(`Prisma Instance ID: ${instanceId} | Listener ID: ${listenerId}`);
122
121
  console.log(`${clean};`);
123
- console.log(`⏰ 耗时: ${ms}ms, ${slow}`);
122
+ console.log(`Duration: ${ms}ms, ${slow}`);
124
123
  };
125
- // 注册包装后的 handler
124
+ // Register the wrapped handler.
126
125
  (_a = prismaClient.$on) === null || _a === void 0 ? void 0 : _a.call(prismaClient, 'query', wrappedHandler);
127
126
  globalForPrisma[REGISTERED_KEY] = true;
128
127
  }
129
128
  }
130
- // ==================== 便捷方法, 入参事务客户端不存在或者不传, 就返回全局非事务客户端 ====================
129
+ // ==================== Client Helper: fall back to the global non-transaction client when no transaction client is provided ====================
131
130
  function checkAndFallbackWithNonTCClient(tx) {
132
131
  return tx !== null && tx !== void 0 ? tx : getBackendCorePrisma();
133
132
  }
@@ -1,5 +1,5 @@
1
1
  const globalForPrisma = globalThis;
2
- // ==================== 日志配置 ====================
2
+ // ==================== Logging Configuration ====================
3
3
  const getLogConfig = () => {
4
4
  if (process.env.PRISMA_DEBUG === 'true') {
5
5
  return [
@@ -65,41 +65,40 @@ function registerDevelopmentQueryLogger(prismaClient, instanceId) {
65
65
  const listenerId = `listener_${Date.now()}_${Math.random().toString(36).substr(2, 5)}`;
66
66
  globalForPrisma[ID_KEY] = listenerId;
67
67
  console.log(`Prisma Query Logger Registered | Listener ID: ${listenerId} | Instance ID: ${instanceId}`);
68
- // --- 自定义SQL拼接 ---
68
+ // --- Custom SQL interpolation ---
69
69
  const interpolate = (query, params) => {
70
- // 1. 【核心修改】:安全检查和参数解析
70
+ // 1. Validate and parse parameters safely.
71
71
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
72
  let parameters = [];
73
73
  try {
74
- // 尝试解析 params 字符串
75
- // 如果 params 是空字符串 "",或者不是有效的 JSON,这里会捕获错误
74
+ // Parse the params string. Empty strings or invalid JSON are handled by the catch block.
76
75
  parameters = params && params.length > 0 ? JSON.parse(params) : [];
77
76
  // eslint-disable-next-line unused-imports/no-unused-vars
78
77
  }
79
78
  catch (e) {
80
- // 如果无法解析,则直接返回原始查询,跳过替换
79
+ // If parsing fails, return the original query without interpolation.
81
80
  return query;
82
81
  }
83
- // 确保 parameters 是一个数组
82
+ // Ensure parameters is an array.
84
83
  if (!Array.isArray(parameters)) {
85
- console.warn('Prisma params解析结果不是数组,跳过参数替换。Result:', parameters);
84
+ console.warn('Prisma params did not parse to an array; skipping parameter interpolation. Result:', parameters);
86
85
  return query;
87
86
  }
88
- // 如果没有参数,直接返回查询
87
+ // If there are no parameters, return the query as-is.
89
88
  if (parameters.length === 0) {
90
89
  return query;
91
90
  }
92
- // 2. 将参数列表的值进行安全的字符串化处理
91
+ // 2. Safely stringify parameter values.
93
92
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
93
  const safeValues = parameters.map((p) => {
95
94
  if (p === null)
96
95
  return 'NULL';
97
- // 对字符串类型的值加上单引号并转义(这是SQL安全的关键)
96
+ // Quote and escape string values for readable SQL logging.
98
97
  if (typeof p === 'string')
99
98
  return `'${p.replace(/'/g, "''")}'`;
100
- return p; // 数字、布尔值等直接返回
99
+ return p; // Numbers, booleans, and similar values can be returned directly.
101
100
  });
102
- // 3. 循环替换 $1, $2, ...
101
+ // 3. Replace $1, $2, ... placeholders.
103
102
  let sql = query;
104
103
  for (let i = 0; i < safeValues.length; i++) {
105
104
  const placeholder = new RegExp('\\$' + (i + 1) + '(?!\\d)', 'g');
@@ -112,20 +111,20 @@ function registerDevelopmentQueryLogger(prismaClient, instanceId) {
112
111
  const slow = ms >= 200 ? '🐌 SLOW SQL ' : '🚀 SQL';
113
112
  const interpolatedSql = interpolate(event.query, event.params);
114
113
  const clean = interpolatedSql
115
- .replace(/"[^"]+"\./g, '') // "".
116
- .replace(/= '([^']+)'/g, `= '$1'`) // 已经替换成单引号,此处可以优化
117
- .replace(/"/g, ''); // 彻底灭双引号
114
+ .replace(/"[^"]+"\./g, '') // Remove "table". prefixes.
115
+ .replace(/= '([^']+)'/g, `= '$1'`) // Keep normalized quoted values.
116
+ .replace(/"/g, ''); // Remove remaining double quotes.
118
117
  console.log('─'.repeat(60));
119
118
  console.log(`Prisma Instance ID: ${instanceId} | Listener ID: ${listenerId}`);
120
119
  console.log(`${clean};`);
121
- console.log(`⏰ 耗时: ${ms}ms, ${slow}`);
120
+ console.log(`Duration: ${ms}ms, ${slow}`);
122
121
  };
123
- // 注册包装后的 handler
122
+ // Register the wrapped handler.
124
123
  (_a = prismaClient.$on) === null || _a === void 0 ? void 0 : _a.call(prismaClient, 'query', wrappedHandler);
125
124
  globalForPrisma[REGISTERED_KEY] = true;
126
125
  }
127
126
  }
128
- // ==================== 便捷方法, 入参事务客户端不存在或者不传, 就返回全局非事务客户端 ====================
127
+ // ==================== Client Helper: fall back to the global non-transaction client when no transaction client is provided ====================
129
128
  function checkAndFallbackWithNonTCClient(tx) {
130
129
  return tx !== null && tx !== void 0 ? tx : getBackendCorePrisma();
131
130
  }
@@ -14,7 +14,7 @@ class BillingAggregateService {
14
14
  yield prismaTransactionUtil.runInTransaction((tx) => tslib.__awaiter(this, void 0, void 0, function* () {
15
15
  var _a, _b, _c, _d, _e, _f, _g, _h;
16
16
  const now = new Date();
17
- // 订阅截止时间统一为到期日最后1s
17
+ // Set subscription expiry to the last second of the expiration date
18
18
  const originSubPeriodEnd = context.periodEnd;
19
19
  const specialEnd = originSubPeriodEnd ? new Date(originSubPeriodEnd.setHours(23, 59, 59, 999)) : originSubPeriodEnd;
20
20
  const updatedSubscription = yield subscription_service.subscriptionService.updateSubscription(context.subIdKey, {
@@ -132,7 +132,7 @@ class BillingAggregateService {
132
132
  paidEmail: context.paidEmail,
133
133
  payUpdatedAt: new Date(),
134
134
  }, tx);
135
- // 订阅截止时间统一为到期日最后1s
135
+ // Set subscription expiry to the last second of the expiration date
136
136
  const originSubPeriodEnd = context.periodEnd;
137
137
  const specialEnd = originSubPeriodEnd ? new Date(originSubPeriodEnd.setHours(23, 59, 59, 999)) : originSubPeriodEnd;
138
138
  yield subscription_service.subscriptionService.updateSubscription(context.subIdKey, {
@@ -218,7 +218,7 @@ class BillingAggregateService {
218
218
  return tslib.__awaiter(this, void 0, void 0, function* () {
219
219
  yield prismaTransactionUtil.runInTransaction((tx) => tslib.__awaiter(this, void 0, void 0, function* () {
220
220
  if (params.isUserCancel) {
221
- // 记录用户取消订阅的时间信息
221
+ // Record the time when the user unsubscribes
222
222
  yield transaction_service.transactionService.update(params.orderId, {
223
223
  subLastTryCancelAt: new Date(),
224
224
  }, tx);
@@ -236,14 +236,14 @@ class BillingAggregateService {
236
236
  return tslib.__awaiter(this, void 0, void 0, function* () {
237
237
  yield prismaTransactionUtil.runInTransaction((tx) => tslib.__awaiter(this, void 0, void 0, function* () {
238
238
  var _a;
239
- // 更新订单, 记录取消信息
239
+ // Update the order and log cancellation details
240
240
  yield transaction_service.transactionService.update(context.orderId, {
241
241
  subPeriodCanceledAt: context.canceledAt,
242
242
  subCancellationDetail: (_a = context.cancellationDetail) !== null && _a !== void 0 ? _a : undefined
243
243
  }, tx);
244
- // 更新订阅信息
244
+ // Update subscription information
245
245
  yield subscription_service.subscriptionService.updateStatus(context.subIdKey, constants.SubscriptionStatus.CANCELED, tx);
246
- // 清理积分并留痕
246
+ // Clear credits and keep audit trail
247
247
  yield credit_service.creditService.purgePaidCredit(context.userId, 'cancel_subscription_purge', context.orderId, tx);
248
248
  }));
249
249
  });
@@ -12,7 +12,7 @@ class BillingAggregateService {
12
12
  yield runInTransaction((tx) => __awaiter(this, void 0, void 0, function* () {
13
13
  var _a, _b, _c, _d, _e, _f, _g, _h;
14
14
  const now = new Date();
15
- // 订阅截止时间统一为到期日最后1s
15
+ // Set subscription expiry to the last second of the expiration date
16
16
  const originSubPeriodEnd = context.periodEnd;
17
17
  const specialEnd = originSubPeriodEnd ? new Date(originSubPeriodEnd.setHours(23, 59, 59, 999)) : originSubPeriodEnd;
18
18
  const updatedSubscription = yield subscriptionService.updateSubscription(context.subIdKey, {
@@ -130,7 +130,7 @@ class BillingAggregateService {
130
130
  paidEmail: context.paidEmail,
131
131
  payUpdatedAt: new Date(),
132
132
  }, tx);
133
- // 订阅截止时间统一为到期日最后1s
133
+ // Set subscription expiry to the last second of the expiration date
134
134
  const originSubPeriodEnd = context.periodEnd;
135
135
  const specialEnd = originSubPeriodEnd ? new Date(originSubPeriodEnd.setHours(23, 59, 59, 999)) : originSubPeriodEnd;
136
136
  yield subscriptionService.updateSubscription(context.subIdKey, {
@@ -216,7 +216,7 @@ class BillingAggregateService {
216
216
  return __awaiter(this, void 0, void 0, function* () {
217
217
  yield runInTransaction((tx) => __awaiter(this, void 0, void 0, function* () {
218
218
  if (params.isUserCancel) {
219
- // 记录用户取消订阅的时间信息
219
+ // Record the time when the user unsubscribes
220
220
  yield transactionService.update(params.orderId, {
221
221
  subLastTryCancelAt: new Date(),
222
222
  }, tx);
@@ -234,14 +234,14 @@ class BillingAggregateService {
234
234
  return __awaiter(this, void 0, void 0, function* () {
235
235
  yield runInTransaction((tx) => __awaiter(this, void 0, void 0, function* () {
236
236
  var _a;
237
- // 更新订单, 记录取消信息
237
+ // Update the order and log cancellation details
238
238
  yield transactionService.update(context.orderId, {
239
239
  subPeriodCanceledAt: context.canceledAt,
240
240
  subCancellationDetail: (_a = context.cancellationDetail) !== null && _a !== void 0 ? _a : undefined
241
241
  }, tx);
242
- // 更新订阅信息
242
+ // Update subscription information
243
243
  yield subscriptionService.updateStatus(context.subIdKey, SubscriptionStatus.CANCELED, tx);
244
- // 清理积分并留痕
244
+ // Clear credits and keep audit trail
245
245
  yield creditService.purgePaidCredit(context.userId, 'cancel_subscription_purge', context.orderId, tx);
246
246
  }));
247
247
  });
@@ -7,17 +7,17 @@ export declare class UserAggregateService {
7
7
  credit: Credit;
8
8
  }>;
9
9
  /**
10
- * 创建新的注册用户
10
+ * Create a new registered user
11
11
  *
12
- * 初始化步骤(与 credit 平行):
13
- * 1. 创建 User 记录
14
- * 2. 初始化 Credit 记录(免费积分)
15
- * 3. 初始化 Subscription 记录(占位符,status=INCOMPLETE
16
- * 4. 记录 CreditUsage(审计)
12
+ * Initialization steps (parallel to credit):
13
+ * 1. Create User record
14
+ * 2. Initialize Credit record (free credits)
15
+ * 3. Initialize Subscription record (placeholder, status=INCOMPLETE)
16
+ * 4. Record CreditUsage (audit)
17
17
  *
18
- * 后续当用户通过 Stripe 订阅时:
19
- * - session.completed invoice.paid UPDATE subscription 记录
20
- * - 不需要 CREATE,只需 UPDATE 确保逻辑一致
18
+ * When the user subscribes via Stripe later:
19
+ * - session.completed or invoice.paid will UPDATE the subscription record
20
+ * - No CREATE needed, only UPDATE to ensure logical consistency
21
21
  */
22
22
  createNewRegisteredUser(clerkUserId: string, email?: string, fingerprintId?: string, userName?: string, sourceRef?: CoreJsonValue): Promise<{
23
23
  newUser: User;
@@ -32,17 +32,17 @@ class UserAggregateService {
32
32
  });
33
33
  }
34
34
  /**
35
- * 创建新的注册用户
35
+ * Create a new registered user
36
36
  *
37
- * 初始化步骤(与 credit 平行):
38
- * 1. 创建 User 记录
39
- * 2. 初始化 Credit 记录(免费积分)
40
- * 3. 初始化 Subscription 记录(占位符,status=INCOMPLETE
41
- * 4. 记录 CreditUsage(审计)
37
+ * Initialization steps (parallel to credit):
38
+ * 1. Create User record
39
+ * 2. Initialize Credit record (free credits)
40
+ * 3. Initialize Subscription record (placeholder, status=INCOMPLETE)
41
+ * 4. Record CreditUsage (audit)
42
42
  *
43
- * 后续当用户通过 Stripe 订阅时:
44
- * - session.completed invoice.paid UPDATE subscription 记录
45
- * - 不需要 CREATE,只需 UPDATE 确保逻辑一致
43
+ * When the user subscribes via Stripe later:
44
+ * - session.completed or invoice.paid will UPDATE the subscription record
45
+ * - No CREATE needed, only UPDATE to ensure logical consistency
46
46
  */
47
47
  createNewRegisteredUser(clerkUserId, email, fingerprintId, userName, sourceRef) {
48
48
  return tslib.__awaiter(this, void 0, void 0, function* () {
@@ -68,7 +68,7 @@ class UserAggregateService {
68
68
  }));
69
69
  });
70
70
  }
71
- // 注意积分审查日志的处理
71
+ // Note: Handle credit review logs
72
72
  upgradeToRegistered(userId, email, clerkUserId, userName) {
73
73
  return tslib.__awaiter(this, void 0, void 0, function* () {
74
74
  return prismaTransactionUtil.runInTransaction((tx) => tslib.__awaiter(this, void 0, void 0, function* () {
@@ -77,9 +77,9 @@ class UserAggregateService {
77
77
  clerkUserId,
78
78
  userName
79
79
  }, tx);
80
- // 先清空匿名积分并审计日志留痕
80
+ // Clear anonymous credits first and audit for traceability
81
81
  yield credit_service.creditService.purgeFreeCredit(userId, 'user_registered_purge', userId, tx);
82
- // 再初始化完成注册获得免费积分
82
+ // Then initialize free credits upon successful registration
83
83
  const credit = yield credit_service.creditService.initializeCreditWithFree({
84
84
  userId: updateUser.userId,
85
85
  feature: 'user_registration_init',
@@ -95,20 +95,20 @@ class UserAggregateService {
95
95
  handleUserUnregister(clerkUserId) {
96
96
  return tslib.__awaiter(this, void 0, void 0, function* () {
97
97
  return prismaTransactionUtil.runInTransaction((tx) => tslib.__awaiter(this, void 0, void 0, function* () {
98
- // 根据clerkUserId查找用户
98
+ // query DB user
99
99
  const user = yield user_service.userService.findByClerkUserId(clerkUserId, tx);
100
100
  if (!user) {
101
101
  console.log(`User with clerkUserId ${clerkUserId} not found`);
102
102
  return null;
103
103
  }
104
104
  const userId = user.userId;
105
- // 更改用户状态,保留user信息尤其是FingerprintId,防止反复注册薅羊毛
105
+ // Update user status and retain user info (especially FingerprintId) to prevent repeated registration abuse
106
106
  yield user_service.userService.unregister(user.userId, tx);
107
- // 清空积分
107
+ // Clear credits
108
108
  yield credit_service.creditService.purgeCredit(userId, 'soft_delete_user', userId, tx);
109
109
  const subscription = yield subscription_service.subscriptionService.getActiveSubscription(userId, tx);
110
110
  if (subscription) {
111
- // 如果有订阅信息,则要更新
111
+ // Update subscription info if it exists
112
112
  yield subscription_service.subscriptionService.cancelSubscription(subscription.id, true, tx);
113
113
  }
114
114
  return user.userId;
@@ -30,17 +30,17 @@ class UserAggregateService {
30
30
  });
31
31
  }
32
32
  /**
33
- * 创建新的注册用户
33
+ * Create a new registered user
34
34
  *
35
- * 初始化步骤(与 credit 平行):
36
- * 1. 创建 User 记录
37
- * 2. 初始化 Credit 记录(免费积分)
38
- * 3. 初始化 Subscription 记录(占位符,status=INCOMPLETE
39
- * 4. 记录 CreditUsage(审计)
35
+ * Initialization steps (parallel to credit):
36
+ * 1. Create User record
37
+ * 2. Initialize Credit record (free credits)
38
+ * 3. Initialize Subscription record (placeholder, status=INCOMPLETE)
39
+ * 4. Record CreditUsage (audit)
40
40
  *
41
- * 后续当用户通过 Stripe 订阅时:
42
- * - session.completed invoice.paid UPDATE subscription 记录
43
- * - 不需要 CREATE,只需 UPDATE 确保逻辑一致
41
+ * When the user subscribes via Stripe later:
42
+ * - session.completed or invoice.paid will UPDATE the subscription record
43
+ * - No CREATE needed, only UPDATE to ensure logical consistency
44
44
  */
45
45
  createNewRegisteredUser(clerkUserId, email, fingerprintId, userName, sourceRef) {
46
46
  return __awaiter(this, void 0, void 0, function* () {
@@ -66,7 +66,7 @@ class UserAggregateService {
66
66
  }));
67
67
  });
68
68
  }
69
- // 注意积分审查日志的处理
69
+ // Note: Handle credit review logs
70
70
  upgradeToRegistered(userId, email, clerkUserId, userName) {
71
71
  return __awaiter(this, void 0, void 0, function* () {
72
72
  return runInTransaction((tx) => __awaiter(this, void 0, void 0, function* () {
@@ -75,9 +75,9 @@ class UserAggregateService {
75
75
  clerkUserId,
76
76
  userName
77
77
  }, tx);
78
- // 先清空匿名积分并审计日志留痕
78
+ // Clear anonymous credits first and audit for traceability
79
79
  yield creditService.purgeFreeCredit(userId, 'user_registered_purge', userId, tx);
80
- // 再初始化完成注册获得免费积分
80
+ // Then initialize free credits upon successful registration
81
81
  const credit = yield creditService.initializeCreditWithFree({
82
82
  userId: updateUser.userId,
83
83
  feature: 'user_registration_init',
@@ -93,20 +93,20 @@ class UserAggregateService {
93
93
  handleUserUnregister(clerkUserId) {
94
94
  return __awaiter(this, void 0, void 0, function* () {
95
95
  return runInTransaction((tx) => __awaiter(this, void 0, void 0, function* () {
96
- // 根据clerkUserId查找用户
96
+ // query DB user
97
97
  const user = yield userService.findByClerkUserId(clerkUserId, tx);
98
98
  if (!user) {
99
99
  console.log(`User with clerkUserId ${clerkUserId} not found`);
100
100
  return null;
101
101
  }
102
102
  const userId = user.userId;
103
- // 更改用户状态,保留user信息尤其是FingerprintId,防止反复注册薅羊毛
103
+ // Update user status and retain user info (especially FingerprintId) to prevent repeated registration abuse
104
104
  yield userService.unregister(user.userId, tx);
105
- // 清空积分
105
+ // Clear credits
106
106
  yield creditService.purgeCredit(userId, 'soft_delete_user', userId, tx);
107
107
  const subscription = yield subscriptionService.getActiveSubscription(userId, tx);
108
108
  if (subscription) {
109
- // 如果有订阅信息,则要更新
109
+ // Update subscription info if it exists
110
110
  yield subscriptionService.cancelSubscription(subscription.id, true, tx);
111
111
  }
112
112
  return user.userId;