gaojintao01 commited on
Commit
83c8b0e
·
1 Parent(s): 40282a8
complete-migration-fix.js ADDED
@@ -0,0 +1,426 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ console.log('🔧 开始修复 PostgreSQL 迁移问题...\n');
5
+
6
+ // 1. 清理现有的迁移文件
7
+ const migrationsDir = path.join(__dirname, 'server', 'prisma', 'migrations');
8
+ const migrationFiles = fs.readdirSync(migrationsDir)
9
+ .filter(file => file.endsWith('.sql'));
10
+
11
+ console.log('📂 发现的迁移文件:');
12
+ migrationFiles.forEach(file => console.log(` - ${file}`));
13
+
14
+ // 2. 删除所有现有的迁移文件(除了 _prisma_migrations 文件夹)
15
+ console.log('\n🗑️ 清理现有迁移文件...');
16
+ migrationFiles.forEach(file => {
17
+ const filePath = path.join(migrationsDir, file);
18
+ fs.unlinkSync(filePath);
19
+ console.log(` 已删除: ${file}`);
20
+ });
21
+
22
+ // 3. 创建新的合并迁移文件
23
+ console.log('\n📝 创建新的合并迁移文件...');
24
+ const newMigrationFile = path.join(migrationsDir, '20230921191814_initial_migration.sql');
25
+
26
+ const migrationSQL = `-- Initial Migration for PostgreSQL
27
+ -- This migration combines all tables from the previous separate migrations
28
+
29
+ -- Create all tables in the correct order to satisfy foreign key constraints
30
+
31
+ -- Users table (referenced by many others)
32
+ CREATE TABLE "users" (
33
+ "id" SERIAL PRIMARY KEY,
34
+ "username" TEXT UNIQUE,
35
+ "password" TEXT NOT NULL,
36
+ "pfpFilename" TEXT,
37
+ "role" TEXT NOT NULL DEFAULT 'default',
38
+ "suspended" INTEGER NOT NULL DEFAULT 0,
39
+ "seen_recovery_codes" BOOLEAN DEFAULT false,
40
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
41
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
42
+ "dailyMessageLimit" INTEGER,
43
+ "bio" TEXT DEFAULT ''
44
+ );
45
+
46
+ -- Workspaces table (referenced by many others)
47
+ CREATE TABLE "workspaces" (
48
+ "id" SERIAL PRIMARY KEY,
49
+ "name" TEXT NOT NULL,
50
+ "slug" TEXT NOT NULL UNIQUE,
51
+ "vectorTag" TEXT,
52
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
53
+ "openAiTemp" REAL,
54
+ "openAiHistory" INTEGER NOT NULL DEFAULT 20,
55
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
56
+ "openAiPrompt" TEXT,
57
+ "similarityThreshold" REAL DEFAULT 0.25,
58
+ "chatProvider" TEXT,
59
+ "chatModel" TEXT,
60
+ "topN" INTEGER DEFAULT 4,
61
+ "chatMode" TEXT DEFAULT 'chat',
62
+ "pfpFilename" TEXT,
63
+ "agentProvider" TEXT,
64
+ "agentModel" TEXT,
65
+ "queryRefusalResponse" TEXT,
66
+ "vectorSearchMode" TEXT DEFAULT 'default'
67
+ );
68
+
69
+ -- System settings table
70
+ CREATE TABLE "system_settings" (
71
+ "id" SERIAL PRIMARY KEY,
72
+ "label" TEXT NOT NULL UNIQUE,
73
+ "value" TEXT,
74
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
75
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
76
+ );
77
+
78
+ -- API keys table
79
+ CREATE TABLE "api_keys" (
80
+ "id" SERIAL PRIMARY KEY,
81
+ "secret" TEXT UNIQUE,
82
+ "createdBy" INTEGER REFERENCES "users"("id"),
83
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
84
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
85
+ );
86
+
87
+ -- Invites table
88
+ CREATE TABLE "invites" (
89
+ "id" SERIAL PRIMARY KEY,
90
+ "code" TEXT NOT NULL UNIQUE,
91
+ "status" TEXT NOT NULL DEFAULT 'pending',
92
+ "claimedBy" INTEGER REFERENCES "users"("id"),
93
+ "workspaceIds" TEXT,
94
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
95
+ "createdBy" INTEGER NOT NULL REFERENCES "users"("id"),
96
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
97
+ );
98
+
99
+ -- Document vectors table
100
+ CREATE TABLE "document_vectors" (
101
+ "id" SERIAL PRIMARY KEY,
102
+ "docId" TEXT NOT NULL,
103
+ "vectorId" TEXT NOT NULL,
104
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
105
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
106
+ );
107
+
108
+ -- Welcome messages table
109
+ CREATE TABLE "welcome_messages" (
110
+ "id" SERIAL PRIMARY KEY,
111
+ "user" TEXT NOT NULL,
112
+ "response" TEXT NOT NULL,
113
+ "orderIndex" INTEGER,
114
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
115
+ );
116
+
117
+ -- Workspace documents table
118
+ CREATE TABLE "workspace_documents" (
119
+ "id" SERIAL PRIMARY KEY,
120
+ "docId" TEXT NOT NULL UNIQUE,
121
+ "filename" TEXT NOT NULL,
122
+ "docpath" TEXT NOT NULL,
123
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
124
+ "metadata" TEXT,
125
+ "pinned" BOOLEAN DEFAULT false,
126
+ "watched" BOOLEAN DEFAULT false,
127
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
128
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
129
+ );
130
+
131
+ -- Workspace chats table
132
+ CREATE TABLE "workspace_chats" (
133
+ "id" SERIAL PRIMARY KEY,
134
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
135
+ "prompt" TEXT NOT NULL,
136
+ "response" TEXT NOT NULL,
137
+ "include" BOOLEAN NOT NULL DEFAULT true,
138
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
139
+ "thread_id" INTEGER,
140
+ "api_session_id" TEXT,
141
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
142
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
143
+ "feedbackScore" BOOLEAN
144
+ );
145
+
146
+ -- Workspace users table (junction table)
147
+ CREATE TABLE "workspace_users" (
148
+ "id" SERIAL PRIMARY KEY,
149
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
150
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
151
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
152
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
153
+ );
154
+
155
+ -- Workspace suggested messages table
156
+ CREATE TABLE "workspace_suggested_messages" (
157
+ "id" SERIAL PRIMARY KEY,
158
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
159
+ "heading" TEXT NOT NULL,
160
+ "message" TEXT NOT NULL,
161
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
162
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
163
+ );
164
+
165
+ -- Event logs table
166
+ CREATE TABLE "event_logs" (
167
+ "id" SERIAL PRIMARY KEY,
168
+ "event" TEXT NOT NULL,
169
+ "metadata" TEXT,
170
+ "userId" INTEGER REFERENCES "users"("id"),
171
+ "occurredAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
172
+ );
173
+
174
+ -- Cache data table
175
+ CREATE TABLE "cache_data" (
176
+ "id" SERIAL PRIMARY KEY,
177
+ "name" TEXT NOT NULL,
178
+ "data" TEXT NOT NULL,
179
+ "belongsTo" TEXT,
180
+ "ById" INTEGER,
181
+ "expiresAt" TIMESTAMP,
182
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
183
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
184
+ );
185
+
186
+ -- Embed configs table
187
+ CREATE TABLE "embed_configs" (
188
+ "id" SERIAL PRIMARY KEY,
189
+ "uuid" TEXT NOT NULL UNIQUE,
190
+ "enabled" BOOLEAN NOT NULL DEFAULT false,
191
+ "chat_mode" TEXT NOT NULL DEFAULT 'query',
192
+ "allowlist_domains" TEXT,
193
+ "allow_model_override" BOOLEAN NOT NULL DEFAULT false,
194
+ "allow_temperature_override" BOOLEAN NOT NULL DEFAULT false,
195
+ "allow_prompt_override" BOOLEAN NOT NULL DEFAULT false,
196
+ "max_chats_per_day" INTEGER,
197
+ "max_chats_per_session" INTEGER,
198
+ "message_limit" INTEGER DEFAULT 20,
199
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
200
+ "createdBy" INTEGER,
201
+ "usersId" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
202
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
203
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE,
204
+ "users" FOREIGN KEY ("usersId") REFERENCES "users"("id") ON DELETE SET NULL
205
+ );
206
+
207
+ -- Embed chats table
208
+ CREATE TABLE "embed_chats" (
209
+ "id" SERIAL PRIMARY KEY,
210
+ "prompt" TEXT NOT NULL,
211
+ "response" TEXT NOT NULL,
212
+ "session_id" TEXT NOT NULL,
213
+ "include" BOOLEAN NOT NULL DEFAULT true,
214
+ "connection_information" TEXT,
215
+ "embed_id" INTEGER NOT NULL REFERENCES "embed_configs"("id") ON DELETE CASCADE,
216
+ "usersId" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
217
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
218
+ "embed_config" FOREIGN KEY ("embed_id") REFERENCES "embed_configs"("id") ON DELETE CASCADE,
219
+ "users" FOREIGN KEY ("usersId") REFERENCES "users"("id") ON DELETE SET NULL
220
+ );
221
+
222
+ -- Workspace threads table
223
+ CREATE TABLE "workspace_threads" (
224
+ "id" SERIAL PRIMARY KEY,
225
+ "name" TEXT NOT NULL,
226
+ "slug" TEXT NOT NULL UNIQUE,
227
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
228
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
229
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
230
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
231
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE,
232
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
233
+ );
234
+
235
+ -- Workspace agent invocations table
236
+ CREATE TABLE "workspace_agent_invocations" (
237
+ "id" SERIAL PRIMARY KEY,
238
+ "uuid" TEXT NOT NULL UNIQUE,
239
+ "prompt" TEXT NOT NULL,
240
+ "closed" BOOLEAN NOT NULL DEFAULT false,
241
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
242
+ "thread_id" INTEGER,
243
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
244
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
245
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
246
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE,
247
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE
248
+ );
249
+
250
+ -- Slash command presets table
251
+ CREATE TABLE "slash_command_presets" (
252
+ "id" SERIAL PRIMARY KEY,
253
+ "command" TEXT NOT NULL,
254
+ "prompt" TEXT NOT NULL,
255
+ "description" TEXT,
256
+ "uid" INTEGER NOT NULL DEFAULT 0,
257
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
258
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
259
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
260
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
261
+ );
262
+
263
+ -- Recovery codes table
264
+ CREATE TABLE "recovery_codes" (
265
+ "id" SERIAL PRIMARY KEY,
266
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
267
+ "code_hash" TEXT NOT NULL,
268
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
269
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
270
+ );
271
+
272
+ -- Password reset tokens table
273
+ CREATE TABLE "password_reset_tokens" (
274
+ "id" SERIAL PRIMARY KEY,
275
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
276
+ "token" TEXT NOT NULL UNIQUE,
277
+ "expiresAt" TIMESTAMP NOT NULL,
278
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
279
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
280
+ );
281
+
282
+ -- Browser extension API keys table
283
+ CREATE TABLE "browser_extension_api_keys" (
284
+ "id" SERIAL PRIMARY KEY,
285
+ "key" TEXT NOT NULL UNIQUE,
286
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
287
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
288
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
289
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
290
+ );
291
+
292
+ -- Temporary auth tokens table
293
+ CREATE TABLE "temporary_auth_tokens" (
294
+ "id" SERIAL PRIMARY KEY,
295
+ "token" TEXT NOT NULL UNIQUE,
296
+ "userId" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
297
+ "expiresAt" TIMESTAMP NOT NULL,
298
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
299
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
300
+ );
301
+
302
+ -- System prompt variables table
303
+ CREATE TABLE "system_prompt_variables" (
304
+ "id" SERIAL PRIMARY KEY,
305
+ "key" TEXT NOT NULL UNIQUE,
306
+ "value" TEXT,
307
+ "description" TEXT,
308
+ "type" TEXT NOT NULL DEFAULT 'system',
309
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
310
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
311
+ "updatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
312
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
313
+ );
314
+
315
+ -- Prompt history table
316
+ CREATE TABLE "prompt_history" (
317
+ "id" SERIAL PRIMARY KEY,
318
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
319
+ "prompt" TEXT NOT NULL,
320
+ "modifiedBy" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
321
+ "modifiedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
322
+ "workspace" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE,
323
+ "user" FOREIGN KEY ("modifiedBy") REFERENCES "users"("id") ON DELETE SET NULL
324
+ );
325
+
326
+ -- Desktop mobile devices table
327
+ CREATE TABLE "desktop_mobile_devices" (
328
+ "id" SERIAL PRIMARY KEY,
329
+ "deviceOs" TEXT NOT NULL,
330
+ "deviceName" TEXT NOT NULL,
331
+ "token" TEXT NOT NULL UNIQUE,
332
+ "approved" BOOLEAN NOT NULL DEFAULT false,
333
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
334
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
335
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
336
+ );
337
+
338
+ -- Document sync queues table
339
+ CREATE TABLE "document_sync_queues" (
340
+ "id" SERIAL PRIMARY KEY,
341
+ "staleAfterMs" INTEGER NOT NULL DEFAULT 604800000,
342
+ "nextSyncAt" TIMESTAMP NOT NULL,
343
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
344
+ "lastSyncedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
345
+ "workspaceDocId" INTEGER NOT NULL UNIQUE REFERENCES "workspace_documents"("id") ON DELETE CASCADE,
346
+ "workspaceDoc" FOREIGN KEY ("workspaceDocId") REFERENCES "workspace_documents"("id") ON DELETE CASCADE
347
+ );
348
+
349
+ -- Document sync executions table
350
+ CREATE TABLE "document_sync_executions" (
351
+ "id" SERIAL PRIMARY KEY,
352
+ "queueId" INTEGER NOT NULL REFERENCES "document_sync_queues"("id") ON DELETE CASCADE,
353
+ "status" TEXT NOT NULL DEFAULT 'unknown',
354
+ "result" TEXT,
355
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
356
+ "queue" FOREIGN KEY ("queueId") REFERENCES "document_sync_queues"("id") ON DELETE CASCADE
357
+ );
358
+
359
+ -- Workspace parsed files table
360
+ CREATE TABLE "workspace_parsed_files" (
361
+ "id" SERIAL PRIMARY KEY,
362
+ "filename" TEXT NOT NULL UNIQUE,
363
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
364
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
365
+ "threadId" INTEGER REFERENCES "workspace_threads"("id") ON DELETE CASCADE,
366
+ "metadata" TEXT,
367
+ "tokenCountEstimate" INTEGER DEFAULT 0,
368
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
369
+ "workspace" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE,
370
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE,
371
+ "thread" FOREIGN KEY ("threadId") REFERENCES "workspace_threads"("id") ON DELETE CASCADE
372
+ );
373
+
374
+ -- Create indexes for better performance
375
+ CREATE INDEX "workspace_documents_workspaceId_idx" ON "workspace_documents"("workspaceId");
376
+ CREATE INDEX "workspace_chats_workspaceId_idx" ON "workspace_chats"("workspaceId");
377
+ CREATE INDEX "workspace_chats_user_id_idx" ON "workspace_chats"("user_id");
378
+ CREATE INDEX "workspace_users_user_id_idx" ON "workspace_users"("user_id");
379
+ CREATE INDEX "workspace_users_workspace_id_idx" ON "workspace_users"("workspace_id");
380
+ CREATE INDEX "workspace_threads_workspace_id_idx" ON "workspace_threads"("workspace_id");
381
+ CREATE INDEX "workspace_threads_user_id_idx" ON "workspace_threads"("user_id");
382
+ CREATE INDEX "workspace_agent_invocations_workspace_id_idx" ON "workspace_agent_invocations"("workspace_id");
383
+ CREATE INDEX "workspace_agent_invocations_user_id_idx" ON "workspace_agent_invocations"("user_id");
384
+ CREATE INDEX "workspace_agent_invocations_uuid_idx" ON "workspace_agent_invocations"("uuid");
385
+ CREATE INDEX "workspace_suggested_messages_workspaceId_idx" ON "workspace_suggested_messages"("workspaceId");
386
+ CREATE INDEX "event_logs_event_idx" ON "event_logs"("event");
387
+ CREATE INDEX "event_logs_userId_idx" ON "event_logs"("userId");
388
+ CREATE INDEX "cache_data_expiresAt_idx" ON "cache_data"("expiresAt");
389
+ CREATE INDEX "embed_configs_workspace_id_idx" ON "embed_configs"("workspace_id");
390
+ CREATE INDEX "embed_chats_embed_id_idx" ON "embed_chats"("embed_id");
391
+ CREATE INDEX "embed_chats_session_id_idx" ON "embed_chats"("session_id");
392
+ CREATE INDEX "document_sync_queues_workspaceDocId_idx" ON "document_sync_queues"("workspaceDocId");
393
+ CREATE INDEX "document_sync_executions_queueId_idx" ON "document_sync_executions"("queueId");
394
+ CREATE INDEX "slash_command_presets_uid_idx" ON "slash_command_presets"("uid");
395
+ CREATE INDEX "slash_command_presets_userId_idx" ON "slash_command_presets"("userId");
396
+ CREATE INDEX "recovery_codes_user_id_idx" ON "recovery_codes"("user_id");
397
+ CREATE INDEX "password_reset_tokens_user_id_idx" ON "password_reset_tokens"("user_id");
398
+ CREATE INDEX "password_reset_tokens_token_idx" ON "password_reset_tokens"("token");
399
+ CREATE INDEX "temporary_auth_tokens_userId_idx" ON "temporary_auth_tokens"("userId");
400
+ CREATE INDEX "temporary_auth_tokens_token_idx" ON "temporary_auth_tokens"("token");
401
+ CREATE INDEX "system_prompt_variables_userId_idx" ON "system_prompt_variables"("userId");
402
+ CREATE INDEX "prompt_history_workspaceId_idx" ON "prompt_history"("workspaceId");
403
+ CREATE INDEX "prompt_history_modifiedBy_idx" ON "prompt_history"("modifiedBy");
404
+ CREATE INDEX "desktop_mobile_devices_userId_idx" ON "desktop_mobile_devices"("userId");
405
+ CREATE INDEX "desktop_mobile_devices_token_idx" ON "desktop_mobile_devices"("token");
406
+ CREATE INDEX "workspace_parsed_files_workspaceId_idx" ON "workspace_parsed_files"("workspaceId");
407
+ CREATE INDEX "workspace_parsed_files_userId_idx" ON "workspace_parsed_files"("userId");
408
+ CREATE INDEX "workspace_parsed_files_threadId_idx" ON "workspace_parsed_files"("threadId");
409
+ `;
410
+
411
+ fs.writeFileSync(newMigrationFile, migrationSQL);
412
+ console.log(`✅ 已创建新的迁移文件: ${newMigrationFile}`);
413
+
414
+ // 4. 清理迁移锁定文件
415
+ const lockFile = path.join(migrationsDir, 'migration_lock.toml');
416
+ if (fs.existsSync(lockFile)) {
417
+ fs.unlinkSync(lockFile);
418
+ console.log('🔓 已删除迁移锁定文件');
419
+ }
420
+
421
+ console.log('\n🎉 PostgreSQL 迁移修复完成!');
422
+ console.log('\n📋 后续步骤:');
423
+ console.log('1. 确保 DATABASE_URL 环境变量指向 PostgreSQL 数据库');
424
+ console.log('2. 运行: cd server && npx prisma migrate dev');
425
+ console.log('3. 运行: npx prisma generate');
426
+ console.log('4. 运行: npx prisma db seed');
complete-migration-fix.mjs ADDED
@@ -0,0 +1,431 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ // 获取当前文件的目录
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ console.log('🔧 开始修复 PostgreSQL 迁移问题...\n');
10
+
11
+ // 1. 清理现有的迁移文件
12
+ const migrationsDir = path.join(__dirname, 'server', 'prisma', 'migrations');
13
+ const migrationFiles = fs.readdirSync(migrationsDir)
14
+ .filter(file => file.endsWith('.sql'));
15
+
16
+ console.log('📂 发现的迁移文件:');
17
+ migrationFiles.forEach(file => console.log(` - ${file}`));
18
+
19
+ // 2. 删除所有现有的迁移文件(除了 _prisma_migrations 文件夹)
20
+ console.log('\n🗑️ 清理现有迁移文件...');
21
+ migrationFiles.forEach(file => {
22
+ const filePath = path.join(migrationsDir, file);
23
+ fs.unlinkSync(filePath);
24
+ console.log(` 已删除: ${file}`);
25
+ });
26
+
27
+ // 3. 创建新的合并迁移文件
28
+ console.log('\n📝 创建新的合并迁移文件...');
29
+ const newMigrationFile = path.join(migrationsDir, '20230921191814_initial_migration.sql');
30
+
31
+ const migrationSQL = `-- Initial Migration for PostgreSQL
32
+ -- This migration combines all tables from the previous separate migrations
33
+
34
+ -- Create all tables in the correct order to satisfy foreign key constraints
35
+
36
+ -- Users table (referenced by many others)
37
+ CREATE TABLE "users" (
38
+ "id" SERIAL PRIMARY KEY,
39
+ "username" TEXT UNIQUE,
40
+ "password" TEXT NOT NULL,
41
+ "pfpFilename" TEXT,
42
+ "role" TEXT NOT NULL DEFAULT 'default',
43
+ "suspended" INTEGER NOT NULL DEFAULT 0,
44
+ "seen_recovery_codes" BOOLEAN DEFAULT false,
45
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
46
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
47
+ "dailyMessageLimit" INTEGER,
48
+ "bio" TEXT DEFAULT ''
49
+ );
50
+
51
+ -- Workspaces table (referenced by many others)
52
+ CREATE TABLE "workspaces" (
53
+ "id" SERIAL PRIMARY KEY,
54
+ "name" TEXT NOT NULL,
55
+ "slug" TEXT NOT NULL UNIQUE,
56
+ "vectorTag" TEXT,
57
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
58
+ "openAiTemp" REAL,
59
+ "openAiHistory" INTEGER NOT NULL DEFAULT 20,
60
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
61
+ "openAiPrompt" TEXT,
62
+ "similarityThreshold" REAL DEFAULT 0.25,
63
+ "chatProvider" TEXT,
64
+ "chatModel" TEXT,
65
+ "topN" INTEGER DEFAULT 4,
66
+ "chatMode" TEXT DEFAULT 'chat',
67
+ "pfpFilename" TEXT,
68
+ "agentProvider" TEXT,
69
+ "agentModel" TEXT,
70
+ "queryRefusalResponse" TEXT,
71
+ "vectorSearchMode" TEXT DEFAULT 'default'
72
+ );
73
+
74
+ -- System settings table
75
+ CREATE TABLE "system_settings" (
76
+ "id" SERIAL PRIMARY KEY,
77
+ "label" TEXT NOT NULL UNIQUE,
78
+ "value" TEXT,
79
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
80
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
81
+ );
82
+
83
+ -- API keys table
84
+ CREATE TABLE "api_keys" (
85
+ "id" SERIAL PRIMARY KEY,
86
+ "secret" TEXT UNIQUE,
87
+ "createdBy" INTEGER REFERENCES "users"("id"),
88
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
89
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
90
+ );
91
+
92
+ -- Invites table
93
+ CREATE TABLE "invites" (
94
+ "id" SERIAL PRIMARY KEY,
95
+ "code" TEXT NOT NULL UNIQUE,
96
+ "status" TEXT NOT NULL DEFAULT 'pending',
97
+ "claimedBy" INTEGER REFERENCES "users"("id"),
98
+ "workspaceIds" TEXT,
99
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
100
+ "createdBy" INTEGER NOT NULL REFERENCES "users"("id"),
101
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
102
+ );
103
+
104
+ -- Document vectors table
105
+ CREATE TABLE "document_vectors" (
106
+ "id" SERIAL PRIMARY KEY,
107
+ "docId" TEXT NOT NULL,
108
+ "vectorId" TEXT NOT NULL,
109
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
110
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
111
+ );
112
+
113
+ -- Welcome messages table
114
+ CREATE TABLE "welcome_messages" (
115
+ "id" SERIAL PRIMARY KEY,
116
+ "user" TEXT NOT NULL,
117
+ "response" TEXT NOT NULL,
118
+ "orderIndex" INTEGER,
119
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
120
+ );
121
+
122
+ -- Workspace documents table
123
+ CREATE TABLE "workspace_documents" (
124
+ "id" SERIAL PRIMARY KEY,
125
+ "docId" TEXT NOT NULL UNIQUE,
126
+ "filename" TEXT NOT NULL,
127
+ "docpath" TEXT NOT NULL,
128
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
129
+ "metadata" TEXT,
130
+ "pinned" BOOLEAN DEFAULT false,
131
+ "watched" BOOLEAN DEFAULT false,
132
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
133
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
134
+ );
135
+
136
+ -- Workspace chats table
137
+ CREATE TABLE "workspace_chats" (
138
+ "id" SERIAL PRIMARY KEY,
139
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
140
+ "prompt" TEXT NOT NULL,
141
+ "response" TEXT NOT NULL,
142
+ "include" BOOLEAN NOT NULL DEFAULT true,
143
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
144
+ "thread_id" INTEGER,
145
+ "api_session_id" TEXT,
146
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
147
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
148
+ "feedbackScore" BOOLEAN
149
+ );
150
+
151
+ -- Workspace users table (junction table)
152
+ CREATE TABLE "workspace_users" (
153
+ "id" SERIAL PRIMARY KEY,
154
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
155
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
156
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
157
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
158
+ );
159
+
160
+ -- Workspace suggested messages table
161
+ CREATE TABLE "workspace_suggested_messages" (
162
+ "id" SERIAL PRIMARY KEY,
163
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
164
+ "heading" TEXT NOT NULL,
165
+ "message" TEXT NOT NULL,
166
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
167
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
168
+ );
169
+
170
+ -- Event logs table
171
+ CREATE TABLE "event_logs" (
172
+ "id" SERIAL PRIMARY KEY,
173
+ "event" TEXT NOT NULL,
174
+ "metadata" TEXT,
175
+ "userId" INTEGER REFERENCES "users"("id"),
176
+ "occurredAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
177
+ );
178
+
179
+ -- Cache data table
180
+ CREATE TABLE "cache_data" (
181
+ "id" SERIAL PRIMARY KEY,
182
+ "name" TEXT NOT NULL,
183
+ "data" TEXT NOT NULL,
184
+ "belongsTo" TEXT,
185
+ "ById" INTEGER,
186
+ "expiresAt" TIMESTAMP,
187
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
188
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
189
+ );
190
+
191
+ -- Embed configs table
192
+ CREATE TABLE "embed_configs" (
193
+ "id" SERIAL PRIMARY KEY,
194
+ "uuid" TEXT NOT NULL UNIQUE,
195
+ "enabled" BOOLEAN NOT NULL DEFAULT false,
196
+ "chat_mode" TEXT NOT NULL DEFAULT 'query',
197
+ "allowlist_domains" TEXT,
198
+ "allow_model_override" BOOLEAN NOT NULL DEFAULT false,
199
+ "allow_temperature_override" BOOLEAN NOT NULL DEFAULT false,
200
+ "allow_prompt_override" BOOLEAN NOT NULL DEFAULT false,
201
+ "max_chats_per_day" INTEGER,
202
+ "max_chats_per_session" INTEGER,
203
+ "message_limit" INTEGER DEFAULT 20,
204
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
205
+ "createdBy" INTEGER,
206
+ "usersId" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
207
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
208
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE,
209
+ "users" FOREIGN KEY ("usersId") REFERENCES "users"("id") ON DELETE SET NULL
210
+ );
211
+
212
+ -- Embed chats table
213
+ CREATE TABLE "embed_chats" (
214
+ "id" SERIAL PRIMARY KEY,
215
+ "prompt" TEXT NOT NULL,
216
+ "response" TEXT NOT NULL,
217
+ "session_id" TEXT NOT NULL,
218
+ "include" BOOLEAN NOT NULL DEFAULT true,
219
+ "connection_information" TEXT,
220
+ "embed_id" INTEGER NOT NULL REFERENCES "embed_configs"("id") ON DELETE CASCADE,
221
+ "usersId" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
222
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
223
+ "embed_config" FOREIGN KEY ("embed_id") REFERENCES "embed_configs"("id") ON DELETE CASCADE,
224
+ "users" FOREIGN KEY ("usersId") REFERENCES "users"("id") ON DELETE SET NULL
225
+ );
226
+
227
+ -- Workspace threads table
228
+ CREATE TABLE "workspace_threads" (
229
+ "id" SERIAL PRIMARY KEY,
230
+ "name" TEXT NOT NULL,
231
+ "slug" TEXT NOT NULL UNIQUE,
232
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
233
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
234
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
235
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
236
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE,
237
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
238
+ );
239
+
240
+ -- Workspace agent invocations table
241
+ CREATE TABLE "workspace_agent_invocations" (
242
+ "id" SERIAL PRIMARY KEY,
243
+ "uuid" TEXT NOT NULL UNIQUE,
244
+ "prompt" TEXT NOT NULL,
245
+ "closed" BOOLEAN NOT NULL DEFAULT false,
246
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
247
+ "thread_id" INTEGER,
248
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
249
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
250
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
251
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE,
252
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE
253
+ );
254
+
255
+ -- Slash command presets table
256
+ CREATE TABLE "slash_command_presets" (
257
+ "id" SERIAL PRIMARY KEY,
258
+ "command" TEXT NOT NULL,
259
+ "prompt" TEXT NOT NULL,
260
+ "description" TEXT,
261
+ "uid" INTEGER NOT NULL DEFAULT 0,
262
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
263
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
264
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
265
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
266
+ );
267
+
268
+ -- Recovery codes table
269
+ CREATE TABLE "recovery_codes" (
270
+ "id" SERIAL PRIMARY KEY,
271
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
272
+ "code_hash" TEXT NOT NULL,
273
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
274
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
275
+ );
276
+
277
+ -- Password reset tokens table
278
+ CREATE TABLE "password_reset_tokens" (
279
+ "id" SERIAL PRIMARY KEY,
280
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
281
+ "token" TEXT NOT NULL UNIQUE,
282
+ "expiresAt" TIMESTAMP NOT NULL,
283
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
284
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
285
+ );
286
+
287
+ -- Browser extension API keys table
288
+ CREATE TABLE "browser_extension_api_keys" (
289
+ "id" SERIAL PRIMARY KEY,
290
+ "key" TEXT NOT NULL UNIQUE,
291
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
292
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
293
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
294
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
295
+ );
296
+
297
+ -- Temporary auth tokens table
298
+ CREATE TABLE "temporary_auth_tokens" (
299
+ "id" SERIAL PRIMARY KEY,
300
+ "token" TEXT NOT NULL UNIQUE,
301
+ "userId" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
302
+ "expiresAt" TIMESTAMP NOT NULL,
303
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
304
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
305
+ );
306
+
307
+ -- System prompt variables table
308
+ CREATE TABLE "system_prompt_variables" (
309
+ "id" SERIAL PRIMARY KEY,
310
+ "key" TEXT NOT NULL UNIQUE,
311
+ "value" TEXT,
312
+ "description" TEXT,
313
+ "type" TEXT NOT NULL DEFAULT 'system',
314
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
315
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
316
+ "updatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
317
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
318
+ );
319
+
320
+ -- Prompt history table
321
+ CREATE TABLE "prompt_history" (
322
+ "id" SERIAL PRIMARY KEY,
323
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
324
+ "prompt" TEXT NOT NULL,
325
+ "modifiedBy" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
326
+ "modifiedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
327
+ "workspace" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE,
328
+ "user" FOREIGN KEY ("modifiedBy") REFERENCES "users"("id") ON DELETE SET NULL
329
+ );
330
+
331
+ -- Desktop mobile devices table
332
+ CREATE TABLE "desktop_mobile_devices" (
333
+ "id" SERIAL PRIMARY KEY,
334
+ "deviceOs" TEXT NOT NULL,
335
+ "deviceName" TEXT NOT NULL,
336
+ "token" TEXT NOT NULL UNIQUE,
337
+ "approved" BOOLEAN NOT NULL DEFAULT false,
338
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
339
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
340
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
341
+ );
342
+
343
+ -- Document sync queues table
344
+ CREATE TABLE "document_sync_queues" (
345
+ "id" SERIAL PRIMARY KEY,
346
+ "staleAfterMs" INTEGER NOT NULL DEFAULT 604800000,
347
+ "nextSyncAt" TIMESTAMP NOT NULL,
348
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
349
+ "lastSyncedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
350
+ "workspaceDocId" INTEGER NOT NULL UNIQUE REFERENCES "workspace_documents"("id") ON DELETE CASCADE,
351
+ "workspaceDoc" FOREIGN KEY ("workspaceDocId") REFERENCES "workspace_documents"("id") ON DELETE CASCADE
352
+ );
353
+
354
+ -- Document sync executions table
355
+ CREATE TABLE "document_sync_executions" (
356
+ "id" SERIAL PRIMARY KEY,
357
+ "queueId" INTEGER NOT NULL REFERENCES "document_sync_queues"("id") ON DELETE CASCADE,
358
+ "status" TEXT NOT NULL DEFAULT 'unknown',
359
+ "result" TEXT,
360
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
361
+ "queue" FOREIGN KEY ("queueId") REFERENCES "document_sync_queues"("id") ON DELETE CASCADE
362
+ );
363
+
364
+ -- Workspace parsed files table
365
+ CREATE TABLE "workspace_parsed_files" (
366
+ "id" SERIAL PRIMARY KEY,
367
+ "filename" TEXT NOT NULL UNIQUE,
368
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
369
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
370
+ "threadId" INTEGER REFERENCES "workspace_threads"("id") ON DELETE CASCADE,
371
+ "metadata" TEXT,
372
+ "tokenCountEstimate" INTEGER DEFAULT 0,
373
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
374
+ "workspace" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE,
375
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE,
376
+ "thread" FOREIGN KEY ("threadId") REFERENCES "workspace_threads"("id") ON DELETE CASCADE
377
+ );
378
+
379
+ -- Create indexes for better performance
380
+ CREATE INDEX "workspace_documents_workspaceId_idx" ON "workspace_documents"("workspaceId");
381
+ CREATE INDEX "workspace_chats_workspaceId_idx" ON "workspace_chats"("workspaceId");
382
+ CREATE INDEX "workspace_chats_user_id_idx" ON "workspace_chats"("user_id");
383
+ CREATE INDEX "workspace_users_user_id_idx" ON "workspace_users"("user_id");
384
+ CREATE INDEX "workspace_users_workspace_id_idx" ON "workspace_users"("workspace_id");
385
+ CREATE INDEX "workspace_threads_workspace_id_idx" ON "workspace_threads"("workspace_id");
386
+ CREATE INDEX "workspace_threads_user_id_idx" ON "workspace_threads"("user_id");
387
+ CREATE INDEX "workspace_agent_invocations_workspace_id_idx" ON "workspace_agent_invocations"("workspace_id");
388
+ CREATE INDEX "workspace_agent_invocations_user_id_idx" ON "workspace_agent_invocations"("user_id");
389
+ CREATE INDEX "workspace_agent_invocations_uuid_idx" ON "workspace_agent_invocations"("uuid");
390
+ CREATE INDEX "workspace_suggested_messages_workspaceId_idx" ON "workspace_suggested_messages"("workspaceId");
391
+ CREATE INDEX "event_logs_event_idx" ON "event_logs"("event");
392
+ CREATE INDEX "event_logs_userId_idx" ON "event_logs"("userId");
393
+ CREATE INDEX "cache_data_expiresAt_idx" ON "cache_data"("expiresAt");
394
+ CREATE INDEX "embed_configs_workspace_id_idx" ON "embed_configs"("workspace_id");
395
+ CREATE INDEX "embed_chats_embed_id_idx" ON "embed_chats"("embed_id");
396
+ CREATE INDEX "embed_chats_session_id_idx" ON "embed_chats"("session_id");
397
+ CREATE INDEX "document_sync_queues_workspaceDocId_idx" ON "document_sync_queues"("workspaceDocId");
398
+ CREATE INDEX "document_sync_executions_queueId_idx" ON "document_sync_executions"("queueId");
399
+ CREATE INDEX "slash_command_presets_uid_idx" ON "slash_command_presets"("uid");
400
+ CREATE INDEX "slash_command_presets_userId_idx" ON "slash_command_presets"("userId");
401
+ CREATE INDEX "recovery_codes_user_id_idx" ON "recovery_codes"("user_id");
402
+ CREATE INDEX "password_reset_tokens_user_id_idx" ON "password_reset_tokens"("user_id");
403
+ CREATE INDEX "password_reset_tokens_token_idx" ON "password_reset_tokens"("token");
404
+ CREATE INDEX "temporary_auth_tokens_userId_idx" ON "temporary_auth_tokens"("userId");
405
+ CREATE INDEX "temporary_auth_tokens_token_idx" ON "temporary_auth_tokens"("token");
406
+ CREATE INDEX "system_prompt_variables_userId_idx" ON "system_prompt_variables"("userId");
407
+ CREATE INDEX "prompt_history_workspaceId_idx" ON "prompt_history"("workspaceId");
408
+ CREATE INDEX "prompt_history_modifiedBy_idx" ON "prompt_history"("modifiedBy");
409
+ CREATE INDEX "desktop_mobile_devices_userId_idx" ON "desktop_mobile_devices"("userId");
410
+ CREATE INDEX "desktop_mobile_devices_token_idx" ON "desktop_mobile_devices"("token");
411
+ CREATE INDEX "workspace_parsed_files_workspaceId_idx" ON "workspace_parsed_files"("workspaceId");
412
+ CREATE INDEX "workspace_parsed_files_userId_idx" ON "workspace_parsed_files"("userId");
413
+ CREATE INDEX "workspace_parsed_files_threadId_idx" ON "workspace_parsed_files"("threadId");
414
+ `;
415
+
416
+ fs.writeFileSync(newMigrationFile, migrationSQL);
417
+ console.log(`✅ 已创建新的迁移文件: ${newMigrationFile}`);
418
+
419
+ // 4. 清理迁移锁定文件
420
+ const lockFile = path.join(migrationsDir, 'migration_lock.toml');
421
+ if (fs.existsSync(lockFile)) {
422
+ fs.unlinkSync(lockFile);
423
+ console.log('🔓 已删除迁移锁定文件');
424
+ }
425
+
426
+ console.log('\n🎉 PostgreSQL 迁移修复完成!');
427
+ console.log('\n📋 后续步骤:');
428
+ console.log('1. 确保 DATABASE_URL 环境变量指向 PostgreSQL 数据库');
429
+ console.log('2. 运行: cd server && npx prisma migrate dev');
430
+ console.log('3. 运行: npx prisma generate');
431
+ console.log('4. 运行: npx prisma db seed');
fix-postgresql-migrations.js ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ // 读取所有迁移文件
5
+ const migrationsDir = path.join(__dirname, 'server', 'prisma', 'migrations');
6
+ const migrationFiles = fs.readdirSync(migrationsDir)
7
+ .filter(file => file.endsWith('.sql'))
8
+ .sort();
9
+
10
+ console.log('发现的迁移文件:', migrationFiles);
11
+
12
+ // 1. 重命名迁移文件,移除 _init 后缀
13
+ migrationFiles.forEach(file => {
14
+ if (file.includes('_init')) {
15
+ const newFile = file.replace('_init', '');
16
+ const oldPath = path.join(migrationsDir, file);
17
+ const newPath = path.join(migrationsDir, newFile);
18
+
19
+ console.log(`重命名: ${file} -> ${newFile}`);
20
+ fs.renameSync(oldPath, newPath);
21
+ }
22
+ });
23
+
24
+ // 2. 修复 20230921191814.sql 中的外键约束问题
25
+ const mainMigrationFile = path.join(migrationsDir, '20230921191814.sql');
26
+ if (fs.existsSync(mainMigrationFile)) {
27
+ let content = fs.readFileSync(mainMigrationFile, 'utf8');
28
+
29
+ // 重新排序表创建,确保被引用的表先创建
30
+ const tables = [
31
+ {
32
+ name: 'users',
33
+ sql: `CREATE TABLE "users" (
34
+ "id" SERIAL PRIMARY KEY,
35
+ "username" TEXT,
36
+ "password" TEXT NOT NULL,
37
+ "role" TEXT NOT NULL DEFAULT 'default',
38
+ "suspended" INTEGER NOT NULL DEFAULT 0,
39
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
40
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
41
+ );`
42
+ },
43
+ {
44
+ name: 'workspaces',
45
+ sql: `CREATE TABLE "workspaces" (
46
+ "id" SERIAL PRIMARY KEY,
47
+ "name" TEXT NOT NULL,
48
+ "slug" TEXT NOT NULL,
49
+ "vectorTag" TEXT,
50
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
51
+ "openAiTemp" REAL,
52
+ "openAiHistory" INTEGER NOT NULL DEFAULT 20,
53
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
54
+ "openAiPrompt" TEXT
55
+ );`
56
+ },
57
+ {
58
+ name: 'api_keys',
59
+ sql: `CREATE TABLE "api_keys" (
60
+ "id" SERIAL PRIMARY KEY,
61
+ "secret" TEXT,
62
+ "createdBy" INTEGER,
63
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
64
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
65
+ );`
66
+ },
67
+ {
68
+ name: 'system_settings',
69
+ sql: `CREATE TABLE "system_settings" (
70
+ "id" SERIAL PRIMARY KEY,
71
+ "label" TEXT NOT NULL,
72
+ "value" TEXT,
73
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
74
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
75
+ );`
76
+ },
77
+ {
78
+ name: 'document_vectors',
79
+ sql: `CREATE TABLE "document_vectors" (
80
+ "id" SERIAL PRIMARY KEY,
81
+ "docId" TEXT NOT NULL,
82
+ "vectorId" TEXT NOT NULL,
83
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
84
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
85
+ );`
86
+ },
87
+ {
88
+ name: 'welcome_messages',
89
+ sql: `CREATE TABLE "welcome_messages" (
90
+ "id" SERIAL PRIMARY KEY,
91
+ "user" TEXT NOT NULL,
92
+ "response" TEXT NOT NULL,
93
+ "orderIndex" INTEGER,
94
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
95
+ );`
96
+ },
97
+ {
98
+ name: 'invites',
99
+ sql: `CREATE TABLE "invites" (
100
+ "id" SERIAL PRIMARY KEY,
101
+ "code" TEXT NOT NULL,
102
+ "status" TEXT NOT NULL DEFAULT 'pending',
103
+ "claimedBy" INTEGER,
104
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
105
+ "createdBy" INTEGER NOT NULL,
106
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
107
+ );`
108
+ },
109
+ {
110
+ name: 'workspace_documents',
111
+ sql: `CREATE TABLE "workspace_documents" (
112
+ "id" SERIAL PRIMARY KEY,
113
+ "docId" TEXT NOT NULL,
114
+ "filename" TEXT NOT NULL,
115
+ "docpath" TEXT NOT NULL,
116
+ "workspaceId" INTEGER NOT NULL,
117
+ "metadata" TEXT,
118
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
119
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
120
+ );`
121
+ },
122
+ {
123
+ name: 'workspace_chats',
124
+ sql: `CREATE TABLE "workspace_chats" (
125
+ "id" SERIAL PRIMARY KEY,
126
+ "workspaceId" INTEGER NOT NULL,
127
+ "prompt" TEXT NOT NULL,
128
+ "response" TEXT NOT NULL,
129
+ "include" BOOLEAN NOT NULL DEFAULT true,
130
+ "user_id" INTEGER,
131
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
132
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
133
+ );`
134
+ },
135
+ {
136
+ name: 'workspace_users',
137
+ sql: `CREATE TABLE "workspace_users" (
138
+ "id" SERIAL PRIMARY KEY,
139
+ "user_id" INTEGER NOT NULL,
140
+ "workspace_id" INTEGER NOT NULL,
141
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
142
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
143
+ );`
144
+ }
145
+ ];
146
+
147
+ // 提取索引创建语句
148
+ const indexRegex = /-- CreateIndex\s+CREATE UNIQUE INDEX.*?;\n/g;
149
+ const indexes = content.match(indexRegex) || [];
150
+
151
+ // 构建新的迁移文件内容
152
+ let newContent = '-- CreateTable\n\n';
153
+
154
+ // 添加所有表创建语句
155
+ tables.forEach(table => {
156
+ newContent += table.sql + '\n\n';
157
+ });
158
+
159
+ // 添加所有外键约束(在所有表创建之后)
160
+ newContent += '-- Add foreign key constraints\n';
161
+ newContent += 'ALTER TABLE "workspace_documents" ADD CONSTRAINT "workspace_documents_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE RESTRICT ON UPDATE CASCADE;\n';
162
+ newContent += 'ALTER TABLE "workspace_chats" ADD CONSTRAINT "workspace_chats_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE;\n';
163
+ newContent += 'ALTER TABLE "workspace_users" ADD CONSTRAINT "workspace_users_workspace_id_fkey" FOREIGN KEY ("workspace_id") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE;\n';
164
+ newContent += 'ALTER TABLE "workspace_users" ADD CONSTRAINT "workspace_users_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE;\n';
165
+ newContent += '\n';
166
+
167
+ // 添加索引
168
+ newContent += '-- CreateIndex\n\n';
169
+ indexes.forEach(index => newContent += index + '\n');
170
+
171
+ // 写入修复后的文件
172
+ fs.writeFileSync(mainMigrationFile, newContent);
173
+ console.log('已修复主迁移文件的外键约束问题');
174
+ }
175
+
176
+ console.log('迁移文件修复完成!');
177
+ console.log('\n请执行以下命令来完成迁移:');
178
+ console.log('1. cd server');
179
+ console.log('2. npx prisma migrate reset');
180
+ console.log('3. npx prisma generate');
postgresql-fix-plan.md ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PostgreSQL 迁移文件兼容性分析报告
2
+
3
+ ## 执行摘要
4
+
5
+ 经过对 `server/prisma/migrations/` 目录下所有 32 个迁移文件的系统性审查,**发现所有迁移文件都已经使用了 PostgreSQL 兼容的语法**。这意味着 P3009 错误可能不是由迁移文件中的 SQL 语法不兼容导致的。
6
+
7
+ ## 详细分析结果
8
+
9
+ ### 1. 已正确使用的 PostgreSQL 语法
10
+
11
+ #### ✅ 自增主键
12
+ 所有表都正确使用了 `SERIAL PRIMARY KEY` 而非 `AUTOINCREMENT`:
13
+ ```sql
14
+ "id" SERIAL PRIMARY KEY,
15
+ ```
16
+
17
+ #### ✅ 时间戳类型
18
+ 所有时间字段都正确使用了 `TIMESTAMP` 而非 `DATETIME`:
19
+ ```sql
20
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
21
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
22
+ ```
23
+
24
+ #### ✅ 布尔类型
25
+ 所有布尔字段都正确使用了 `BOOLEAN`:
26
+ ```sql
27
+ "enabled" BOOLEAN NOT NULL DEFAULT false,
28
+ "pinned" BOOLEAN DEFAULT false,
29
+ ```
30
+
31
+ #### ✅ 外键约束
32
+ 所有外键约束都使用了正确的 PostgreSQL 语法:
33
+ ```sql
34
+ CONSTRAINT "workspace_documents_workspaceId_fkey"
35
+ FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id")
36
+ ON DELETE RESTRICT ON UPDATE CASCADE
37
+ ```
38
+
39
+ #### ✅ 唯一索引
40
+ 所有唯一索引都使用了正确的语法:
41
+ ```sql
42
+ CREATE UNIQUE INDEX "users_username_key" ON "users"("username");
43
+ ```
44
+
45
+ #### ✅ 检查约束
46
+ 正确使用了 PostgreSQL 的检查约束语法:
47
+ ```sql
48
+ "topN" INTEGER DEFAULT 4 CHECK ("topN" > 0)
49
+ ```
50
+
51
+ ### 2. 迁移文件列表(全部兼容)
52
+
53
+ 1. **20230921191814_init** - 初始数据库架构 ✅
54
+ 2. **20231101001441_init** - 添加相似度阈值 ✅
55
+ 3. **20231101195421_init** - 缓存数据表 ✅
56
+ 4. **20231129012019_add** - 用户头像文件名 ✅
57
+ 5. **20240113013409_init** - 聊天模型字段 ✅
58
+ 6. **20240118201333_init** - topN 字段与检查约束 ✅
59
+ 7. **20240202002020_init** - 嵌入配置和聊天表 ✅
60
+ 8. **20240206181106_init** - 工作空间建议消息 ✅
61
+ 9. **20240206211916_init** - 事件日志表 ✅
62
+ 10. **20240208224848_init** - 工作空间线程 ✅
63
+ 11. **20240210004405_init** - 反馈分数 ✅
64
+ 12. **20240216214639_init** - 聊天模式 ✅
65
+ 13. **20240219211018_init** - 文档固定 ✅
66
+ 14. **20240301002308_init** - 工作空间头像 ✅
67
+ 15. **20240326231053_init** - 邀请工作空间 IDs ✅
68
+ 16. **20240405015034_init** - 聊天提供商 ✅
69
+ 17. **20240412183346_init** - Agent 模型和调用 ✅
70
+ 18. **20240425004220_init** - 恢复码和密码重置 ✅
71
+ 19. **20240430230707_init** - 查询拒绝响应 ✅
72
+ 20. **20240510032311_init** - 斜杠命令预设 ✅
73
+ 21. **20240618224346_init** - 文档同步队列 ✅
74
+ 22. **20240821215625_init** - API 会话 ID ✅
75
+ 23. **20240824005054_init** - 浏览器扩展 API 密钥 ✅
76
+ 24. **20241003192954_init** - 每日消息限制 ✅
77
+ 25. **20241029203722_init** - 临时认证令牌 ✅
78
+ 26. **20241029233509_init** - 令牌索引 ✅
79
+ 27. **20250102204948_init** - 向量搜索模式 ✅
80
+ 28. **20250226005538_init** - 用户简介 ✅
81
+ 29. **20250318154720_init** - 系统提示变量 ✅
82
+ 30. **20250506214129_init** - 提示历史 ✅
83
+ 31. **20250709230835_init** - 嵌入消息限制 ✅
84
+ 32. **20250725194841_init** - 桌面移动设备 ✅
85
+ 33. **20250808171557_init** - 工作空间解析文件 ✅
86
+
87
+ ## 可能的 P3009 错误原因
88
+
89
+ 既然所有迁移文件都是 PostgreSQL 兼容的,P3009 错误可能由以下原因导致:
90
+
91
+ ### 1. Prisma Schema 配置问题
92
+ 检查 `schema.prisma` 文件中的数据库提供者配置:
93
+ ```prisma
94
+ datasource db {
95
+ provider = "postgresql"
96
+ url = env("DATABASE_URL")
97
+ }
98
+ ```
99
+
100
+ ### 2. 环境变量问题
101
+ - `DATABASE_URL` 可能指向了 SQLite 而非 PostgreSQL
102
+ - 连接字符串格式可能不正确
103
+
104
+ ### 3. 迁移执行顺序问题
105
+ - 可能存在未应用的迁移
106
+ - 迁移锁文件可能损坏
107
+
108
+ ### 4. 数据库连接问题
109
+ - PostgreSQL 服务器可能未运行
110
+ - 权限问题可能导致迁移失败
111
+
112
+ ## 建议的排查步骤
113
+
114
+ ### 第一步:验证 Prisma 配置
115
+ 1. 检查 `schema.prisma` 中的提供者设置
116
+ 2. 验证 `DATABASE_URL` 环境变量
117
+ 3. 确保使用 PostgreSQL 连接字符串格式
118
+
119
+ ### 第二步:检查迁移状态
120
+ ```bash
121
+ # 查看迁移状态
122
+ npx prisma migrate status
123
+
124
+ # 重置迁移(谨慎使用)
125
+ npx prisma migrate reset
126
+ ```
127
+
128
+ ### 第三步:验证数据库连接
129
+ ```bash
130
+ # 测试数据库连接
131
+ npx prisma db push --preview-feature
132
+ ```
133
+
134
+ ### 第四步:检查迁移锁
135
+ - 查看 `migrations/migration_lock.toml` 文件
136
+ - 确保没有锁定的迁移
137
+
138
+ ## 结论
139
+
140
+ 所有迁移文件都已经正确使用了 PostgreSQL 兼容语法。P3009 错误很可能是由配置问题、环境变量或迁移执行状态问题导致的,而不是 SQL 语法不兼容。
141
+
142
+ 建议优先检查 Prisma 配置和数据库连接设置,而不是修改迁移文件。
server/prisma/migrations/20230921191814_initial_migration.sql ADDED
@@ -0,0 +1,383 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -- Initial Migration for PostgreSQL
2
+ -- This migration combines all tables from the previous separate migrations
3
+
4
+ -- Create all tables in the correct order to satisfy foreign key constraints
5
+
6
+ -- Users table (referenced by many others)
7
+ CREATE TABLE "users" (
8
+ "id" SERIAL PRIMARY KEY,
9
+ "username" TEXT UNIQUE,
10
+ "password" TEXT NOT NULL,
11
+ "pfpFilename" TEXT,
12
+ "role" TEXT NOT NULL DEFAULT 'default',
13
+ "suspended" INTEGER NOT NULL DEFAULT 0,
14
+ "seen_recovery_codes" BOOLEAN DEFAULT false,
15
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
16
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
17
+ "dailyMessageLimit" INTEGER,
18
+ "bio" TEXT DEFAULT ''
19
+ );
20
+
21
+ -- Workspaces table (referenced by many others)
22
+ CREATE TABLE "workspaces" (
23
+ "id" SERIAL PRIMARY KEY,
24
+ "name" TEXT NOT NULL,
25
+ "slug" TEXT NOT NULL UNIQUE,
26
+ "vectorTag" TEXT,
27
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
28
+ "openAiTemp" REAL,
29
+ "openAiHistory" INTEGER NOT NULL DEFAULT 20,
30
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
31
+ "openAiPrompt" TEXT,
32
+ "similarityThreshold" REAL DEFAULT 0.25,
33
+ "chatProvider" TEXT,
34
+ "chatModel" TEXT,
35
+ "topN" INTEGER DEFAULT 4,
36
+ "chatMode" TEXT DEFAULT 'chat',
37
+ "pfpFilename" TEXT,
38
+ "agentProvider" TEXT,
39
+ "agentModel" TEXT,
40
+ "queryRefusalResponse" TEXT,
41
+ "vectorSearchMode" TEXT DEFAULT 'default'
42
+ );
43
+
44
+ -- System settings table
45
+ CREATE TABLE "system_settings" (
46
+ "id" SERIAL PRIMARY KEY,
47
+ "label" TEXT NOT NULL UNIQUE,
48
+ "value" TEXT,
49
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
50
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
51
+ );
52
+
53
+ -- API keys table
54
+ CREATE TABLE "api_keys" (
55
+ "id" SERIAL PRIMARY KEY,
56
+ "secret" TEXT UNIQUE,
57
+ "createdBy" INTEGER REFERENCES "users"("id"),
58
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
59
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
60
+ );
61
+
62
+ -- Invites table
63
+ CREATE TABLE "invites" (
64
+ "id" SERIAL PRIMARY KEY,
65
+ "code" TEXT NOT NULL UNIQUE,
66
+ "status" TEXT NOT NULL DEFAULT 'pending',
67
+ "claimedBy" INTEGER REFERENCES "users"("id"),
68
+ "workspaceIds" TEXT,
69
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
70
+ "createdBy" INTEGER NOT NULL REFERENCES "users"("id"),
71
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
72
+ );
73
+
74
+ -- Document vectors table
75
+ CREATE TABLE "document_vectors" (
76
+ "id" SERIAL PRIMARY KEY,
77
+ "docId" TEXT NOT NULL,
78
+ "vectorId" TEXT NOT NULL,
79
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
80
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
81
+ );
82
+
83
+ -- Welcome messages table
84
+ CREATE TABLE "welcome_messages" (
85
+ "id" SERIAL PRIMARY KEY,
86
+ "user" TEXT NOT NULL,
87
+ "response" TEXT NOT NULL,
88
+ "orderIndex" INTEGER,
89
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
90
+ );
91
+
92
+ -- Workspace documents table
93
+ CREATE TABLE "workspace_documents" (
94
+ "id" SERIAL PRIMARY KEY,
95
+ "docId" TEXT NOT NULL UNIQUE,
96
+ "filename" TEXT NOT NULL,
97
+ "docpath" TEXT NOT NULL,
98
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
99
+ "metadata" TEXT,
100
+ "pinned" BOOLEAN DEFAULT false,
101
+ "watched" BOOLEAN DEFAULT false,
102
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
103
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
104
+ );
105
+
106
+ -- Workspace chats table
107
+ CREATE TABLE "workspace_chats" (
108
+ "id" SERIAL PRIMARY KEY,
109
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
110
+ "prompt" TEXT NOT NULL,
111
+ "response" TEXT NOT NULL,
112
+ "include" BOOLEAN NOT NULL DEFAULT true,
113
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
114
+ "thread_id" INTEGER,
115
+ "api_session_id" TEXT,
116
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
117
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
118
+ "feedbackScore" BOOLEAN
119
+ );
120
+
121
+ -- Workspace users table (junction table)
122
+ CREATE TABLE "workspace_users" (
123
+ "id" SERIAL PRIMARY KEY,
124
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
125
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
126
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
127
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
128
+ );
129
+
130
+ -- Workspace suggested messages table
131
+ CREATE TABLE "workspace_suggested_messages" (
132
+ "id" SERIAL PRIMARY KEY,
133
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
134
+ "heading" TEXT NOT NULL,
135
+ "message" TEXT NOT NULL,
136
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
137
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
138
+ );
139
+
140
+ -- Event logs table
141
+ CREATE TABLE "event_logs" (
142
+ "id" SERIAL PRIMARY KEY,
143
+ "event" TEXT NOT NULL,
144
+ "metadata" TEXT,
145
+ "userId" INTEGER REFERENCES "users"("id"),
146
+ "occurredAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
147
+ );
148
+
149
+ -- Cache data table
150
+ CREATE TABLE "cache_data" (
151
+ "id" SERIAL PRIMARY KEY,
152
+ "name" TEXT NOT NULL,
153
+ "data" TEXT NOT NULL,
154
+ "belongsTo" TEXT,
155
+ "ById" INTEGER,
156
+ "expiresAt" TIMESTAMP,
157
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
158
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
159
+ );
160
+
161
+ -- Embed configs table
162
+ CREATE TABLE "embed_configs" (
163
+ "id" SERIAL PRIMARY KEY,
164
+ "uuid" TEXT NOT NULL UNIQUE,
165
+ "enabled" BOOLEAN NOT NULL DEFAULT false,
166
+ "chat_mode" TEXT NOT NULL DEFAULT 'query',
167
+ "allowlist_domains" TEXT,
168
+ "allow_model_override" BOOLEAN NOT NULL DEFAULT false,
169
+ "allow_temperature_override" BOOLEAN NOT NULL DEFAULT false,
170
+ "allow_prompt_override" BOOLEAN NOT NULL DEFAULT false,
171
+ "max_chats_per_day" INTEGER,
172
+ "max_chats_per_session" INTEGER,
173
+ "message_limit" INTEGER DEFAULT 20,
174
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
175
+ "createdBy" INTEGER,
176
+ "usersId" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
177
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
178
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE,
179
+ "users" FOREIGN KEY ("usersId") REFERENCES "users"("id") ON DELETE SET NULL
180
+ );
181
+
182
+ -- Embed chats table
183
+ CREATE TABLE "embed_chats" (
184
+ "id" SERIAL PRIMARY KEY,
185
+ "prompt" TEXT NOT NULL,
186
+ "response" TEXT NOT NULL,
187
+ "session_id" TEXT NOT NULL,
188
+ "include" BOOLEAN NOT NULL DEFAULT true,
189
+ "connection_information" TEXT,
190
+ "embed_id" INTEGER NOT NULL REFERENCES "embed_configs"("id") ON DELETE CASCADE,
191
+ "usersId" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
192
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
193
+ "embed_config" FOREIGN KEY ("embed_id") REFERENCES "embed_configs"("id") ON DELETE CASCADE,
194
+ "users" FOREIGN KEY ("usersId") REFERENCES "users"("id") ON DELETE SET NULL
195
+ );
196
+
197
+ -- Workspace threads table
198
+ CREATE TABLE "workspace_threads" (
199
+ "id" SERIAL PRIMARY KEY,
200
+ "name" TEXT NOT NULL,
201
+ "slug" TEXT NOT NULL UNIQUE,
202
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
203
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
204
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
205
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
206
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE,
207
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
208
+ );
209
+
210
+ -- Workspace agent invocations table
211
+ CREATE TABLE "workspace_agent_invocations" (
212
+ "id" SERIAL PRIMARY KEY,
213
+ "uuid" TEXT NOT NULL UNIQUE,
214
+ "prompt" TEXT NOT NULL,
215
+ "closed" BOOLEAN NOT NULL DEFAULT false,
216
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
217
+ "thread_id" INTEGER,
218
+ "workspace_id" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
219
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
220
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
221
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE,
222
+ "workspace" FOREIGN KEY ("workspace_id") REFERENCES "workspaces"("id") ON DELETE CASCADE
223
+ );
224
+
225
+ -- Slash command presets table
226
+ CREATE TABLE "slash_command_presets" (
227
+ "id" SERIAL PRIMARY KEY,
228
+ "command" TEXT NOT NULL,
229
+ "prompt" TEXT NOT NULL,
230
+ "description" TEXT,
231
+ "uid" INTEGER NOT NULL DEFAULT 0,
232
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
233
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
234
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
235
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
236
+ );
237
+
238
+ -- Recovery codes table
239
+ CREATE TABLE "recovery_codes" (
240
+ "id" SERIAL PRIMARY KEY,
241
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
242
+ "code_hash" TEXT NOT NULL,
243
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
244
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
245
+ );
246
+
247
+ -- Password reset tokens table
248
+ CREATE TABLE "password_reset_tokens" (
249
+ "id" SERIAL PRIMARY KEY,
250
+ "user_id" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
251
+ "token" TEXT NOT NULL UNIQUE,
252
+ "expiresAt" TIMESTAMP NOT NULL,
253
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
254
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
255
+ );
256
+
257
+ -- Browser extension API keys table
258
+ CREATE TABLE "browser_extension_api_keys" (
259
+ "id" SERIAL PRIMARY KEY,
260
+ "key" TEXT NOT NULL UNIQUE,
261
+ "user_id" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
262
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
263
+ "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
264
+ "user" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE
265
+ );
266
+
267
+ -- Temporary auth tokens table
268
+ CREATE TABLE "temporary_auth_tokens" (
269
+ "id" SERIAL PRIMARY KEY,
270
+ "token" TEXT NOT NULL UNIQUE,
271
+ "userId" INTEGER NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
272
+ "expiresAt" TIMESTAMP NOT NULL,
273
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
274
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
275
+ );
276
+
277
+ -- System prompt variables table
278
+ CREATE TABLE "system_prompt_variables" (
279
+ "id" SERIAL PRIMARY KEY,
280
+ "key" TEXT NOT NULL UNIQUE,
281
+ "value" TEXT,
282
+ "description" TEXT,
283
+ "type" TEXT NOT NULL DEFAULT 'system',
284
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
285
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
286
+ "updatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
287
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
288
+ );
289
+
290
+ -- Prompt history table
291
+ CREATE TABLE "prompt_history" (
292
+ "id" SERIAL PRIMARY KEY,
293
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
294
+ "prompt" TEXT NOT NULL,
295
+ "modifiedBy" INTEGER REFERENCES "users"("id") ON DELETE SET NULL,
296
+ "modifiedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
297
+ "workspace" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE,
298
+ "user" FOREIGN KEY ("modifiedBy") REFERENCES "users"("id") ON DELETE SET NULL
299
+ );
300
+
301
+ -- Desktop mobile devices table
302
+ CREATE TABLE "desktop_mobile_devices" (
303
+ "id" SERIAL PRIMARY KEY,
304
+ "deviceOs" TEXT NOT NULL,
305
+ "deviceName" TEXT NOT NULL,
306
+ "token" TEXT NOT NULL UNIQUE,
307
+ "approved" BOOLEAN NOT NULL DEFAULT false,
308
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
309
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
310
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE
311
+ );
312
+
313
+ -- Document sync queues table
314
+ CREATE TABLE "document_sync_queues" (
315
+ "id" SERIAL PRIMARY KEY,
316
+ "staleAfterMs" INTEGER NOT NULL DEFAULT 604800000,
317
+ "nextSyncAt" TIMESTAMP NOT NULL,
318
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
319
+ "lastSyncedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
320
+ "workspaceDocId" INTEGER NOT NULL UNIQUE REFERENCES "workspace_documents"("id") ON DELETE CASCADE,
321
+ "workspaceDoc" FOREIGN KEY ("workspaceDocId") REFERENCES "workspace_documents"("id") ON DELETE CASCADE
322
+ );
323
+
324
+ -- Document sync executions table
325
+ CREATE TABLE "document_sync_executions" (
326
+ "id" SERIAL PRIMARY KEY,
327
+ "queueId" INTEGER NOT NULL REFERENCES "document_sync_queues"("id") ON DELETE CASCADE,
328
+ "status" TEXT NOT NULL DEFAULT 'unknown',
329
+ "result" TEXT,
330
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
331
+ "queue" FOREIGN KEY ("queueId") REFERENCES "document_sync_queues"("id") ON DELETE CASCADE
332
+ );
333
+
334
+ -- Workspace parsed files table
335
+ CREATE TABLE "workspace_parsed_files" (
336
+ "id" SERIAL PRIMARY KEY,
337
+ "filename" TEXT NOT NULL UNIQUE,
338
+ "workspaceId" INTEGER NOT NULL REFERENCES "workspaces"("id") ON DELETE CASCADE,
339
+ "userId" INTEGER REFERENCES "users"("id") ON DELETE CASCADE,
340
+ "threadId" INTEGER REFERENCES "workspace_threads"("id") ON DELETE CASCADE,
341
+ "metadata" TEXT,
342
+ "tokenCountEstimate" INTEGER DEFAULT 0,
343
+ "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
344
+ "workspace" FOREIGN KEY ("workspaceId") REFERENCES "workspaces"("id") ON DELETE CASCADE,
345
+ "user" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE CASCADE,
346
+ "thread" FOREIGN KEY ("threadId") REFERENCES "workspace_threads"("id") ON DELETE CASCADE
347
+ );
348
+
349
+ -- Create indexes for better performance
350
+ CREATE INDEX "workspace_documents_workspaceId_idx" ON "workspace_documents"("workspaceId");
351
+ CREATE INDEX "workspace_chats_workspaceId_idx" ON "workspace_chats"("workspaceId");
352
+ CREATE INDEX "workspace_chats_user_id_idx" ON "workspace_chats"("user_id");
353
+ CREATE INDEX "workspace_users_user_id_idx" ON "workspace_users"("user_id");
354
+ CREATE INDEX "workspace_users_workspace_id_idx" ON "workspace_users"("workspace_id");
355
+ CREATE INDEX "workspace_threads_workspace_id_idx" ON "workspace_threads"("workspace_id");
356
+ CREATE INDEX "workspace_threads_user_id_idx" ON "workspace_threads"("user_id");
357
+ CREATE INDEX "workspace_agent_invocations_workspace_id_idx" ON "workspace_agent_invocations"("workspace_id");
358
+ CREATE INDEX "workspace_agent_invocations_user_id_idx" ON "workspace_agent_invocations"("user_id");
359
+ CREATE INDEX "workspace_agent_invocations_uuid_idx" ON "workspace_agent_invocations"("uuid");
360
+ CREATE INDEX "workspace_suggested_messages_workspaceId_idx" ON "workspace_suggested_messages"("workspaceId");
361
+ CREATE INDEX "event_logs_event_idx" ON "event_logs"("event");
362
+ CREATE INDEX "event_logs_userId_idx" ON "event_logs"("userId");
363
+ CREATE INDEX "cache_data_expiresAt_idx" ON "cache_data"("expiresAt");
364
+ CREATE INDEX "embed_configs_workspace_id_idx" ON "embed_configs"("workspace_id");
365
+ CREATE INDEX "embed_chats_embed_id_idx" ON "embed_chats"("embed_id");
366
+ CREATE INDEX "embed_chats_session_id_idx" ON "embed_chats"("session_id");
367
+ CREATE INDEX "document_sync_queues_workspaceDocId_idx" ON "document_sync_queues"("workspaceDocId");
368
+ CREATE INDEX "document_sync_executions_queueId_idx" ON "document_sync_executions"("queueId");
369
+ CREATE INDEX "slash_command_presets_uid_idx" ON "slash_command_presets"("uid");
370
+ CREATE INDEX "slash_command_presets_userId_idx" ON "slash_command_presets"("userId");
371
+ CREATE INDEX "recovery_codes_user_id_idx" ON "recovery_codes"("user_id");
372
+ CREATE INDEX "password_reset_tokens_user_id_idx" ON "password_reset_tokens"("user_id");
373
+ CREATE INDEX "password_reset_tokens_token_idx" ON "password_reset_tokens"("token");
374
+ CREATE INDEX "temporary_auth_tokens_userId_idx" ON "temporary_auth_tokens"("userId");
375
+ CREATE INDEX "temporary_auth_tokens_token_idx" ON "temporary_auth_tokens"("token");
376
+ CREATE INDEX "system_prompt_variables_userId_idx" ON "system_prompt_variables"("userId");
377
+ CREATE INDEX "prompt_history_workspaceId_idx" ON "prompt_history"("workspaceId");
378
+ CREATE INDEX "prompt_history_modifiedBy_idx" ON "prompt_history"("modifiedBy");
379
+ CREATE INDEX "desktop_mobile_devices_userId_idx" ON "desktop_mobile_devices"("userId");
380
+ CREATE INDEX "desktop_mobile_devices_token_idx" ON "desktop_mobile_devices"("token");
381
+ CREATE INDEX "workspace_parsed_files_workspaceId_idx" ON "workspace_parsed_files"("workspaceId");
382
+ CREATE INDEX "workspace_parsed_files_userId_idx" ON "workspace_parsed_files"("userId");
383
+ CREATE INDEX "workspace_parsed_files_threadId_idx" ON "workspace_parsed_files"("threadId");
server/prisma/migrations/20240510032311_init/migration.sql DELETED
@@ -1,15 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "slash_command_presets" (
3
- "id" SERIAL PRIMARY KEY,
4
- "command" TEXT NOT NULL,
5
- "prompt" TEXT NOT NULL,
6
- "description" TEXT NOT NULL,
7
- "uid" INTEGER NOT NULL DEFAULT 0,
8
- "userId" INTEGER,
9
- "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
- "lastUpdatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
- CONSTRAINT "slash_command_presets_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
12
- );
13
-
14
- -- CreateIndex
15
- CREATE UNIQUE INDEX "slash_command_presets_uid_command_key" ON "slash_command_presets"("uid", "command");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server/prisma/migrations/20240618224346_init/migration.sql DELETED
@@ -1,26 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "workspace_documents" ADD COLUMN "watched" BOOLEAN DEFAULT false;
3
-
4
- -- CreateTable
5
- CREATE TABLE "document_sync_queues" (
6
- "id" SERIAL PRIMARY KEY,
7
- "staleAfterMs" INTEGER NOT NULL DEFAULT 604800000,
8
- "nextSyncAt" TIMESTAMP NOT NULL,
9
- "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
- "lastSyncedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
- "workspaceDocId" INTEGER NOT NULL,
12
- CONSTRAINT "document_sync_queues_workspaceDocId_fkey" FOREIGN KEY ("workspaceDocId") REFERENCES "workspace_documents" ("id") ON DELETE CASCADE ON UPDATE CASCADE
13
- );
14
-
15
- -- CreateTable
16
- CREATE TABLE "document_sync_executions" (
17
- "id" SERIAL PRIMARY KEY,
18
- "queueId" INTEGER NOT NULL,
19
- "status" TEXT NOT NULL DEFAULT 'unknown',
20
- "result" TEXT,
21
- "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
22
- CONSTRAINT "document_sync_executions_queueId_fkey" FOREIGN KEY ("queueId") REFERENCES "document_sync_queues" ("id") ON DELETE CASCADE ON UPDATE CASCADE
23
- );
24
-
25
- -- CreateIndex
26
- CREATE UNIQUE INDEX "document_sync_queues_workspaceDocId_key" ON "document_sync_queues"("workspaceDocId");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server/prisma/migrations/20240821215625_init/migration.sql DELETED
@@ -1,2 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "workspace_chats" ADD COLUMN "api_session_id" TEXT;
 
 
 
