@lobehub/chat 1.71.5 → 1.72.0
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/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/docs/developer/database-schema.dbml +16 -0
- package/package.json +3 -3
- package/src/database/client/db.ts +14 -8
- package/src/database/client/migrations.json +62 -0
- package/src/database/migrations/0017_add_user_id_to_tables.sql +225 -0
- package/src/database/migrations/meta/0017_snapshot.json +3858 -0
- package/src/database/migrations/meta/_journal.json +7 -0
- package/src/database/{server/models → models}/__tests__/_test_template.ts +2 -2
- package/src/database/models/__tests__/_util.ts +12 -0
- package/src/database/{server/models → models}/__tests__/agent.test.ts +6 -5
- package/src/database/{server/models → models}/__tests__/aiModel.test.ts +5 -4
- package/src/database/{server/models → models}/__tests__/aiProvider.test.ts +5 -4
- package/src/database/{server/models → models}/__tests__/asyncTask.test.ts +5 -4
- package/src/database/{server/models → models}/__tests__/chunk.test.ts +25 -21
- package/src/database/{server/models → models}/__tests__/file.test.ts +19 -5
- package/src/database/{server/models → models}/__tests__/knowledgeBase.test.ts +9 -4
- package/src/database/{server/models → models}/__tests__/message.test.ts +625 -29
- package/src/database/{server/models → models}/__tests__/plugin.test.ts +5 -4
- package/src/database/{server/models → models}/__tests__/session.test.ts +23 -20
- package/src/database/{server/models → models}/__tests__/sessionGroup.test.ts +5 -4
- package/src/database/{server/models → models}/__tests__/topic.test.ts +5 -4
- package/src/database/repositories/dataImporter/index.ts +3 -0
- package/src/database/schemas/file.ts +38 -32
- package/src/database/schemas/message.ts +21 -0
- package/src/database/schemas/relations.ts +10 -0
- package/src/database/server/models/__tests__/nextauth.test.ts +2 -0
- package/src/database/server/models/__tests__/user.test.ts +13 -1
- package/src/database/server/models/chunk.ts +5 -1
- package/src/database/server/models/file.ts +6 -3
- package/src/database/server/models/message.ts +29 -12
- package/src/database/server/models/session.ts +1 -0
- package/src/services/file/client.test.ts +2 -1
- package/src/services/message/client.test.ts +3 -3
- package/src/services/session/client.test.ts +5 -3
- package/src/types/message/base.ts +7 -0
- package/vitest.server.config.ts +1 -1
- package/src/database/server/models/user.test.ts +0 -58
- /package/src/database/{server/models → models}/__tests__/fixtures/embedding.ts +0 -0
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,31 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
## [Version 1.72.0](https://github.com/lobehub/lobe-chat/compare/v1.71.5...v1.72.0)
|
6
|
+
|
7
|
+
<sup>Released on **2025-03-18**</sup>
|
8
|
+
|
9
|
+
#### ✨ Features
|
10
|
+
|
11
|
+
- **misc**: Update db schema to add `user_id` for data export.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### What's improved
|
19
|
+
|
20
|
+
- **misc**: Update db schema to add `user_id` for data export, closes [#7022](https://github.com/lobehub/lobe-chat/issues/7022) ([c35471a](https://github.com/lobehub/lobe-chat/commit/c35471a))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
5
30
|
### [Version 1.71.5](https://github.com/lobehub/lobe-chat/compare/v1.71.4...v1.71.5)
|
6
31
|
|
7
32
|
<sup>Released on **2025-03-17**</sup>
|
package/changelog/v1.json
CHANGED
@@ -122,6 +122,10 @@ table files {
|
|
122
122
|
accessed_at "timestamp with time zone" [not null, default: `now()`]
|
123
123
|
created_at "timestamp with time zone" [not null, default: `now()`]
|
124
124
|
updated_at "timestamp with time zone" [not null, default: `now()`]
|
125
|
+
|
126
|
+
indexes {
|
127
|
+
file_hash [name: 'file_hash_idx']
|
128
|
+
}
|
125
129
|
}
|
126
130
|
|
127
131
|
table global_files {
|
@@ -130,6 +134,7 @@ table global_files {
|
|
130
134
|
size integer [not null]
|
131
135
|
url text [not null]
|
132
136
|
metadata jsonb
|
137
|
+
creator text [not null]
|
133
138
|
created_at "timestamp with time zone" [not null, default: `now()`]
|
134
139
|
accessed_at "timestamp with time zone" [not null, default: `now()`]
|
135
140
|
}
|
@@ -137,6 +142,7 @@ table global_files {
|
|
137
142
|
table knowledge_base_files {
|
138
143
|
knowledge_base_id text [not null]
|
139
144
|
file_id text [not null]
|
145
|
+
user_id text [not null]
|
140
146
|
created_at "timestamp with time zone" [not null, default: `now()`]
|
141
147
|
|
142
148
|
indexes {
|
@@ -161,6 +167,7 @@ table knowledge_bases {
|
|
161
167
|
table message_chunks {
|
162
168
|
message_id text
|
163
169
|
chunk_id uuid
|
170
|
+
user_id text [not null]
|
164
171
|
|
165
172
|
indexes {
|
166
173
|
(chunk_id, message_id) [pk]
|
@@ -176,6 +183,7 @@ table message_plugins {
|
|
176
183
|
identifier text
|
177
184
|
state jsonb
|
178
185
|
error jsonb
|
186
|
+
user_id text [not null]
|
179
187
|
}
|
180
188
|
|
181
189
|
table message_queries {
|
@@ -183,6 +191,7 @@ table message_queries {
|
|
183
191
|
message_id text [not null]
|
184
192
|
rewrite_query text
|
185
193
|
user_query text
|
194
|
+
user_id text [not null]
|
186
195
|
embeddings_id uuid
|
187
196
|
}
|
188
197
|
|
@@ -191,6 +200,7 @@ table message_query_chunks {
|
|
191
200
|
query_id uuid
|
192
201
|
chunk_id uuid
|
193
202
|
similarity "numeric(6, 5)"
|
203
|
+
user_id text [not null]
|
194
204
|
|
195
205
|
indexes {
|
196
206
|
(chunk_id, id, query_id) [pk]
|
@@ -202,6 +212,7 @@ table message_tts {
|
|
202
212
|
content_md5 text
|
203
213
|
file_id text
|
204
214
|
voice text
|
215
|
+
user_id text [not null]
|
205
216
|
}
|
206
217
|
|
207
218
|
table message_translates {
|
@@ -209,6 +220,7 @@ table message_translates {
|
|
209
220
|
content text
|
210
221
|
from text
|
211
222
|
to text
|
223
|
+
user_id text [not null]
|
212
224
|
}
|
213
225
|
|
214
226
|
table messages {
|
@@ -249,6 +261,7 @@ table messages {
|
|
249
261
|
table messages_files {
|
250
262
|
file_id text [not null]
|
251
263
|
message_id text [not null]
|
264
|
+
user_id text [not null]
|
252
265
|
|
253
266
|
indexes {
|
254
267
|
(file_id, message_id) [pk]
|
@@ -404,6 +417,7 @@ table rag_eval_evaluation_records {
|
|
404
417
|
table agents_to_sessions {
|
405
418
|
agent_id text [not null]
|
406
419
|
session_id text [not null]
|
420
|
+
user_id text [not null]
|
407
421
|
|
408
422
|
indexes {
|
409
423
|
(agent_id, session_id) [pk]
|
@@ -414,6 +428,7 @@ table file_chunks {
|
|
414
428
|
file_id varchar
|
415
429
|
chunk_id uuid
|
416
430
|
created_at "timestamp with time zone" [not null, default: `now()`]
|
431
|
+
user_id text [not null]
|
417
432
|
|
418
433
|
indexes {
|
419
434
|
(file_id, chunk_id) [pk]
|
@@ -423,6 +438,7 @@ table file_chunks {
|
|
423
438
|
table files_to_sessions {
|
424
439
|
file_id text [not null]
|
425
440
|
session_id text [not null]
|
441
|
+
user_id text [not null]
|
426
442
|
|
427
443
|
indexes {
|
428
444
|
(file_id, session_id) [pk]
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.72.0",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -65,8 +65,8 @@
|
|
65
65
|
"test": "npm run test-app && npm run test-server",
|
66
66
|
"test-app": "vitest run --config vitest.config.ts",
|
67
67
|
"test-app:coverage": "vitest run --config vitest.config.ts --coverage",
|
68
|
-
"test-server": "vitest run --config vitest.server.config.ts",
|
69
|
-
"test-server:coverage": "vitest run --config vitest.server.config.ts --coverage",
|
68
|
+
"test-server": "TEST_SERVER_DB=1 vitest run --config vitest.server.config.ts",
|
69
|
+
"test-server:coverage": "TEST_SERVER_DB=1 vitest run --config vitest.server.config.ts --coverage",
|
70
70
|
"test:update": "vitest -u",
|
71
71
|
"type-check": "tsc --noEmit",
|
72
72
|
"webhook:ngrok": "ngrok http http://localhost:3011",
|
@@ -146,13 +146,15 @@ export class DatabaseManager {
|
|
146
146
|
private async migrate(skipMultiRun = false): Promise<DrizzleInstance> {
|
147
147
|
if (this.isLocalDBSchemaSynced && skipMultiRun) return this.db;
|
148
148
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
149
|
+
let hash: string | undefined;
|
150
|
+
if (typeof localStorage !== 'undefined') {
|
151
|
+
const cacheHash = localStorage.getItem(pgliteSchemaHashCache);
|
152
|
+
hash = Md5.hashStr(JSON.stringify(migrations));
|
153
|
+
// if hash is the same, no need to migrate
|
154
|
+
if (hash === cacheHash) {
|
155
|
+
this.isLocalDBSchemaSynced = true;
|
156
|
+
return this.db;
|
157
|
+
}
|
156
158
|
}
|
157
159
|
|
158
160
|
const start = Date.now();
|
@@ -162,7 +164,11 @@ export class DatabaseManager {
|
|
162
164
|
// refs: https://github.com/drizzle-team/drizzle-orm/discussions/2532
|
163
165
|
// @ts-expect-error
|
164
166
|
await this.db.dialect.migrate(migrations, this.db.session, {});
|
165
|
-
|
167
|
+
|
168
|
+
if (typeof localStorage !== 'undefined' && hash) {
|
169
|
+
localStorage.setItem(pgliteSchemaHashCache, hash);
|
170
|
+
}
|
171
|
+
|
166
172
|
this.isLocalDBSchemaSynced = true;
|
167
173
|
|
168
174
|
console.info(`🗂 Migration success, take ${Date.now() - start}ms`);
|
@@ -323,5 +323,67 @@
|
|
323
323
|
"bps": true,
|
324
324
|
"folderMillis": 1741844738677,
|
325
325
|
"hash": "2a7a98be2e49361391444d6fabf3fb5db0bcb6a65e5540e9c3d426ceeb1f7f3a"
|
326
|
+
},
|
327
|
+
{
|
328
|
+
"sql": [
|
329
|
+
"-- Complete User ID Migration Script\n-- Includes adding columns to all tables, populating data, and setting constraints\n\nBEGIN;",
|
330
|
+
"\n\nCREATE INDEX \"file_hash_idx\" ON \"files\" USING btree (\"file_hash\");",
|
331
|
+
"\n\n-- Step 1: Add nullable user_id columns to all required tables\nALTER TABLE \"global_files\" ADD COLUMN IF NOT EXISTS \"creator\" text;",
|
332
|
+
"\nALTER TABLE \"knowledge_base_files\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
333
|
+
"\nALTER TABLE \"message_chunks\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
334
|
+
"\nALTER TABLE \"message_plugins\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
335
|
+
"\nALTER TABLE \"message_queries\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
336
|
+
"\nALTER TABLE \"message_query_chunks\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
337
|
+
"\nALTER TABLE \"message_tts\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
338
|
+
"\nALTER TABLE \"message_translates\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
339
|
+
"\nALTER TABLE \"messages_files\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
340
|
+
"\nALTER TABLE \"agents_to_sessions\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
341
|
+
"\nALTER TABLE \"file_chunks\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
342
|
+
"\nALTER TABLE \"files_to_sessions\" ADD COLUMN IF NOT EXISTS \"user_id\" text;",
|
343
|
+
"\n\n-- Step 2: Populate user_id fields\n-- Retrieve user_id from associated tables\n\n-- Populate user_id for knowledge_base_files\nUPDATE \"knowledge_base_files\" AS kbf\nSET \"user_id\" = kb.\"user_id\"\n FROM \"knowledge_bases\" AS kb\nWHERE kbf.\"knowledge_base_id\" = kb.\"id\";",
|
344
|
+
"\n\n-- Populate user_id for message_chunks\nUPDATE \"message_chunks\" AS mc\nSET \"user_id\" = m.\"user_id\"\n FROM \"messages\" AS m\nWHERE mc.\"message_id\" = m.\"id\";",
|
345
|
+
"\n\n-- Populate user_id for message_plugins (directly from messages table)\nUPDATE \"message_plugins\" AS mp\nSET \"user_id\" = m.\"user_id\"\n FROM \"messages\" AS m\nWHERE mp.\"id\" = m.\"id\";",
|
346
|
+
"\n\n-- Populate user_id for message_queries\nUPDATE \"message_queries\" AS mq\nSET \"user_id\" = m.\"user_id\"\n FROM \"messages\" AS m\nWHERE mq.\"message_id\" = m.\"id\";",
|
347
|
+
"\n\n-- Populate user_id for message_query_chunks\nUPDATE \"message_query_chunks\" AS mqc\nSET \"user_id\" = mq.\"user_id\"\n FROM \"message_queries\" AS mq\nWHERE mqc.\"query_id\" = mq.\"id\";",
|
348
|
+
"\n\n-- Populate user_id for message_tts\nUPDATE \"message_tts\" AS mt\nSET \"user_id\" = m.\"user_id\"\n FROM \"messages\" AS m\nWHERE mt.\"id\" = m.\"id\";",
|
349
|
+
"\n\n-- Populate user_id for message_translates\nUPDATE \"message_translates\" AS mt\nSET \"user_id\" = m.\"user_id\"\n FROM \"messages\" AS m\nWHERE mt.\"id\" = m.\"id\";",
|
350
|
+
"\n\n-- Populate user_id for messages_files\nUPDATE \"messages_files\" AS mf\nSET \"user_id\" = m.\"user_id\"\n FROM \"messages\" AS m\nWHERE mf.\"message_id\" = m.\"id\";",
|
351
|
+
"\n\n-- Populate creator for global_files (get the first user who created the file from files table)\nUPDATE \"global_files\" AS gf\nSET \"creator\" = (\n SELECT f.\"user_id\"\n FROM \"files\" AS f\n WHERE f.\"file_hash\" = gf.\"hash_id\"\n ORDER BY f.\"created_at\" ASC\n LIMIT 1\n );",
|
352
|
+
"\n\n-- Delete global_files records where no user has used the file in the files table\nDELETE FROM \"global_files\"\nWHERE \"creator\" IS NULL;",
|
353
|
+
"\n\n-- Populate user_id for agents_to_sessions\nUPDATE \"agents_to_sessions\" AS ats\nSET \"user_id\" = a.\"user_id\"\n FROM \"agents\" AS a\nWHERE ats.\"agent_id\" = a.\"id\";",
|
354
|
+
"\n\n-- Populate user_id for file_chunks\nUPDATE \"file_chunks\" AS fc\nSET \"user_id\" = f.\"user_id\"\n FROM \"files\" AS f\nWHERE fc.\"file_id\" = f.\"id\";",
|
355
|
+
"\n\n-- Populate user_id for files_to_sessions\nUPDATE \"files_to_sessions\" AS fts\nSET \"user_id\" = f.\"user_id\"\n FROM \"files\" AS f\nWHERE fts.\"file_id\" = f.\"id\";",
|
356
|
+
"\n\n-- Get user_id from sessions table (handle potential NULL values)\nUPDATE \"files_to_sessions\" AS fts\nSET \"user_id\" = s.\"user_id\"\n FROM \"sessions\" AS s\nWHERE fts.\"session_id\" = s.\"id\" AND fts.\"user_id\" IS NULL;",
|
357
|
+
"\n\nUPDATE \"agents_to_sessions\" AS ats\nSET \"user_id\" = s.\"user_id\"\n FROM \"sessions\" AS s\nWHERE ats.\"session_id\" = s.\"id\" AND ats.\"user_id\" IS NULL;",
|
358
|
+
"\n\n-- Step 3: Check for any unpopulated records\nDO $$\nDECLARE\nkb_files_count INTEGER;\n msg_chunks_count INTEGER;\n msg_plugins_count INTEGER;\n msg_queries_count INTEGER;\n msg_query_chunks_count INTEGER;\n msg_tts_count INTEGER;\n msg_translates_count INTEGER;\n msgs_files_count INTEGER;\n agents_sessions_count INTEGER;\n file_chunks_count INTEGER;\n files_sessions_count INTEGER;\nBEGIN\nSELECT COUNT(*) INTO kb_files_count FROM \"knowledge_base_files\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO msg_chunks_count FROM \"message_chunks\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO msg_plugins_count FROM \"message_plugins\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO msg_queries_count FROM \"message_queries\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO msg_query_chunks_count FROM \"message_query_chunks\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO msg_tts_count FROM \"message_tts\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO msg_translates_count FROM \"message_translates\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO msgs_files_count FROM \"messages_files\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO agents_sessions_count FROM \"agents_to_sessions\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO file_chunks_count FROM \"file_chunks\" WHERE \"user_id\" IS NULL;\nSELECT COUNT(*) INTO files_sessions_count FROM \"files_to_sessions\" WHERE \"user_id\" IS NULL;\n\nIF kb_files_count > 0 OR msg_chunks_count > 0 OR msg_plugins_count > 0 OR\n msg_queries_count > 0 OR msg_query_chunks_count > 0 OR msg_tts_count > 0 OR\n msg_translates_count > 0 OR msgs_files_count > 0 OR agents_sessions_count > 0 OR\n file_chunks_count > 0 OR files_sessions_count > 0 THEN\n RAISE EXCEPTION 'There are records with NULL user_id values that could not be populated';\nEND IF;\nEND $$;",
|
359
|
+
"\n\n-- Step 4: Add NOT NULL constraints and foreign keys\nALTER TABLE \"knowledge_base_files\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
360
|
+
"\nALTER TABLE \"message_chunks\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
361
|
+
"\nALTER TABLE \"message_plugins\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
362
|
+
"\nALTER TABLE \"message_queries\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
363
|
+
"\nALTER TABLE \"message_query_chunks\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
364
|
+
"\nALTER TABLE \"message_tts\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
365
|
+
"\nALTER TABLE \"message_translates\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
366
|
+
"\nALTER TABLE \"messages_files\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
367
|
+
"\nALTER TABLE \"agents_to_sessions\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
368
|
+
"\nALTER TABLE \"file_chunks\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
369
|
+
"\nALTER TABLE \"files_to_sessions\" ALTER COLUMN \"user_id\" SET NOT NULL;",
|
370
|
+
"\n\n-- Add foreign key constraints\nALTER TABLE \"global_files\"\n ADD CONSTRAINT \"global_files_creator_users_id_fk\"\n FOREIGN KEY (\"creator\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE SET NULL ON UPDATE NO ACTION;",
|
371
|
+
"\n\nALTER TABLE \"knowledge_base_files\"\n ADD CONSTRAINT \"knowledge_base_files_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
372
|
+
"\n\nALTER TABLE \"message_chunks\"\n ADD CONSTRAINT \"message_chunks_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
373
|
+
"\n\nALTER TABLE \"message_plugins\"\n ADD CONSTRAINT \"message_plugins_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
374
|
+
"\n\nALTER TABLE \"message_queries\"\n ADD CONSTRAINT \"message_queries_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
375
|
+
"\n\nALTER TABLE \"message_query_chunks\"\n ADD CONSTRAINT \"message_query_chunks_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
376
|
+
"\n\nALTER TABLE \"message_tts\"\n ADD CONSTRAINT \"message_tts_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
377
|
+
"\n\nALTER TABLE \"message_translates\"\n ADD CONSTRAINT \"message_translates_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
378
|
+
"\n\nALTER TABLE \"messages_files\"\n ADD CONSTRAINT \"messages_files_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
379
|
+
"\n\nALTER TABLE \"agents_to_sessions\"\n ADD CONSTRAINT \"agents_to_sessions_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
380
|
+
"\n\nALTER TABLE \"file_chunks\"\n ADD CONSTRAINT \"file_chunks_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
381
|
+
"\n\nALTER TABLE \"files_to_sessions\"\n ADD CONSTRAINT \"files_to_sessions_user_id_users_id_fk\"\n FOREIGN KEY (\"user_id\") REFERENCES \"public\".\"users\"(\"id\")\n ON DELETE CASCADE ON UPDATE NO ACTION;",
|
382
|
+
"\n\nCOMMIT;",
|
383
|
+
"\n"
|
384
|
+
],
|
385
|
+
"bps": true,
|
386
|
+
"folderMillis": 1742269437903,
|
387
|
+
"hash": "89e91285be422d5f44511c7405f57b57f8dfda4f0304126ae9b0f266e5fd60f1"
|
326
388
|
}
|
327
389
|
]
|
@@ -0,0 +1,225 @@
|
|
1
|
+
-- Complete User ID Migration Script
|
2
|
+
-- Includes adding columns to all tables, populating data, and setting constraints
|
3
|
+
|
4
|
+
BEGIN;--> statement-breakpoint
|
5
|
+
|
6
|
+
CREATE INDEX "file_hash_idx" ON "files" USING btree ("file_hash");--> statement-breakpoint
|
7
|
+
|
8
|
+
-- Step 1: Add nullable user_id columns to all required tables
|
9
|
+
ALTER TABLE "global_files" ADD COLUMN IF NOT EXISTS "creator" text;--> statement-breakpoint
|
10
|
+
ALTER TABLE "knowledge_base_files" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
11
|
+
ALTER TABLE "message_chunks" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
12
|
+
ALTER TABLE "message_plugins" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
13
|
+
ALTER TABLE "message_queries" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
14
|
+
ALTER TABLE "message_query_chunks" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
15
|
+
ALTER TABLE "message_tts" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
16
|
+
ALTER TABLE "message_translates" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
17
|
+
ALTER TABLE "messages_files" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
18
|
+
ALTER TABLE "agents_to_sessions" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
19
|
+
ALTER TABLE "file_chunks" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
20
|
+
ALTER TABLE "files_to_sessions" ADD COLUMN IF NOT EXISTS "user_id" text;--> statement-breakpoint
|
21
|
+
|
22
|
+
-- Step 2: Populate user_id fields
|
23
|
+
-- Retrieve user_id from associated tables
|
24
|
+
|
25
|
+
-- Populate user_id for knowledge_base_files
|
26
|
+
UPDATE "knowledge_base_files" AS kbf
|
27
|
+
SET "user_id" = kb."user_id"
|
28
|
+
FROM "knowledge_bases" AS kb
|
29
|
+
WHERE kbf."knowledge_base_id" = kb."id";--> statement-breakpoint
|
30
|
+
|
31
|
+
-- Populate user_id for message_chunks
|
32
|
+
UPDATE "message_chunks" AS mc
|
33
|
+
SET "user_id" = m."user_id"
|
34
|
+
FROM "messages" AS m
|
35
|
+
WHERE mc."message_id" = m."id";--> statement-breakpoint
|
36
|
+
|
37
|
+
-- Populate user_id for message_plugins (directly from messages table)
|
38
|
+
UPDATE "message_plugins" AS mp
|
39
|
+
SET "user_id" = m."user_id"
|
40
|
+
FROM "messages" AS m
|
41
|
+
WHERE mp."id" = m."id";--> statement-breakpoint
|
42
|
+
|
43
|
+
-- Populate user_id for message_queries
|
44
|
+
UPDATE "message_queries" AS mq
|
45
|
+
SET "user_id" = m."user_id"
|
46
|
+
FROM "messages" AS m
|
47
|
+
WHERE mq."message_id" = m."id";--> statement-breakpoint
|
48
|
+
|
49
|
+
-- Populate user_id for message_query_chunks
|
50
|
+
UPDATE "message_query_chunks" AS mqc
|
51
|
+
SET "user_id" = mq."user_id"
|
52
|
+
FROM "message_queries" AS mq
|
53
|
+
WHERE mqc."query_id" = mq."id";--> statement-breakpoint
|
54
|
+
|
55
|
+
-- Populate user_id for message_tts
|
56
|
+
UPDATE "message_tts" AS mt
|
57
|
+
SET "user_id" = m."user_id"
|
58
|
+
FROM "messages" AS m
|
59
|
+
WHERE mt."id" = m."id";--> statement-breakpoint
|
60
|
+
|
61
|
+
-- Populate user_id for message_translates
|
62
|
+
UPDATE "message_translates" AS mt
|
63
|
+
SET "user_id" = m."user_id"
|
64
|
+
FROM "messages" AS m
|
65
|
+
WHERE mt."id" = m."id";--> statement-breakpoint
|
66
|
+
|
67
|
+
-- Populate user_id for messages_files
|
68
|
+
UPDATE "messages_files" AS mf
|
69
|
+
SET "user_id" = m."user_id"
|
70
|
+
FROM "messages" AS m
|
71
|
+
WHERE mf."message_id" = m."id";--> statement-breakpoint
|
72
|
+
|
73
|
+
-- Populate creator for global_files (get the first user who created the file from files table)
|
74
|
+
UPDATE "global_files" AS gf
|
75
|
+
SET "creator" = (
|
76
|
+
SELECT f."user_id"
|
77
|
+
FROM "files" AS f
|
78
|
+
WHERE f."file_hash" = gf."hash_id"
|
79
|
+
ORDER BY f."created_at" ASC
|
80
|
+
LIMIT 1
|
81
|
+
);--> statement-breakpoint
|
82
|
+
|
83
|
+
-- Delete global_files records where no user has used the file in the files table
|
84
|
+
DELETE FROM "global_files"
|
85
|
+
WHERE "creator" IS NULL;--> statement-breakpoint
|
86
|
+
|
87
|
+
-- Populate user_id for agents_to_sessions
|
88
|
+
UPDATE "agents_to_sessions" AS ats
|
89
|
+
SET "user_id" = a."user_id"
|
90
|
+
FROM "agents" AS a
|
91
|
+
WHERE ats."agent_id" = a."id";--> statement-breakpoint
|
92
|
+
|
93
|
+
-- Populate user_id for file_chunks
|
94
|
+
UPDATE "file_chunks" AS fc
|
95
|
+
SET "user_id" = f."user_id"
|
96
|
+
FROM "files" AS f
|
97
|
+
WHERE fc."file_id" = f."id";--> statement-breakpoint
|
98
|
+
|
99
|
+
-- Populate user_id for files_to_sessions
|
100
|
+
UPDATE "files_to_sessions" AS fts
|
101
|
+
SET "user_id" = f."user_id"
|
102
|
+
FROM "files" AS f
|
103
|
+
WHERE fts."file_id" = f."id";--> statement-breakpoint
|
104
|
+
|
105
|
+
-- Get user_id from sessions table (handle potential NULL values)
|
106
|
+
UPDATE "files_to_sessions" AS fts
|
107
|
+
SET "user_id" = s."user_id"
|
108
|
+
FROM "sessions" AS s
|
109
|
+
WHERE fts."session_id" = s."id" AND fts."user_id" IS NULL;--> statement-breakpoint
|
110
|
+
|
111
|
+
UPDATE "agents_to_sessions" AS ats
|
112
|
+
SET "user_id" = s."user_id"
|
113
|
+
FROM "sessions" AS s
|
114
|
+
WHERE ats."session_id" = s."id" AND ats."user_id" IS NULL;--> statement-breakpoint
|
115
|
+
|
116
|
+
-- Step 3: Check for any unpopulated records
|
117
|
+
DO $$
|
118
|
+
DECLARE
|
119
|
+
kb_files_count INTEGER;
|
120
|
+
msg_chunks_count INTEGER;
|
121
|
+
msg_plugins_count INTEGER;
|
122
|
+
msg_queries_count INTEGER;
|
123
|
+
msg_query_chunks_count INTEGER;
|
124
|
+
msg_tts_count INTEGER;
|
125
|
+
msg_translates_count INTEGER;
|
126
|
+
msgs_files_count INTEGER;
|
127
|
+
agents_sessions_count INTEGER;
|
128
|
+
file_chunks_count INTEGER;
|
129
|
+
files_sessions_count INTEGER;
|
130
|
+
BEGIN
|
131
|
+
SELECT COUNT(*) INTO kb_files_count FROM "knowledge_base_files" WHERE "user_id" IS NULL;
|
132
|
+
SELECT COUNT(*) INTO msg_chunks_count FROM "message_chunks" WHERE "user_id" IS NULL;
|
133
|
+
SELECT COUNT(*) INTO msg_plugins_count FROM "message_plugins" WHERE "user_id" IS NULL;
|
134
|
+
SELECT COUNT(*) INTO msg_queries_count FROM "message_queries" WHERE "user_id" IS NULL;
|
135
|
+
SELECT COUNT(*) INTO msg_query_chunks_count FROM "message_query_chunks" WHERE "user_id" IS NULL;
|
136
|
+
SELECT COUNT(*) INTO msg_tts_count FROM "message_tts" WHERE "user_id" IS NULL;
|
137
|
+
SELECT COUNT(*) INTO msg_translates_count FROM "message_translates" WHERE "user_id" IS NULL;
|
138
|
+
SELECT COUNT(*) INTO msgs_files_count FROM "messages_files" WHERE "user_id" IS NULL;
|
139
|
+
SELECT COUNT(*) INTO agents_sessions_count FROM "agents_to_sessions" WHERE "user_id" IS NULL;
|
140
|
+
SELECT COUNT(*) INTO file_chunks_count FROM "file_chunks" WHERE "user_id" IS NULL;
|
141
|
+
SELECT COUNT(*) INTO files_sessions_count FROM "files_to_sessions" WHERE "user_id" IS NULL;
|
142
|
+
|
143
|
+
IF kb_files_count > 0 OR msg_chunks_count > 0 OR msg_plugins_count > 0 OR
|
144
|
+
msg_queries_count > 0 OR msg_query_chunks_count > 0 OR msg_tts_count > 0 OR
|
145
|
+
msg_translates_count > 0 OR msgs_files_count > 0 OR agents_sessions_count > 0 OR
|
146
|
+
file_chunks_count > 0 OR files_sessions_count > 0 THEN
|
147
|
+
RAISE EXCEPTION 'There are records with NULL user_id values that could not be populated';
|
148
|
+
END IF;
|
149
|
+
END $$;--> statement-breakpoint
|
150
|
+
|
151
|
+
-- Step 4: Add NOT NULL constraints and foreign keys
|
152
|
+
ALTER TABLE "knowledge_base_files" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
153
|
+
ALTER TABLE "message_chunks" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
154
|
+
ALTER TABLE "message_plugins" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
155
|
+
ALTER TABLE "message_queries" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
156
|
+
ALTER TABLE "message_query_chunks" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
157
|
+
ALTER TABLE "message_tts" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
158
|
+
ALTER TABLE "message_translates" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
159
|
+
ALTER TABLE "messages_files" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
160
|
+
ALTER TABLE "agents_to_sessions" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
161
|
+
ALTER TABLE "file_chunks" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
162
|
+
ALTER TABLE "files_to_sessions" ALTER COLUMN "user_id" SET NOT NULL;--> statement-breakpoint
|
163
|
+
|
164
|
+
-- Add foreign key constraints
|
165
|
+
ALTER TABLE "global_files"
|
166
|
+
ADD CONSTRAINT "global_files_creator_users_id_fk"
|
167
|
+
FOREIGN KEY ("creator") REFERENCES "public"."users"("id")
|
168
|
+
ON DELETE SET NULL ON UPDATE NO ACTION;--> statement-breakpoint
|
169
|
+
|
170
|
+
ALTER TABLE "knowledge_base_files"
|
171
|
+
ADD CONSTRAINT "knowledge_base_files_user_id_users_id_fk"
|
172
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
173
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
174
|
+
|
175
|
+
ALTER TABLE "message_chunks"
|
176
|
+
ADD CONSTRAINT "message_chunks_user_id_users_id_fk"
|
177
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
178
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
179
|
+
|
180
|
+
ALTER TABLE "message_plugins"
|
181
|
+
ADD CONSTRAINT "message_plugins_user_id_users_id_fk"
|
182
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
183
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
184
|
+
|
185
|
+
ALTER TABLE "message_queries"
|
186
|
+
ADD CONSTRAINT "message_queries_user_id_users_id_fk"
|
187
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
188
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
189
|
+
|
190
|
+
ALTER TABLE "message_query_chunks"
|
191
|
+
ADD CONSTRAINT "message_query_chunks_user_id_users_id_fk"
|
192
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
193
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
194
|
+
|
195
|
+
ALTER TABLE "message_tts"
|
196
|
+
ADD CONSTRAINT "message_tts_user_id_users_id_fk"
|
197
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
198
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
199
|
+
|
200
|
+
ALTER TABLE "message_translates"
|
201
|
+
ADD CONSTRAINT "message_translates_user_id_users_id_fk"
|
202
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
203
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
204
|
+
|
205
|
+
ALTER TABLE "messages_files"
|
206
|
+
ADD CONSTRAINT "messages_files_user_id_users_id_fk"
|
207
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
208
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
209
|
+
|
210
|
+
ALTER TABLE "agents_to_sessions"
|
211
|
+
ADD CONSTRAINT "agents_to_sessions_user_id_users_id_fk"
|
212
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
213
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
214
|
+
|
215
|
+
ALTER TABLE "file_chunks"
|
216
|
+
ADD CONSTRAINT "file_chunks_user_id_users_id_fk"
|
217
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
218
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
219
|
+
|
220
|
+
ALTER TABLE "files_to_sessions"
|
221
|
+
ADD CONSTRAINT "files_to_sessions_user_id_users_id_fk"
|
222
|
+
FOREIGN KEY ("user_id") REFERENCES "public"."users"("id")
|
223
|
+
ON DELETE CASCADE ON UPDATE NO ACTION;--> statement-breakpoint
|
224
|
+
|
225
|
+
COMMIT;--> statement-breakpoint
|