@memberjunction/db-auto-doc 2.117.0 → 2.118.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 +652 -165
- package/bin/run.js +7 -0
- package/dist/api/DBAutoDocAPI.d.ts +252 -0
- package/dist/api/DBAutoDocAPI.d.ts.map +1 -0
- package/dist/api/DBAutoDocAPI.js +530 -0
- package/dist/api/DBAutoDocAPI.js.map +1 -0
- package/dist/api/index.d.ts +7 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +10 -0
- package/dist/api/index.js.map +1 -0
- package/dist/commands/analyze.d.ts +6 -4
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +58 -71
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/export.d.ts +14 -4
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +156 -61
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/init.d.ts +3 -4
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +155 -146
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/reset.d.ts +4 -1
- package/dist/commands/reset.d.ts.map +1 -1
- package/dist/commands/reset.js +33 -19
- package/dist/commands/reset.js.map +1 -1
- package/dist/commands/status.d.ts +10 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +66 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/core/AnalysisEngine.d.ts +108 -0
- package/dist/core/AnalysisEngine.d.ts.map +1 -0
- package/dist/core/AnalysisEngine.js +716 -0
- package/dist/core/AnalysisEngine.js.map +1 -0
- package/dist/core/AnalysisOrchestrator.d.ts +37 -0
- package/dist/core/AnalysisOrchestrator.d.ts.map +1 -0
- package/dist/core/AnalysisOrchestrator.js +294 -0
- package/dist/core/AnalysisOrchestrator.js.map +1 -0
- package/dist/core/BackpropagationEngine.d.ts +32 -0
- package/dist/core/BackpropagationEngine.d.ts.map +1 -0
- package/dist/core/BackpropagationEngine.js +121 -0
- package/dist/core/BackpropagationEngine.js.map +1 -0
- package/dist/core/ConvergenceDetector.d.ts +27 -0
- package/dist/core/ConvergenceDetector.d.ts.map +1 -0
- package/dist/core/ConvergenceDetector.js +92 -0
- package/dist/core/ConvergenceDetector.js.map +1 -0
- package/dist/core/GuardrailsManager.d.ts +78 -0
- package/dist/core/GuardrailsManager.d.ts.map +1 -0
- package/dist/core/GuardrailsManager.js +367 -0
- package/dist/core/GuardrailsManager.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -0
- package/dist/core/index.js.map +1 -0
- package/dist/database/Database.d.ts +56 -0
- package/dist/database/Database.d.ts.map +1 -0
- package/dist/database/Database.js +172 -0
- package/dist/database/Database.js.map +1 -0
- package/dist/database/TopologicalSorter.d.ts +25 -0
- package/dist/database/TopologicalSorter.d.ts.map +1 -0
- package/dist/database/TopologicalSorter.js +150 -0
- package/dist/database/TopologicalSorter.js.map +1 -0
- package/dist/database/index.d.ts +6 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +14 -0
- package/dist/database/index.js.map +1 -0
- package/dist/discovery/ColumnStatsCache.d.ts +91 -0
- package/dist/discovery/ColumnStatsCache.d.ts.map +1 -0
- package/dist/discovery/ColumnStatsCache.js +231 -0
- package/dist/discovery/ColumnStatsCache.js.map +1 -0
- package/dist/discovery/DiscoveryEngine.d.ts +100 -0
- package/dist/discovery/DiscoveryEngine.d.ts.map +1 -0
- package/dist/discovery/DiscoveryEngine.js +726 -0
- package/dist/discovery/DiscoveryEngine.js.map +1 -0
- package/dist/discovery/DiscoveryTriggerAnalyzer.d.ts +57 -0
- package/dist/discovery/DiscoveryTriggerAnalyzer.d.ts.map +1 -0
- package/dist/discovery/DiscoveryTriggerAnalyzer.js +186 -0
- package/dist/discovery/DiscoveryTriggerAnalyzer.js.map +1 -0
- package/dist/discovery/FKDetector.d.ts +47 -0
- package/dist/discovery/FKDetector.d.ts.map +1 -0
- package/dist/discovery/FKDetector.js +317 -0
- package/dist/discovery/FKDetector.js.map +1 -0
- package/dist/discovery/LLMDiscoveryValidator.d.ts +64 -0
- package/dist/discovery/LLMDiscoveryValidator.d.ts.map +1 -0
- package/dist/discovery/LLMDiscoveryValidator.js +431 -0
- package/dist/discovery/LLMDiscoveryValidator.js.map +1 -0
- package/dist/discovery/LLMSanityChecker.d.ts +38 -0
- package/dist/discovery/LLMSanityChecker.d.ts.map +1 -0
- package/dist/discovery/LLMSanityChecker.js +156 -0
- package/dist/discovery/LLMSanityChecker.js.map +1 -0
- package/dist/discovery/PKDetector.d.ts +62 -0
- package/dist/discovery/PKDetector.d.ts.map +1 -0
- package/dist/discovery/PKDetector.js +436 -0
- package/dist/discovery/PKDetector.js.map +1 -0
- package/dist/discovery/index.d.ts +9 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +25 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/drivers/BaseAutoDocDriver.d.ts +132 -0
- package/dist/drivers/BaseAutoDocDriver.d.ts.map +1 -0
- package/dist/drivers/BaseAutoDocDriver.js +121 -0
- package/dist/drivers/BaseAutoDocDriver.js.map +1 -0
- package/dist/drivers/MySQLDriver.d.ts +61 -0
- package/dist/drivers/MySQLDriver.d.ts.map +1 -0
- package/dist/drivers/MySQLDriver.js +668 -0
- package/dist/drivers/MySQLDriver.js.map +1 -0
- package/dist/drivers/PostgreSQLDriver.d.ts +65 -0
- package/dist/drivers/PostgreSQLDriver.d.ts.map +1 -0
- package/dist/drivers/PostgreSQLDriver.js +704 -0
- package/dist/drivers/PostgreSQLDriver.js.map +1 -0
- package/dist/drivers/SQLServerDriver.d.ts +61 -0
- package/dist/drivers/SQLServerDriver.d.ts.map +1 -0
- package/dist/drivers/SQLServerDriver.js +667 -0
- package/dist/drivers/SQLServerDriver.js.map +1 -0
- package/dist/generators/CSVGenerator.d.ts +35 -0
- package/dist/generators/CSVGenerator.d.ts.map +1 -0
- package/dist/generators/CSVGenerator.js +154 -0
- package/dist/generators/CSVGenerator.js.map +1 -0
- package/dist/generators/HTMLGenerator.d.ts +29 -0
- package/dist/generators/HTMLGenerator.d.ts.map +1 -0
- package/dist/generators/HTMLGenerator.js +710 -0
- package/dist/generators/HTMLGenerator.js.map +1 -0
- package/dist/generators/MarkdownGenerator.d.ts +27 -0
- package/dist/generators/MarkdownGenerator.d.ts.map +1 -0
- package/dist/generators/MarkdownGenerator.js +361 -0
- package/dist/generators/MarkdownGenerator.js.map +1 -0
- package/dist/generators/MermaidGenerator.d.ts +35 -0
- package/dist/generators/MermaidGenerator.d.ts.map +1 -0
- package/dist/generators/MermaidGenerator.js +321 -0
- package/dist/generators/MermaidGenerator.js.map +1 -0
- package/dist/generators/ReportGenerator.d.ts +22 -0
- package/dist/generators/ReportGenerator.d.ts.map +1 -0
- package/dist/generators/ReportGenerator.js +176 -0
- package/dist/generators/ReportGenerator.js.map +1 -0
- package/dist/generators/SQLGenerator.d.ts +31 -0
- package/dist/generators/SQLGenerator.d.ts.map +1 -0
- package/dist/generators/SQLGenerator.js +168 -0
- package/dist/generators/SQLGenerator.js.map +1 -0
- package/dist/generators/index.d.ts +10 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +19 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/index.d.ts +11 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -20
- package/dist/index.js.map +1 -1
- package/dist/prompts/PromptEngine.d.ts +65 -0
- package/dist/prompts/PromptEngine.d.ts.map +1 -0
- package/dist/prompts/PromptEngine.js +282 -0
- package/dist/prompts/PromptEngine.js.map +1 -0
- package/dist/prompts/PromptFileLoader.d.ts +21 -0
- package/dist/prompts/PromptFileLoader.d.ts.map +1 -0
- package/dist/prompts/PromptFileLoader.js +74 -0
- package/dist/prompts/PromptFileLoader.js.map +1 -0
- package/dist/prompts/index.d.ts +6 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +11 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/state/IterationTracker.d.ts +64 -0
- package/dist/state/IterationTracker.d.ts.map +1 -0
- package/dist/state/IterationTracker.js +136 -0
- package/dist/state/IterationTracker.js.map +1 -0
- package/dist/state/StateManager.d.ts +79 -0
- package/dist/state/StateManager.d.ts.map +1 -0
- package/dist/state/StateManager.js +348 -0
- package/dist/state/StateManager.js.map +1 -0
- package/dist/state/StateValidator.d.ts +24 -0
- package/dist/state/StateValidator.d.ts.map +1 -0
- package/dist/state/StateValidator.js +147 -0
- package/dist/state/StateValidator.js.map +1 -0
- package/dist/state/index.d.ts +7 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +13 -0
- package/dist/state/index.js.map +1 -0
- package/dist/types/analysis.d.ts +76 -0
- package/dist/types/analysis.d.ts.map +1 -0
- package/dist/types/analysis.js +6 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/types/config.d.ts +132 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +7 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/discovery.d.ts +277 -0
- package/dist/types/discovery.d.ts.map +1 -0
- package/dist/types/discovery.js +7 -0
- package/dist/types/discovery.js.map +1 -0
- package/dist/types/driver.d.ts +148 -0
- package/dist/types/driver.d.ts.map +1 -0
- package/dist/types/driver.js +7 -0
- package/dist/types/driver.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +24 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/prompts.d.ts +158 -0
- package/dist/types/prompts.d.ts.map +1 -0
- package/dist/types/prompts.js +6 -0
- package/dist/types/prompts.js.map +1 -0
- package/dist/types/state.d.ts +278 -0
- package/dist/types/state.d.ts.map +1 -0
- package/dist/types/state.js +7 -0
- package/dist/types/state.js.map +1 -0
- package/dist/utils/config-loader.d.ts +29 -0
- package/dist/utils/config-loader.d.ts.map +1 -0
- package/dist/utils/config-loader.js +163 -0
- package/dist/utils/config-loader.js.map +1 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +24 -3
- package/dist/ai/simple-ai-client.d.ts +0 -70
- package/dist/ai/simple-ai-client.d.ts.map +0 -1
- package/dist/ai/simple-ai-client.js +0 -181
- package/dist/ai/simple-ai-client.js.map +0 -1
- package/dist/analyzers/analyzer.d.ts +0 -23
- package/dist/analyzers/analyzer.d.ts.map +0 -1
- package/dist/analyzers/analyzer.js +0 -127
- package/dist/analyzers/analyzer.js.map +0 -1
- package/dist/cli-old/cli.d.ts +0 -3
- package/dist/cli-old/cli.d.ts.map +0 -1
- package/dist/cli-old/cli.js +0 -388
- package/dist/cli-old/cli.js.map +0 -1
- package/dist/commands/review.d.ts +0 -11
- package/dist/commands/review.d.ts.map +0 -1
- package/dist/commands/review.js +0 -82
- package/dist/commands/review.js.map +0 -1
- package/dist/database/connection.d.ts +0 -40
- package/dist/database/connection.d.ts.map +0 -1
- package/dist/database/connection.js +0 -136
- package/dist/database/connection.js.map +0 -1
- package/dist/database/introspection.d.ts +0 -59
- package/dist/database/introspection.d.ts.map +0 -1
- package/dist/database/introspection.js +0 -124
- package/dist/database/introspection.js.map +0 -1
- package/dist/generators/markdown-generator.d.ts +0 -8
- package/dist/generators/markdown-generator.d.ts.map +0 -1
- package/dist/generators/markdown-generator.js +0 -106
- package/dist/generators/markdown-generator.js.map +0 -1
- package/dist/generators/sql-generator.d.ts +0 -20
- package/dist/generators/sql-generator.d.ts.map +0 -1
- package/dist/generators/sql-generator.js +0 -83
- package/dist/generators/sql-generator.js.map +0 -1
- package/dist/state/state-manager.d.ts +0 -95
- package/dist/state/state-manager.d.ts.map +0 -1
- package/dist/state/state-manager.js +0 -236
- package/dist/state/state-manager.js.map +0 -1
- package/dist/types/state-file.d.ts +0 -124
- package/dist/types/state-file.d.ts.map +0 -1
- package/dist/types/state-file.js +0 -79
- package/dist/types/state-file.js.map +0 -1
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Foreign Key Detection
|
|
4
|
+
* Analyzes columns to find potential foreign key relationships based on
|
|
5
|
+
* naming patterns, value overlap, and cardinality analysis
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.FKDetector = void 0;
|
|
9
|
+
class FKDetector {
|
|
10
|
+
constructor(driver, config) {
|
|
11
|
+
this.driver = driver;
|
|
12
|
+
this.config = config;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Detect foreign key candidates for a table
|
|
16
|
+
*/
|
|
17
|
+
async detectFKCandidates(schemas, sourceSchema, sourceTable, discoveredPKs, iteration) {
|
|
18
|
+
const candidates = [];
|
|
19
|
+
console.log(`[FKDetector] Analyzing table ${sourceSchema}.${sourceTable.name} with ${sourceTable.columns.length} columns`);
|
|
20
|
+
console.log(`[FKDetector] Available PKs: ${discoveredPKs.length}`);
|
|
21
|
+
// For each column in source table
|
|
22
|
+
for (const sourceColumn of sourceTable.columns) {
|
|
23
|
+
// Skip if column is a discovered PK
|
|
24
|
+
const isPK = discoveredPKs.some(pk => pk.schemaName === sourceSchema &&
|
|
25
|
+
pk.tableName === sourceTable.name &&
|
|
26
|
+
pk.columnNames.includes(sourceColumn.name));
|
|
27
|
+
if (isPK) {
|
|
28
|
+
console.log(`[FKDetector] Skip ${sourceColumn.name} - is a PK`);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// Find potential target tables/columns
|
|
32
|
+
const potentialTargets = this.findPotentialTargets(schemas, sourceSchema, sourceTable.name, sourceColumn, discoveredPKs);
|
|
33
|
+
console.log(`[FKDetector] Column ${sourceColumn.name}: Found ${potentialTargets.length} potential targets`);
|
|
34
|
+
if (potentialTargets.length > 0) {
|
|
35
|
+
console.log(`[FKDetector] Targets: ${potentialTargets.map(t => `${t.schemaName}.${t.tableName}.${t.columnName}`).join(', ')}`);
|
|
36
|
+
}
|
|
37
|
+
// Analyze each potential target
|
|
38
|
+
for (const target of potentialTargets) {
|
|
39
|
+
const candidate = await this.analyzeFKCandidate(sourceSchema, sourceTable.name, sourceColumn, target.schemaName, target.tableName, target.columnName, target.isPK, iteration);
|
|
40
|
+
if (candidate) {
|
|
41
|
+
console.log(`[FKDetector] Candidate confidence: ${candidate.confidence} (min: ${this.config.confidence.foreignKeyMinimum * 100})`);
|
|
42
|
+
}
|
|
43
|
+
if (candidate && candidate.confidence >= this.config.confidence.foreignKeyMinimum * 100) {
|
|
44
|
+
candidates.push(candidate);
|
|
45
|
+
console.log(`[FKDetector] ✓ Added FK candidate: ${sourceColumn.name} -> ${target.tableName}.${target.columnName}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
console.log(`[FKDetector] Table ${sourceSchema}.${sourceTable.name}: Found ${candidates.length} FK candidates`);
|
|
50
|
+
// Sort by confidence descending
|
|
51
|
+
return candidates.sort((a, b) => b.confidence - a.confidence);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Find potential FK target tables/columns based on naming
|
|
55
|
+
*/
|
|
56
|
+
findPotentialTargets(schemas, sourceSchema, sourceTable, sourceColumn, discoveredPKs) {
|
|
57
|
+
const targets = [];
|
|
58
|
+
// Pattern 1: CustomerID -> Customer.ID (exact match on table name)
|
|
59
|
+
const tableNamePattern = this.extractTableNameFromColumn(sourceColumn.name);
|
|
60
|
+
if (tableNamePattern) {
|
|
61
|
+
for (const schema of schemas) {
|
|
62
|
+
const matchingTable = schema.tables.find(t => t.name.toLowerCase() === tableNamePattern.toLowerCase());
|
|
63
|
+
if (matchingTable && matchingTable.name !== sourceTable) {
|
|
64
|
+
// Look for ID column
|
|
65
|
+
const idColumn = matchingTable.columns.find(c => c.name.toLowerCase() === 'id' ||
|
|
66
|
+
c.name.toLowerCase() === `${matchingTable.name.toLowerCase()}id`);
|
|
67
|
+
if (idColumn) {
|
|
68
|
+
const isPK = discoveredPKs.some(pk => pk.schemaName === schema.name &&
|
|
69
|
+
pk.tableName === matchingTable.name &&
|
|
70
|
+
pk.columnNames.includes(idColumn.name));
|
|
71
|
+
targets.push({
|
|
72
|
+
schemaName: schema.name,
|
|
73
|
+
tableName: matchingTable.name,
|
|
74
|
+
columnName: idColumn.name,
|
|
75
|
+
isPK
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Pattern 2: Check all discovered PKs with similar names
|
|
82
|
+
for (const pk of discoveredPKs) {
|
|
83
|
+
const pkSchema = schemas.find(s => s.name === pk.schemaName);
|
|
84
|
+
if (!pkSchema)
|
|
85
|
+
continue;
|
|
86
|
+
const pkTable = pkSchema.tables.find(t => t.name === pk.tableName);
|
|
87
|
+
if (!pkTable || pkTable.name === sourceTable)
|
|
88
|
+
continue;
|
|
89
|
+
for (const pkColumnName of pk.columnNames) {
|
|
90
|
+
const similarity = this.calculateNameSimilarity(sourceColumn.name, pkColumnName);
|
|
91
|
+
if (similarity > 0.6) {
|
|
92
|
+
targets.push({
|
|
93
|
+
schemaName: pk.schemaName,
|
|
94
|
+
tableName: pk.tableName,
|
|
95
|
+
columnName: pkColumnName,
|
|
96
|
+
isPK: true
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Pattern 3: Same column name in different tables (might be FK)
|
|
102
|
+
for (const schema of schemas) {
|
|
103
|
+
for (const table of schema.tables) {
|
|
104
|
+
if (table.name === sourceTable)
|
|
105
|
+
continue;
|
|
106
|
+
const matchingColumn = table.columns.find(c => c.name.toLowerCase() === sourceColumn.name.toLowerCase() &&
|
|
107
|
+
c.dataType === sourceColumn.dataType);
|
|
108
|
+
if (matchingColumn) {
|
|
109
|
+
const isPK = discoveredPKs.some(pk => pk.schemaName === schema.name &&
|
|
110
|
+
pk.tableName === table.name &&
|
|
111
|
+
pk.columnNames.includes(matchingColumn.name));
|
|
112
|
+
// Only add if it's a PK in target table (more likely to be FK)
|
|
113
|
+
if (isPK) {
|
|
114
|
+
targets.push({
|
|
115
|
+
schemaName: schema.name,
|
|
116
|
+
tableName: table.name,
|
|
117
|
+
columnName: matchingColumn.name,
|
|
118
|
+
isPK: true
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return targets;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Extract table name from column name (e.g., "CustomerID" -> "Customer")
|
|
128
|
+
*/
|
|
129
|
+
extractTableNameFromColumn(columnName) {
|
|
130
|
+
// Remove common suffixes
|
|
131
|
+
const suffixes = ['ID', 'Id', 'id', 'KEY', 'Key', 'key', 'FK', 'Fk', 'fk'];
|
|
132
|
+
for (const suffix of suffixes) {
|
|
133
|
+
if (columnName.endsWith(suffix)) {
|
|
134
|
+
const tableName = columnName.slice(0, -suffix.length);
|
|
135
|
+
if (tableName.length > 0) {
|
|
136
|
+
return tableName;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Calculate name similarity (0-1)
|
|
144
|
+
*/
|
|
145
|
+
calculateNameSimilarity(name1, name2) {
|
|
146
|
+
const lower1 = name1.toLowerCase();
|
|
147
|
+
const lower2 = name2.toLowerCase();
|
|
148
|
+
// Exact match
|
|
149
|
+
if (lower1 === lower2)
|
|
150
|
+
return 1.0;
|
|
151
|
+
// One contains the other
|
|
152
|
+
if (lower1.includes(lower2) || lower2.includes(lower1)) {
|
|
153
|
+
return 0.8;
|
|
154
|
+
}
|
|
155
|
+
// Levenshtein distance
|
|
156
|
+
const distance = this.levenshteinDistance(lower1, lower2);
|
|
157
|
+
const maxLength = Math.max(lower1.length, lower2.length);
|
|
158
|
+
return 1 - (distance / maxLength);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Calculate Levenshtein distance between two strings
|
|
162
|
+
*/
|
|
163
|
+
levenshteinDistance(str1, str2) {
|
|
164
|
+
const matrix = [];
|
|
165
|
+
for (let i = 0; i <= str2.length; i++) {
|
|
166
|
+
matrix[i] = [i];
|
|
167
|
+
}
|
|
168
|
+
for (let j = 0; j <= str1.length; j++) {
|
|
169
|
+
matrix[0][j] = j;
|
|
170
|
+
}
|
|
171
|
+
for (let i = 1; i <= str2.length; i++) {
|
|
172
|
+
for (let j = 1; j <= str1.length; j++) {
|
|
173
|
+
if (str2.charAt(i - 1) === str1.charAt(j - 1)) {
|
|
174
|
+
matrix[i][j] = matrix[i - 1][j - 1];
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return matrix[str2.length][str1.length];
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Analyze a specific FK candidate
|
|
185
|
+
*/
|
|
186
|
+
async analyzeFKCandidate(sourceSchema, sourceTable, sourceColumn, targetSchema, targetTable, targetColumn, targetIsPK, iteration) {
|
|
187
|
+
// Get target column info
|
|
188
|
+
const targetColumnDef = await this.driver.getColumnInfo(targetSchema, targetTable, targetColumn);
|
|
189
|
+
// Check data type match
|
|
190
|
+
const dataTypeMatch = this.isDataTypeCompatible(sourceColumn.dataType, targetColumnDef.type);
|
|
191
|
+
if (!dataTypeMatch) {
|
|
192
|
+
return null; // Data types must match
|
|
193
|
+
}
|
|
194
|
+
// Calculate naming match
|
|
195
|
+
const namingMatch = this.calculateNameSimilarity(sourceColumn.name, targetColumn);
|
|
196
|
+
// Check value overlap
|
|
197
|
+
const overlapResult = await this.driver.testValueOverlap(`${sourceSchema}.${sourceTable}`, sourceColumn.name, `${targetSchema}.${targetTable}`, targetColumn, this.config.sampling.valueOverlapSampleSize);
|
|
198
|
+
// Get column statistics for cardinality analysis
|
|
199
|
+
const sourceStats = await this.driver.getColumnStatisticsForDiscovery(sourceSchema, sourceTable, sourceColumn.name, sourceColumn.dataType, this.config.sampling.maxRowsPerTable);
|
|
200
|
+
const targetStats = await this.driver.getColumnStatisticsForDiscovery(targetSchema, targetTable, targetColumn, targetColumnDef.type, this.config.sampling.maxRowsPerTable);
|
|
201
|
+
// Calculate cardinality ratio (should be many:one for FK)
|
|
202
|
+
const cardinalityRatio = targetStats.distinctCount > 0
|
|
203
|
+
? sourceStats.distinctCount / targetStats.distinctCount
|
|
204
|
+
: 0;
|
|
205
|
+
// Calculate null percentage
|
|
206
|
+
const nullPercentage = sourceStats.totalRows > 0
|
|
207
|
+
? sourceStats.nullCount / sourceStats.totalRows
|
|
208
|
+
: 0;
|
|
209
|
+
// Calculate orphan count
|
|
210
|
+
const orphanCount = Math.floor(sourceStats.totalRows * (1 - overlapResult));
|
|
211
|
+
// Build evidence
|
|
212
|
+
const evidence = {
|
|
213
|
+
namingMatch,
|
|
214
|
+
valueOverlap: overlapResult,
|
|
215
|
+
cardinalityRatio,
|
|
216
|
+
dataTypeMatch: true,
|
|
217
|
+
nullPercentage,
|
|
218
|
+
sampleSize: this.config.sampling.valueOverlapSampleSize,
|
|
219
|
+
orphanCount,
|
|
220
|
+
warnings: []
|
|
221
|
+
};
|
|
222
|
+
// Add warnings
|
|
223
|
+
if (overlapResult < 0.8) {
|
|
224
|
+
evidence.warnings.push(`Only ${(overlapResult * 100).toFixed(1)}% of values exist in target`);
|
|
225
|
+
}
|
|
226
|
+
if (orphanCount > 0) {
|
|
227
|
+
evidence.warnings.push(`${orphanCount} orphaned values found`);
|
|
228
|
+
}
|
|
229
|
+
if (nullPercentage > 0.5) {
|
|
230
|
+
evidence.warnings.push(`${(nullPercentage * 100).toFixed(1)}% null values (optional FK)`);
|
|
231
|
+
}
|
|
232
|
+
if (cardinalityRatio < 0.5) {
|
|
233
|
+
evidence.warnings.push('Cardinality suggests one:many instead of many:one');
|
|
234
|
+
}
|
|
235
|
+
// Calculate confidence
|
|
236
|
+
const confidence = this.calculateFKConfidence(evidence, targetIsPK);
|
|
237
|
+
// Don't return if confidence too low
|
|
238
|
+
if (confidence < 40) {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
schemaName: sourceSchema,
|
|
243
|
+
sourceTable,
|
|
244
|
+
sourceColumn: sourceColumn.name,
|
|
245
|
+
targetSchema,
|
|
246
|
+
targetTable,
|
|
247
|
+
targetColumn,
|
|
248
|
+
confidence,
|
|
249
|
+
evidence,
|
|
250
|
+
discoveredInIteration: iteration,
|
|
251
|
+
validatedByLLM: false,
|
|
252
|
+
status: 'candidate'
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Check if data types are compatible for FK relationship
|
|
257
|
+
*/
|
|
258
|
+
isDataTypeCompatible(sourceType, targetType) {
|
|
259
|
+
const normalize = (type) => type.toLowerCase()
|
|
260
|
+
.replace(/\([^)]*\)/g, '') // Remove size specifiers
|
|
261
|
+
.replace(/\s+/g, '');
|
|
262
|
+
const source = normalize(sourceType);
|
|
263
|
+
const target = normalize(targetType);
|
|
264
|
+
// Exact match
|
|
265
|
+
if (source === target)
|
|
266
|
+
return true;
|
|
267
|
+
// INT variants
|
|
268
|
+
const intTypes = ['int', 'integer', 'bigint', 'smallint', 'tinyint'];
|
|
269
|
+
if (intTypes.some(t => source.includes(t)) && intTypes.some(t => target.includes(t))) {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
// String variants
|
|
273
|
+
const stringTypes = ['varchar', 'char', 'nvarchar', 'nchar', 'text'];
|
|
274
|
+
if (stringTypes.some(t => source.includes(t)) && stringTypes.some(t => target.includes(t))) {
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
// GUID variants
|
|
278
|
+
if ((source.includes('uniqueidentifier') || source.includes('uuid') || source.includes('guid')) &&
|
|
279
|
+
(target.includes('uniqueidentifier') || target.includes('uuid') || target.includes('guid'))) {
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Calculate FK confidence score (0-100)
|
|
286
|
+
*/
|
|
287
|
+
calculateFKConfidence(evidence, targetIsPK) {
|
|
288
|
+
let score = 0;
|
|
289
|
+
// Value overlap is critical (40% weight)
|
|
290
|
+
score += evidence.valueOverlap * 40;
|
|
291
|
+
// Naming match (20% weight)
|
|
292
|
+
score += evidence.namingMatch * 20;
|
|
293
|
+
// Cardinality check (15% weight)
|
|
294
|
+
// We want many:one ratio (ratio > 1 is good)
|
|
295
|
+
const cardinalityScore = Math.min(evidence.cardinalityRatio, 2) / 2; // Cap at 2:1
|
|
296
|
+
score += cardinalityScore * 15;
|
|
297
|
+
// Target is PK bonus (15% weight)
|
|
298
|
+
if (targetIsPK) {
|
|
299
|
+
score += 15;
|
|
300
|
+
}
|
|
301
|
+
// Null handling (10% weight)
|
|
302
|
+
// Some nulls are OK (optional FK), but too many is suspicious
|
|
303
|
+
const nullScore = evidence.nullPercentage < 0.3 ? 10 :
|
|
304
|
+
evidence.nullPercentage < 0.7 ? 5 : 0;
|
|
305
|
+
score += nullScore;
|
|
306
|
+
// Penalties
|
|
307
|
+
if (evidence.orphanCount > evidence.sampleSize * 0.2) {
|
|
308
|
+
score *= 0.7; // 30% penalty for many orphans
|
|
309
|
+
}
|
|
310
|
+
if (!evidence.dataTypeMatch) {
|
|
311
|
+
score *= 0.5; // 50% penalty for type mismatch
|
|
312
|
+
}
|
|
313
|
+
return Math.round(Math.min(score, 100));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
exports.FKDetector = FKDetector;
|
|
317
|
+
//# sourceMappingURL=FKDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FKDetector.js","sourceRoot":"","sources":["../../src/discovery/FKDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Discovery Validator
|
|
3
|
+
* Uses LLM reasoning to validate and refine PK/FK candidates discovered through statistical analysis
|
|
4
|
+
* Processes one table at a time with rich statistical context
|
|
5
|
+
*/
|
|
6
|
+
import { BaseAutoDocDriver } from '../drivers/BaseAutoDocDriver.js';
|
|
7
|
+
import { ColumnStatsCache } from './ColumnStatsCache.js';
|
|
8
|
+
import { SchemaDefinition } from '../types/state.js';
|
|
9
|
+
import { PKCandidate, FKCandidate, LLMValidationResult } from '../types/discovery.js';
|
|
10
|
+
import { RelationshipDiscoveryConfig, AIConfig } from '../types/config.js';
|
|
11
|
+
export declare class LLMDiscoveryValidator {
|
|
12
|
+
private driver;
|
|
13
|
+
private config;
|
|
14
|
+
private aiConfig;
|
|
15
|
+
private statsCache;
|
|
16
|
+
private schemas;
|
|
17
|
+
private llm;
|
|
18
|
+
constructor(driver: BaseAutoDocDriver, config: RelationshipDiscoveryConfig, aiConfig: AIConfig, statsCache: ColumnStatsCache, schemas: SchemaDefinition[]);
|
|
19
|
+
/**
|
|
20
|
+
* Validate PK/FK candidates for a single table using LLM reasoning
|
|
21
|
+
*/
|
|
22
|
+
validateTableRelationships(schemaName: string, tableName: string, pkCandidates: PKCandidate[], fkCandidates: FKCandidate[]): Promise<LLMValidationResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Build rich context for a table including stats from cache
|
|
25
|
+
*/
|
|
26
|
+
private buildTableContext;
|
|
27
|
+
/**
|
|
28
|
+
* Find tables that might be related based on column name patterns
|
|
29
|
+
*/
|
|
30
|
+
private findRelatedTables;
|
|
31
|
+
/**
|
|
32
|
+
* Calculate similarity between two columns
|
|
33
|
+
*/
|
|
34
|
+
private calculateColumnSimilarity;
|
|
35
|
+
/**
|
|
36
|
+
* Calculate name similarity using Levenshtein distance
|
|
37
|
+
*/
|
|
38
|
+
private calculateNameSimilarity;
|
|
39
|
+
/**
|
|
40
|
+
* Calculate Levenshtein distance
|
|
41
|
+
*/
|
|
42
|
+
private levenshteinDistance;
|
|
43
|
+
/**
|
|
44
|
+
* Check if data types are compatible
|
|
45
|
+
*/
|
|
46
|
+
private areDataTypesCompatible;
|
|
47
|
+
/**
|
|
48
|
+
* Explain why two columns are similar
|
|
49
|
+
*/
|
|
50
|
+
private explainSimilarity;
|
|
51
|
+
/**
|
|
52
|
+
* Build reasoning string for PK candidate
|
|
53
|
+
*/
|
|
54
|
+
private buildPKReasoning;
|
|
55
|
+
/**
|
|
56
|
+
* Build reasoning string for FK candidate
|
|
57
|
+
*/
|
|
58
|
+
private buildFKReasoning;
|
|
59
|
+
/**
|
|
60
|
+
* Build LLM validation prompt
|
|
61
|
+
*/
|
|
62
|
+
private buildValidationPrompt;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=LLMDiscoveryValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LLMDiscoveryValidator.d.ts","sourceRoot":"","sources":["../../src/discovery/LLMDiscoveryValidator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EACL,WAAW,EACX,WAAW,EAGX,mBAAmB,EACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,2BAA2B,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE3E,qBAAa,qBAAqB;IAI9B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,OAAO;IAPjB,OAAO,CAAC,GAAG,CAAU;gBAGX,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,2BAA2B,EACnC,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,gBAAgB,EAC5B,OAAO,EAAE,gBAAgB,EAAE;IAkBrC;;OAEG;IACU,0BAA0B,CACrC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,WAAW,EAAE,EAC3B,YAAY,EAAE,WAAW,EAAE,GAC1B,OAAO,CAAC,mBAAmB,CAAC;IAgF/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgFzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAqFzB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAyBjC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAkB/B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA4B3B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAsC9B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA2BzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAyF9B"}
|