@windrun-huaiin/backend-core 10.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/LICENSE +21 -0
- package/dist/app/api/stripe/checkout/route.d.ts +19 -0
- package/dist/app/api/stripe/checkout/route.d.ts.map +1 -0
- package/dist/app/api/stripe/checkout/route.js +120 -0
- package/dist/app/api/stripe/checkout/route.mjs +118 -0
- package/dist/app/api/stripe/customer-portal/route.d.ts +11 -0
- package/dist/app/api/stripe/customer-portal/route.d.ts.map +1 -0
- package/dist/app/api/stripe/customer-portal/route.js +73 -0
- package/dist/app/api/stripe/customer-portal/route.mjs +71 -0
- package/dist/app/api/user/anonymous/init/route.d.ts +7 -0
- package/dist/app/api/user/anonymous/init/route.d.ts.map +1 -0
- package/dist/app/api/user/anonymous/init/route.js +210 -0
- package/dist/app/api/user/anonymous/init/route.mjs +208 -0
- package/dist/app/api/webhook/clerk/user/route.d.ts +7 -0
- package/dist/app/api/webhook/clerk/user/route.d.ts.map +1 -0
- package/dist/app/api/webhook/clerk/user/route.js +202 -0
- package/dist/app/api/webhook/clerk/user/route.mjs +200 -0
- package/dist/app/api/webhook/stripe/route.d.ts +8 -0
- package/dist/app/api/webhook/stripe/route.d.ts.map +1 -0
- package/dist/app/api/webhook/stripe/route.js +70 -0
- package/dist/app/api/webhook/stripe/route.mjs +67 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.mjs +18 -0
- package/dist/lib/auth-utils.d.ts +46 -0
- package/dist/lib/auth-utils.d.ts.map +1 -0
- package/dist/lib/auth-utils.js +107 -0
- package/dist/lib/auth-utils.mjs +102 -0
- package/dist/lib/credit-init.d.ts +8 -0
- package/dist/lib/credit-init.d.ts.map +1 -0
- package/dist/lib/credit-init.js +16 -0
- package/dist/lib/credit-init.mjs +10 -0
- package/dist/lib/index.d.ts +5 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +31 -0
- package/dist/lib/index.mjs +4 -0
- package/dist/lib/money-price-config.d.ts +51 -0
- package/dist/lib/money-price-config.d.ts.map +1 -0
- package/dist/lib/money-price-config.js +156 -0
- package/dist/lib/money-price-config.mjs +151 -0
- package/dist/lib/stripe-config.d.ts +31 -0
- package/dist/lib/stripe-config.d.ts.map +1 -0
- package/dist/lib/stripe-config.js +278 -0
- package/dist/lib/stripe-config.mjs +268 -0
- package/dist/node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js +48 -0
- package/dist/node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs +45 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/errors.js +54 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/errors.mjs +51 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/iso.js +44 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/iso.mjs +35 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/parse.js +31 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/parse.mjs +18 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/schemas.js +587 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/classic/schemas.mjs +527 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/api.js +447 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/api.mjs +399 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/checks.js +245 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/checks.mjs +232 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/core.js +68 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/core.mjs +62 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/doc.js +39 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/doc.mjs +37 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/errors.js +80 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/errors.mjs +75 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/parse.js +101 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/parse.mjs +86 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/regexes.js +102 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/regexes.mjs +76 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/registries.js +56 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/registries.mjs +52 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/schemas.js +1205 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/schemas.mjs +1157 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/util.js +407 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/util.mjs +374 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/versions.js +9 -0
- package/dist/node_modules/.pnpm/zod@4.1.12/node_modules/zod/v4/core/versions.mjs +7 -0
- package/dist/prisma/client.d.ts +2 -0
- package/dist/prisma/client.d.ts.map +1 -0
- package/dist/prisma/client.js +12 -0
- package/dist/prisma/client.mjs +1 -0
- package/dist/prisma/index.d.ts +4 -0
- package/dist/prisma/index.d.ts.map +1 -0
- package/dist/prisma/index.js +10 -0
- package/dist/prisma/index.mjs +2 -0
- package/dist/prisma/prisma-transaction-util.d.ts +3 -0
- package/dist/prisma/prisma-transaction-util.d.ts.map +1 -0
- package/dist/prisma/prisma-transaction-util.js +29 -0
- package/dist/prisma/prisma-transaction-util.mjs +27 -0
- package/dist/prisma/prisma.d.ts +4 -0
- package/dist/prisma/prisma.d.ts.map +1 -0
- package/dist/prisma/prisma.js +109 -0
- package/dist/prisma/prisma.mjs +106 -0
- package/dist/services/aggregate/billing.aggregate.service.d.ts +83 -0
- package/dist/services/aggregate/billing.aggregate.service.d.ts.map +1 -0
- package/dist/services/aggregate/billing.aggregate.service.js +308 -0
- package/dist/services/aggregate/billing.aggregate.service.mjs +306 -0
- package/dist/services/aggregate/index.d.ts +3 -0
- package/dist/services/aggregate/index.d.ts.map +1 -0
- package/dist/services/aggregate/index.js +9 -0
- package/dist/services/aggregate/index.mjs +2 -0
- package/dist/services/aggregate/user.aggregate.service.d.ts +34 -0
- package/dist/services/aggregate/user.aggregate.service.d.ts.map +1 -0
- package/dist/services/aggregate/user.aggregate.service.js +136 -0
- package/dist/services/aggregate/user.aggregate.service.mjs +133 -0
- package/dist/services/context/index.d.ts +2 -0
- package/dist/services/context/index.d.ts.map +1 -0
- package/dist/services/context/index.js +13 -0
- package/dist/services/context/index.mjs +1 -0
- package/dist/services/context/user-context-service.d.ts +30 -0
- package/dist/services/context/user-context-service.d.ts.map +1 -0
- package/dist/services/context/user-context-service.js +170 -0
- package/dist/services/context/user-context-service.mjs +162 -0
- package/dist/services/database/apilog.service.d.ts +39 -0
- package/dist/services/database/apilog.service.d.ts.map +1 -0
- package/dist/services/database/apilog.service.js +174 -0
- package/dist/services/database/apilog.service.mjs +170 -0
- package/dist/services/database/constants.d.ts +73 -0
- package/dist/services/database/constants.d.ts.map +1 -0
- package/dist/services/database/constants.js +135 -0
- package/dist/services/database/constants.mjs +117 -0
- package/dist/services/database/credit.service.d.ts +107 -0
- package/dist/services/database/credit.service.d.ts.map +1 -0
- package/dist/services/database/credit.service.js +515 -0
- package/dist/services/database/credit.service.mjs +512 -0
- package/dist/services/database/creditAuditLog.service.d.ts +73 -0
- package/dist/services/database/creditAuditLog.service.d.ts.map +1 -0
- package/dist/services/database/creditAuditLog.service.js +305 -0
- package/dist/services/database/creditAuditLog.service.mjs +302 -0
- package/dist/services/database/index.d.ts +10 -0
- package/dist/services/database/index.d.ts.map +1 -0
- package/dist/services/database/index.js +38 -0
- package/dist/services/database/index.mjs +8 -0
- package/dist/services/database/prisma-model-type.d.ts +3 -0
- package/dist/services/database/prisma-model-type.d.ts.map +1 -0
- package/dist/services/database/subscription.service.d.ts +48 -0
- package/dist/services/database/subscription.service.d.ts.map +1 -0
- package/dist/services/database/subscription.service.js +267 -0
- package/dist/services/database/subscription.service.mjs +264 -0
- package/dist/services/database/transaction.service.d.ts +92 -0
- package/dist/services/database/transaction.service.d.ts.map +1 -0
- package/dist/services/database/transaction.service.js +326 -0
- package/dist/services/database/transaction.service.mjs +323 -0
- package/dist/services/database/user.service.d.ts +45 -0
- package/dist/services/database/user.service.d.ts.map +1 -0
- package/dist/services/database/user.service.js +180 -0
- package/dist/services/database/user.service.mjs +177 -0
- package/dist/services/database/userBackup.service.d.ts +45 -0
- package/dist/services/database/userBackup.service.d.ts.map +1 -0
- package/dist/services/database/userBackup.service.js +249 -0
- package/dist/services/database/userBackup.service.mjs +246 -0
- package/dist/services/stripe/index.d.ts +2 -0
- package/dist/services/stripe/index.d.ts.map +1 -0
- package/dist/services/stripe/index.js +7 -0
- package/dist/services/stripe/index.mjs +1 -0
- package/dist/services/stripe/webhook-handler.d.ts +6 -0
- package/dist/services/stripe/webhook-handler.d.ts.map +1 -0
- package/dist/services/stripe/webhook-handler.js +537 -0
- package/dist/services/stripe/webhook-handler.mjs +535 -0
- package/migrations/create.sql +176 -0
- package/migrations/db.init.sql +13 -0
- package/migrations/init-schema.sql +19 -0
- package/migrations/purge.sql +27 -0
- package/migrations/test-check.sql +167 -0
- package/package.json +123 -0
- package/prisma/schema.prisma +191 -0
- package/src/app/api/stripe/checkout/route.ts +145 -0
- package/src/app/api/stripe/customer-portal/route.ts +83 -0
- package/src/app/api/user/anonymous/init/route.ts +284 -0
- package/src/app/api/webhook/clerk/user/route.ts +249 -0
- package/src/app/api/webhook/stripe/route.ts +93 -0
- package/src/index.ts +6 -0
- package/src/lib/auth-utils.ts +101 -0
- package/src/lib/credit-init.ts +9 -0
- package/src/lib/index.ts +4 -0
- package/src/lib/money-price-config.ts +168 -0
- package/src/lib/stripe-config.ts +333 -0
- package/src/prisma/client.ts +2 -0
- package/src/prisma/index.ts +3 -0
- package/src/prisma/prisma-transaction-util.ts +24 -0
- package/src/prisma/prisma.ts +122 -0
- package/src/services/aggregate/billing.aggregate.service.ts +498 -0
- package/src/services/aggregate/index.ts +2 -0
- package/src/services/aggregate/user.aggregate.service.ts +168 -0
- package/src/services/context/index.ts +1 -0
- package/src/services/context/user-context-service.ts +200 -0
- package/src/services/database/apilog.service.ts +185 -0
- package/src/services/database/constants.ts +148 -0
- package/src/services/database/credit.service.ts +747 -0
- package/src/services/database/creditAuditLog.service.ts +402 -0
- package/src/services/database/index.ts +41 -0
- package/src/services/database/prisma-model-type.ts +13 -0
- package/src/services/database/subscription.service.ts +319 -0
- package/src/services/database/transaction.service.ts +447 -0
- package/src/services/database/user.service.ts +218 -0
- package/src/services/database/userBackup.service.ts +290 -0
- package/src/services/stripe/index.ts +1 -0
- package/src/services/stripe/webhook-handler.ts +648 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
-- 用户表
|
|
2
|
+
CREATE TABLE IF NOT EXISTS nextai.users (
|
|
3
|
+
id BIGSERIAL PRIMARY KEY,
|
|
4
|
+
user_id UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
5
|
+
status VARCHAR(50) NOT NULL DEFAULT 'anonymous',
|
|
6
|
+
fingerprint_id VARCHAR(255),
|
|
7
|
+
clerk_user_id VARCHAR(255),
|
|
8
|
+
stripe_cus_id VARCHAR(255),
|
|
9
|
+
email VARCHAR(255),
|
|
10
|
+
user_name VARCHAR(255),
|
|
11
|
+
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
13
|
+
source_ref JSONB,
|
|
14
|
+
CONSTRAINT users_user_id_key UNIQUE (user_id),
|
|
15
|
+
CONSTRAINT users_status_check CHECK (status::text = ANY (ARRAY['anonymous'::character varying, 'registered'::character varying, 'frozen'::character varying, 'deleted'::character varying]::text[]))
|
|
16
|
+
);
|
|
17
|
+
-- 创建用户表的部分索引
|
|
18
|
+
CREATE UNIQUE INDEX IF NOT EXISTS users_clerk_user_id_key
|
|
19
|
+
ON nextai.users (clerk_user_id)
|
|
20
|
+
WHERE status <> 'deleted';
|
|
21
|
+
|
|
22
|
+
CREATE UNIQUE INDEX IF NOT EXISTS users_stripe_cus_id_key
|
|
23
|
+
ON nextai.users (stripe_cus_id)
|
|
24
|
+
WHERE status <> 'deleted';
|
|
25
|
+
|
|
26
|
+
CREATE INDEX IF NOT EXISTS idx_users_fingerprint_id ON nextai.users (fingerprint_id);
|
|
27
|
+
|
|
28
|
+
-- 订阅表
|
|
29
|
+
CREATE TABLE IF NOT EXISTS nextai.subscriptions (
|
|
30
|
+
id BIGSERIAL PRIMARY KEY,
|
|
31
|
+
user_id UUID NOT NULL,
|
|
32
|
+
status VARCHAR(50) NOT NULL DEFAULT 'incomplete',
|
|
33
|
+
pay_subscription_id VARCHAR(255),
|
|
34
|
+
order_id VARCHAR(255),
|
|
35
|
+
price_id VARCHAR(255),
|
|
36
|
+
price_name VARCHAR(255),
|
|
37
|
+
credits_allocated INTEGER NOT NULL DEFAULT 0,
|
|
38
|
+
sub_period_start TIMESTAMPTZ,
|
|
39
|
+
sub_period_end TIMESTAMPTZ,
|
|
40
|
+
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
41
|
+
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
42
|
+
deleted INTEGER NOT NULL DEFAULT 0,
|
|
43
|
+
CONSTRAINT subscriptions_user_id_key UNIQUE (user_id),
|
|
44
|
+
CONSTRAINT subscriptions_status_check CHECK (status::text = ANY (ARRAY['active'::character varying, 'canceled'::character varying, 'past_due'::character varying, 'incomplete'::character varying, 'trialing'::character varying]::text[])),
|
|
45
|
+
CONSTRAINT transactions_deleted_check CHECK (deleted = ANY (ARRAY[0, 1]))
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
CREATE INDEX IF NOT EXISTS idx_subscriptions_pay_subscription_id ON nextai.subscriptions (pay_subscription_id);
|
|
49
|
+
CREATE INDEX IF NOT EXISTS idx_subscriptions_order_id ON nextai.subscriptions (order_id);
|
|
50
|
+
CREATE INDEX IF NOT EXISTS idx_subscriptions_user_id ON nextai.subscriptions (user_id);
|
|
51
|
+
|
|
52
|
+
-- 积分表
|
|
53
|
+
CREATE TABLE IF NOT EXISTS nextai.credits (
|
|
54
|
+
id BIGSERIAL PRIMARY KEY,
|
|
55
|
+
user_id UUID NOT NULL,
|
|
56
|
+
balance_free INTEGER NOT NULL DEFAULT 0,
|
|
57
|
+
total_free_limit INTEGER NOT NULL DEFAULT 0,
|
|
58
|
+
free_start TIMESTAMPTZ,
|
|
59
|
+
free_end TIMESTAMPTZ,
|
|
60
|
+
balance_paid INTEGER NOT NULL DEFAULT 0,
|
|
61
|
+
total_paid_limit INTEGER NOT NULL DEFAULT 0,
|
|
62
|
+
paid_start TIMESTAMPTZ,
|
|
63
|
+
paid_end TIMESTAMPTZ,
|
|
64
|
+
balance_onetime_paid INTEGER NOT NULL DEFAULT 0,
|
|
65
|
+
total_onetime_paid_limit INTEGER NOT NULL DEFAULT 0,
|
|
66
|
+
onetime_paid_start TIMESTAMPTZ,
|
|
67
|
+
onetime_paid_end TIMESTAMPTZ,
|
|
68
|
+
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
69
|
+
updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
70
|
+
CONSTRAINT credits_user_id_key UNIQUE (user_id)
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
CREATE INDEX IF NOT EXISTS idx_credits_user_id ON nextai.credits (user_id);
|
|
74
|
+
|
|
75
|
+
-- 交易订单表
|
|
76
|
+
CREATE TABLE IF NOT EXISTS nextai.transactions (
|
|
77
|
+
id BIGSERIAL PRIMARY KEY,
|
|
78
|
+
user_id UUID NOT NULL,
|
|
79
|
+
order_id VARCHAR(255) NOT NULL,
|
|
80
|
+
order_status VARCHAR(50) NOT NULL DEFAULT 'created',
|
|
81
|
+
order_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
82
|
+
order_expired_at TIMESTAMPTZ,
|
|
83
|
+
order_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
84
|
+
type VARCHAR(50),
|
|
85
|
+
pay_supplier VARCHAR(255),
|
|
86
|
+
pay_session_id VARCHAR(255),
|
|
87
|
+
pay_transaction_id VARCHAR(255),
|
|
88
|
+
pay_subscription_id VARCHAR(255),
|
|
89
|
+
sub_period_start TIMESTAMPTZ,
|
|
90
|
+
sub_period_end TIMESTAMPTZ,
|
|
91
|
+
sub_last_try_cancel_at TIMESTAMPTZ,
|
|
92
|
+
sub_period_canceled_at TIMESTAMPTZ,
|
|
93
|
+
sub_cancellation_detail TEXT,
|
|
94
|
+
price_id VARCHAR(255),
|
|
95
|
+
price_name VARCHAR(255),
|
|
96
|
+
amount NUMERIC(10, 2),
|
|
97
|
+
currency VARCHAR(50),
|
|
98
|
+
credits_granted INTEGER NOT NULL DEFAULT 0,
|
|
99
|
+
pay_invoice_id VARCHAR(255),
|
|
100
|
+
payment_status VARCHAR(50) NOT NULL DEFAULT 'un_paid',
|
|
101
|
+
billing_reason VARCHAR(100),
|
|
102
|
+
hosted_invoice_url TEXT,
|
|
103
|
+
invoice_pdf TEXT,
|
|
104
|
+
order_detail TEXT,
|
|
105
|
+
paid_email VARCHAR(255),
|
|
106
|
+
paid_at TIMESTAMPTZ,
|
|
107
|
+
paid_detail TEXT,
|
|
108
|
+
pay_updated_at TIMESTAMPTZ,
|
|
109
|
+
deleted INTEGER NOT NULL DEFAULT 0,
|
|
110
|
+
CONSTRAINT transactions_order_id_key UNIQUE (order_id),
|
|
111
|
+
CONSTRAINT transactions_pay_transaction_id_key UNIQUE (pay_transaction_id),
|
|
112
|
+
CONSTRAINT transactions_order_status_check CHECK (order_status::text = ANY (ARRAY['created'::character varying, 'pending_unpaid'::character varying, 'success'::character varying, 'refunded'::character varying, 'canceled'::character varying, 'failed'::character varying]::text[])),
|
|
113
|
+
CONSTRAINT transactions_pay_supplier_check CHECK (pay_supplier::text = ANY (ARRAY['Stripe'::character varying, 'Apple'::character varying, 'Paypal'::character varying]::text[])),
|
|
114
|
+
CONSTRAINT transactions_type_check CHECK (type::text = ANY (ARRAY['subscription'::character varying, 'one_time'::character varying]::text[])),
|
|
115
|
+
CONSTRAINT transactions_payment_status_check CHECK (payment_status::text = ANY (ARRAY['un_paid'::character varying, 'paid'::character varying, 'no_payment_required'::character varying]::text[])),
|
|
116
|
+
CONSTRAINT transactions_deleted_check CHECK (deleted = ANY (ARRAY[0, 1]))
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
CREATE INDEX IF NOT EXISTS idx_transactions_order_id ON nextai.transactions (order_id);
|
|
120
|
+
CREATE INDEX IF NOT EXISTS idx_transactions_pay_subscription_id ON nextai.transactions (pay_subscription_id);
|
|
121
|
+
CREATE INDEX IF NOT EXISTS idx_transactions_user_id ON nextai.transactions (user_id);
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
-- 积分使用审计表
|
|
125
|
+
CREATE TABLE IF NOT EXISTS nextai.credit_audit_log (
|
|
126
|
+
id BIGSERIAL PRIMARY KEY,
|
|
127
|
+
user_id UUID NOT NULL,
|
|
128
|
+
credits_change INTEGER NOT NULL,
|
|
129
|
+
feature VARCHAR(255),
|
|
130
|
+
credit_type VARCHAR(50) NOT NULL,
|
|
131
|
+
operation_type VARCHAR(100) NOT NULL,
|
|
132
|
+
operation_refer_id VARCHAR(255),
|
|
133
|
+
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
134
|
+
deleted INTEGER NOT NULL DEFAULT 0,
|
|
135
|
+
CONSTRAINT credit_audit_log_deleted_check CHECK (deleted = ANY (ARRAY[0, 1]))
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
CREATE INDEX IF NOT EXISTS idx_credit_audit_log_credit_type ON nextai.credit_audit_log (credit_type);
|
|
139
|
+
CREATE INDEX IF NOT EXISTS idx_credit_audit_log_operation_type ON nextai.credit_audit_log (operation_type);
|
|
140
|
+
CREATE INDEX IF NOT EXISTS idx_credit_audit_log_user_id ON nextai.credit_audit_log (user_id);
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
-- 用户信息备份表
|
|
144
|
+
CREATE TABLE IF NOT EXISTS nextai.user_backup (
|
|
145
|
+
id BIGSERIAL PRIMARY KEY,
|
|
146
|
+
original_user_id UUID NOT NULL,
|
|
147
|
+
status VARCHAR(50),
|
|
148
|
+
fingerprint_id VARCHAR(255),
|
|
149
|
+
clerk_user_id VARCHAR(255),
|
|
150
|
+
stripe_cus_id VARCHAR(255),
|
|
151
|
+
email VARCHAR(255),
|
|
152
|
+
user_name VARCHAR(255),
|
|
153
|
+
backup_data JSONB,
|
|
154
|
+
deleted_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
155
|
+
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
156
|
+
deleted INTEGER NOT NULL DEFAULT 0,
|
|
157
|
+
CONSTRAINT user_backup_deleted_check CHECK (deleted = ANY (ARRAY[0, 1]))
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
CREATE INDEX IF NOT EXISTS idx_user_backup_clerk_user_id ON nextai.user_backup (clerk_user_id);
|
|
161
|
+
CREATE INDEX IF NOT EXISTS idx_user_backup_email ON nextai.user_backup (email);
|
|
162
|
+
CREATE INDEX IF NOT EXISTS idx_user_backup_fingerprint_id ON nextai.user_backup (fingerprint_id);
|
|
163
|
+
CREATE INDEX IF NOT EXISTS idx_user_backup_original_user_id ON nextai.user_backup (original_user_id);
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
-- 第三方对接日志审计表
|
|
167
|
+
CREATE TABLE IF NOT EXISTS nextai.apilog (
|
|
168
|
+
id BIGSERIAL PRIMARY KEY,
|
|
169
|
+
api_type VARCHAR(100) NOT NULL,
|
|
170
|
+
method_name VARCHAR(255) NOT NULL,
|
|
171
|
+
summary TEXT,
|
|
172
|
+
request TEXT,
|
|
173
|
+
response TEXT,
|
|
174
|
+
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
|
|
175
|
+
);
|
|
176
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- 第一步:彻底删除 nextai schema(连里面的表、序列、权限全炸)
|
|
2
|
+
DROP SCHEMA IF EXISTS nextai CASCADE;
|
|
3
|
+
|
|
4
|
+
-- 第二步:重新创建干净的 nextai schema
|
|
5
|
+
CREATE SCHEMA nextai;
|
|
6
|
+
|
|
7
|
+
-- 第三步:把所有权给 postgres(防止任何权限问题)
|
|
8
|
+
ALTER SCHEMA nextai OWNER TO postgres;
|
|
9
|
+
|
|
10
|
+
-- 第四步:给常用角色全开权限(本地开发保险起见)
|
|
11
|
+
GRANT ALL ON SCHEMA nextai TO postgres;
|
|
12
|
+
GRANT ALL ON SCHEMA nextai TO anon;
|
|
13
|
+
GRANT ALL ON SCHEMA nextai TO authenticated;
|
|
14
|
+
GRANT ALL ON SCHEMA nextai TO service_role;
|
|
15
|
+
|
|
16
|
+
-- 第五步:以后在这个 schema 里建的表默认关闭 RLS(本地开发神器)
|
|
17
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA nextai REVOKE EXECUTE ON FUNCTIONS FROM PUBLIC;
|
|
18
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA nextai GRANT ALL ON TABLES TO postgres, anon, authenticated, service_role;
|
|
19
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA nextai GRANT ALL ON SEQUENCES TO postgres, anon, authenticated, service_role;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-- 清空所有数据表
|
|
2
|
+
|
|
3
|
+
TRUNCATE TABLE
|
|
4
|
+
users,
|
|
5
|
+
subscriptions,
|
|
6
|
+
credits,
|
|
7
|
+
credit_audit_log,
|
|
8
|
+
transactions,
|
|
9
|
+
user_backup,
|
|
10
|
+
apilog
|
|
11
|
+
RESTART IDENTITY;
|
|
12
|
+
|
|
13
|
+
-- 验证结果
|
|
14
|
+
|
|
15
|
+
SELECT 'users' AS table_name, COUNT(*) AS row_count FROM users
|
|
16
|
+
UNION ALL
|
|
17
|
+
SELECT 'subscriptions' AS table_name, COUNT(*) AS row_count FROM subscriptions
|
|
18
|
+
UNION ALL
|
|
19
|
+
SELECT 'credits' AS table_name, COUNT(*) AS row_count FROM credits
|
|
20
|
+
UNION ALL
|
|
21
|
+
SELECT 'credit_audit_log' AS table_name, COUNT(*) AS row_count FROM credit_usage
|
|
22
|
+
UNION ALL
|
|
23
|
+
SELECT 'transactions' AS table_name, COUNT(*) AS row_count FROM transactions
|
|
24
|
+
UNION ALL
|
|
25
|
+
SELECT 'user_backup' AS table_name, COUNT(*) AS row_count FROM user_backup
|
|
26
|
+
UNION ALL
|
|
27
|
+
SELECT 'apilog' AS table_name, COUNT(*) AS row_count FROM apilog;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
SELECT
|
|
2
|
+
u.id AS user_pk,
|
|
3
|
+
u.user_id,
|
|
4
|
+
u.status,
|
|
5
|
+
u.fingerprint_id,
|
|
6
|
+
u.clerk_user_id,
|
|
7
|
+
u.stripe_cus_id,
|
|
8
|
+
u.email,
|
|
9
|
+
u.created_at AS user_created_at,
|
|
10
|
+
u.updated_at AS user_updated_at,
|
|
11
|
+
c.id AS credit_pk,
|
|
12
|
+
c.balance_free,
|
|
13
|
+
c.total_free_limit,
|
|
14
|
+
c.free_start,
|
|
15
|
+
c.free_end,
|
|
16
|
+
c.balance_paid,
|
|
17
|
+
c.total_paid_limit,
|
|
18
|
+
c.paid_start,
|
|
19
|
+
c.paid_end,
|
|
20
|
+
c.balance_onetime_paid,
|
|
21
|
+
c.total_onetime_paid_limit,
|
|
22
|
+
c.onetime_paid_start,
|
|
23
|
+
c.onetime_paid_end,
|
|
24
|
+
c.created_at AS credit_created_at,
|
|
25
|
+
c.updated_at AS credit_updated_at,
|
|
26
|
+
s.id AS subscription_pk,
|
|
27
|
+
s.status AS subscription_status,
|
|
28
|
+
s.pay_subscription_id,
|
|
29
|
+
s.price_id,
|
|
30
|
+
s.price_name,
|
|
31
|
+
s.credits_allocated,
|
|
32
|
+
s.sub_period_start,
|
|
33
|
+
s.sub_period_end,
|
|
34
|
+
s.created_at AS subscription_created_at,
|
|
35
|
+
s.updated_at AS subscription_updated_at,
|
|
36
|
+
s.deleted AS subscription_deleted
|
|
37
|
+
FROM public.users u
|
|
38
|
+
LEFT JOIN public.credits c ON c.user_id = u.user_id
|
|
39
|
+
LEFT JOIN public.subscriptions s ON s.user_id = u.user_id
|
|
40
|
+
WHERE u.user_id = '48e4619a-5b9e-47eb-a854-3eeca66856f9';
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
-- PostgreSQL 新增字段·重建表
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
-- ==============================
|
|
47
|
+
-- 1. 开始事务
|
|
48
|
+
-- ==============================
|
|
49
|
+
BEGIN;
|
|
50
|
+
|
|
51
|
+
-- ==============================
|
|
52
|
+
-- 2. 创建新表(正确字段顺序)
|
|
53
|
+
-- ==============================
|
|
54
|
+
CREATE TABLE public.transactions_new (
|
|
55
|
+
id BIGSERIAL PRIMARY KEY,
|
|
56
|
+
user_id UUID NOT NULL,
|
|
57
|
+
order_id VARCHAR(255) NOT NULL,
|
|
58
|
+
order_status VARCHAR(50) NOT NULL DEFAULT 'created',
|
|
59
|
+
order_created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
60
|
+
order_expired_at TIMESTAMPTZ,
|
|
61
|
+
order_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
|
|
62
|
+
type VARCHAR(50),
|
|
63
|
+
pay_supplier VARCHAR(255),
|
|
64
|
+
pay_session_id VARCHAR(255),
|
|
65
|
+
pay_transaction_id VARCHAR(255),
|
|
66
|
+
pay_subscription_id VARCHAR(255),
|
|
67
|
+
sub_period_start TIMESTAMPTZ,
|
|
68
|
+
sub_period_end TIMESTAMPTZ,
|
|
69
|
+
sub_last_try_cancel_at TIMESTAMPTZ,
|
|
70
|
+
sub_period_canceled_at TIMESTAMPTZ,
|
|
71
|
+
sub_cancellation_detail TEXT,
|
|
72
|
+
price_id VARCHAR(255),
|
|
73
|
+
price_name VARCHAR(255),
|
|
74
|
+
amount NUMERIC(10, 2),
|
|
75
|
+
currency VARCHAR(50),
|
|
76
|
+
credits_granted INTEGER NOT NULL DEFAULT 0,
|
|
77
|
+
pay_invoice_id VARCHAR(255),
|
|
78
|
+
payment_status VARCHAR(50) NOT NULL DEFAULT 'un_paid',
|
|
79
|
+
billing_reason VARCHAR(100),
|
|
80
|
+
hosted_invoice_url TEXT,
|
|
81
|
+
invoice_pdf TEXT,
|
|
82
|
+
order_detail TEXT,
|
|
83
|
+
paid_email VARCHAR(255),
|
|
84
|
+
paid_at TIMESTAMPTZ,
|
|
85
|
+
paid_detail TEXT,
|
|
86
|
+
pay_updated_at TIMESTAMPTZ,
|
|
87
|
+
deleted INTEGER NOT NULL DEFAULT 0
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
-- ==============================
|
|
91
|
+
-- 3. 复制数据
|
|
92
|
+
-- ==============================
|
|
93
|
+
INSERT INTO public.transactions_new (
|
|
94
|
+
id, user_id, order_id, order_status, order_created_at, order_expired_at,
|
|
95
|
+
order_updated_at, type, pay_supplier, pay_session_id, pay_transaction_id,
|
|
96
|
+
pay_subscription_id, sub_period_start, sub_period_end,
|
|
97
|
+
sub_period_canceled_at, sub_cancellation_detail, price_id, price_name,
|
|
98
|
+
amount, currency, credits_granted, pay_invoice_id, payment_status,
|
|
99
|
+
billing_reason, hosted_invoice_url, invoice_pdf, order_detail,
|
|
100
|
+
paid_email, paid_at, paid_detail, pay_updated_at, deleted
|
|
101
|
+
)
|
|
102
|
+
SELECT
|
|
103
|
+
id, user_id, order_id, order_status, order_created_at, order_expired_at,
|
|
104
|
+
order_updated_at, type, pay_supplier, pay_session_id, pay_transaction_id,
|
|
105
|
+
pay_subscription_id, sub_period_start, sub_period_end,
|
|
106
|
+
sub_period_canceled_at, sub_cancellation_detail, price_id, price_name,
|
|
107
|
+
amount, currency, credits_granted, pay_invoice_id, payment_status,
|
|
108
|
+
billing_reason, hosted_invoice_url, invoice_pdf, order_detail,
|
|
109
|
+
paid_email, paid_at, paid_detail, pay_updated_at, deleted
|
|
110
|
+
FROM public.transactions;
|
|
111
|
+
|
|
112
|
+
-- ==============================
|
|
113
|
+
-- 4. 删除旧表(释放约束名 + 旧序列)
|
|
114
|
+
-- ==============================
|
|
115
|
+
DROP TABLE public.transactions;
|
|
116
|
+
|
|
117
|
+
-- ==============================
|
|
118
|
+
-- 5. 重命名新表(此时新表已有自己的序列!)
|
|
119
|
+
-- ==============================
|
|
120
|
+
ALTER TABLE public.transactions_new RENAME TO transactions;
|
|
121
|
+
|
|
122
|
+
-- ==============================
|
|
123
|
+
-- 6. 重建序列(新表 BIGSERIAL 自动创建了新序列)
|
|
124
|
+
-- ==============================
|
|
125
|
+
DO $$
|
|
126
|
+
DECLARE
|
|
127
|
+
max_id BIGINT;
|
|
128
|
+
seq_name TEXT;
|
|
129
|
+
BEGIN
|
|
130
|
+
-- 获取新表自动创建的序列名
|
|
131
|
+
SELECT pg_get_serial_sequence('public.transactions', 'id') INTO seq_name;
|
|
132
|
+
|
|
133
|
+
-- 计算最大 ID
|
|
134
|
+
SELECT COALESCE(MAX(id), 0) INTO max_id FROM public.transactions;
|
|
135
|
+
|
|
136
|
+
-- 重启序列
|
|
137
|
+
IF seq_name IS NOT NULL THEN
|
|
138
|
+
EXECUTE format('ALTER SEQUENCE %s RESTART WITH %s', seq_name, max_id + 1);
|
|
139
|
+
END IF;
|
|
140
|
+
END $$;
|
|
141
|
+
|
|
142
|
+
-- ==============================
|
|
143
|
+
-- 7. 添加所有约束(旧约束已随 DROP TABLE 删除)
|
|
144
|
+
-- ==============================
|
|
145
|
+
ALTER TABLE public.transactions ADD CONSTRAINT transactions_order_id_key UNIQUE (order_id);
|
|
146
|
+
ALTER TABLE public.transactions ADD CONSTRAINT transactions_pay_transaction_id_key UNIQUE (pay_transaction_id);
|
|
147
|
+
|
|
148
|
+
ALTER TABLE public.transactions ADD CONSTRAINT transactions_order_status_check
|
|
149
|
+
CHECK (order_status::text = ANY (ARRAY['created', 'pending_unpaid', 'success', 'refunded', 'canceled', 'failed']::text[]));
|
|
150
|
+
|
|
151
|
+
ALTER TABLE public.transactions ADD CONSTRAINT transactions_pay_supplier_check
|
|
152
|
+
CHECK (pay_supplier::text = ANY (ARRAY['Stripe', 'Apple', 'Paypal']::text[]));
|
|
153
|
+
|
|
154
|
+
ALTER TABLE public.transactions ADD CONSTRAINT transactions_type_check
|
|
155
|
+
CHECK (type::text = ANY (ARRAY['subscription', 'one_time']::text[]));
|
|
156
|
+
|
|
157
|
+
ALTER TABLE public.transactions ADD CONSTRAINT transactions_payment_status_check
|
|
158
|
+
CHECK (payment_status::text = ANY (ARRAY['un_paid', 'paid', 'no_payment_required']::text[]));
|
|
159
|
+
|
|
160
|
+
ALTER TABLE public.transactions ADD CONSTRAINT transactions_deleted_check
|
|
161
|
+
CHECK (deleted = ANY (ARRAY[0, 1]));
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
-- ==============================
|
|
165
|
+
-- 8. 提交
|
|
166
|
+
-- ==============================
|
|
167
|
+
COMMIT;
|
package/package.json
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@windrun-huaiin/backend-core",
|
|
3
|
+
"version": "10.0.1",
|
|
4
|
+
"description": "Shared backend primitives: Prisma schema/client, database services, routing helpers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./prisma": {
|
|
16
|
+
"types": "./dist/prisma/index.d.ts",
|
|
17
|
+
"import": "./dist/prisma/index.mjs",
|
|
18
|
+
"require": "./dist/prisma/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./prisma/client": {
|
|
21
|
+
"types": "./dist/prisma/client.d.ts",
|
|
22
|
+
"import": "./dist/prisma/client.mjs",
|
|
23
|
+
"require": "./dist/prisma/client.js"
|
|
24
|
+
},
|
|
25
|
+
"./database": {
|
|
26
|
+
"types": "./dist/services/database/index.d.ts",
|
|
27
|
+
"import": "./dist/services/database/index.mjs",
|
|
28
|
+
"require": "./dist/services/database/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./aggregate": {
|
|
31
|
+
"types": "./dist/services/aggregate/index.d.ts",
|
|
32
|
+
"import": "./dist/services/aggregate/index.mjs",
|
|
33
|
+
"require": "./dist/services/aggregate/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./context": {
|
|
36
|
+
"types": "./dist/services/context/index.d.ts",
|
|
37
|
+
"import": "./dist/services/context/index.mjs",
|
|
38
|
+
"require": "./dist/services/context/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./stripe": {
|
|
41
|
+
"types": "./dist/services/stripe/index.d.ts",
|
|
42
|
+
"import": "./dist/services/stripe/index.mjs",
|
|
43
|
+
"require": "./dist/services/stripe/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./lib": {
|
|
46
|
+
"types": "./dist/lib/index.d.ts",
|
|
47
|
+
"import": "./dist/lib/index.mjs",
|
|
48
|
+
"require": "./dist/lib/index.js"
|
|
49
|
+
},
|
|
50
|
+
"./app/api/webhook/stripe/route": {
|
|
51
|
+
"types": "./dist/app/api/webhook/stripe/route.d.ts",
|
|
52
|
+
"import": "./dist/app/api/webhook/stripe/route.mjs",
|
|
53
|
+
"require": "./dist/app/api/webhook/stripe/route.js"
|
|
54
|
+
},
|
|
55
|
+
"./app/api/webhook/clerk/user/route": {
|
|
56
|
+
"types": "./dist/app/api/webhook/clerk/user/route.d.ts",
|
|
57
|
+
"import": "./dist/app/api/webhook/clerk/user/route.mjs",
|
|
58
|
+
"require": "./dist/app/api/webhook/clerk/user/route.js"
|
|
59
|
+
},
|
|
60
|
+
"./app/api/user/anonymous/init/route": {
|
|
61
|
+
"types": "./dist/app/api/user/anonymous/init/route.d.ts",
|
|
62
|
+
"import": "./dist/app/api/user/anonymous/init/route.mjs",
|
|
63
|
+
"require": "./dist/app/api/user/anonymous/init/route.js"
|
|
64
|
+
},
|
|
65
|
+
"./app/api/stripe/checkout/route": {
|
|
66
|
+
"types": "./dist/app/api/stripe/checkout/route.d.ts",
|
|
67
|
+
"import": "./dist/app/api/stripe/checkout/route.mjs",
|
|
68
|
+
"require": "./dist/app/api/stripe/checkout/route.js"
|
|
69
|
+
},
|
|
70
|
+
"./app/api/stripe/customer-portal/route": {
|
|
71
|
+
"types": "./dist/app/api/stripe/customer-portal/route.d.ts",
|
|
72
|
+
"import": "./dist/app/api/stripe/customer-portal/route.mjs",
|
|
73
|
+
"require": "./dist/app/api/stripe/customer-portal/route.js"
|
|
74
|
+
},
|
|
75
|
+
"./package.json": "./package.json"
|
|
76
|
+
},
|
|
77
|
+
"files": [
|
|
78
|
+
"dist",
|
|
79
|
+
"src",
|
|
80
|
+
"prisma",
|
|
81
|
+
"migrations",
|
|
82
|
+
"package.json",
|
|
83
|
+
"README.md",
|
|
84
|
+
"LICENSE"
|
|
85
|
+
],
|
|
86
|
+
"dependencies": {
|
|
87
|
+
"@clerk/nextjs": "^6.19.4",
|
|
88
|
+
"@prisma/client": "^6.17.1",
|
|
89
|
+
"next": "16.0.0",
|
|
90
|
+
"prisma": "^6.17.1",
|
|
91
|
+
"stripe": "19.3.0",
|
|
92
|
+
"svix": "^1.81.0",
|
|
93
|
+
"zod": "^4.1.12",
|
|
94
|
+
"@windrun-huaiin/lib": "^10.1.0",
|
|
95
|
+
"@windrun-huaiin/third-ui": "^10.1.3"
|
|
96
|
+
},
|
|
97
|
+
"devDependencies": {
|
|
98
|
+
"@rollup/plugin-commonjs": "28.0.6",
|
|
99
|
+
"@rollup/plugin-node-resolve": "16.0.1",
|
|
100
|
+
"@rollup/plugin-typescript": "12.1.4",
|
|
101
|
+
"rollup": "4.46.2",
|
|
102
|
+
"@types/node": "22.17.2",
|
|
103
|
+
"typescript": "^5.8.3"
|
|
104
|
+
},
|
|
105
|
+
"peerDependencies": {
|
|
106
|
+
"@clerk/nextjs": "^6.19.4",
|
|
107
|
+
"@prisma/client": "^6.17.1",
|
|
108
|
+
"next": "16.0.0",
|
|
109
|
+
"prisma": "^6.17.1",
|
|
110
|
+
"stripe": "19.3.0",
|
|
111
|
+
"svix": "^1.81.0"
|
|
112
|
+
},
|
|
113
|
+
"publishConfig": {
|
|
114
|
+
"access": "public"
|
|
115
|
+
},
|
|
116
|
+
"scripts": {
|
|
117
|
+
"build": "rollup -c rollup.config.mjs",
|
|
118
|
+
"build:prod": "rollup -c rollup.config.mjs",
|
|
119
|
+
"dev": "rollup -c rollup.config.mjs --watch",
|
|
120
|
+
"clean": "rm -rf dist",
|
|
121
|
+
"type-check": "tsc --noEmit"
|
|
122
|
+
}
|
|
123
|
+
}
|