@naisys/hub-database 3.0.0-beta.10
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/README.md +84 -0
- package/dist/dbConfig.js +4 -0
- package/dist/generated/prisma/browser.js +17 -0
- package/dist/generated/prisma/client.js +34 -0
- package/dist/generated/prisma/commonInputTypes.js +10 -0
- package/dist/generated/prisma/enums.js +56 -0
- package/dist/generated/prisma/internal/class.js +49 -0
- package/dist/generated/prisma/internal/prismaNamespace.js +248 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +219 -0
- package/dist/generated/prisma/models/attachments.js +1 -0
- package/dist/generated/prisma/models/config_revisions.js +1 -0
- package/dist/generated/prisma/models/context_log.js +1 -0
- package/dist/generated/prisma/models/costs.js +1 -0
- package/dist/generated/prisma/models/hosts.js +1 -0
- package/dist/generated/prisma/models/mail_attachments.js +1 -0
- package/dist/generated/prisma/models/mail_messages.js +1 -0
- package/dist/generated/prisma/models/mail_recipients.js +1 -0
- package/dist/generated/prisma/models/models.js +1 -0
- package/dist/generated/prisma/models/run_session.js +1 -0
- package/dist/generated/prisma/models/schema_version.js +1 -0
- package/dist/generated/prisma/models/user_hosts.js +1 -0
- package/dist/generated/prisma/models/user_notifications.js +1 -0
- package/dist/generated/prisma/models/users.js +1 -0
- package/dist/generated/prisma/models/variables.js +1 -0
- package/dist/generated/prisma/models.js +1 -0
- package/dist/hubDatabaseService.js +38 -0
- package/dist/hubSessionService.js +112 -0
- package/dist/index.js +13 -0
- package/dist/prismaClient.js +21 -0
- package/package.json +42 -0
- package/prisma/migrations/20260223234341_init/migration.sql +237 -0
- package/prisma/migrations/20260225041145_add_host_restricted/migration.sql +20 -0
- package/prisma/migrations/20260227000000_add_host_type/migration.sql +21 -0
- package/prisma/migrations/20260302000000_make_from_user_id_not_null/migration.sql +37 -0
- package/prisma/migrations/20260302100000_add_cost_suspended_reason/migration.sql +2 -0
- package/prisma/migrations/20260305000000_make_participant_ids_not_null/migration.sql +31 -0
- package/prisma/migrations/20260306000000_add_host_last_ip/migration.sql +1 -0
- package/prisma/migrations/20260310000000_rename_participant_ids_to_participants/migration.sql +61 -0
- package/prisma/migrations/20260312000000_fix_empty_enum_strings/migration.sql +31 -0
- package/prisma/migrations/20260313000000_add_user_enabled/migration.sql +5 -0
- package/prisma/migrations/20260327000000_add_config_revisions/migration.sql +13 -0
- package/prisma/migrations/20260328000000_add_from_recipient_type/migration.sql +13 -0
- package/prisma/migrations/20260328100000_add_spend_limit_reset_at/migration.sql +1 -0
- package/prisma/migrations/20260328200000_add_budget_left/migration.sql +1 -0
- package/prisma/migrations/20260401000000_rename_workspace_to_tool/migration.sql +2 -0
- package/prisma/migrations/20260403000000_add_export_to_shell/migration.sql +2 -0
- package/prisma/migrations/20260404000000_add_attachment_public_id/migration.sql +8 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +307 -0
- package/prisma.config.ts +18 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
|
|
2
|
+
import { PrismaClient } from "./generated/prisma/client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Create a Prisma client with a dynamic database path
|
|
5
|
+
* @param databasePath - Absolute path to the SQLite database file
|
|
6
|
+
* @returns Configured PrismaClient instance
|
|
7
|
+
*/
|
|
8
|
+
export async function createPrismaClient(databasePath) {
|
|
9
|
+
const adapter = new PrismaBetterSqlite3({
|
|
10
|
+
url: `file:${databasePath}`,
|
|
11
|
+
timeout: 10_000, // Wait up to 10s for SQLite lock to be released
|
|
12
|
+
});
|
|
13
|
+
const prisma = new PrismaClient({ adapter });
|
|
14
|
+
// Enable WAL mode for better concurrent read/write performance
|
|
15
|
+
await prisma.$executeRawUnsafe("PRAGMA journal_mode=WAL");
|
|
16
|
+
// NORMAL is safe with WAL and avoids an extra fsync per commit
|
|
17
|
+
await prisma.$executeRawUnsafe("PRAGMA synchronous=NORMAL");
|
|
18
|
+
// SQLite doesn't enforce foreign keys by default — must be enabled per connection
|
|
19
|
+
await prisma.$executeRawUnsafe("PRAGMA foreign_keys=ON");
|
|
20
|
+
return prisma;
|
|
21
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@naisys/hub-database",
|
|
3
|
+
"version": "3.0.0-beta.10",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "[internal] Hub database schema and Prisma client for NAISYS",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"prisma.config.ts",
|
|
9
|
+
"prisma/schema.prisma",
|
|
10
|
+
"prisma/migrations",
|
|
11
|
+
"!dist/**/*.map",
|
|
12
|
+
"!dist/**/*.d.ts",
|
|
13
|
+
"!dist/**/*.d.ts.map"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"clean": "rimraf dist",
|
|
17
|
+
"prisma:migrate": "prisma migrate dev --create-only",
|
|
18
|
+
"prisma:generate": "prisma generate",
|
|
19
|
+
"prisma:studio": "prisma studio",
|
|
20
|
+
"build": "npm run prisma:generate && tsc",
|
|
21
|
+
"npm:publish:dryrun": "npm publish --dry-run",
|
|
22
|
+
"npm:publish": "npm publish --access public"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
26
|
+
"typescript": "^5.9.3"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@naisys/common": "3.0.0-beta.10",
|
|
30
|
+
"@naisys/common-node": "3.0.0-beta.10",
|
|
31
|
+
"@prisma/adapter-better-sqlite3": "^7.5.0",
|
|
32
|
+
"@prisma/client": "^7.5.0",
|
|
33
|
+
"better-sqlite3": "^12.6.2",
|
|
34
|
+
"prisma": "^7.5.0"
|
|
35
|
+
},
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"default": "./dist/index.js"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "context_log" (
|
|
3
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
4
|
+
"user_id" INTEGER NOT NULL,
|
|
5
|
+
"run_id" INTEGER NOT NULL,
|
|
6
|
+
"session_id" INTEGER NOT NULL,
|
|
7
|
+
"host_id" INTEGER NOT NULL,
|
|
8
|
+
"role" TEXT NOT NULL,
|
|
9
|
+
"source" TEXT NOT NULL,
|
|
10
|
+
"type" TEXT NOT NULL,
|
|
11
|
+
"message" TEXT NOT NULL,
|
|
12
|
+
"attachment_id" INTEGER,
|
|
13
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
14
|
+
CONSTRAINT "context_log_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
15
|
+
CONSTRAINT "context_log_user_id_run_id_session_id_fkey" FOREIGN KEY ("user_id", "run_id", "session_id") REFERENCES "run_session" ("user_id", "run_id", "session_id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
16
|
+
CONSTRAINT "context_log_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
|
17
|
+
CONSTRAINT "context_log_attachment_id_fkey" FOREIGN KEY ("attachment_id") REFERENCES "attachments" ("id") ON DELETE SET NULL ON UPDATE NO ACTION
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
-- CreateTable
|
|
21
|
+
CREATE TABLE "costs" (
|
|
22
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
23
|
+
"user_id" INTEGER NOT NULL,
|
|
24
|
+
"run_id" INTEGER NOT NULL,
|
|
25
|
+
"session_id" INTEGER NOT NULL,
|
|
26
|
+
"host_id" INTEGER NOT NULL,
|
|
27
|
+
"source" TEXT NOT NULL,
|
|
28
|
+
"model" TEXT NOT NULL,
|
|
29
|
+
"cost" REAL DEFAULT 0,
|
|
30
|
+
"input_tokens" INTEGER DEFAULT 0,
|
|
31
|
+
"output_tokens" INTEGER DEFAULT 0,
|
|
32
|
+
"cache_write_tokens" INTEGER DEFAULT 0,
|
|
33
|
+
"cache_read_tokens" INTEGER DEFAULT 0,
|
|
34
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
35
|
+
CONSTRAINT "costs_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
36
|
+
CONSTRAINT "costs_user_id_run_id_session_id_fkey" FOREIGN KEY ("user_id", "run_id", "session_id") REFERENCES "run_session" ("user_id", "run_id", "session_id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
37
|
+
CONSTRAINT "costs_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
-- CreateTable
|
|
41
|
+
CREATE TABLE "mail_messages" (
|
|
42
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
43
|
+
"from_user_id" INTEGER,
|
|
44
|
+
"host_id" INTEGER,
|
|
45
|
+
"kind" TEXT NOT NULL DEFAULT 'mail',
|
|
46
|
+
"participant_ids" TEXT,
|
|
47
|
+
"subject" TEXT NOT NULL,
|
|
48
|
+
"body" TEXT NOT NULL,
|
|
49
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
50
|
+
CONSTRAINT "mail_messages_from_user_id_fkey" FOREIGN KEY ("from_user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
51
|
+
CONSTRAINT "mail_messages_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
-- CreateTable
|
|
55
|
+
CREATE TABLE "attachments" (
|
|
56
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
57
|
+
"filepath" TEXT NOT NULL,
|
|
58
|
+
"filename" TEXT NOT NULL,
|
|
59
|
+
"file_size" INTEGER NOT NULL,
|
|
60
|
+
"file_hash" TEXT NOT NULL,
|
|
61
|
+
"purpose" TEXT NOT NULL,
|
|
62
|
+
"uploaded_by" INTEGER NOT NULL,
|
|
63
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
64
|
+
CONSTRAINT "attachments_uploaded_by_fkey" FOREIGN KEY ("uploaded_by") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
-- CreateTable
|
|
68
|
+
CREATE TABLE "mail_attachments" (
|
|
69
|
+
"message_id" INTEGER NOT NULL,
|
|
70
|
+
"attachment_id" INTEGER NOT NULL,
|
|
71
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
72
|
+
|
|
73
|
+
PRIMARY KEY ("message_id", "attachment_id"),
|
|
74
|
+
CONSTRAINT "mail_attachments_message_id_fkey" FOREIGN KEY ("message_id") REFERENCES "mail_messages" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
75
|
+
CONSTRAINT "mail_attachments_attachment_id_fkey" FOREIGN KEY ("attachment_id") REFERENCES "attachments" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
-- CreateTable
|
|
79
|
+
CREATE TABLE "mail_recipients" (
|
|
80
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
81
|
+
"message_id" INTEGER NOT NULL,
|
|
82
|
+
"user_id" INTEGER NOT NULL,
|
|
83
|
+
"type" TEXT NOT NULL,
|
|
84
|
+
"read_at" DATETIME,
|
|
85
|
+
"archived_at" DATETIME,
|
|
86
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
87
|
+
CONSTRAINT "mail_recipients_message_id_fkey" FOREIGN KEY ("message_id") REFERENCES "mail_messages" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
88
|
+
CONSTRAINT "mail_recipients_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
-- CreateTable
|
|
92
|
+
CREATE TABLE "users" (
|
|
93
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
94
|
+
"uuid" TEXT NOT NULL,
|
|
95
|
+
"username" TEXT NOT NULL,
|
|
96
|
+
"title" TEXT NOT NULL,
|
|
97
|
+
"api_key" TEXT NOT NULL,
|
|
98
|
+
"lead_user_id" INTEGER,
|
|
99
|
+
"config" TEXT NOT NULL DEFAULT '{}',
|
|
100
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
101
|
+
"updated_at" DATETIME NOT NULL,
|
|
102
|
+
"archived" BOOLEAN NOT NULL DEFAULT false,
|
|
103
|
+
CONSTRAINT "users_lead_user_id_fkey" FOREIGN KEY ("lead_user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
-- CreateTable
|
|
107
|
+
CREATE TABLE "user_notifications" (
|
|
108
|
+
"user_id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
109
|
+
"latest_host_id" INTEGER,
|
|
110
|
+
"latest_log_id" INTEGER NOT NULL DEFAULT 0,
|
|
111
|
+
"latest_mail_id" INTEGER NOT NULL DEFAULT 0,
|
|
112
|
+
"latest_chat_id" INTEGER NOT NULL DEFAULT 0,
|
|
113
|
+
"last_active" DATETIME,
|
|
114
|
+
"updated_at" DATETIME NOT NULL,
|
|
115
|
+
CONSTRAINT "user_notifications_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
116
|
+
CONSTRAINT "user_notifications_latest_host_id_fkey" FOREIGN KEY ("latest_host_id") REFERENCES "hosts" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
-- CreateTable
|
|
120
|
+
CREATE TABLE "user_hosts" (
|
|
121
|
+
"user_id" INTEGER NOT NULL,
|
|
122
|
+
"host_id" INTEGER NOT NULL,
|
|
123
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
124
|
+
|
|
125
|
+
PRIMARY KEY ("user_id", "host_id"),
|
|
126
|
+
CONSTRAINT "user_hosts_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
127
|
+
CONSTRAINT "user_hosts_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
-- CreateTable
|
|
131
|
+
CREATE TABLE "run_session" (
|
|
132
|
+
"user_id" INTEGER NOT NULL,
|
|
133
|
+
"run_id" INTEGER NOT NULL,
|
|
134
|
+
"session_id" INTEGER NOT NULL,
|
|
135
|
+
"host_id" INTEGER NOT NULL,
|
|
136
|
+
"last_active" DATETIME NOT NULL,
|
|
137
|
+
"model_name" TEXT NOT NULL,
|
|
138
|
+
"latest_log_id" INTEGER NOT NULL DEFAULT 0,
|
|
139
|
+
"total_lines" INTEGER NOT NULL DEFAULT 0,
|
|
140
|
+
"total_cost" REAL NOT NULL DEFAULT 0,
|
|
141
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
142
|
+
"updated_at" DATETIME NOT NULL,
|
|
143
|
+
|
|
144
|
+
PRIMARY KEY ("user_id", "run_id", "session_id"),
|
|
145
|
+
CONSTRAINT "run_session_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
146
|
+
CONSTRAINT "run_session_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
-- CreateTable
|
|
150
|
+
CREATE TABLE "schema_version" (
|
|
151
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT DEFAULT 1,
|
|
152
|
+
"version" INTEGER NOT NULL,
|
|
153
|
+
"updated" DATETIME NOT NULL
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
-- CreateTable
|
|
157
|
+
CREATE TABLE "hosts" (
|
|
158
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
159
|
+
"name" TEXT NOT NULL,
|
|
160
|
+
"last_active" DATETIME,
|
|
161
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
-- CreateTable
|
|
165
|
+
CREATE TABLE "variables" (
|
|
166
|
+
"key" TEXT NOT NULL PRIMARY KEY,
|
|
167
|
+
"value" TEXT NOT NULL,
|
|
168
|
+
"created_by" TEXT NOT NULL,
|
|
169
|
+
"updated_by" TEXT NOT NULL,
|
|
170
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
171
|
+
"updated_at" DATETIME NOT NULL
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
-- CreateTable
|
|
175
|
+
CREATE TABLE "models" (
|
|
176
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
177
|
+
"key" TEXT NOT NULL,
|
|
178
|
+
"type" TEXT NOT NULL,
|
|
179
|
+
"label" TEXT NOT NULL,
|
|
180
|
+
"version_name" TEXT NOT NULL,
|
|
181
|
+
"is_builtin" BOOLEAN NOT NULL DEFAULT false,
|
|
182
|
+
"is_custom" BOOLEAN NOT NULL DEFAULT false,
|
|
183
|
+
"meta" TEXT NOT NULL,
|
|
184
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
185
|
+
"updated_at" DATETIME NOT NULL
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
-- CreateIndex
|
|
189
|
+
CREATE INDEX "idx_context_log_user_run_session" ON "context_log"("user_id", "run_id", "session_id");
|
|
190
|
+
|
|
191
|
+
-- CreateIndex
|
|
192
|
+
CREATE INDEX "idx_costs_created_at" ON "costs"("created_at");
|
|
193
|
+
|
|
194
|
+
-- CreateIndex
|
|
195
|
+
CREATE INDEX "idx_costs_user_id" ON "costs"("user_id");
|
|
196
|
+
|
|
197
|
+
-- CreateIndex
|
|
198
|
+
CREATE INDEX "idx_costs_user_run_session_source_model" ON "costs"("user_id", "run_id", "session_id", "source", "model");
|
|
199
|
+
|
|
200
|
+
-- CreateIndex
|
|
201
|
+
CREATE INDEX "idx_mail_messages_from_user_id" ON "mail_messages"("from_user_id");
|
|
202
|
+
|
|
203
|
+
-- CreateIndex
|
|
204
|
+
CREATE INDEX "idx_mail_messages_created_at_desc" ON "mail_messages"("created_at" DESC);
|
|
205
|
+
|
|
206
|
+
-- CreateIndex
|
|
207
|
+
CREATE INDEX "idx_mail_messages_participant_ids" ON "mail_messages"("participant_ids");
|
|
208
|
+
|
|
209
|
+
-- CreateIndex
|
|
210
|
+
CREATE INDEX "idx_mail_recipients_message_user" ON "mail_recipients"("message_id", "user_id");
|
|
211
|
+
|
|
212
|
+
-- CreateIndex
|
|
213
|
+
CREATE INDEX "idx_mail_recipients_user_message_desc" ON "mail_recipients"("user_id", "message_id" DESC);
|
|
214
|
+
|
|
215
|
+
-- CreateIndex
|
|
216
|
+
CREATE UNIQUE INDEX "users_uuid_key" ON "users"("uuid");
|
|
217
|
+
|
|
218
|
+
-- CreateIndex
|
|
219
|
+
CREATE UNIQUE INDEX "users_api_key_key" ON "users"("api_key");
|
|
220
|
+
|
|
221
|
+
-- CreateIndex
|
|
222
|
+
CREATE INDEX "idx_users_username" ON "users"("username");
|
|
223
|
+
|
|
224
|
+
-- CreateIndex
|
|
225
|
+
CREATE INDEX "idx_run_session_run_id_desc" ON "run_session"("run_id" DESC);
|
|
226
|
+
|
|
227
|
+
-- CreateIndex
|
|
228
|
+
CREATE INDEX "idx_run_session_user_last_active_desc" ON "run_session"("user_id", "last_active" DESC);
|
|
229
|
+
|
|
230
|
+
-- CreateIndex
|
|
231
|
+
CREATE UNIQUE INDEX "unq_schema_version_version" ON "schema_version"("version");
|
|
232
|
+
|
|
233
|
+
-- CreateIndex
|
|
234
|
+
CREATE UNIQUE INDEX "unq_hosts_name" ON "hosts"("name");
|
|
235
|
+
|
|
236
|
+
-- CreateIndex
|
|
237
|
+
CREATE UNIQUE INDEX "models_key_key" ON "models"("key");
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- RedefineTables
|
|
2
|
+
PRAGMA defer_foreign_keys=ON;
|
|
3
|
+
PRAGMA foreign_keys=OFF;
|
|
4
|
+
CREATE TABLE "new_hosts" (
|
|
5
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
6
|
+
"name" TEXT NOT NULL,
|
|
7
|
+
"restricted" BOOLEAN NOT NULL DEFAULT false,
|
|
8
|
+
"last_active" DATETIME,
|
|
9
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
10
|
+
);
|
|
11
|
+
INSERT INTO "new_hosts" ("created_at", "id", "last_active", "name") SELECT "created_at", "id", "last_active", "name" FROM "hosts";
|
|
12
|
+
DROP TABLE "hosts";
|
|
13
|
+
ALTER TABLE "new_hosts" RENAME TO "hosts";
|
|
14
|
+
CREATE UNIQUE INDEX "unq_hosts_name" ON "hosts"("name");
|
|
15
|
+
PRAGMA foreign_keys=ON;
|
|
16
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
17
|
+
|
|
18
|
+
-- Update schema version
|
|
19
|
+
INSERT INTO "schema_version" ("id", "version", "updated") VALUES (1, 20, datetime('now'))
|
|
20
|
+
ON CONFLICT ("id") DO UPDATE SET "version" = 20, "updated" = datetime('now');
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
-- RedefineTables
|
|
2
|
+
PRAGMA defer_foreign_keys=ON;
|
|
3
|
+
PRAGMA foreign_keys=OFF;
|
|
4
|
+
CREATE TABLE "new_hosts" (
|
|
5
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
6
|
+
"name" TEXT NOT NULL,
|
|
7
|
+
"restricted" BOOLEAN NOT NULL DEFAULT false,
|
|
8
|
+
"host_type" TEXT NOT NULL DEFAULT 'naisys',
|
|
9
|
+
"last_active" DATETIME,
|
|
10
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
11
|
+
);
|
|
12
|
+
INSERT INTO "new_hosts" ("created_at", "id", "last_active", "name", "restricted") SELECT "created_at", "id", "last_active", "name", "restricted" FROM "hosts";
|
|
13
|
+
DROP TABLE "hosts";
|
|
14
|
+
ALTER TABLE "new_hosts" RENAME TO "hosts";
|
|
15
|
+
CREATE UNIQUE INDEX "unq_hosts_name" ON "hosts"("name");
|
|
16
|
+
PRAGMA foreign_keys=ON;
|
|
17
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
18
|
+
|
|
19
|
+
-- Update schema version
|
|
20
|
+
INSERT INTO "schema_version" ("id", "version", "updated") VALUES (1, 21, datetime('now'))
|
|
21
|
+
ON CONFLICT ("id") DO UPDATE SET "version" = 21, "updated" = datetime('now');
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
-- Delete orphaned mail data for messages with NULL from_user_id
|
|
2
|
+
DELETE FROM "mail_attachments" WHERE "message_id" IN (
|
|
3
|
+
SELECT "id" FROM "mail_messages" WHERE "from_user_id" IS NULL
|
|
4
|
+
);
|
|
5
|
+
DELETE FROM "mail_recipients" WHERE "message_id" IN (
|
|
6
|
+
SELECT "id" FROM "mail_messages" WHERE "from_user_id" IS NULL
|
|
7
|
+
);
|
|
8
|
+
DELETE FROM "mail_messages" WHERE "from_user_id" IS NULL;
|
|
9
|
+
|
|
10
|
+
-- RedefineTables
|
|
11
|
+
PRAGMA defer_foreign_keys=ON;
|
|
12
|
+
PRAGMA foreign_keys=OFF;
|
|
13
|
+
CREATE TABLE "new_mail_messages" (
|
|
14
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
15
|
+
"from_user_id" INTEGER NOT NULL,
|
|
16
|
+
"host_id" INTEGER,
|
|
17
|
+
"kind" TEXT NOT NULL DEFAULT 'mail',
|
|
18
|
+
"participant_ids" TEXT,
|
|
19
|
+
"subject" TEXT NOT NULL,
|
|
20
|
+
"body" TEXT NOT NULL,
|
|
21
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
22
|
+
CONSTRAINT "mail_messages_from_user_id_fkey" FOREIGN KEY ("from_user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
|
|
23
|
+
CONSTRAINT "mail_messages_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
24
|
+
);
|
|
25
|
+
INSERT INTO "new_mail_messages" ("id", "from_user_id", "host_id", "kind", "participant_ids", "subject", "body", "created_at")
|
|
26
|
+
SELECT "id", "from_user_id", "host_id", "kind", "participant_ids", "subject", "body", "created_at" FROM "mail_messages";
|
|
27
|
+
DROP TABLE "mail_messages";
|
|
28
|
+
ALTER TABLE "new_mail_messages" RENAME TO "mail_messages";
|
|
29
|
+
CREATE INDEX "idx_mail_messages_from_user_id" ON "mail_messages"("from_user_id");
|
|
30
|
+
CREATE INDEX "idx_mail_messages_created_at_desc" ON "mail_messages"("created_at" DESC);
|
|
31
|
+
CREATE INDEX "idx_mail_messages_participant_ids" ON "mail_messages"("participant_ids");
|
|
32
|
+
PRAGMA foreign_keys=ON;
|
|
33
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
34
|
+
|
|
35
|
+
-- Update schema version
|
|
36
|
+
INSERT INTO "schema_version" ("id", "version", "updated") VALUES (1, 22, datetime('now'))
|
|
37
|
+
ON CONFLICT ("id") DO UPDATE SET "version" = 22, "updated" = datetime('now');
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- Backfill any NULL participant_ids (shouldn't exist, but just in case)
|
|
2
|
+
UPDATE "mail_messages" SET "participant_ids" = '' WHERE "participant_ids" IS NULL;
|
|
3
|
+
|
|
4
|
+
-- RedefineTables
|
|
5
|
+
PRAGMA defer_foreign_keys=ON;
|
|
6
|
+
PRAGMA foreign_keys=OFF;
|
|
7
|
+
CREATE TABLE "new_mail_messages" (
|
|
8
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
9
|
+
"from_user_id" INTEGER NOT NULL,
|
|
10
|
+
"host_id" INTEGER,
|
|
11
|
+
"kind" TEXT NOT NULL DEFAULT 'mail',
|
|
12
|
+
"participant_ids" TEXT NOT NULL,
|
|
13
|
+
"subject" TEXT NOT NULL,
|
|
14
|
+
"body" TEXT NOT NULL,
|
|
15
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
16
|
+
CONSTRAINT "mail_messages_from_user_id_fkey" FOREIGN KEY ("from_user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
|
|
17
|
+
CONSTRAINT "mail_messages_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
18
|
+
);
|
|
19
|
+
INSERT INTO "new_mail_messages" ("id", "from_user_id", "host_id", "kind", "participant_ids", "subject", "body", "created_at")
|
|
20
|
+
SELECT "id", "from_user_id", "host_id", "kind", "participant_ids", "subject", "body", "created_at" FROM "mail_messages";
|
|
21
|
+
DROP TABLE "mail_messages";
|
|
22
|
+
ALTER TABLE "new_mail_messages" RENAME TO "mail_messages";
|
|
23
|
+
CREATE INDEX "idx_mail_messages_from_user_id" ON "mail_messages"("from_user_id");
|
|
24
|
+
CREATE INDEX "idx_mail_messages_created_at_desc" ON "mail_messages"("created_at" DESC);
|
|
25
|
+
CREATE INDEX "idx_mail_messages_participant_ids" ON "mail_messages"("participant_ids");
|
|
26
|
+
PRAGMA foreign_keys=ON;
|
|
27
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
28
|
+
|
|
29
|
+
-- Update schema version
|
|
30
|
+
INSERT INTO "schema_version" ("id", "version", "updated") VALUES (1, 24, datetime('now'))
|
|
31
|
+
ON CONFLICT ("id") DO UPDATE SET "version" = 24, "updated" = datetime('now');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "hosts" ADD COLUMN "last_ip" TEXT;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
-- Step 1: Add participants column
|
|
2
|
+
ALTER TABLE "mail_messages" ADD COLUMN "participants" TEXT NOT NULL DEFAULT '';
|
|
3
|
+
|
|
4
|
+
-- Step 2: Backfill using recursive CTE (split participant_ids CSV into rows,
|
|
5
|
+
-- join to users for usernames, GROUP_CONCAT back into sorted CSV)
|
|
6
|
+
WITH RECURSIVE split(msg_id, pid_str, participant_id, rest) AS (
|
|
7
|
+
SELECT id, participant_ids,
|
|
8
|
+
CAST(CASE WHEN INSTR(participant_ids, ',') > 0
|
|
9
|
+
THEN SUBSTR(participant_ids, 1, INSTR(participant_ids, ',') - 1)
|
|
10
|
+
ELSE participant_ids END AS INTEGER),
|
|
11
|
+
CASE WHEN INSTR(participant_ids, ',') > 0
|
|
12
|
+
THEN SUBSTR(participant_ids, INSTR(participant_ids, ',') + 1)
|
|
13
|
+
ELSE '' END
|
|
14
|
+
FROM mail_messages WHERE participant_ids != ''
|
|
15
|
+
UNION ALL
|
|
16
|
+
SELECT msg_id, pid_str,
|
|
17
|
+
CAST(CASE WHEN INSTR(rest, ',') > 0
|
|
18
|
+
THEN SUBSTR(rest, 1, INSTR(rest, ',') - 1)
|
|
19
|
+
ELSE rest END AS INTEGER),
|
|
20
|
+
CASE WHEN INSTR(rest, ',') > 0
|
|
21
|
+
THEN SUBSTR(rest, INSTR(rest, ',') + 1)
|
|
22
|
+
ELSE '' END
|
|
23
|
+
FROM split WHERE rest != ''
|
|
24
|
+
),
|
|
25
|
+
resolved AS (
|
|
26
|
+
SELECT s.msg_id, s.pid_str, u.username
|
|
27
|
+
FROM split s JOIN users u ON u.id = s.participant_id
|
|
28
|
+
),
|
|
29
|
+
grouped AS (
|
|
30
|
+
SELECT pid_str, GROUP_CONCAT(username, ',') AS participants
|
|
31
|
+
FROM (SELECT DISTINCT pid_str, username FROM resolved ORDER BY pid_str, username)
|
|
32
|
+
GROUP BY pid_str
|
|
33
|
+
)
|
|
34
|
+
UPDATE mail_messages SET participants = (
|
|
35
|
+
SELECT g.participants FROM grouped g WHERE g.pid_str = mail_messages.participant_ids
|
|
36
|
+
) WHERE participant_ids != '';
|
|
37
|
+
|
|
38
|
+
-- Step 3: Redefine table without participant_ids
|
|
39
|
+
PRAGMA defer_foreign_keys=ON;
|
|
40
|
+
PRAGMA foreign_keys=OFF;
|
|
41
|
+
CREATE TABLE "new_mail_messages" (
|
|
42
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
43
|
+
"from_user_id" INTEGER NOT NULL,
|
|
44
|
+
"host_id" INTEGER,
|
|
45
|
+
"kind" TEXT NOT NULL DEFAULT 'mail',
|
|
46
|
+
"participants" TEXT NOT NULL DEFAULT '',
|
|
47
|
+
"subject" TEXT NOT NULL,
|
|
48
|
+
"body" TEXT NOT NULL,
|
|
49
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
50
|
+
CONSTRAINT "mail_messages_from_user_id_fkey" FOREIGN KEY ("from_user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
|
|
51
|
+
CONSTRAINT "mail_messages_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
52
|
+
);
|
|
53
|
+
INSERT INTO "new_mail_messages" ("id", "from_user_id", "host_id", "kind", "participants", "subject", "body", "created_at")
|
|
54
|
+
SELECT "id", "from_user_id", "host_id", "kind", "participants", "subject", "body", "created_at" FROM "mail_messages";
|
|
55
|
+
DROP TABLE "mail_messages";
|
|
56
|
+
ALTER TABLE "new_mail_messages" RENAME TO "mail_messages";
|
|
57
|
+
CREATE INDEX "idx_mail_messages_from_user_id" ON "mail_messages"("from_user_id");
|
|
58
|
+
CREATE INDEX "idx_mail_messages_created_at_desc" ON "mail_messages"("created_at" DESC);
|
|
59
|
+
CREATE INDEX "idx_mail_messages_participants" ON "mail_messages"("participants");
|
|
60
|
+
PRAGMA foreign_keys=ON;
|
|
61
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- RedefineTables
|
|
2
|
+
PRAGMA defer_foreign_keys=ON;
|
|
3
|
+
PRAGMA foreign_keys=OFF;
|
|
4
|
+
CREATE TABLE "new_context_log" (
|
|
5
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
6
|
+
"user_id" INTEGER NOT NULL,
|
|
7
|
+
"run_id" INTEGER NOT NULL,
|
|
8
|
+
"session_id" INTEGER NOT NULL,
|
|
9
|
+
"host_id" INTEGER NOT NULL,
|
|
10
|
+
"role" TEXT NOT NULL,
|
|
11
|
+
"source" TEXT,
|
|
12
|
+
"type" TEXT,
|
|
13
|
+
"message" TEXT NOT NULL,
|
|
14
|
+
"attachment_id" INTEGER,
|
|
15
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
16
|
+
CONSTRAINT "context_log_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
17
|
+
CONSTRAINT "context_log_user_id_run_id_session_id_fkey" FOREIGN KEY ("user_id", "run_id", "session_id") REFERENCES "run_session" ("user_id", "run_id", "session_id") ON DELETE NO ACTION ON UPDATE NO ACTION,
|
|
18
|
+
CONSTRAINT "context_log_host_id_fkey" FOREIGN KEY ("host_id") REFERENCES "hosts" ("id") ON DELETE RESTRICT ON UPDATE CASCADE,
|
|
19
|
+
CONSTRAINT "context_log_attachment_id_fkey" FOREIGN KEY ("attachment_id") REFERENCES "attachments" ("id") ON DELETE SET NULL ON UPDATE NO ACTION
|
|
20
|
+
);
|
|
21
|
+
INSERT INTO "new_context_log" ("id", "user_id", "run_id", "session_id", "host_id", "role", "source", "type", "message", "attachment_id", "created_at")
|
|
22
|
+
SELECT "id", "user_id", "run_id", "session_id", "host_id", "role",
|
|
23
|
+
NULLIF("source", ''),
|
|
24
|
+
NULLIF("type", ''),
|
|
25
|
+
"message", "attachment_id", "created_at"
|
|
26
|
+
FROM "context_log";
|
|
27
|
+
DROP TABLE "context_log";
|
|
28
|
+
ALTER TABLE "new_context_log" RENAME TO "context_log";
|
|
29
|
+
CREATE INDEX "idx_context_log_user_run_session" ON "context_log"("user_id", "run_id", "session_id");
|
|
30
|
+
PRAGMA foreign_keys=ON;
|
|
31
|
+
PRAGMA defer_foreign_keys=OFF;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- CreateTable
|
|
2
|
+
CREATE TABLE "config_revisions" (
|
|
3
|
+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
4
|
+
"user_id" INTEGER NOT NULL,
|
|
5
|
+
"config" TEXT NOT NULL,
|
|
6
|
+
"changed_by_id" INTEGER NOT NULL,
|
|
7
|
+
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
8
|
+
CONSTRAINT "config_revisions_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE NO ACTION,
|
|
9
|
+
CONSTRAINT "config_revisions_changed_by_id_fkey" FOREIGN KEY ("changed_by_id") REFERENCES "users" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
-- CreateIndex
|
|
13
|
+
CREATE INDEX "idx_config_revisions_user_created_desc" ON "config_revisions"("user_id", "created_at" DESC);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
-- SQLite has no enum types; Prisma stores RecipientType as text.
|
|
2
|
+
-- No ALTER TYPE needed — 'from' is valid as soon as it's inserted.
|
|
3
|
+
|
|
4
|
+
-- Backfill: add 'from' recipient records for all existing messages
|
|
5
|
+
-- where the sender doesn't already have a recipient record.
|
|
6
|
+
-- Sets read_at = created_at since the sender has already "read" their own message.
|
|
7
|
+
INSERT INTO mail_recipients (message_id, user_id, type, read_at, created_at)
|
|
8
|
+
SELECT m.id, m.from_user_id, 'from', m.created_at, m.created_at
|
|
9
|
+
FROM mail_messages m
|
|
10
|
+
WHERE NOT EXISTS (
|
|
11
|
+
SELECT 1 FROM mail_recipients r
|
|
12
|
+
WHERE r.message_id = m.id AND r.user_id = m.from_user_id
|
|
13
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "user_notifications" ADD COLUMN "spend_limit_reset_at" DATETIME;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ALTER TABLE "user_notifications" ADD COLUMN "budget_left" DECIMAL;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- Add public_id column to attachments (nullable initially for migration)
|
|
2
|
+
ALTER TABLE "attachments" ADD COLUMN "public_id" TEXT;
|
|
3
|
+
|
|
4
|
+
-- Populate existing rows with 12-char random hex
|
|
5
|
+
UPDATE "attachments" SET "public_id" = lower(hex(randomblob(6)));
|
|
6
|
+
|
|
7
|
+
-- Make non-nullable and add unique index
|
|
8
|
+
CREATE UNIQUE INDEX "attachments_public_id_key" ON "attachments"("public_id");
|