@apart-tech/intelligence-core 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.
Files changed (62) hide show
  1. package/dist/config/index.d.ts +3 -0
  2. package/dist/config/index.d.ts.map +1 -0
  3. package/dist/config/index.js +97 -0
  4. package/dist/config/index.js.map +1 -0
  5. package/dist/db/connection.d.ts +7 -0
  6. package/dist/db/connection.d.ts.map +1 -0
  7. package/dist/db/connection.js +49 -0
  8. package/dist/db/connection.js.map +1 -0
  9. package/dist/db/schema.d.ts +507 -0
  10. package/dist/db/schema.d.ts.map +1 -0
  11. package/dist/db/schema.js +77 -0
  12. package/dist/db/schema.js.map +1 -0
  13. package/dist/db/tenant.d.ts +8 -0
  14. package/dist/db/tenant.d.ts.map +1 -0
  15. package/dist/db/tenant.js +92 -0
  16. package/dist/db/tenant.js.map +1 -0
  17. package/dist/index.d.ts +16 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +18 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/providers/index.d.ts +5 -0
  22. package/dist/providers/index.d.ts.map +1 -0
  23. package/dist/providers/index.js +16 -0
  24. package/dist/providers/index.js.map +1 -0
  25. package/dist/providers/openai.d.ts +9 -0
  26. package/dist/providers/openai.d.ts.map +1 -0
  27. package/dist/providers/openai.js +34 -0
  28. package/dist/providers/openai.js.map +1 -0
  29. package/dist/services/cleaning-service.d.ts +152 -0
  30. package/dist/services/cleaning-service.d.ts.map +1 -0
  31. package/dist/services/cleaning-service.js +632 -0
  32. package/dist/services/cleaning-service.js.map +1 -0
  33. package/dist/services/context-service.d.ts +13 -0
  34. package/dist/services/context-service.d.ts.map +1 -0
  35. package/dist/services/context-service.js +74 -0
  36. package/dist/services/context-service.js.map +1 -0
  37. package/dist/services/domain-seed-data.d.ts +8 -0
  38. package/dist/services/domain-seed-data.d.ts.map +1 -0
  39. package/dist/services/domain-seed-data.js +84 -0
  40. package/dist/services/domain-seed-data.js.map +1 -0
  41. package/dist/services/domain-service.d.ts +26 -0
  42. package/dist/services/domain-service.d.ts.map +1 -0
  43. package/dist/services/domain-service.js +101 -0
  44. package/dist/services/domain-service.js.map +1 -0
  45. package/dist/services/edge-service.d.ts +25 -0
  46. package/dist/services/edge-service.d.ts.map +1 -0
  47. package/dist/services/edge-service.js +90 -0
  48. package/dist/services/edge-service.js.map +1 -0
  49. package/dist/services/node-service.d.ts +34 -0
  50. package/dist/services/node-service.d.ts.map +1 -0
  51. package/dist/services/node-service.js +113 -0
  52. package/dist/services/node-service.js.map +1 -0
  53. package/dist/services/search-service.d.ts +15 -0
  54. package/dist/services/search-service.d.ts.map +1 -0
  55. package/dist/services/search-service.js +118 -0
  56. package/dist/services/search-service.js.map +1 -0
  57. package/dist/types/index.d.ts +74 -0
  58. package/dist/types/index.d.ts.map +1 -0
  59. package/dist/types/index.js +2 -0
  60. package/dist/types/index.js.map +1 -0
  61. package/package.json +42 -0
  62. package/prisma/schema.prisma +114 -0