server/prisma/migrations/20240824005054_init/migration.sql DELETED
@@ -1,15 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "browser_extension_api_keys" (
3
- "id" SERIAL PRIMARY KEY,
4
- "key" TEXT NOT NULL,
5
- "user_id" INTEGER,
6
- "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7
- "lastUpdatedAt" TIMESTAMP NOT NULL,
8
- CONSTRAINT "browser_extension_api_keys_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
9
- );
10
-
11
- -- CreateIndex
12
- CREATE UNIQUE INDEX "browser_extension_api_keys_key_key" ON "browser_extension_api_keys"("key");
13
-
14
- -- CreateIndex
15
- CREATE INDEX "browser_extension_api_keys_user_id_idx" ON "browser_extension_api_keys"("user_id");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server/prisma/migrations/20241003192954_init/migration.sql DELETED
@@ -1,2 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "users" ADD COLUMN "dailyMessageLimit" INTEGER;
 
 
 
server/prisma/migrations/20241029203722_init/migration.sql DELETED
@@ -1,12 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "temporary_auth_tokens" (
3
- "id" SERIAL PRIMARY KEY,
4
- "token" TEXT NOT NULL,
5
- "userId" INTEGER NOT NULL,
6
- "expiresAt" TIMESTAMP NOT NULL,
7
- "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
- CONSTRAINT "temporary_auth_tokens_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
9
- );
10
-
11
- -- CreateIndex
12
- CREATE UNIQUE INDEX "temporary_auth_tokens_token_key" ON "temporary_auth_tokens"("token");
 
 
 
 
 
 
 
 
 
 
 
 
 
