@omiron33/omi-neuron-web 0.1.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/README.md +55 -0
- package/dist/api/index.cjs +943 -0
- package/dist/api/index.cjs.map +1 -0
- package/dist/api/index.d.cts +140 -0
- package/dist/api/index.d.ts +140 -0
- package/dist/api/index.js +934 -0
- package/dist/api/index.js.map +1 -0
- package/dist/chunk-BSOSHBDR.cjs +300 -0
- package/dist/chunk-BSOSHBDR.cjs.map +1 -0
- package/dist/chunk-COO66N7H.cjs +950 -0
- package/dist/chunk-COO66N7H.cjs.map +1 -0
- package/dist/chunk-FXKXMSLY.cjs +270 -0
- package/dist/chunk-FXKXMSLY.cjs.map +1 -0
- package/dist/chunk-PSDVPB7Y.js +289 -0
- package/dist/chunk-PSDVPB7Y.js.map +1 -0
- package/dist/chunk-RQCGONPN.js +937 -0
- package/dist/chunk-RQCGONPN.js.map +1 -0
- package/dist/chunk-RTSFO7BW.cjs +592 -0
- package/dist/chunk-RTSFO7BW.cjs.map +1 -0
- package/dist/chunk-TFLMPBX7.js +262 -0
- package/dist/chunk-TFLMPBX7.js.map +1 -0
- package/dist/chunk-XNR42GCJ.js +547 -0
- package/dist/chunk-XNR42GCJ.js.map +1 -0
- package/dist/cli/index.cjs +571 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +563 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/database-B0vplyA4.d.cts +41 -0
- package/dist/database-B0vplyA4.d.ts +41 -0
- package/dist/edge-BzsYe2Ed.d.cts +269 -0
- package/dist/edge-BzsYe2Ed.d.ts +269 -0
- package/dist/index.cjs +895 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1484 -0
- package/dist/index.d.ts +1484 -0
- package/dist/index.js +654 -0
- package/dist/index.js.map +1 -0
- package/dist/migration/index.cjs +32 -0
- package/dist/migration/index.cjs.map +1 -0
- package/dist/migration/index.d.cts +51 -0
- package/dist/migration/index.d.ts +51 -0
- package/dist/migration/index.js +3 -0
- package/dist/migration/index.js.map +1 -0
- package/dist/query-helpers-D8po5Mn-.d.cts +777 -0
- package/dist/query-helpers-DvQTA2_Z.d.ts +777 -0
- package/dist/visualization/index.cjs +485 -0
- package/dist/visualization/index.cjs.map +1 -0
- package/dist/visualization/index.d.cts +134 -0
- package/dist/visualization/index.d.ts +134 -0
- package/dist/visualization/index.js +460 -0
- package/dist/visualization/index.js.map +1 -0
- package/docker/docker-compose.template.yml +28 -0
- package/package.json +116 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
|
|
3
|
+
// src/storage/migrations/001_initial_schema.ts
|
|
4
|
+
var migration001 = {
|
|
5
|
+
version: "001",
|
|
6
|
+
name: "initial_schema",
|
|
7
|
+
up: `
|
|
8
|
+
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
9
|
+
|
|
10
|
+
CREATE TABLE IF NOT EXISTS nodes (
|
|
11
|
+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
12
|
+
slug VARCHAR(255) UNIQUE NOT NULL,
|
|
13
|
+
label VARCHAR(500) NOT NULL,
|
|
14
|
+
node_type VARCHAR(100) NOT NULL DEFAULT 'concept',
|
|
15
|
+
domain VARCHAR(100) NOT NULL DEFAULT 'general',
|
|
16
|
+
summary TEXT,
|
|
17
|
+
description TEXT,
|
|
18
|
+
content TEXT,
|
|
19
|
+
metadata JSONB DEFAULT '{}',
|
|
20
|
+
tier VARCHAR(20),
|
|
21
|
+
visual_priority INTEGER DEFAULT 50,
|
|
22
|
+
position_override DOUBLE PRECISION[3],
|
|
23
|
+
connection_count INTEGER DEFAULT 0,
|
|
24
|
+
inbound_count INTEGER DEFAULT 0,
|
|
25
|
+
outbound_count INTEGER DEFAULT 0,
|
|
26
|
+
analysis_status VARCHAR(20) DEFAULT 'pending',
|
|
27
|
+
analysis_error TEXT,
|
|
28
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
29
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
CREATE TABLE IF NOT EXISTS edges (
|
|
33
|
+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
34
|
+
from_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
|
|
35
|
+
to_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,
|
|
36
|
+
relationship_type VARCHAR(100) NOT NULL DEFAULT 'related_to',
|
|
37
|
+
strength DOUBLE PRECISION DEFAULT 0.5,
|
|
38
|
+
confidence DOUBLE PRECISION DEFAULT 1.0,
|
|
39
|
+
evidence JSONB DEFAULT '[]',
|
|
40
|
+
label VARCHAR(255),
|
|
41
|
+
description TEXT,
|
|
42
|
+
metadata JSONB DEFAULT '{}',
|
|
43
|
+
source VARCHAR(20) NOT NULL DEFAULT 'manual',
|
|
44
|
+
source_model VARCHAR(100),
|
|
45
|
+
bidirectional BOOLEAN DEFAULT FALSE,
|
|
46
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
47
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
48
|
+
UNIQUE(from_node_id, to_node_id, relationship_type)
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
CREATE TABLE IF NOT EXISTS settings (
|
|
52
|
+
id VARCHAR(50) PRIMARY KEY DEFAULT 'default',
|
|
53
|
+
visualization JSONB DEFAULT '{}',
|
|
54
|
+
analysis JSONB DEFAULT '{}',
|
|
55
|
+
node_types JSONB DEFAULT '[]',
|
|
56
|
+
domains JSONB DEFAULT '[]',
|
|
57
|
+
relationship_types JSONB DEFAULT '[]',
|
|
58
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_slug ON nodes(slug);
|
|
62
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_domain ON nodes(domain);
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_node_type ON nodes(node_type);
|
|
64
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_analysis_status ON nodes(analysis_status);
|
|
65
|
+
CREATE INDEX IF NOT EXISTS idx_edges_from_node ON edges(from_node_id);
|
|
66
|
+
CREATE INDEX IF NOT EXISTS idx_edges_to_node ON edges(to_node_id);
|
|
67
|
+
CREATE INDEX IF NOT EXISTS idx_edges_type ON edges(relationship_type);
|
|
68
|
+
`.trim(),
|
|
69
|
+
down: `
|
|
70
|
+
DROP TABLE IF EXISTS settings;
|
|
71
|
+
DROP TABLE IF EXISTS edges;
|
|
72
|
+
DROP TABLE IF EXISTS nodes;
|
|
73
|
+
DROP EXTENSION IF EXISTS "uuid-ossp";
|
|
74
|
+
`.trim()
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// src/storage/migrations/002_embeddings.ts
|
|
78
|
+
var migration002 = {
|
|
79
|
+
version: "002",
|
|
80
|
+
name: "embeddings",
|
|
81
|
+
up: `
|
|
82
|
+
CREATE EXTENSION IF NOT EXISTS vector;
|
|
83
|
+
|
|
84
|
+
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS embedding vector(1536);
|
|
85
|
+
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS embedding_model VARCHAR(100);
|
|
86
|
+
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS embedding_generated_at TIMESTAMP WITH TIME ZONE;
|
|
87
|
+
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_embedding ON nodes
|
|
89
|
+
USING hnsw (embedding vector_cosine_ops)
|
|
90
|
+
WITH (m = 16, ef_construction = 64);
|
|
91
|
+
`.trim(),
|
|
92
|
+
down: `
|
|
93
|
+
DROP INDEX IF EXISTS idx_nodes_embedding;
|
|
94
|
+
ALTER TABLE nodes DROP COLUMN IF EXISTS embedding;
|
|
95
|
+
ALTER TABLE nodes DROP COLUMN IF EXISTS embedding_model;
|
|
96
|
+
ALTER TABLE nodes DROP COLUMN IF EXISTS embedding_generated_at;
|
|
97
|
+
DROP EXTENSION IF EXISTS vector;
|
|
98
|
+
`.trim()
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// src/storage/migrations/003_clusters.ts
|
|
102
|
+
var migration003 = {
|
|
103
|
+
version: "003",
|
|
104
|
+
name: "clusters",
|
|
105
|
+
up: `
|
|
106
|
+
CREATE TABLE IF NOT EXISTS clusters (
|
|
107
|
+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
108
|
+
label VARCHAR(255) NOT NULL,
|
|
109
|
+
cluster_type VARCHAR(100) DEFAULT 'topic',
|
|
110
|
+
centroid vector(1536),
|
|
111
|
+
member_count INTEGER DEFAULT 0,
|
|
112
|
+
avg_similarity DOUBLE PRECISION,
|
|
113
|
+
cohesion DOUBLE PRECISION,
|
|
114
|
+
description TEXT,
|
|
115
|
+
keywords TEXT[] DEFAULT '{}',
|
|
116
|
+
metadata JSONB DEFAULT '{}',
|
|
117
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
118
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
119
|
+
last_recomputed_at TIMESTAMP WITH TIME ZONE
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
CREATE TABLE IF NOT EXISTS cluster_memberships (
|
|
123
|
+
node_id UUID REFERENCES nodes(id) ON DELETE CASCADE,
|
|
124
|
+
cluster_id UUID REFERENCES clusters(id) ON DELETE CASCADE,
|
|
125
|
+
similarity_score DOUBLE PRECISION NOT NULL,
|
|
126
|
+
is_primary BOOLEAN DEFAULT FALSE,
|
|
127
|
+
assigned_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
128
|
+
PRIMARY KEY (node_id, cluster_id)
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS cluster_id UUID REFERENCES clusters(id) ON DELETE SET NULL;
|
|
132
|
+
ALTER TABLE nodes ADD COLUMN IF NOT EXISTS cluster_similarity DOUBLE PRECISION;
|
|
133
|
+
|
|
134
|
+
CREATE INDEX IF NOT EXISTS idx_cluster_memberships_cluster ON cluster_memberships(cluster_id);
|
|
135
|
+
CREATE INDEX IF NOT EXISTS idx_nodes_cluster ON nodes(cluster_id);
|
|
136
|
+
`.trim(),
|
|
137
|
+
down: `
|
|
138
|
+
DROP TABLE IF EXISTS cluster_memberships;
|
|
139
|
+
DROP TABLE IF EXISTS clusters;
|
|
140
|
+
ALTER TABLE nodes DROP COLUMN IF EXISTS cluster_id;
|
|
141
|
+
ALTER TABLE nodes DROP COLUMN IF EXISTS cluster_similarity;
|
|
142
|
+
`.trim()
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// src/storage/migrations/004_analysis_runs.ts
|
|
146
|
+
var migration004 = {
|
|
147
|
+
version: "004",
|
|
148
|
+
name: "analysis_runs",
|
|
149
|
+
up: `
|
|
150
|
+
CREATE TABLE IF NOT EXISTS analysis_runs (
|
|
151
|
+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
152
|
+
run_type VARCHAR(50) NOT NULL,
|
|
153
|
+
input_params JSONB DEFAULT '{}',
|
|
154
|
+
results JSONB DEFAULT '{}',
|
|
155
|
+
status VARCHAR(20) NOT NULL DEFAULT 'queued',
|
|
156
|
+
progress INTEGER DEFAULT 0,
|
|
157
|
+
started_at TIMESTAMP WITH TIME ZONE,
|
|
158
|
+
completed_at TIMESTAMP WITH TIME ZONE,
|
|
159
|
+
duration_ms INTEGER,
|
|
160
|
+
error_message TEXT,
|
|
161
|
+
error_stack TEXT,
|
|
162
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
CREATE INDEX IF NOT EXISTS idx_analysis_runs_status ON analysis_runs(status);
|
|
166
|
+
CREATE INDEX IF NOT EXISTS idx_analysis_runs_created ON analysis_runs(created_at DESC);
|
|
167
|
+
`.trim(),
|
|
168
|
+
down: `
|
|
169
|
+
DROP TABLE IF EXISTS analysis_runs;
|
|
170
|
+
`.trim()
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// src/storage/migrations/index.ts
|
|
174
|
+
var migrations = [
|
|
175
|
+
migration001,
|
|
176
|
+
migration002,
|
|
177
|
+
migration003,
|
|
178
|
+
migration004
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
// src/storage/migrations/runner.ts
|
|
182
|
+
var MigrationRunner = class {
|
|
183
|
+
constructor(db) {
|
|
184
|
+
this.db = db;
|
|
185
|
+
}
|
|
186
|
+
async getStatus() {
|
|
187
|
+
await this.ensureMigrationTable();
|
|
188
|
+
const applied = await this.getApplied();
|
|
189
|
+
const appliedMap = new Map(applied.map((item) => [item.version, item]));
|
|
190
|
+
return migrations.map((migration) => ({
|
|
191
|
+
version: migration.version,
|
|
192
|
+
name: migration.name,
|
|
193
|
+
appliedAt: appliedMap.get(migration.version)?.appliedAt ?? null,
|
|
194
|
+
status: appliedMap.has(migration.version) ? "applied" : "pending"
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
async getPending() {
|
|
198
|
+
const status = await this.getStatus();
|
|
199
|
+
return status.filter((item) => item.status === "pending").map((item) => migrations.find((m) => m.version === item.version)).filter(Boolean);
|
|
200
|
+
}
|
|
201
|
+
async getApplied() {
|
|
202
|
+
await this.ensureMigrationTable();
|
|
203
|
+
const rows = await this.db.query(
|
|
204
|
+
"SELECT version, name, applied_at FROM neuron_migrations ORDER BY version"
|
|
205
|
+
);
|
|
206
|
+
return rows.map((row) => ({
|
|
207
|
+
version: row.version,
|
|
208
|
+
name: row.name,
|
|
209
|
+
appliedAt: row.applied_at
|
|
210
|
+
}));
|
|
211
|
+
}
|
|
212
|
+
async up(options) {
|
|
213
|
+
const pending = await this.getPending();
|
|
214
|
+
const targetIndex = options?.to ? pending.findIndex((m) => m.version === options.to) + 1 : pending.length;
|
|
215
|
+
const toApply = pending.slice(0, targetIndex > 0 ? targetIndex : pending.length);
|
|
216
|
+
for (const migration of toApply) {
|
|
217
|
+
await this.applyMigration(migration);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
async down(options) {
|
|
221
|
+
await this.ensureMigrationTable();
|
|
222
|
+
const applied = await this.getApplied();
|
|
223
|
+
const appliedMigrations = applied.map((item) => migrations.find((m) => m.version === item.version)).filter(Boolean);
|
|
224
|
+
const reversed = [...appliedMigrations].reverse();
|
|
225
|
+
let toRollback = [];
|
|
226
|
+
if (options?.to) {
|
|
227
|
+
const idx = reversed.findIndex((m) => m.version === options.to);
|
|
228
|
+
toRollback = idx >= 0 ? reversed.slice(0, idx + 1) : [];
|
|
229
|
+
} else if (options?.count) {
|
|
230
|
+
toRollback = reversed.slice(0, options.count);
|
|
231
|
+
} else {
|
|
232
|
+
toRollback = reversed.slice(0, 1);
|
|
233
|
+
}
|
|
234
|
+
for (const migration of toRollback) {
|
|
235
|
+
await this.rollbackMigration(migration);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
async reset() {
|
|
239
|
+
await this.down({ count: migrations.length });
|
|
240
|
+
await this.up();
|
|
241
|
+
}
|
|
242
|
+
async dryRun(direction) {
|
|
243
|
+
if (direction === "up") {
|
|
244
|
+
const pending = await this.getPending();
|
|
245
|
+
return pending.map((m) => m.up);
|
|
246
|
+
}
|
|
247
|
+
const applied = await this.getApplied();
|
|
248
|
+
const appliedMigrations = applied.map((item) => migrations.find((m) => m.version === item.version)).filter(Boolean).reverse();
|
|
249
|
+
return appliedMigrations.map((m) => m.down);
|
|
250
|
+
}
|
|
251
|
+
async ensureMigrationTable() {
|
|
252
|
+
await this.db.execute(`
|
|
253
|
+
CREATE TABLE IF NOT EXISTS neuron_migrations (
|
|
254
|
+
version VARCHAR(10) PRIMARY KEY,
|
|
255
|
+
name VARCHAR(255) NOT NULL,
|
|
256
|
+
applied_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
|
257
|
+
checksum VARCHAR(64)
|
|
258
|
+
);
|
|
259
|
+
`);
|
|
260
|
+
}
|
|
261
|
+
async applyMigration(migration) {
|
|
262
|
+
const checksum = this.computeChecksum(migration);
|
|
263
|
+
await this.db.transaction(async (client) => {
|
|
264
|
+
await client.query(migration.up);
|
|
265
|
+
await client.query(
|
|
266
|
+
"INSERT INTO neuron_migrations (version, name, checksum) VALUES ($1, $2, $3)",
|
|
267
|
+
[migration.version, migration.name, checksum]
|
|
268
|
+
);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
async rollbackMigration(migration) {
|
|
272
|
+
await this.db.transaction(async (client) => {
|
|
273
|
+
await client.query(migration.down);
|
|
274
|
+
await client.query("DELETE FROM neuron_migrations WHERE version = $1", [
|
|
275
|
+
migration.version
|
|
276
|
+
]);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
computeChecksum(migration) {
|
|
280
|
+
const hash = crypto.createHash("sha256");
|
|
281
|
+
hash.update(migration.up);
|
|
282
|
+
hash.update(migration.down);
|
|
283
|
+
return hash.digest("hex");
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
export { MigrationRunner, migration001, migration002, migration003, migration004, migrations };
|
|
288
|
+
//# sourceMappingURL=chunk-PSDVPB7Y.js.map
|
|
289
|
+
//# sourceMappingURL=chunk-PSDVPB7Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/storage/migrations/001_initial_schema.ts","../src/storage/migrations/002_embeddings.ts","../src/storage/migrations/003_clusters.ts","../src/storage/migrations/004_analysis_runs.ts","../src/storage/migrations/index.ts","../src/storage/migrations/runner.ts"],"names":[],"mappings":"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","file":"chunk-PSDVPB7Y.js","sourcesContent":["import type { Migration } from './runner';\n\nexport const migration001: Migration = {\n version: '001',\n name: 'initial_schema',\n up: `\nCREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";\n\nCREATE TABLE IF NOT EXISTS nodes (\n id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),\n slug VARCHAR(255) UNIQUE NOT NULL,\n label VARCHAR(500) NOT NULL,\n node_type VARCHAR(100) NOT NULL DEFAULT 'concept',\n domain VARCHAR(100) NOT NULL DEFAULT 'general',\n summary TEXT,\n description TEXT,\n content TEXT,\n metadata JSONB DEFAULT '{}',\n tier VARCHAR(20),\n visual_priority INTEGER DEFAULT 50,\n position_override DOUBLE PRECISION[3],\n connection_count INTEGER DEFAULT 0,\n inbound_count INTEGER DEFAULT 0,\n outbound_count INTEGER DEFAULT 0,\n analysis_status VARCHAR(20) DEFAULT 'pending',\n analysis_error TEXT,\n created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n);\n\nCREATE TABLE IF NOT EXISTS edges (\n id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),\n from_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,\n to_node_id UUID NOT NULL REFERENCES nodes(id) ON DELETE CASCADE,\n relationship_type VARCHAR(100) NOT NULL DEFAULT 'related_to',\n strength DOUBLE PRECISION DEFAULT 0.5,\n confidence DOUBLE PRECISION DEFAULT 1.0,\n evidence JSONB DEFAULT '[]',\n label VARCHAR(255),\n description TEXT,\n metadata JSONB DEFAULT '{}',\n source VARCHAR(20) NOT NULL DEFAULT 'manual',\n source_model VARCHAR(100),\n bidirectional BOOLEAN DEFAULT FALSE,\n created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n UNIQUE(from_node_id, to_node_id, relationship_type)\n);\n\nCREATE TABLE IF NOT EXISTS settings (\n id VARCHAR(50) PRIMARY KEY DEFAULT 'default',\n visualization JSONB DEFAULT '{}',\n analysis JSONB DEFAULT '{}',\n node_types JSONB DEFAULT '[]',\n domains JSONB DEFAULT '[]',\n relationship_types JSONB DEFAULT '[]',\n updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n);\n\nCREATE INDEX IF NOT EXISTS idx_nodes_slug ON nodes(slug);\nCREATE INDEX IF NOT EXISTS idx_nodes_domain ON nodes(domain);\nCREATE INDEX IF NOT EXISTS idx_nodes_node_type ON nodes(node_type);\nCREATE INDEX IF NOT EXISTS idx_nodes_analysis_status ON nodes(analysis_status);\nCREATE INDEX IF NOT EXISTS idx_edges_from_node ON edges(from_node_id);\nCREATE INDEX IF NOT EXISTS idx_edges_to_node ON edges(to_node_id);\nCREATE INDEX IF NOT EXISTS idx_edges_type ON edges(relationship_type);\n `.trim(),\n down: `\nDROP TABLE IF EXISTS settings;\nDROP TABLE IF EXISTS edges;\nDROP TABLE IF EXISTS nodes;\nDROP EXTENSION IF EXISTS \"uuid-ossp\";\n `.trim(),\n};\n","import type { Migration } from './runner';\n\nexport const migration002: Migration = {\n version: '002',\n name: 'embeddings',\n up: `\nCREATE EXTENSION IF NOT EXISTS vector;\n\nALTER TABLE nodes ADD COLUMN IF NOT EXISTS embedding vector(1536);\nALTER TABLE nodes ADD COLUMN IF NOT EXISTS embedding_model VARCHAR(100);\nALTER TABLE nodes ADD COLUMN IF NOT EXISTS embedding_generated_at TIMESTAMP WITH TIME ZONE;\n\nCREATE INDEX IF NOT EXISTS idx_nodes_embedding ON nodes\nUSING hnsw (embedding vector_cosine_ops)\nWITH (m = 16, ef_construction = 64);\n `.trim(),\n down: `\nDROP INDEX IF EXISTS idx_nodes_embedding;\nALTER TABLE nodes DROP COLUMN IF EXISTS embedding;\nALTER TABLE nodes DROP COLUMN IF EXISTS embedding_model;\nALTER TABLE nodes DROP COLUMN IF EXISTS embedding_generated_at;\nDROP EXTENSION IF EXISTS vector;\n `.trim(),\n};\n","import type { Migration } from './runner';\n\nexport const migration003: Migration = {\n version: '003',\n name: 'clusters',\n up: `\nCREATE TABLE IF NOT EXISTS clusters (\n id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),\n label VARCHAR(255) NOT NULL,\n cluster_type VARCHAR(100) DEFAULT 'topic',\n centroid vector(1536),\n member_count INTEGER DEFAULT 0,\n avg_similarity DOUBLE PRECISION,\n cohesion DOUBLE PRECISION,\n description TEXT,\n keywords TEXT[] DEFAULT '{}',\n metadata JSONB DEFAULT '{}',\n created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n last_recomputed_at TIMESTAMP WITH TIME ZONE\n);\n\nCREATE TABLE IF NOT EXISTS cluster_memberships (\n node_id UUID REFERENCES nodes(id) ON DELETE CASCADE,\n cluster_id UUID REFERENCES clusters(id) ON DELETE CASCADE,\n similarity_score DOUBLE PRECISION NOT NULL,\n is_primary BOOLEAN DEFAULT FALSE,\n assigned_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n PRIMARY KEY (node_id, cluster_id)\n);\n\nALTER TABLE nodes ADD COLUMN IF NOT EXISTS cluster_id UUID REFERENCES clusters(id) ON DELETE SET NULL;\nALTER TABLE nodes ADD COLUMN IF NOT EXISTS cluster_similarity DOUBLE PRECISION;\n\nCREATE INDEX IF NOT EXISTS idx_cluster_memberships_cluster ON cluster_memberships(cluster_id);\nCREATE INDEX IF NOT EXISTS idx_nodes_cluster ON nodes(cluster_id);\n `.trim(),\n down: `\nDROP TABLE IF EXISTS cluster_memberships;\nDROP TABLE IF EXISTS clusters;\nALTER TABLE nodes DROP COLUMN IF EXISTS cluster_id;\nALTER TABLE nodes DROP COLUMN IF EXISTS cluster_similarity;\n `.trim(),\n};\n","import type { Migration } from './runner';\n\nexport const migration004: Migration = {\n version: '004',\n name: 'analysis_runs',\n up: `\nCREATE TABLE IF NOT EXISTS analysis_runs (\n id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),\n run_type VARCHAR(50) NOT NULL,\n input_params JSONB DEFAULT '{}',\n results JSONB DEFAULT '{}',\n status VARCHAR(20) NOT NULL DEFAULT 'queued',\n progress INTEGER DEFAULT 0,\n started_at TIMESTAMP WITH TIME ZONE,\n completed_at TIMESTAMP WITH TIME ZONE,\n duration_ms INTEGER,\n error_message TEXT,\n error_stack TEXT,\n created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n);\n\nCREATE INDEX IF NOT EXISTS idx_analysis_runs_status ON analysis_runs(status);\nCREATE INDEX IF NOT EXISTS idx_analysis_runs_created ON analysis_runs(created_at DESC);\n `.trim(),\n down: `\nDROP TABLE IF EXISTS analysis_runs;\n `.trim(),\n};\n","import type { Migration } from './runner';\nimport { migration001 } from './001_initial_schema';\nimport { migration002 } from './002_embeddings';\nimport { migration003 } from './003_clusters';\nimport { migration004 } from './004_analysis_runs';\n\nexport const migrations: Migration[] = [\n migration001,\n migration002,\n migration003,\n migration004,\n];\n\nexport * from './runner';\nexport * from './001_initial_schema';\nexport * from './002_embeddings';\nexport * from './003_clusters';\nexport * from './004_analysis_runs';\n","import crypto from 'node:crypto';\nimport type { Database } from '../database';\nimport { migrations } from './index';\n\nexport interface Migration {\n version: string;\n name: string;\n up: string;\n down: string;\n}\n\nexport interface MigrationStatus {\n version: string;\n name: string;\n appliedAt: Date | null;\n status: 'applied' | 'pending';\n}\n\nexport class MigrationRunner {\n constructor(private db: Database) {}\n\n async getStatus(): Promise<MigrationStatus[]> {\n await this.ensureMigrationTable();\n const applied = await this.getApplied();\n const appliedMap = new Map(applied.map((item) => [item.version, item]));\n\n return migrations.map((migration) => ({\n version: migration.version,\n name: migration.name,\n appliedAt: appliedMap.get(migration.version)?.appliedAt ?? null,\n status: appliedMap.has(migration.version) ? 'applied' : 'pending',\n }));\n }\n\n async getPending(): Promise<Migration[]> {\n const status = await this.getStatus();\n return status\n .filter((item) => item.status === 'pending')\n .map((item) => migrations.find((m) => m.version === item.version)!)\n .filter(Boolean);\n }\n\n async getApplied(): Promise<Array<{ version: string; name: string; appliedAt: Date }>> {\n await this.ensureMigrationTable();\n const rows = await this.db.query<{ version: string; name: string; applied_at: Date }>(\n 'SELECT version, name, applied_at FROM neuron_migrations ORDER BY version'\n );\n return rows.map((row) => ({\n version: row.version,\n name: row.name,\n appliedAt: row.applied_at,\n }));\n }\n\n async up(options?: { to?: string }): Promise<void> {\n const pending = await this.getPending();\n const targetIndex = options?.to\n ? pending.findIndex((m) => m.version === options.to) + 1\n : pending.length;\n const toApply = pending.slice(0, targetIndex > 0 ? targetIndex : pending.length);\n\n for (const migration of toApply) {\n await this.applyMigration(migration);\n }\n }\n\n async down(options?: { to?: string; count?: number }): Promise<void> {\n await this.ensureMigrationTable();\n const applied = await this.getApplied();\n const appliedMigrations = applied\n .map((item) => migrations.find((m) => m.version === item.version)!)\n .filter(Boolean);\n const reversed = [...appliedMigrations].reverse();\n\n let toRollback: Migration[] = [];\n if (options?.to) {\n const idx = reversed.findIndex((m) => m.version === options.to);\n toRollback = idx >= 0 ? reversed.slice(0, idx + 1) : [];\n } else if (options?.count) {\n toRollback = reversed.slice(0, options.count);\n } else {\n toRollback = reversed.slice(0, 1);\n }\n\n for (const migration of toRollback) {\n await this.rollbackMigration(migration);\n }\n }\n\n async reset(): Promise<void> {\n await this.down({ count: migrations.length });\n await this.up();\n }\n\n async dryRun(direction: 'up' | 'down'): Promise<string[]> {\n if (direction === 'up') {\n const pending = await this.getPending();\n return pending.map((m) => m.up);\n }\n\n const applied = await this.getApplied();\n const appliedMigrations = applied\n .map((item) => migrations.find((m) => m.version === item.version)!)\n .filter(Boolean)\n .reverse();\n\n return appliedMigrations.map((m) => m.down);\n }\n\n private async ensureMigrationTable(): Promise<void> {\n await this.db.execute(`\n CREATE TABLE IF NOT EXISTS neuron_migrations (\n version VARCHAR(10) PRIMARY KEY,\n name VARCHAR(255) NOT NULL,\n applied_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n checksum VARCHAR(64)\n );\n `);\n }\n\n private async applyMigration(migration: Migration): Promise<void> {\n const checksum = this.computeChecksum(migration);\n await this.db.transaction(async (client) => {\n await client.query(migration.up);\n await client.query(\n 'INSERT INTO neuron_migrations (version, name, checksum) VALUES ($1, $2, $3)',\n [migration.version, migration.name, checksum]\n );\n });\n }\n\n private async rollbackMigration(migration: Migration): Promise<void> {\n await this.db.transaction(async (client) => {\n await client.query(migration.down);\n await client.query('DELETE FROM neuron_migrations WHERE version = $1', [\n migration.version,\n ]);\n });\n }\n\n private computeChecksum(migration: Migration): string {\n const hash = crypto.createHash('sha256');\n hash.update(migration.up);\n hash.update(migration.down);\n return hash.digest('hex');\n }\n}\n"]}
|