@@ -0,0 +1,632 @@
1
+ import { tenantWhere, SINGLE_TENANT_ORG_ID } from "../db/tenant.js";
2
+ // ── Service ─────────────────────────────────────────────────────────────────
3
+ export class CleaningService {
4
+ db;
5
+ tenantCtx;
6
+ constructor(db, tenantCtx) {
7
+ this.db = db;
8
+ this.tenantCtx = tenantCtx ?? { organizationId: SINGLE_TENANT_ORG_ID };
9
+ }
10
+ /**
11
+ * Find nodes with zero edges.
12
+ */
13
+ async findOrphans() {
14
+ const orgFilter = tenantWhere(this.tenantCtx, "n");
15
+ const orphanIds = await this.db.$queryRaw `
16
+ SELECT n.id
17
+ FROM nodes n
18
+ LEFT JOIN edges e ON e.source_node_id = n.id OR e.target_node_id = n.id
19
+ WHERE e.id IS NULL
20
+ AND ${orgFilter}
21
+ ORDER BY n.created_at DESC
22
+ `;
23
+ if (orphanIds.length === 0)
24
+ return [];
25
+ const nodes = await this.db.node.findMany({
26
+ where: { id: { in: orphanIds.map((r) => r.id) } },
27
+ orderBy: { createdAt: "desc" },
28
+ });
29
+ return nodes.map((node) => ({ node }));
30
+ }
31
+ /**
32
+ * Find node pairs with cosine similarity above threshold.
33
+ */
34
+ async findDuplicates(threshold = 0.95, limit = 50) {
35
+ const orgFilterA = tenantWhere(this.tenantCtx, "a");
36
+ const pairs = await this.db.$queryRaw `
37
+ SELECT
38
+ a.id AS a_id,
39
+ b.id AS b_id,
40
+ 1 - (a.embedding <=> b.embedding) AS similarity
41
+ FROM nodes a
42
+ JOIN nodes b ON a.id < b.id
43
+ WHERE a.embedding IS NOT NULL
44
+ AND b.embedding IS NOT NULL
45
+ AND 1 - (a.embedding <=> b.embedding) >= ${threshold}
46
+ AND ${orgFilterA}
47
+ ORDER BY similarity DESC
48
+ LIMIT ${limit}
49
+ `;
50
+ if (pairs.length === 0)
51
+ return [];
52
+ // Batch-fetch all involved nodes
53
+ const nodeIds = new Set();
54
+ for (const p of pairs) {
55
+ nodeIds.add(p.a_id);
56
+ nodeIds.add(p.b_id);
57
+ }
58
+ const nodes = await this.db.node.findMany({
59
+ where: { id: { in: [...nodeIds] } },
60
+ });
61
+ const nodeMap = new Map(nodes.map((n) => [n.id, n]));
62
+ return pairs
63
+ .filter((p) => nodeMap.has(p.a_id) && nodeMap.has(p.b_id))
64
+ .map((p) => ({
65
+ nodeA: nodeMap.get(p.a_id),
66
+ nodeB: nodeMap.get(p.b_id),
67
+ similarity: Number(p.similarity),
68
+ }));
69
+ }
70
+ /**
71
+ * Comprehensive graph health report.
72
+ */
73
+ async getHealthReport(staleDays = 90) {
74
+ const staleDate = new Date();
75
+ staleDate.setDate(staleDate.getDate() - staleDays);
76
+ const orgFilterN = tenantWhere(this.tenantCtx, "n");
77
+ const orgFilterE = tenantWhere(this.tenantCtx);
78
+ const orgFilterA = tenantWhere(this.tenantCtx, "a");
79
+ // Run independent queries in parallel
80
+ const [totalNodes, totalEdges, byStatus, byType, byRelType, orphanCount, undomainedCount, staleCount, selfLoopCount, duplicateEdgeRows, duplicateCandidateCount, allEdges,] = await Promise.all([
81
+ this.db.node.count(),
82
+ this.db.edge.count(),
83
+ this.db.node.groupBy({
84
+ by: ["status"],
85
+ _count: { status: true },
86
+ orderBy: { _count: { status: "desc" } },
87
+ }),
88
+ this.db.node.groupBy({
89
+ by: ["type"],
90
+ _count: { type: true },
91
+ orderBy: { _count: { type: "desc" } },
92
+ }),
93
+ this.db.edge.groupBy({
94
+ by: ["relationshipType"],
95
+ _count: { relationshipType: true },
96
+ orderBy: { _count: { relationshipType: "desc" } },
97
+ }),
98
+ this.db.$queryRaw `
99
+ SELECT COUNT(*) as count FROM nodes n
100
+ LEFT JOIN edges e ON e.source_node_id = n.id OR e.target_node_id = n.id
101
+ WHERE e.id IS NULL
102
+ AND ${orgFilterN}
103
+ `.then((r) => Number(r[0].count)),
104
+ this.db.node.count({ where: { domainId: null } }),
105
+ this.db.node.count({ where: { updatedAt: { lt: staleDate } } }),
106
+ this.db.$queryRaw `
107
+ SELECT COUNT(*) as count FROM edges
108
+ WHERE source_node_id = target_node_id
109
+ AND ${orgFilterE}
110
+ `.then((r) => Number(r[0].count)),
111
+ this.db.$queryRaw `
112
+ SELECT COUNT(*) as count FROM (
113
+ SELECT source_node_id, target_node_id, relationship_type
114
+ FROM edges
115
+ WHERE ${orgFilterE}
116
+ GROUP BY source_node_id, target_node_id, relationship_type
117
+ HAVING COUNT(*) > 1
118
+ ) dupes
119
+ `.then((r) => Number(r[0].count)),
120
+ this.db.$queryRaw `
121
+ SELECT COUNT(*) as count FROM (
122
+ SELECT a.id
123
+ FROM nodes a
124
+ JOIN nodes b ON a.id < b.id
125
+ WHERE a.embedding IS NOT NULL
126
+ AND b.embedding IS NOT NULL
127
+ AND 1 - (a.embedding <=> b.embedding) >= 0.95
128
+ AND ${orgFilterA}
129
+ LIMIT 1
130
+ ) pairs
131
+ `.then((r) => Number(r[0].count)),
132
+ this.db.edge.findMany({ select: { sourceNodeId: true, targetNodeId: true } }),
133
+ ]);
134
+ // Compute connected components via union-find
135
+ const componentMap = this.computeComponentMap(allEdges);
136
+ const { components, largestSize } = this.summarizeComponents(componentMap, totalNodes);
137
+ const avgEdgesPerNode = totalNodes > 0 ? (totalEdges * 2) / totalNodes : 0;
138
+ return {
139
+ nodes: {
140
+ total: totalNodes,
141
+ byStatus: byStatus.map((r) => ({
142
+ status: r.status,
143
+ count: r._count.status,
144
+ })),
145
+ byType: byType.map((r) => ({
146
+ type: r.type,
147
+ count: r._count.type,
148
+ })),
149
+ orphanCount,
150
+ undomainedCount,
151
+ staleCount,
152
+ },
153
+ edges: {
154
+ total: totalEdges,
155
+ byRelationshipType: byRelType.map((r) => ({
156
+ relationshipType: r.relationshipType,
157
+ count: r._count.relationshipType,
158
+ })),
159
+ selfLoopCount,
160
+ duplicateCount: duplicateEdgeRows,
161
+ },
162
+ graph: {
163
+ avgEdgesPerNode: Math.round(avgEdgesPerNode * 100) / 100,
164
+ connectedComponents: components,
165
+ largestComponentSize: largestSize,
166
+ },
167
+ duplicateCandidates: duplicateCandidateCount > 0 ? duplicateCandidateCount : 0,
168
+ };
169
+ }
170
+ /**
171
+ * Validate edges for integrity issues.
172
+ */
173
+ async validateEdges({ lowRelevanceThreshold = 0.3, rareTypeThreshold = 1 } = {}) {
174
+ const issues = [];
175
+ const orgFilterE = tenantWhere(this.tenantCtx);
176
+ const orgFilterEdge = tenantWhere(this.tenantCtx, "e");
177
+ const [selfLoopRows, duplicateEdges, lowRelevancePairs, relTypeCounts, allEdges,] = await Promise.all([
178
+ this.db.$queryRaw `
179
+ SELECT id, source_node_id FROM edges WHERE source_node_id = target_node_id AND ${orgFilterE}
180
+ `,
181
+ this.db.$queryRaw `
182
+ SELECT source_node_id, target_node_id, relationship_type, COUNT(*) as cnt,
183
+ array_agg(id::text) as ids
184
+ FROM edges
185
+ WHERE ${orgFilterE}
186
+ GROUP BY source_node_id, target_node_id, relationship_type
187
+ HAVING COUNT(*) > 1
188
+ `,
189
+ this.db.$queryRaw `
190
+ SELECT e.id as edge_id, e.source_node_id, e.target_node_id, e.relationship_type,
191
+ 1 - (a.embedding <=> b.embedding) AS similarity
192
+ FROM edges e
193
+ JOIN nodes a ON a.id = e.source_node_id
194
+ JOIN nodes b ON b.id = e.target_node_id
195
+ WHERE a.embedding IS NOT NULL AND b.embedding IS NOT NULL
196
+ AND 1 - (a.embedding <=> b.embedding) < ${lowRelevanceThreshold}
197
+ AND ${orgFilterEdge}
198
+ ORDER BY similarity ASC
199
+ `,
200
+ this.db.edge.groupBy({
201
+ by: ["relationshipType"],
202
+ _count: { relationshipType: true },
203
+ }),
204
+ this.db.edge.findMany(),
205
+ ]);
206
+ const totalEdgesChecked = allEdges.length;
207
+ // Batch-fetch nodes for all issues
208
+ const nodeIdsNeeded = new Set();
209
+ for (const e of selfLoopRows)
210
+ nodeIdsNeeded.add(e.source_node_id);
211
+ for (const d of duplicateEdges) {
212
+ nodeIdsNeeded.add(d.source_node_id);
213
+ nodeIdsNeeded.add(d.target_node_id);
214
+ }
215
+ for (const lr of lowRelevancePairs) {
216
+ nodeIdsNeeded.add(lr.source_node_id);
217
+ nodeIdsNeeded.add(lr.target_node_id);
218
+ }
219
+ const nodesById = nodeIdsNeeded.size > 0
220
+ ? new Map((await this.db.node.findMany({
221
+ where: { id: { in: [...nodeIdsNeeded] } },
222
+ })).map((n) => [n.id, n]))
223
+ : new Map();
224
+ // 1. Self-loops
225
+ for (const row of selfLoopRows) {
226
+ const edge = allEdges.find((e) => e.id === row.id);
227
+ if (!edge)
228
+ continue;
229
+ const node = nodesById.get(row.source_node_id);
230
+ issues.push({
231
+ severity: "error",
232
+ category: "self-loop",
233
+ message: `Edge points to itself: ${node?.title ?? row.source_node_id}`,
234
+ edges: [edge],
235
+ sourceNode: node,
236
+ targetNode: node,
237
+ });
238
+ }
239
+ // 2. Duplicate edges
240
+ for (const dupe of duplicateEdges) {
241
+ const edgeIds = dupe.ids;
242
+ const edges = allEdges.filter((e) => edgeIds.includes(e.id));
243
+ issues.push({
244
+ severity: "warning",
245
+ category: "duplicate-edge",
246
+ message: `${Number(dupe.cnt)} duplicate "${dupe.relationship_type}" edges between nodes`,
247
+ edges,
248
+ sourceNode: nodesById.get(dupe.source_node_id),
249
+ targetNode: nodesById.get(dupe.target_node_id),
250
+ });
251
+ }
252
+ // 3. Low-relevance connections
253
+ for (const lr of lowRelevancePairs) {
254
+ const edge = allEdges.find((e) => e.id === lr.edge_id);
255
+ if (!edge)
256
+ continue;
257
+ issues.push({
258
+ severity: "warning",
259
+ category: "low-relevance",
260
+ message: `Low similarity (${(Number(lr.similarity) * 100).toFixed(1)}%) between connected nodes`,
261
+ edges: [edge],
262
+ sourceNode: nodesById.get(lr.source_node_id),
263
+ targetNode: nodesById.get(lr.target_node_id),
264
+ similarity: Number(lr.similarity),
265
+ });
266
+ }
267
+ // 4. Contradictory edges (same node pair with opposing relationship types)
268
+ const contradictionPairs = [
269
+ ["supports", "contradicts"],
270
+ ["enables", "blocks"],
271
+ ["requires", "excludes"],
272
+ ];
273
+ const edgesByPair = new Map();
274
+ for (const edge of allEdges) {
275
+ const key = [edge.sourceNodeId, edge.targetNodeId].sort().join("|");
276
+ if (!edgesByPair.has(key))
277
+ edgesByPair.set(key, []);
278
+ edgesByPair.get(key).push(edge);
279
+ }
280
+ for (const [, pairEdges] of edgesByPair) {
281
+ if (pairEdges.length < 2)
282
+ continue;
283
+ const types = new Set(pairEdges.map((e) => e.relationshipType));
284
+ for (const [typeA, typeB] of contradictionPairs) {
285
+ if (types.has(typeA) && types.has(typeB)) {
286
+ const contradicting = pairEdges.filter((e) => e.relationshipType === typeA || e.relationshipType === typeB);
287
+ // Fetch nodes if not already loaded
288
+ for (const e of contradicting) {
289
+ if (!nodesById.has(e.sourceNodeId)) {
290
+ const n = await this.db.node.findUnique({ where: { id: e.sourceNodeId } });
291
+ if (n)
292
+ nodesById.set(n.id, n);
293
+ }
294
+ if (!nodesById.has(e.targetNodeId)) {
295
+ const n = await this.db.node.findUnique({ where: { id: e.targetNodeId } });
296
+ if (n)
297
+ nodesById.set(n.id, n);
298
+ }
299
+ }
300
+ issues.push({
301
+ severity: "error",
302
+ category: "contradictory",
303
+ message: `Contradictory edges: "${typeA}" and "${typeB}" between same nodes`,
304
+ edges: contradicting,
305
+ sourceNode: nodesById.get(contradicting[0].sourceNodeId),
306
+ targetNode: nodesById.get(contradicting[0].targetNodeId),
307
+ });
308
+ }
309
+ }
310
+ }
311
+ // 5. Rare relationship types (potential typos)
312
+ const rareTypes = relTypeCounts.filter((r) => r._count.relationshipType <= rareTypeThreshold);
313
+ for (const rare of rareTypes) {
314
+ const rareEdges = allEdges.filter((e) => e.relationshipType === rare.relationshipType);
315
+ // Fetch nodes for rare edges
316
+ for (const e of rareEdges) {
317
+ if (!nodesById.has(e.sourceNodeId)) {
318
+ const n = await this.db.node.findUnique({ where: { id: e.sourceNodeId } });
319
+ if (n)
320
+ nodesById.set(n.id, n);
321
+ }
322
+ if (!nodesById.has(e.targetNodeId)) {
323
+ const n = await this.db.node.findUnique({ where: { id: e.targetNodeId } });
324
+ if (n)
325
+ nodesById.set(n.id, n);
326
+ }
327
+ }
328
+ issues.push({
329
+ severity: "info",
330
+ category: "rare-relationship-type",
331
+ message: `Relationship type "${rare.relationshipType}" used only ${rare._count.relationshipType} time(s) — possible typo?`,
332
+ edges: rareEdges,
333
+ sourceNode: rareEdges[0] ? nodesById.get(rareEdges[0].sourceNodeId) : undefined,
334
+ targetNode: rareEdges[0] ? nodesById.get(rareEdges[0].targetNodeId) : undefined,
335
+ });
336
+ }
337
+ // Build summary
338
+ const summary = {
339
+ "self-loop": 0,
340
+ "duplicate-edge": 0,
341
+ "low-relevance": 0,
342
+ "contradictory": 0,
343
+ "rare-relationship-type": 0,
344
+ };
345
+ for (const issue of issues) {
346
+ summary[issue.category]++;
347
+ }
348
+ return {
349
+ issues,
350
+ summary,
351
+ totalIssues: issues.length,
352
+ totalEdgesChecked,
353
+ };
354
+ }
355
+ /**
356
+ * Suggest links for a specific node based on embedding similarity,
357
+ * excluding nodes already connected to it.
358
+ */
359
+ async suggestLinksForNode(nodeId, { limit = 10, minSimilarity = 0.7 } = {}) {
360
+ const orgFilterA = tenantWhere(this.tenantCtx, "a");
361
+ const suggestions = await this.db.$queryRaw `
362
+ SELECT
363
+ b.id AS target_id,
364
+ 1 - (a.embedding <=> b.embedding) AS similarity
365
+ FROM nodes a
366
+ JOIN nodes b ON a.id != b.id
367
+ WHERE a.id = ${nodeId}::uuid
368
+ AND a.embedding IS NOT NULL
369
+ AND b.embedding IS NOT NULL
370
+ AND b.id NOT IN (
371
+ SELECT CASE WHEN source_node_id = ${nodeId}::uuid THEN target_node_id ELSE source_node_id END
372
+ FROM edges
373
+ WHERE source_node_id = ${nodeId}::uuid OR target_node_id = ${nodeId}::uuid
374
+ )
375
+ AND 1 - (a.embedding <=> b.embedding) >= ${minSimilarity}
376
+ AND ${orgFilterA}
377
+ ORDER BY similarity DESC
378
+ LIMIT ${limit}
379
+ `;
380
+ if (suggestions.length === 0)
381
+ return [];
382
+ const sourceNode = await this.db.node.findUnique({ where: { id: nodeId } });
383
+ if (!sourceNode)
384
+ return [];
385
+ const targetNodes = await this.db.node.findMany({
386
+ where: { id: { in: suggestions.map((s) => s.target_id) } },
387
+ });
388
+ const targetMap = new Map(targetNodes.map((n) => [n.id, n]));
389
+ return suggestions
390
+ .filter((s) => targetMap.has(s.target_id))
391
+ .map((s) => ({
392
+ source: sourceNode,
393
+ target: targetMap.get(s.target_id),
394
+ similarity: Number(s.similarity),
395
+ }));
396
+ }
397
+ /**
398
+ * Scan the full graph for high-similarity unconnected pairs.
399
+ */
400
+ async suggestLinksGlobal({ limit = 20, minSimilarity = 0.8 } = {}) {
401
+ const orgFilterA = tenantWhere(this.tenantCtx, "a");
402
+ const pairs = await this.db.$queryRaw `
403
+ SELECT
404
+ a.id AS a_id,
405
+ b.id AS b_id,
406
+ 1 - (a.embedding <=> b.embedding) AS similarity
407
+ FROM nodes a
408
+ JOIN nodes b ON a.id < b.id
409
+ WHERE a.embedding IS NOT NULL
410
+ AND b.embedding IS NOT NULL
411
+ AND 1 - (a.embedding <=> b.embedding) >= ${minSimilarity}
412
+ AND NOT EXISTS (
413
+ SELECT 1 FROM edges e
414
+ WHERE (e.source_node_id = a.id AND e.target_node_id = b.id)
415
+ OR (e.source_node_id = b.id AND e.target_node_id = a.id)
416
+ )
417
+ AND ${orgFilterA}
418
+ ORDER BY similarity DESC
419
+ LIMIT ${limit}
420
+ `;
421
+ if (pairs.length === 0)
422
+ return [];
423
+ const nodeIds = new Set();
424
+ for (const p of pairs) {
425
+ nodeIds.add(p.a_id);
426
+ nodeIds.add(p.b_id);
427
+ }
428
+ const nodes = await this.db.node.findMany({
429
+ where: { id: { in: [...nodeIds] } },
430
+ });
431
+ const nodeMap = new Map(nodes.map((n) => [n.id, n]));
432
+ return pairs
433
+ .filter((p) => nodeMap.has(p.a_id) && nodeMap.has(p.b_id))
434
+ .map((p) => ({
435
+ source: nodeMap.get(p.a_id),
436
+ target: nodeMap.get(p.b_id),
437
+ similarity: Number(p.similarity),
438
+ }));
439
+ }
440
+ /**
441
+ * Find all disconnected clusters (islands) in the graph.
442
+ * Returns islands sorted by size descending, excluding orphan nodes (size 1).
443
+ */
444
+ async findIslands() {
445
+ const allEdges = await this.db.edge.findMany({
446
+ select: { sourceNodeId: true, targetNodeId: true },
447
+ });
448
+ const componentMap = this.computeComponentMap(allEdges);
449
+ // Group node IDs by component root
450
+ const groups = new Map();
451
+ for (const [nodeId, root] of componentMap.entries()) {
452
+ if (!groups.has(root))
453
+ groups.set(root, []);
454
+ groups.get(root).push(nodeId);
455
+ }
456
+ // Filter to multi-node components, sort by size desc
457
+ const sortedGroups = [...groups.values()]
458
+ .filter((g) => g.length > 1)
459
+ .sort((a, b) => b.length - a.length);
460
+ // Batch-fetch all nodes involved
461
+ const allNodeIds = sortedGroups.flat();
462
+ const nodes = await this.db.node.findMany({
463
+ where: { id: { in: allNodeIds } },
464
+ });
465
+ const nodeMap = new Map(nodes.map((n) => [n.id, n]));
466
+ return sortedGroups.map((group, idx) => ({
467
+ id: idx + 1,
468
+ size: group.length,
469
+ nodes: group
470
+ .map((id) => nodeMap.get(id))
471
+ .filter((n) => n !== undefined),
472
+ }));
473
+ }
474
+ /**
475
+ * Suggest bridges between the top islands using embedding similarity.
476
+ */
477
+ async suggestBridges(maxBridges = 10) {
478
+ const islands = await this.findIslands();
479
+ if (islands.length < 2)
480
+ return [];
481
+ const bridges = [];
482
+ // For each pair of islands (largest first), find the best cross-island link
483
+ for (let i = 0; i < islands.length && bridges.length < maxBridges; i++) {
484
+ for (let j = i + 1; j < islands.length && bridges.length < maxBridges; j++) {
485
+ const fromIds = islands[i].nodes.map((n) => n.id);
486
+ const toIds = islands[j].nodes.map((n) => n.id);
487
+ const orgFilterA = tenantWhere(this.tenantCtx, "a");
488
+ const best = await this.db.$queryRaw `
489
+ SELECT
490
+ a.id AS a_id,
491
+ b.id AS b_id,
492
+ 1 - (a.embedding <=> b.embedding) AS similarity
493
+ FROM nodes a
494
+ JOIN nodes b ON a.id != b.id
495
+ WHERE a.id = ANY(${fromIds}::uuid[])
496
+ AND b.id = ANY(${toIds}::uuid[])
497
+ AND a.embedding IS NOT NULL
498
+ AND b.embedding IS NOT NULL
499
+ AND ${orgFilterA}
500
+ ORDER BY similarity DESC
501
+ LIMIT 1
502
+ `;
503
+ if (best.length > 0) {
504
+ const nodeA = islands[i].nodes.find((n) => n.id === best[0].a_id);
505
+ const nodeB = islands[j].nodes.find((n) => n.id === best[0].b_id);
506
+ if (nodeA && nodeB) {
507
+ bridges.push({
508
+ from: islands[i],
509
+ to: islands[j],
510
+ suggestion: {
511
+ source: nodeA,
512
+ target: nodeB,
513
+ similarity: Number(best[0].similarity),
514
+ },
515
+ });
516
+ }
517
+ }
518
+ }
519
+ }
520
+ return bridges.sort((a, b) => b.suggestion.similarity - a.suggestion.similarity);
521
+ }
522
+ /**
523
+ * Analyze relationship types and suggest normalizations using embedding similarity.
524
+ * Compares type names semantically to find ones that likely mean the same thing.
525
+ */
526
+ async analyzeRelationshipTypes(embeddings, { minSimilarity = 0.7 } = {}) {
527
+ const typeCounts = await this.db.edge.groupBy({
528
+ by: ["relationshipType"],
529
+ _count: { relationshipType: true },
530
+ orderBy: { _count: { relationshipType: "desc" } },
531
+ });
532
+ const allTypes = typeCounts.map((r) => ({
533
+ relationshipType: r.relationshipType,
534
+ count: r._count.relationshipType,
535
+ }));
536
+ if (allTypes.length < 2) {
537
+ return { suggestions: [], allTypes };
538
+ }
539
+ // Embed all relationship type names (expand hyphens to spaces for better semantics)
540
+ const typeNames = allTypes.map((t) => t.relationshipType.replace(/-/g, " "));
541
+ const typeEmbeddings = await embeddings.embedBatch(typeNames);
542
+ // Compare all pairs, suggest merging rare → common when similar
543
+ const suggestions = [];
544
+ for (let i = 0; i < allTypes.length; i++) {
545
+ for (let j = i + 1; j < allTypes.length; j++) {
546
+ const sim = cosineSimilarity(typeEmbeddings[i], typeEmbeddings[j]);
547
+ if (sim < minSimilarity)
548
+ continue;
549
+ // Suggest merging the less-used type into the more-used one
550
+ const [from, to] = allTypes[i].count >= allTypes[j].count ? [j, i] : [i, j];
551
+ suggestions.push({
552
+ fromType: allTypes[from].relationshipType,
553
+ fromCount: allTypes[from].count,
554
+ toType: allTypes[to].relationshipType,
555
+ toCount: allTypes[to].count,
556
+ similarity: Math.round(sim * 1000) / 1000,
557
+ });
558
+ }
559
+ }
560
+ suggestions.sort((a, b) => b.similarity - a.similarity);
561
+ return { suggestions, allTypes };
562
+ }
563
+ // ── Private helpers ─────────────────────────────────────────────────────
564
+ /**
565
+ * Union-find returning a map of nodeId -> component root.
566
+ */
567
+ computeComponentMap(edges) {
568
+ const parent = new Map();
569
+ function find(x) {
570
+ if (!parent.has(x))
571
+ parent.set(x, x);
572
+ let root = x;
573
+ while (parent.get(root) !== root)
574
+ root = parent.get(root);
575
+ let cur = x;
576
+ while (cur !== root) {
577
+ const next = parent.get(cur);
578
+ parent.set(cur, root);
579
+ cur = next;
580
+ }
581
+ return root;
582
+ }
583
+ function union(a, b) {
584
+ const ra = find(a);
585
+ const rb = find(b);
586
+ if (ra !== rb)
587
+ parent.set(ra, rb);
588
+ }
589
+ for (const edge of edges) {
590
+ union(edge.sourceNodeId, edge.targetNodeId);
591
+ }
592
+ // Normalize all roots
593
+ for (const nodeId of parent.keys()) {
594
+ find(nodeId);
595
+ }
596
+ return parent;
597
+ }
598
+ /**
599
+ * Summarize component map into counts for the health report.
600
+ */
601
+ summarizeComponents(componentMap, totalNodes) {
602
+ const componentSizes = new Map();
603
+ for (const [, root] of componentMap.entries()) {
604
+ componentSizes.set(root, (componentSizes.get(root) ?? 0) + 1);
605
+ }
606
+ const connectedNodeCount = componentMap.size;
607
+ const orphanNodeCount = totalNodes - connectedNodeCount;
608
+ const totalComponents = componentSizes.size + orphanNodeCount;
609
+ let largestSize = 0;
610
+ for (const size of componentSizes.values()) {
611
+ if (size > largestSize)
612
+ largestSize = size;
613
+ }
614
+ if (largestSize === 0 && totalNodes > 0)
615
+ largestSize = 1;
616
+ return { components: totalComponents, largestSize };
617
+ }
618
+ }
619
+ // ── Utilities ───────────────────────────────────────────────────────────────
620
+ function cosineSimilarity(a, b) {
621
+ let dot = 0;
622
+ let magA = 0;
623
+ let magB = 0;
624
+ for (let i = 0; i < a.length; i++) {
625
+ dot += a[i] * b[i];
626
+ magA += a[i] * a[i];
627
+ magB += b[i] * b[i];
628
+ }
629
+ const denom = Math.sqrt(magA) * Math.sqrt(magB);
630
+ return denom === 0 ? 0 : dot / denom;
631
+ }
632
+ //# sourceMappingURL=cleaning-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleaning-service.js","sourceRoot":"","sources":["../../src/services/cleaning-service.ts"],"names":[],"mappings":"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"}