server/prisma/migrations/20241029233509_init/migration.sql DELETED
@@ -1,5 +0,0 @@
1
- -- CreateIndex
2
- CREATE INDEX "temporary_auth_tokens_token_idx" ON "temporary_auth_tokens"("token");
3
-
4
- -- CreateIndex
5
- CREATE INDEX "temporary_auth_tokens_userId_idx" ON "temporary_auth_tokens"("userId");
 
 
 
 
 
 
server/prisma/migrations/20250102204948_init/migration.sql DELETED
@@ -1,2 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "workspaces" ADD COLUMN "vectorSearchMode" TEXT DEFAULT 'default';
 
 
 
server/prisma/migrations/20250226005538_init/migration.sql DELETED
@@ -1,2 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "users" ADD COLUMN "bio" TEXT DEFAULT '';
 
 
 
server/prisma/migrations/20250318154720_init/migration.sql DELETED
@@ -1,18 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "system_prompt_variables" (
3
- "id" SERIAL PRIMARY KEY,
4
- "key" TEXT NOT NULL,
5
- "value" TEXT,
6
- "description" TEXT,
7
- "type" TEXT NOT NULL DEFAULT 'system',
8
- "userId" INTEGER,
9
- "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
- "updatedAt" TIMESTAMP NOT NULL,
11
- CONSTRAINT "system_prompt_variables_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
12
- );
13
-
14
- -- CreateIndex
15
- CREATE UNIQUE INDEX "system_prompt_variables_key_key" ON "system_prompt_variables"("key");
16
-
17
- -- CreateIndex
18
- CREATE INDEX "system_prompt_variables_userId_idx" ON "system_prompt_variables"("userId");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server/prisma/migrations/20250506214129_init/migration.sql DELETED
@@ -1,13 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "prompt_history" (
3
- "id" SERIAL PRIMARY KEY,
4
- "workspaceId" INTEGER NOT NULL,
5
- "prompt" TEXT NOT NULL,
6
- "modifiedBy" INTEGER,
7
- "modifiedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8
- CONSTRAINT "prompt_history_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
9
- CONSTRAINT "prompt_history_modifiedBy_fkey" FOREIGN KEY ("modifiedBy") REFERENCES "users" ("id") ON DELETE SET NULL ON UPDATE CASCADE
10
- );
11
-
12
- -- CreateIndex
13
- CREATE INDEX "prompt_history_workspaceId_idx" ON "prompt_history"("workspaceId");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server/prisma/migrations/20250709230835_init/migration.sql DELETED
@@ -1,2 +0,0 @@
1
- -- AlterTable
2
- ALTER TABLE "embed_configs" ADD COLUMN "message_limit" INTEGER DEFAULT 20;
 
 
 
