@allbluecn/database 0.4.5 → 0.4.6
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/migrations/20260804174501_init/migration.sql +1764 -0
- package/migrations/20260805174545_add_story_activity_is_ai/migration.sql +2 -0
- package/migrations/20260806035202_story_archived/migration.sql +6 -0
- package/migrations/20260806061157_builtin_independent_project/migration.sql +26 -0
- package/migrations/20260806144250_tanstack_ai_persistence/migration.sql +129 -0
- package/migrations/20260809080004_add_monitoring_observability/migration.sql +75 -0
- package/migrations/20260811112502_add_workspace/migration.sql +89 -0
- package/migrations/20260811153719_add_hosted_ai_tables/migration.sql +119 -0
- package/migrations/20260812043944_add_billing_tables/migration.sql +86 -0
- package/migrations/20260813040200_sub3_stripe_subscription_unique/migration.sql +6 -0
- package/migrations/20260813061345_add_enterprise_license_sso_audit_permissions/migration.sql +169 -0
- package/migrations/20260813132026_add_user_locale/migration.sql +2 -0
- package/migrations/20260814000000_add_story_composite_index/migration.sql +2 -0
- package/migrations/20260814161622_add_user_default_workspace_id/migration.sql +2 -0
- package/migrations/20260815025746_p2_seat_addon/migration.sql +15 -0
- package/migrations/20260815120000_creem_billing_neutralization/migration.sql +122 -0
- package/migrations/20260816212027_compliance_content/migration.sql +3 -0
- package/migrations/20260817204928_p6_user_agents_skills/migration.sql +57 -0
- package/migrations/20260818094327_user_level_subscription/migration.sql +43 -0
- package/migrations/20260819014924_team_membership_invitation/migration.sql +65 -0
- package/migrations/migration_lock.toml +3 -0
- package/package.json +8 -3
- package/prisma.config.ts +18 -0
- package/schema.prisma +2014 -0
- package/schema.sqlite.prisma +1584 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "license_keys" (
|
|
3
|
+
"id" TEXT NOT NULL,
|
|
4
|
+
"key" TEXT NOT NULL,
|
|
5
|
+
"signature" TEXT NOT NULL,
|
|
6
|
+
"payload" JSONB NOT NULL,
|
|
7
|
+
"customerId" TEXT NOT NULL,
|
|
8
|
+
"customerName" TEXT NOT NULL,
|
|
9
|
+
"customerEmail" TEXT NOT NULL,
|
|
10
|
+
"plan" TEXT NOT NULL DEFAULT 'enterprise',
|
|
11
|
+
"seats" INTEGER NOT NULL,
|
|
12
|
+
"features" JSONB NOT NULL,
|
|
13
|
+
"issuedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
14
|
+
"expiresAt" TIMESTAMP(3),
|
|
15
|
+
"revokedAt" TIMESTAMP(3),
|
|
16
|
+
"issuedById" TEXT,
|
|
17
|
+
|
|
18
|
+
CONSTRAINT "license_keys_pkey" PRIMARY KEY ("id")
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
-- CreateTable
|
|
22
|
+
CREATE TABLE "license_activations" (
|
|
23
|
+
"id" TEXT NOT NULL,
|
|
24
|
+
"licenseId" TEXT NOT NULL,
|
|
25
|
+
"instanceId" TEXT NOT NULL,
|
|
26
|
+
"fingerprint" TEXT NOT NULL,
|
|
27
|
+
"activatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
28
|
+
"lastSeenAt" TIMESTAMP(3),
|
|
29
|
+
"revokedAt" TIMESTAMP(3),
|
|
30
|
+
|
|
31
|
+
CONSTRAINT "license_activations_pkey" PRIMARY KEY ("id")
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
-- CreateTable
|
|
35
|
+
CREATE TABLE "audit_logs" (
|
|
36
|
+
"id" TEXT NOT NULL,
|
|
37
|
+
"workspaceId" TEXT,
|
|
38
|
+
"userId" TEXT,
|
|
39
|
+
"action" TEXT NOT NULL,
|
|
40
|
+
"resourceType" TEXT NOT NULL,
|
|
41
|
+
"resourceId" TEXT,
|
|
42
|
+
"metadata" JSONB NOT NULL,
|
|
43
|
+
"ip" TEXT,
|
|
44
|
+
"userAgent" TEXT,
|
|
45
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
46
|
+
|
|
47
|
+
CONSTRAINT "audit_logs_pkey" PRIMARY KEY ("id")
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
-- CreateTable
|
|
51
|
+
CREATE TABLE "sso_providers" (
|
|
52
|
+
"id" TEXT NOT NULL,
|
|
53
|
+
"workspaceId" TEXT NOT NULL,
|
|
54
|
+
"type" TEXT NOT NULL,
|
|
55
|
+
"name" TEXT NOT NULL,
|
|
56
|
+
"config" JSONB NOT NULL,
|
|
57
|
+
"domain" TEXT,
|
|
58
|
+
"enabled" BOOLEAN NOT NULL DEFAULT true,
|
|
59
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
60
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
61
|
+
|
|
62
|
+
CONSTRAINT "sso_providers_pkey" PRIMARY KEY ("id")
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
-- CreateTable
|
|
66
|
+
CREATE TABLE "sso_mappings" (
|
|
67
|
+
"id" TEXT NOT NULL,
|
|
68
|
+
"providerId" TEXT NOT NULL,
|
|
69
|
+
"externalId" TEXT NOT NULL,
|
|
70
|
+
"userId" TEXT NOT NULL,
|
|
71
|
+
"email" TEXT,
|
|
72
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
73
|
+
|
|
74
|
+
CONSTRAINT "sso_mappings_pkey" PRIMARY KEY ("id")
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
-- CreateTable
|
|
78
|
+
CREATE TABLE "custom_roles" (
|
|
79
|
+
"id" TEXT NOT NULL,
|
|
80
|
+
"workspaceId" TEXT NOT NULL,
|
|
81
|
+
"name" TEXT NOT NULL,
|
|
82
|
+
"permissions" JSONB NOT NULL,
|
|
83
|
+
"isSystem" BOOLEAN NOT NULL DEFAULT false,
|
|
84
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
85
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
86
|
+
|
|
87
|
+
CONSTRAINT "custom_roles_pkey" PRIMARY KEY ("id")
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
-- CreateTable
|
|
91
|
+
CREATE TABLE "role_assignments" (
|
|
92
|
+
"id" TEXT NOT NULL,
|
|
93
|
+
"roleId" TEXT NOT NULL,
|
|
94
|
+
"userId" TEXT NOT NULL,
|
|
95
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
96
|
+
|
|
97
|
+
CONSTRAINT "role_assignments_pkey" PRIMARY KEY ("id")
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
-- CreateTable
|
|
101
|
+
CREATE TABLE "compliance_exports" (
|
|
102
|
+
"id" TEXT NOT NULL,
|
|
103
|
+
"type" TEXT NOT NULL,
|
|
104
|
+
"scope" TEXT NOT NULL,
|
|
105
|
+
"targetId" TEXT NOT NULL,
|
|
106
|
+
"status" TEXT NOT NULL DEFAULT 'pending',
|
|
107
|
+
"downloadUrl" TEXT,
|
|
108
|
+
"expiresAt" TIMESTAMP(3),
|
|
109
|
+
"error" TEXT,
|
|
110
|
+
"requestedBy" TEXT,
|
|
111
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
112
|
+
"completedAt" TIMESTAMP(3),
|
|
113
|
+
|
|
114
|
+
CONSTRAINT "compliance_exports_pkey" PRIMARY KEY ("id")
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
-- CreateIndex
|
|
118
|
+
CREATE UNIQUE INDEX "license_keys_key_key" ON "license_keys"("key");
|
|
119
|
+
|
|
120
|
+
-- CreateIndex
|
|
121
|
+
CREATE UNIQUE INDEX "license_activations_instanceId_key" ON "license_activations"("instanceId");
|
|
122
|
+
|
|
123
|
+
-- CreateIndex
|
|
124
|
+
CREATE INDEX "audit_logs_workspaceId_createdAt_idx" ON "audit_logs"("workspaceId", "createdAt");
|
|
125
|
+
|
|
126
|
+
-- CreateIndex
|
|
127
|
+
CREATE INDEX "audit_logs_userId_createdAt_idx" ON "audit_logs"("userId", "createdAt");
|
|
128
|
+
|
|
129
|
+
-- CreateIndex
|
|
130
|
+
CREATE INDEX "audit_logs_action_idx" ON "audit_logs"("action");
|
|
131
|
+
|
|
132
|
+
-- CreateIndex
|
|
133
|
+
CREATE UNIQUE INDEX "sso_providers_workspaceId_type_domain_key" ON "sso_providers"("workspaceId", "type", "domain");
|
|
134
|
+
|
|
135
|
+
-- CreateIndex
|
|
136
|
+
CREATE UNIQUE INDEX "sso_mappings_providerId_externalId_key" ON "sso_mappings"("providerId", "externalId");
|
|
137
|
+
|
|
138
|
+
-- CreateIndex
|
|
139
|
+
CREATE UNIQUE INDEX "custom_roles_workspaceId_name_key" ON "custom_roles"("workspaceId", "name");
|
|
140
|
+
|
|
141
|
+
-- CreateIndex
|
|
142
|
+
CREATE UNIQUE INDEX "role_assignments_roleId_userId_key" ON "role_assignments"("roleId", "userId");
|
|
143
|
+
|
|
144
|
+
-- AddForeignKey
|
|
145
|
+
ALTER TABLE "license_keys" ADD CONSTRAINT "license_keys_issuedById_fkey" FOREIGN KEY ("issuedById") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
146
|
+
|
|
147
|
+
-- AddForeignKey
|
|
148
|
+
ALTER TABLE "license_activations" ADD CONSTRAINT "license_activations_licenseId_fkey" FOREIGN KEY ("licenseId") REFERENCES "license_keys"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
149
|
+
|
|
150
|
+
-- AddForeignKey
|
|
151
|
+
ALTER TABLE "audit_logs" ADD CONSTRAINT "audit_logs_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
152
|
+
|
|
153
|
+
-- AddForeignKey
|
|
154
|
+
ALTER TABLE "sso_providers" ADD CONSTRAINT "sso_providers_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
155
|
+
|
|
156
|
+
-- AddForeignKey
|
|
157
|
+
ALTER TABLE "sso_mappings" ADD CONSTRAINT "sso_mappings_providerId_fkey" FOREIGN KEY ("providerId") REFERENCES "sso_providers"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
158
|
+
|
|
159
|
+
-- AddForeignKey
|
|
160
|
+
ALTER TABLE "sso_mappings" ADD CONSTRAINT "sso_mappings_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
161
|
+
|
|
162
|
+
-- AddForeignKey
|
|
163
|
+
ALTER TABLE "custom_roles" ADD CONSTRAINT "custom_roles_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
164
|
+
|
|
165
|
+
-- AddForeignKey
|
|
166
|
+
ALTER TABLE "role_assignments" ADD CONSTRAINT "role_assignments_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "custom_roles"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
167
|
+
|
|
168
|
+
-- AddForeignKey
|
|
169
|
+
ALTER TABLE "role_assignments" ADD CONSTRAINT "role_assignments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- P2 席位加购:Subscription.addonSeats + Plan 席位价格字段
|
|
2
|
+
DO $$ BEGIN
|
|
3
|
+
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'subscriptions' AND column_name = 'addonSeats') THEN
|
|
4
|
+
ALTER TABLE "subscriptions" ADD COLUMN "addonSeats" INTEGER NOT NULL DEFAULT 0;
|
|
5
|
+
END IF;
|
|
6
|
+
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'seatPriceMonthly') THEN
|
|
7
|
+
ALTER TABLE "plans" ADD COLUMN "seatPriceMonthly" INTEGER;
|
|
8
|
+
END IF;
|
|
9
|
+
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripeSeatPriceIdUsd') THEN
|
|
10
|
+
ALTER TABLE "plans" ADD COLUMN "stripeSeatPriceIdUsd" TEXT;
|
|
11
|
+
END IF;
|
|
12
|
+
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripeSeatPriceIdCny') THEN
|
|
13
|
+
ALTER TABLE "plans" ADD COLUMN "stripeSeatPriceIdCny" TEXT;
|
|
14
|
+
END IF;
|
|
15
|
+
END $$;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
-- 计费字段中立化:Stripe → Provider(配合 Creem 计费集成)
|
|
2
|
+
-- 无存量数据,直接 RENAME/DROP/ADD,幂等化
|
|
3
|
+
|
|
4
|
+
-- ── Plan 表 ──
|
|
5
|
+
|
|
6
|
+
-- 删除 stripeProductId(Creem 无独立产品概念,价格点即产品)
|
|
7
|
+
DO $$ BEGIN
|
|
8
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripeProductId') THEN
|
|
9
|
+
ALTER TABLE "plans" DROP COLUMN "stripeProductId";
|
|
10
|
+
END IF;
|
|
11
|
+
END $$;
|
|
12
|
+
|
|
13
|
+
-- 重命名 Plan 价格字段
|
|
14
|
+
DO $$ BEGIN
|
|
15
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripePriceIdUsd') THEN
|
|
16
|
+
ALTER TABLE "plans" RENAME COLUMN "stripePriceIdUsd" TO "providerPriceIdUsd";
|
|
17
|
+
END IF;
|
|
18
|
+
END $$;
|
|
19
|
+
|
|
20
|
+
DO $$ BEGIN
|
|
21
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripePriceIdCny') THEN
|
|
22
|
+
ALTER TABLE "plans" RENAME COLUMN "stripePriceIdCny" TO "providerPriceIdCny";
|
|
23
|
+
END IF;
|
|
24
|
+
END $$;
|
|
25
|
+
|
|
26
|
+
DO $$ BEGIN
|
|
27
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripePriceIdUsdYearly') THEN
|
|
28
|
+
ALTER TABLE "plans" RENAME COLUMN "stripePriceIdUsdYearly" TO "providerPriceIdUsdYearly";
|
|
29
|
+
END IF;
|
|
30
|
+
END $$;
|
|
31
|
+
|
|
32
|
+
DO $$ BEGIN
|
|
33
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripePriceIdCnyYearly') THEN
|
|
34
|
+
ALTER TABLE "plans" RENAME COLUMN "stripePriceIdCnyYearly" TO "providerPriceIdCnyYearly";
|
|
35
|
+
END IF;
|
|
36
|
+
END $$;
|
|
37
|
+
|
|
38
|
+
DO $$ BEGIN
|
|
39
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripeSeatPriceIdUsd') THEN
|
|
40
|
+
ALTER TABLE "plans" RENAME COLUMN "stripeSeatPriceIdUsd" TO "providerSeatPriceIdUsd";
|
|
41
|
+
END IF;
|
|
42
|
+
END $$;
|
|
43
|
+
|
|
44
|
+
DO $$ BEGIN
|
|
45
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'plans' AND column_name = 'stripeSeatPriceIdCny') THEN
|
|
46
|
+
ALTER TABLE "plans" RENAME COLUMN "stripeSeatPriceIdCny" TO "providerSeatPriceIdCny";
|
|
47
|
+
END IF;
|
|
48
|
+
END $$;
|
|
49
|
+
|
|
50
|
+
-- ── Subscription 表 ──
|
|
51
|
+
|
|
52
|
+
DO $$ BEGIN
|
|
53
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'subscriptions' AND column_name = 'stripeCustomerId') THEN
|
|
54
|
+
ALTER TABLE "subscriptions" RENAME COLUMN "stripeCustomerId" TO "providerCustomerId";
|
|
55
|
+
END IF;
|
|
56
|
+
END $$;
|
|
57
|
+
|
|
58
|
+
DO $$ BEGIN
|
|
59
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'subscriptions' AND column_name = 'stripeSubscriptionId') THEN
|
|
60
|
+
ALTER TABLE "subscriptions" RENAME COLUMN "stripeSubscriptionId" TO "providerSubscriptionId";
|
|
61
|
+
END IF;
|
|
62
|
+
END $$;
|
|
63
|
+
|
|
64
|
+
DO $$ BEGIN
|
|
65
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'subscriptions' AND column_name = 'stripePriceId') THEN
|
|
66
|
+
ALTER TABLE "subscriptions" RENAME COLUMN "stripePriceId" TO "providerPriceId";
|
|
67
|
+
END IF;
|
|
68
|
+
END $$;
|
|
69
|
+
|
|
70
|
+
-- 新增 provider 字段
|
|
71
|
+
DO $$ BEGIN
|
|
72
|
+
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'subscriptions' AND column_name = 'provider') THEN
|
|
73
|
+
ALTER TABLE "subscriptions" ADD COLUMN "provider" TEXT NOT NULL DEFAULT 'creem';
|
|
74
|
+
END IF;
|
|
75
|
+
END $$;
|
|
76
|
+
|
|
77
|
+
-- 新增 providerSeatSubscriptionId 字段
|
|
78
|
+
DO $$ BEGIN
|
|
79
|
+
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'subscriptions' AND column_name = 'providerSeatSubscriptionId') THEN
|
|
80
|
+
ALTER TABLE "subscriptions" ADD COLUMN "providerSeatSubscriptionId" TEXT;
|
|
81
|
+
END IF;
|
|
82
|
+
END $$;
|
|
83
|
+
|
|
84
|
+
-- 重建唯一索引
|
|
85
|
+
DROP INDEX IF EXISTS "subscriptions_stripeSubscriptionId_key";
|
|
86
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "subscriptions_providerSubscriptionId_key" ON "subscriptions"("providerSubscriptionId");
|
|
87
|
+
|
|
88
|
+
-- ── Invoice 表 ──
|
|
89
|
+
|
|
90
|
+
DO $$ BEGIN
|
|
91
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'invoices' AND column_name = 'stripeInvoiceId') THEN
|
|
92
|
+
ALTER TABLE "invoices" RENAME COLUMN "stripeInvoiceId" TO "providerInvoiceId";
|
|
93
|
+
END IF;
|
|
94
|
+
END $$;
|
|
95
|
+
|
|
96
|
+
DO $$ BEGIN
|
|
97
|
+
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'invoices' AND column_name = 'stripeEventId') THEN
|
|
98
|
+
ALTER TABLE "invoices" RENAME COLUMN "stripeEventId" TO "providerEventId";
|
|
99
|
+
END IF;
|
|
100
|
+
END $$;
|
|
101
|
+
|
|
102
|
+
-- 重建唯一索引
|
|
103
|
+
DROP INDEX IF EXISTS "invoices_stripeInvoiceId_key";
|
|
104
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "invoices_providerInvoiceId_key" ON "invoices"("providerInvoiceId");
|
|
105
|
+
|
|
106
|
+
-- ── StripeEvent → ProviderEvent ──
|
|
107
|
+
|
|
108
|
+
DROP TABLE IF EXISTS "stripe_events";
|
|
109
|
+
|
|
110
|
+
CREATE TABLE "provider_events" (
|
|
111
|
+
"id" TEXT PRIMARY KEY,
|
|
112
|
+
"providerEventId" TEXT NOT NULL,
|
|
113
|
+
"type" TEXT NOT NULL,
|
|
114
|
+
"status" TEXT NOT NULL DEFAULT 'processing',
|
|
115
|
+
"payload" JSONB,
|
|
116
|
+
"errorMessage" TEXT,
|
|
117
|
+
"processedAt" TIMESTAMPTZ,
|
|
118
|
+
"createdAt" TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "provider_events_providerEventId_key" ON "provider_events"("providerEventId");
|
|
122
|
+
CREATE INDEX IF NOT EXISTS "provider_events_type_createdAt_idx" ON "provider_events"("type", "createdAt");
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
-- AlterTable
|
|
2
|
+
ALTER TABLE "chat_threads" ADD COLUMN "agentId" TEXT;
|
|
3
|
+
|
|
4
|
+
-- AlterTable
|
|
5
|
+
ALTER TABLE "plans" ADD COLUMN "agentQuota" INTEGER,
|
|
6
|
+
ADD COLUMN "skillQuota" INTEGER;
|
|
7
|
+
|
|
8
|
+
-- CreateTable
|
|
9
|
+
CREATE TABLE "user_agents" (
|
|
10
|
+
"id" TEXT NOT NULL,
|
|
11
|
+
"userId" TEXT NOT NULL,
|
|
12
|
+
"name" TEXT NOT NULL,
|
|
13
|
+
"description" TEXT,
|
|
14
|
+
"avatarEmoji" TEXT,
|
|
15
|
+
"systemPrompt" TEXT NOT NULL,
|
|
16
|
+
"allowedTools" JSONB NOT NULL DEFAULT '[]',
|
|
17
|
+
"model" TEXT,
|
|
18
|
+
"temperature" DOUBLE PRECISION,
|
|
19
|
+
"greeting" TEXT,
|
|
20
|
+
"suggestedPrompts" JSONB,
|
|
21
|
+
"knowledgeBaseIds" JSONB NOT NULL DEFAULT '[]',
|
|
22
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
23
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
24
|
+
"isDeleted" BOOLEAN NOT NULL DEFAULT false,
|
|
25
|
+
|
|
26
|
+
CONSTRAINT "user_agents_pkey" PRIMARY KEY ("id")
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
-- CreateTable
|
|
30
|
+
CREATE TABLE "user_skills" (
|
|
31
|
+
"id" TEXT NOT NULL,
|
|
32
|
+
"userId" TEXT NOT NULL,
|
|
33
|
+
"name" TEXT NOT NULL,
|
|
34
|
+
"title" TEXT NOT NULL,
|
|
35
|
+
"template" TEXT NOT NULL,
|
|
36
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
37
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
38
|
+
"isDeleted" BOOLEAN NOT NULL DEFAULT false,
|
|
39
|
+
|
|
40
|
+
CONSTRAINT "user_skills_pkey" PRIMARY KEY ("id")
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
-- CreateIndex
|
|
44
|
+
CREATE INDEX "user_agents_userId_idx" ON "user_agents"("userId");
|
|
45
|
+
|
|
46
|
+
-- CreateIndex
|
|
47
|
+
CREATE UNIQUE INDEX "user_skills_userId_name_key" ON "user_skills"("userId", "name");
|
|
48
|
+
|
|
49
|
+
-- AddForeignKey
|
|
50
|
+
ALTER TABLE "chat_threads" ADD CONSTRAINT "chat_threads_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "user_agents"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
51
|
+
|
|
52
|
+
-- AddForeignKey
|
|
53
|
+
ALTER TABLE "user_agents" ADD CONSTRAINT "user_agents_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
54
|
+
|
|
55
|
+
-- AddForeignKey
|
|
56
|
+
ALTER TABLE "user_skills" ADD CONSTRAINT "user_skills_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
57
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
-- ── 数据迁移:workspace 级订阅 → user 级(按 workspace owner 回填)──
|
|
2
|
+
|
|
3
|
+
-- ① 同 owner 多条订阅:保留 plan.sortOrder 最高,同分用 id 小者,删除其余
|
|
4
|
+
DELETE FROM "subscriptions" s
|
|
5
|
+
USING "subscriptions" s2, "workspaces" w, "workspaces" w2, "plans" p, "plans" p2
|
|
6
|
+
WHERE s."workspaceId" = w."id"
|
|
7
|
+
AND s2."workspaceId" = w2."id"
|
|
8
|
+
AND w."ownerId" = w2."ownerId"
|
|
9
|
+
AND s."planId" = p."id"
|
|
10
|
+
AND s2."planId" = p2."id"
|
|
11
|
+
AND s.id <> s2.id
|
|
12
|
+
AND (p2."sortOrder" > p."sortOrder" OR (p2."sortOrder" = p."sortOrder" AND s2.id < s.id));
|
|
13
|
+
|
|
14
|
+
-- ② 解除旧约束
|
|
15
|
+
ALTER TABLE "subscriptions" DROP CONSTRAINT IF EXISTS "subscriptions_workspaceId_fkey";
|
|
16
|
+
DROP INDEX IF EXISTS "subscriptions_workspaceId_key";
|
|
17
|
+
|
|
18
|
+
-- ③ 添加可空 userId 列
|
|
19
|
+
ALTER TABLE "subscriptions" ADD COLUMN IF NOT EXISTS "userId" TEXT;
|
|
20
|
+
|
|
21
|
+
-- ④ 添加 FK(NULL 值不受 FK 约束)
|
|
22
|
+
ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
23
|
+
|
|
24
|
+
-- ⑤ 按 workspace owner 回填
|
|
25
|
+
UPDATE "subscriptions" s
|
|
26
|
+
SET "userId" = w."ownerId"
|
|
27
|
+
FROM "workspaces" w
|
|
28
|
+
WHERE s."workspaceId" = w."id" AND s."userId" IS NULL;
|
|
29
|
+
|
|
30
|
+
-- ⑥ 孤儿订阅(理论不存在,防御):删除
|
|
31
|
+
DELETE FROM "subscriptions" WHERE "userId" IS NULL;
|
|
32
|
+
|
|
33
|
+
-- ⑦ userId 收紧为 NOT NULL
|
|
34
|
+
ALTER TABLE "subscriptions" ALTER COLUMN "userId" SET NOT NULL;
|
|
35
|
+
|
|
36
|
+
-- ⑧ 删除废弃列
|
|
37
|
+
ALTER TABLE "subscriptions" DROP COLUMN "workspaceId";
|
|
38
|
+
|
|
39
|
+
-- ⑨ 删除废弃 seats 列
|
|
40
|
+
ALTER TABLE "subscriptions" DROP COLUMN "seats";
|
|
41
|
+
|
|
42
|
+
-- ⑩ 创建 userId 唯一索引
|
|
43
|
+
CREATE UNIQUE INDEX "subscriptions_userId_key" ON "subscriptions"("userId");
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
-- DropForeignKey
|
|
2
|
+
ALTER TABLE "workspace_members" DROP CONSTRAINT "workspace_members_userId_fkey";
|
|
3
|
+
|
|
4
|
+
-- DropForeignKey
|
|
5
|
+
ALTER TABLE "workspace_members" DROP CONSTRAINT "workspace_members_workspaceId_fkey";
|
|
6
|
+
|
|
7
|
+
-- AlterTable
|
|
8
|
+
ALTER TABLE "plans" ADD COLUMN "maxGuestSeats" INTEGER;
|
|
9
|
+
|
|
10
|
+
-- DropTable
|
|
11
|
+
DROP TABLE "workspace_members";
|
|
12
|
+
|
|
13
|
+
-- CreateTable
|
|
14
|
+
CREATE TABLE "team_memberships" (
|
|
15
|
+
"id" TEXT NOT NULL,
|
|
16
|
+
"ownerId" TEXT NOT NULL,
|
|
17
|
+
"memberId" TEXT NOT NULL,
|
|
18
|
+
"seatType" TEXT NOT NULL DEFAULT 'member',
|
|
19
|
+
"joinedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
20
|
+
|
|
21
|
+
CONSTRAINT "team_memberships_pkey" PRIMARY KEY ("id")
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
-- CreateTable
|
|
25
|
+
CREATE TABLE "team_invitations" (
|
|
26
|
+
"id" TEXT NOT NULL,
|
|
27
|
+
"ownerId" TEXT NOT NULL,
|
|
28
|
+
"email" TEXT NOT NULL,
|
|
29
|
+
"seatType" TEXT NOT NULL DEFAULT 'member',
|
|
30
|
+
"token" TEXT NOT NULL,
|
|
31
|
+
"channel" TEXT NOT NULL DEFAULT 'email',
|
|
32
|
+
"status" TEXT NOT NULL DEFAULT 'pending',
|
|
33
|
+
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
34
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
35
|
+
"acceptedBy" TEXT,
|
|
36
|
+
|
|
37
|
+
CONSTRAINT "team_invitations_pkey" PRIMARY KEY ("id")
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
-- CreateIndex
|
|
41
|
+
CREATE INDEX "team_memberships_ownerId_idx" ON "team_memberships"("ownerId");
|
|
42
|
+
|
|
43
|
+
-- CreateIndex
|
|
44
|
+
CREATE UNIQUE INDEX "team_memberships_memberId_key" ON "team_memberships"("memberId");
|
|
45
|
+
|
|
46
|
+
-- CreateIndex
|
|
47
|
+
CREATE UNIQUE INDEX "team_invitations_token_key" ON "team_invitations"("token");
|
|
48
|
+
|
|
49
|
+
-- CreateIndex
|
|
50
|
+
CREATE INDEX "team_invitations_ownerId_idx" ON "team_invitations"("ownerId");
|
|
51
|
+
|
|
52
|
+
-- CreateIndex
|
|
53
|
+
CREATE INDEX "team_invitations_email_idx" ON "team_invitations"("email");
|
|
54
|
+
|
|
55
|
+
-- CreateIndex
|
|
56
|
+
CREATE UNIQUE INDEX "team_invitations_ownerId_email_key" ON "team_invitations"("ownerId", "email");
|
|
57
|
+
|
|
58
|
+
-- AddForeignKey
|
|
59
|
+
ALTER TABLE "team_memberships" ADD CONSTRAINT "team_memberships_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
60
|
+
|
|
61
|
+
-- AddForeignKey
|
|
62
|
+
ALTER TABLE "team_memberships" ADD CONSTRAINT "team_memberships_memberId_fkey" FOREIGN KEY ("memberId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
63
|
+
|
|
64
|
+
-- AddForeignKey
|
|
65
|
+
ALTER TABLE "team_invitations" ADD CONSTRAINT "team_invitations_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@allbluecn/database",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.6",
|
|
4
4
|
"license": "AGPL-3.0-or-later",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.ts",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"pg": "^8.22.0",
|
|
16
16
|
"sqlite-vec": "^0.1.9",
|
|
17
17
|
"bcryptjs": "^3.0.2",
|
|
18
|
-
"@allbluecn/shared": "0.4.
|
|
18
|
+
"@allbluecn/shared": "0.4.6"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/better-sqlite3": "^7.6.13",
|
|
@@ -41,8 +41,13 @@
|
|
|
41
41
|
"!src/**/__tests__/**",
|
|
42
42
|
"generated",
|
|
43
43
|
"generated-sqlite",
|
|
44
|
+
"schema.prisma",
|
|
45
|
+
"schema.sqlite.prisma",
|
|
46
|
+
"prisma.config.ts",
|
|
47
|
+
"migrations",
|
|
44
48
|
"desktop-init.ts",
|
|
45
|
-
"desktop-init.d.ts"
|
|
49
|
+
"desktop-init.d.ts",
|
|
50
|
+
"index.ts"
|
|
46
51
|
],
|
|
47
52
|
"scripts": {
|
|
48
53
|
"generate": "prisma generate",
|
package/prisma.config.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
import { defineConfig, env } from "prisma/config";
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
schema: "schema.prisma",
|
|
6
|
+
migrations: {
|
|
7
|
+
path: "migrations",
|
|
8
|
+
seed: "tsx seed.ts",
|
|
9
|
+
},
|
|
10
|
+
datasource: {
|
|
11
|
+
url: env("DATABASE_URL"),
|
|
12
|
+
// shadowDatabaseUrl 仅本地 `migrate dev` 需要(生成迁移时做 diff/reset)。
|
|
13
|
+
// 生产 `migrate deploy` 完全不读此字段,但 Prisma 7 config 加载阶段会全量求值,
|
|
14
|
+
// 用严格 env() 会在 Vercel 等未配置该变量的环境抛 PrismaConfigEnvError。
|
|
15
|
+
// 改用 process.env 兜底,缺失时为 undefined,赋给可选字段合法。
|
|
16
|
+
shadowDatabaseUrl: process.env.SHADOW_DATABASE_URL || undefined,
|
|
17
|
+
},
|
|
18
|
+
});
|