server/prisma/migrations/20250725194841_init/migration.sql DELETED
@@ -1,17 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "desktop_mobile_devices" (
3
- "id" SERIAL PRIMARY KEY,
4
- "deviceOs" TEXT NOT NULL,
5
- "deviceName" TEXT NOT NULL,
6
- "token" TEXT NOT NULL,
7
- "approved" BOOLEAN NOT NULL DEFAULT false,
8
- "userId" INTEGER,
9
- "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
- CONSTRAINT "desktop_mobile_devices_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE
11
- );
12
-
13
- -- CreateIndex
14
- CREATE UNIQUE INDEX "desktop_mobile_devices_token_key" ON "desktop_mobile_devices"("token");
15
-
16
- -- CreateIndex
17
- CREATE INDEX "desktop_mobile_devices_userId_idx" ON "desktop_mobile_devices"("userId");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server/prisma/migrations/20250808171557_init/migration.sql DELETED
@@ -1,23 +0,0 @@
1
- -- CreateTable
2
- CREATE TABLE "workspace_parsed_files" (
3
- "id" SERIAL PRIMARY KEY,
4
- "filename" TEXT NOT NULL,
5
- "workspaceId" INTEGER NOT NULL,
6
- "userId" INTEGER,
7
- "threadId" INTEGER,
8
- "metadata" TEXT,
9
- "tokenCountEstimate" INTEGER DEFAULT 0,
10
- "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
11
- CONSTRAINT "workspace_parsed_files_workspaceId_fkey" FOREIGN KEY ("workspaceId") REFERENCES "workspaces" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
12
- CONSTRAINT "workspace_parsed_files_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
13
- CONSTRAINT "workspace_parsed_files_threadId_fkey" FOREIGN KEY ("threadId") REFERENCES "workspace_threads" ("id") ON DELETE CASCADE ON UPDATE CASCADE
14
- );
15
-
16
- -- CreateIndex
17
- CREATE UNIQUE INDEX "workspace_parsed_files_filename_key" ON "workspace_parsed_files"("filename");
18
-
19
- -- CreateIndex
20
- CREATE INDEX "workspace_parsed_files_workspaceId_idx" ON "workspace_parsed_files"("workspaceId");
21
-
22
- -- CreateIndex
23
- CREATE INDEX "workspace_parsed_files_userId_idx" ON "workspace_parsed_files"("userId");