@memberjunction/db-auto-doc 6.2.0-edge.3 → 6.2.0-edge.5
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 +200 -3
- package/dist/commands/analyze.d.ts +1 -0
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +6 -0
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/export.d.ts +32 -15
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +144 -14
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/init.js.map +1 -1
- package/dist/core/AnalysisEngine.d.ts +15 -6
- package/dist/core/AnalysisEngine.d.ts.map +1 -1
- package/dist/core/AnalysisEngine.js +41 -40
- package/dist/core/AnalysisEngine.js.map +1 -1
- package/dist/core/AnalysisOrchestrator.d.ts +25 -1
- package/dist/core/AnalysisOrchestrator.d.ts.map +1 -1
- package/dist/core/AnalysisOrchestrator.js +163 -27
- package/dist/core/AnalysisOrchestrator.js.map +1 -1
- package/dist/core/PKProposalGate.d.ts +22 -0
- package/dist/core/PKProposalGate.d.ts.map +1 -0
- package/dist/core/PKProposalGate.js +52 -0
- package/dist/core/PKProposalGate.js.map +1 -0
- package/dist/database/Database.d.ts +8 -0
- package/dist/database/Database.d.ts.map +1 -1
- package/dist/database/Database.js +23 -1
- package/dist/database/Database.js.map +1 -1
- package/dist/discovery/EnumCandidateGate.d.ts +19 -0
- package/dist/discovery/EnumCandidateGate.d.ts.map +1 -1
- package/dist/discovery/EnumCandidateGate.js +47 -5
- package/dist/discovery/EnumCandidateGate.js.map +1 -1
- package/dist/discovery/FKGraphWalker.d.ts +35 -0
- package/dist/discovery/FKGraphWalker.d.ts.map +1 -1
- package/dist/discovery/FKGraphWalker.js +113 -12
- package/dist/discovery/FKGraphWalker.js.map +1 -1
- package/dist/discovery/LLMDiscoveryValidator.d.ts +2 -0
- package/dist/discovery/LLMDiscoveryValidator.d.ts.map +1 -1
- package/dist/discovery/LLMDiscoveryValidator.js +20 -9
- package/dist/discovery/LLMDiscoveryValidator.js.map +1 -1
- package/dist/discovery/OrganicKeyDetector.d.ts.map +1 -1
- package/dist/discovery/OrganicKeyDetector.js +8 -2
- package/dist/discovery/OrganicKeyDetector.js.map +1 -1
- package/dist/discovery/StructuralPhase.d.ts +27 -5
- package/dist/discovery/StructuralPhase.d.ts.map +1 -1
- package/dist/discovery/StructuralPhase.js +42 -9
- package/dist/discovery/StructuralPhase.js.map +1 -1
- package/dist/discovery/TransitiveBridgeDetector.d.ts +5 -1
- package/dist/discovery/TransitiveBridgeDetector.d.ts.map +1 -1
- package/dist/discovery/TransitiveBridgeDetector.js +25 -3
- package/dist/discovery/TransitiveBridgeDetector.js.map +1 -1
- package/dist/drivers/BaseAutoDocDriver.d.ts +6 -1
- package/dist/drivers/BaseAutoDocDriver.d.ts.map +1 -1
- package/dist/drivers/BaseAutoDocDriver.js +3 -5
- package/dist/drivers/BaseAutoDocDriver.js.map +1 -1
- package/dist/drivers/IndexCatalog.d.ts +54 -0
- package/dist/drivers/IndexCatalog.d.ts.map +1 -0
- package/dist/drivers/IndexCatalog.js +145 -0
- package/dist/drivers/IndexCatalog.js.map +1 -0
- package/dist/drivers/MySQLDriver.d.ts +5 -1
- package/dist/drivers/MySQLDriver.d.ts.map +1 -1
- package/dist/drivers/MySQLDriver.js +15 -6
- package/dist/drivers/MySQLDriver.js.map +1 -1
- package/dist/drivers/PostgreSQLDriver.d.ts +14 -2
- package/dist/drivers/PostgreSQLDriver.d.ts.map +1 -1
- package/dist/drivers/PostgreSQLDriver.js +52 -19
- package/dist/drivers/PostgreSQLDriver.js.map +1 -1
- package/dist/drivers/SQLServerDriver.d.ts +5 -1
- package/dist/drivers/SQLServerDriver.d.ts.map +1 -1
- package/dist/drivers/SQLServerDriver.js +13 -1
- package/dist/drivers/SQLServerDriver.js.map +1 -1
- package/dist/generators/AdditionalSchemaInfoGenerator.d.ts +34 -0
- package/dist/generators/AdditionalSchemaInfoGenerator.d.ts.map +1 -1
- package/dist/generators/AdditionalSchemaInfoGenerator.js +85 -4
- package/dist/generators/AdditionalSchemaInfoGenerator.js.map +1 -1
- package/dist/generators/ErdClusterGenerator.d.ts +44 -0
- package/dist/generators/ErdClusterGenerator.d.ts.map +1 -0
- package/dist/generators/ErdClusterGenerator.js +216 -0
- package/dist/generators/ErdClusterGenerator.js.map +1 -0
- package/dist/generators/ErdClusterer.d.ts +130 -0
- package/dist/generators/ErdClusterer.d.ts.map +1 -0
- package/dist/generators/ErdClusterer.js +308 -0
- package/dist/generators/ErdClusterer.js.map +1 -0
- package/dist/generators/HTMLGenerator.d.ts +6 -0
- package/dist/generators/HTMLGenerator.d.ts.map +1 -1
- package/dist/generators/HTMLGenerator.js +41 -6
- package/dist/generators/HTMLGenerator.js.map +1 -1
- package/dist/generators/MermaidGenerator.d.ts +3 -0
- package/dist/generators/MermaidGenerator.d.ts.map +1 -1
- package/dist/generators/MermaidGenerator.js +4 -0
- package/dist/generators/MermaidGenerator.js.map +1 -1
- package/dist/generators/index.d.ts +2 -0
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +2 -0
- package/dist/generators/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/plugins/BaseAutoDocPlugin.d.ts +33 -0
- package/dist/plugins/BaseAutoDocPlugin.d.ts.map +1 -0
- package/dist/plugins/BaseAutoDocPlugin.js +70 -0
- package/dist/plugins/BaseAutoDocPlugin.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +54 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +115 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/builtins.d.ts +13 -0
- package/dist/plugins/builtins.d.ts.map +1 -0
- package/dist/plugins/builtins.js +12 -0
- package/dist/plugins/builtins.js.map +1 -0
- package/dist/plugins/index-advisor/IndexAdvisorPlugin.d.ts +25 -0
- package/dist/plugins/index-advisor/IndexAdvisorPlugin.d.ts.map +1 -0
- package/dist/plugins/index-advisor/IndexAdvisorPlugin.js +128 -0
- package/dist/plugins/index-advisor/IndexAdvisorPlugin.js.map +1 -0
- package/dist/plugins/index-advisor/IndexAdvisorTypes.d.ts +111 -0
- package/dist/plugins/index-advisor/IndexAdvisorTypes.d.ts.map +1 -0
- package/dist/plugins/index-advisor/IndexAdvisorTypes.js +5 -0
- package/dist/plugins/index-advisor/IndexAdvisorTypes.js.map +1 -0
- package/dist/plugins/index-advisor/IndexLLMReview.d.ts +48 -0
- package/dist/plugins/index-advisor/IndexLLMReview.d.ts.map +1 -0
- package/dist/plugins/index-advisor/IndexLLMReview.js +181 -0
- package/dist/plugins/index-advisor/IndexLLMReview.js.map +1 -0
- package/dist/plugins/index-advisor/IndexMigrationGenerator.d.ts +28 -0
- package/dist/plugins/index-advisor/IndexMigrationGenerator.d.ts.map +1 -0
- package/dist/plugins/index-advisor/IndexMigrationGenerator.js +98 -0
- package/dist/plugins/index-advisor/IndexMigrationGenerator.js.map +1 -0
- package/dist/plugins/index-advisor/IndexRules.d.ts +19 -0
- package/dist/plugins/index-advisor/IndexRules.d.ts.map +1 -0
- package/dist/plugins/index-advisor/IndexRules.js +154 -0
- package/dist/plugins/index-advisor/IndexRules.js.map +1 -0
- package/dist/plugins/index.d.ts +13 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +13 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/types.d.ts +82 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +9 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/types/analysis.d.ts +2 -0
- package/dist/types/analysis.d.ts.map +1 -1
- package/dist/types/config.d.ts +52 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +7 -4
- package/dist/types/config.js.map +1 -1
- package/dist/types/discovery.d.ts +2 -0
- package/dist/types/discovery.d.ts.map +1 -1
- package/dist/types/driver.d.ts +30 -0
- package/dist/types/driver.d.ts.map +1 -1
- package/dist/types/driver.js +5 -1
- package/dist/types/driver.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/state.d.ts +36 -0
- package/dist/types/state.d.ts.map +1 -1
- package/dist/utils/config-loader.d.ts +5 -0
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js +38 -1
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/index-hints.d.ts +36 -0
- package/dist/utils/index-hints.d.ts.map +1 -0
- package/dist/utils/index-hints.js +65 -0
- package/dist/utils/index-hints.js.map +1 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/llm-factory.d.ts +1 -0
- package/dist/utils/llm-factory.d.ts.map +1 -1
- package/dist/utils/llm-factory.js +6 -1
- package/dist/utils/llm-factory.js.map +1 -1
- package/package.json +5 -5
- package/prompts/fk-pruning-table.md +13 -1
- package/prompts/index-review.md +60 -0
- package/prompts/pk-pruning-table.md +10 -0
- package/prompts/table-analysis.md +11 -0
|
@@ -14,6 +14,8 @@ export class ConfigLoader {
|
|
|
14
14
|
// Expand environment variables in the content
|
|
15
15
|
const expandedContent = this.expandEnvVars(content);
|
|
16
16
|
const config = JSON.parse(expandedContent);
|
|
17
|
+
// Resolve seedContext.file or seedContext.files if specified
|
|
18
|
+
await this.resolveSeedContextFiles(config, path.dirname(configPath));
|
|
17
19
|
// Validate required fields
|
|
18
20
|
this.validate(config);
|
|
19
21
|
// Apply defaults for optional sections
|
|
@@ -77,7 +79,7 @@ export class ConfigLoader {
|
|
|
77
79
|
},
|
|
78
80
|
ai: {
|
|
79
81
|
provider: 'gemini',
|
|
80
|
-
model: 'gemini-3-flash
|
|
82
|
+
model: 'gemini-3.8-flash',
|
|
81
83
|
apiKey: '',
|
|
82
84
|
temperature: 0.1,
|
|
83
85
|
maxTokens: 4000
|
|
@@ -162,9 +164,44 @@ export class ConfigLoader {
|
|
|
162
164
|
if (!config.ai.model) {
|
|
163
165
|
throw new Error('Missing ai.model');
|
|
164
166
|
}
|
|
167
|
+
config.ai.model = config.ai.model.trim();
|
|
165
168
|
if (!config.ai.apiKey) {
|
|
166
169
|
throw new Error('Missing ai.apiKey');
|
|
167
170
|
}
|
|
168
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Resolve seedContext.file or seedContext.files if specified,
|
|
174
|
+
* reading contents and appending to customInstructions.
|
|
175
|
+
*/
|
|
176
|
+
static async resolveSeedContextFiles(config, baseDir) {
|
|
177
|
+
if (!config.seedContext)
|
|
178
|
+
return;
|
|
179
|
+
const filesToLoad = [];
|
|
180
|
+
if (config.seedContext.file) {
|
|
181
|
+
filesToLoad.push(config.seedContext.file);
|
|
182
|
+
}
|
|
183
|
+
if (Array.isArray(config.seedContext.files)) {
|
|
184
|
+
filesToLoad.push(...config.seedContext.files);
|
|
185
|
+
}
|
|
186
|
+
if (filesToLoad.length === 0)
|
|
187
|
+
return;
|
|
188
|
+
const contents = [];
|
|
189
|
+
for (const relOrAbsPath of filesToLoad) {
|
|
190
|
+
const resolvedPath = path.isAbsolute(relOrAbsPath)
|
|
191
|
+
? relOrAbsPath
|
|
192
|
+
: path.resolve(baseDir, relOrAbsPath);
|
|
193
|
+
try {
|
|
194
|
+
contents.push(await fs.readFile(resolvedPath, 'utf-8'));
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
const setting = config.seedContext.file === relOrAbsPath ? 'seedContext.file' : 'seedContext.files';
|
|
198
|
+
throw new Error(`Could not read ${setting} entry '${relOrAbsPath}' (resolved to ${resolvedPath}): ${error.message}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const loadedText = contents.join('\n\n---\n\n');
|
|
202
|
+
config.seedContext.customInstructions = config.seedContext.customInstructions
|
|
203
|
+
? `${config.seedContext.customInstructions}\n\n${loadedText}`
|
|
204
|
+
: loadedText;
|
|
205
|
+
}
|
|
169
206
|
}
|
|
170
207
|
//# sourceMappingURL=config-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/utils/config-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,OAAO,YAAY;IACvB;;;OAGG;IACI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAkB;QACzC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAEvD,8CAA8C;YAC9C,MAAM,eAAe,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAEpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAoB,CAAC;YAE9D,2BAA2B;YAC3B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAEtB,uCAAuC;YACvC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAE3B,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,iCAAkC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,oCAAoC;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAkB;QACzC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACK,MAAM,CAAC,aAAa,CAAC,OAAe;QAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,iBAAiB,CAAC,CAAC;YACpE,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAuB,EAAE,UAAkB;QAClE,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACrC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAEzC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAChD,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,iCAAkC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,oCAAoC;IAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAuB,EAAE,UAAkB;QAClE,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,aAAa;QACzB,OAAO;YACL,OAAO,EAAE,OAAO;YAChB,QAAQ,EAAE;gBACR,MAAM,EAAE,WAAW;gBACnB,IAAI,EAAE,IAAI;gBACV,QAAQ,EAAE,EAAE;gBACZ,IAAI,EAAE,EAAE;gBACR,QAAQ,EAAE,EAAE;gBACZ,OAAO,EAAE,IAAI;gBACb,sBAAsB,EAAE,KAAK;gBAC7B,iBAAiB,EAAE,KAAK;aACzB;YACD,EAAE,EAAE;gBACF,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/utils/config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Existing indexes as evidence for the LLM passes.
|
|
3
|
+
*
|
|
4
|
+
* Databases "in the wild" often declare no primary or foreign keys but still have indexes on the
|
|
5
|
+
* columns people join and filter on. A unique index on non-null columns usually marks a primary or
|
|
6
|
+
* alternate key, and a non-unique index led by an ID-like column often marks a foreign key. These
|
|
7
|
+
* helpers turn the indexes stored on a table (`TableDefinition.indexes`) into prompt context.
|
|
8
|
+
*/
|
|
9
|
+
import type { AutoDocIndex } from '../types/driver.js';
|
|
10
|
+
import type { TableDefinition } from '../types/state.js';
|
|
11
|
+
/** One existing index, trimmed to what a prompt needs. */
|
|
12
|
+
export interface IndexHint {
|
|
13
|
+
Columns: string[];
|
|
14
|
+
IncludeColumns: string[];
|
|
15
|
+
IsUnique: boolean;
|
|
16
|
+
IsPrimaryKey: boolean;
|
|
17
|
+
/** Partial-index predicate, when the index covers only some rows. */
|
|
18
|
+
Filter?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Most indexes a single table contributes to a prompt. */
|
|
21
|
+
export declare const MAX_INDEX_HINTS_PER_TABLE = 25;
|
|
22
|
+
/**
|
|
23
|
+
* The table's indexes as prompt hints, primary key first, then unique, then the rest, capped at
|
|
24
|
+
* `max`. Returns an empty array when the table has none or they were not loaded.
|
|
25
|
+
*/
|
|
26
|
+
export declare function BuildIndexHints(table: Pick<TableDefinition, 'indexes'> | undefined, max?: number): IndexHint[];
|
|
27
|
+
/** One line per hint, e.g. `UNIQUE (Code) INCLUDE (Name) WHERE (Active = 1)`. */
|
|
28
|
+
export declare function FormatIndexHint(hint: IndexHint): string;
|
|
29
|
+
/**
|
|
30
|
+
* True when the column alone is the key of a primary-key or unique, unfiltered index on the table,
|
|
31
|
+
* i.e. the database already guarantees its values are distinct. Undefined when indexes were not loaded.
|
|
32
|
+
*/
|
|
33
|
+
export declare function IsUniquelyIndexed(table: Pick<TableDefinition, 'indexes'> | undefined, column: string): boolean | undefined;
|
|
34
|
+
/** Attaches catalog indexes to the matching tables (exact name first, then case-insensitive). */
|
|
35
|
+
export declare function AttachIndexesToTables(tables: TableDefinition[], indexes: AutoDocIndex[]): void;
|
|
36
|
+
//# sourceMappingURL=index-hints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-hints.d.ts","sourceRoot":"","sources":["../../src/utils/index-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,0DAA0D;AAC1D,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,2DAA2D;AAC3D,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,GAAG,SAAS,EAAE,GAAG,SAA4B,GAAG,SAAS,EAAE,CAYjI;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAKvD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAQ1H;AAED,iGAAiG;AACjG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,IAAI,CAc9F"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Existing indexes as evidence for the LLM passes.
|
|
3
|
+
*
|
|
4
|
+
* Databases "in the wild" often declare no primary or foreign keys but still have indexes on the
|
|
5
|
+
* columns people join and filter on. A unique index on non-null columns usually marks a primary or
|
|
6
|
+
* alternate key, and a non-unique index led by an ID-like column often marks a foreign key. These
|
|
7
|
+
* helpers turn the indexes stored on a table (`TableDefinition.indexes`) into prompt context.
|
|
8
|
+
*/
|
|
9
|
+
/** Most indexes a single table contributes to a prompt. */
|
|
10
|
+
export const MAX_INDEX_HINTS_PER_TABLE = 25;
|
|
11
|
+
/**
|
|
12
|
+
* The table's indexes as prompt hints, primary key first, then unique, then the rest, capped at
|
|
13
|
+
* `max`. Returns an empty array when the table has none or they were not loaded.
|
|
14
|
+
*/
|
|
15
|
+
export function BuildIndexHints(table, max = MAX_INDEX_HINTS_PER_TABLE) {
|
|
16
|
+
const indexes = table?.indexes ?? [];
|
|
17
|
+
return [...indexes]
|
|
18
|
+
.sort((a, b) => hintRank(a) - hintRank(b))
|
|
19
|
+
.slice(0, max)
|
|
20
|
+
.map((ix) => ({
|
|
21
|
+
Columns: ix.Columns,
|
|
22
|
+
IncludeColumns: ix.IncludeColumns,
|
|
23
|
+
IsUnique: ix.IsUnique || ix.IsPrimaryKey,
|
|
24
|
+
IsPrimaryKey: ix.IsPrimaryKey,
|
|
25
|
+
Filter: ix.FilterDefinition || undefined
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
/** One line per hint, e.g. `UNIQUE (Code) INCLUDE (Name) WHERE (Active = 1)`. */
|
|
29
|
+
export function FormatIndexHint(hint) {
|
|
30
|
+
const kind = hint.IsPrimaryKey ? 'PRIMARY KEY' : hint.IsUnique ? 'UNIQUE' : 'INDEX';
|
|
31
|
+
const include = hint.IncludeColumns.length ? ` INCLUDE (${hint.IncludeColumns.join(', ')})` : '';
|
|
32
|
+
const filter = hint.Filter ? ` WHERE ${hint.Filter}` : '';
|
|
33
|
+
return `${kind} (${hint.Columns.join(', ')})${include}${filter}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* True when the column alone is the key of a primary-key or unique, unfiltered index on the table,
|
|
37
|
+
* i.e. the database already guarantees its values are distinct. Undefined when indexes were not loaded.
|
|
38
|
+
*/
|
|
39
|
+
export function IsUniquelyIndexed(table, column) {
|
|
40
|
+
if (!table?.indexes) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
const target = column.toLowerCase();
|
|
44
|
+
return table.indexes.some((ix) => (ix.IsUnique || ix.IsPrimaryKey) && !ix.FilterDefinition && ix.Columns.length === 1 && ix.Columns[0].toLowerCase() === target);
|
|
45
|
+
}
|
|
46
|
+
/** Attaches catalog indexes to the matching tables (exact name first, then case-insensitive). */
|
|
47
|
+
export function AttachIndexesToTables(tables, indexes) {
|
|
48
|
+
const exact = new Map();
|
|
49
|
+
for (const ix of indexes) {
|
|
50
|
+
const list = exact.get(ix.TableName) ?? [];
|
|
51
|
+
list.push(ix);
|
|
52
|
+
exact.set(ix.TableName, list);
|
|
53
|
+
}
|
|
54
|
+
const folded = new Map();
|
|
55
|
+
for (const [name, list] of exact) {
|
|
56
|
+
folded.set(name.toLowerCase(), [...(folded.get(name.toLowerCase()) ?? []), ...list]);
|
|
57
|
+
}
|
|
58
|
+
for (const table of tables) {
|
|
59
|
+
table.indexes = exact.get(table.name) ?? folded.get(table.name.toLowerCase()) ?? [];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function hintRank(ix) {
|
|
63
|
+
return ix.IsPrimaryKey ? 0 : ix.IsUnique ? 1 : 2;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=index-hints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-hints.js","sourceRoot":"","sources":["../../src/utils/index-hints.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,cAAc,kBAAkB,CAAC"}
|
package/dist/utils/index.js
CHANGED
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,cAAc,kBAAkB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-factory.d.ts","sourceRoot":"","sources":["../../src/utils/llm-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"llm-factory.d.ts","sourceRoot":"","sources":["../../src/utils/llm-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAI7C,OAAO,8DAA8D,CAAC;AAmBtE;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAyB3E;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAE3E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvE;AAED,kDAAkD;AAClD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEvE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED,qDAAqD;AACrD,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD"}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { BaseLLM } from '@memberjunction/ai';
|
|
8
8
|
import { MJGlobal } from '@memberjunction/global';
|
|
9
|
+
// The LLM drivers register with MJGlobal.ClassFactory as a side effect of this manifest; without it a
|
|
10
|
+
// standalone CLI process has no provider classes to instantiate.
|
|
11
|
+
import '@memberjunction/server-bootstrap-lite/mj-class-registrations';
|
|
9
12
|
/**
|
|
10
13
|
* Provider name to LLM driver class name mapping
|
|
11
14
|
*/
|
|
@@ -37,7 +40,9 @@ export function CreateLLMInstance(provider, apiKey) {
|
|
|
37
40
|
throw new Error(`Unknown provider: ${provider}. Supported providers: ${supportedProviders}`);
|
|
38
41
|
}
|
|
39
42
|
const llm = MJGlobal.Instance.ClassFactory.CreateInstance(BaseLLM, driverClass, apiKey);
|
|
40
|
-
|
|
43
|
+
// The ClassFactory falls back to the base class when nothing is registered under the key, and a bare
|
|
44
|
+
// BaseLLM fails on every call, so treat that as "not installed" too.
|
|
45
|
+
if (!llm || Object.getPrototypeOf(llm) === BaseLLM.prototype) {
|
|
41
46
|
throw new Error(`Failed to create LLM instance for provider: ${provider} (driver class: ${driverClass}). Check that the provider is installed.`);
|
|
42
47
|
}
|
|
43
48
|
return llm;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm-factory.js","sourceRoot":"","sources":["../../src/utils/llm-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"llm-factory.js","sourceRoot":"","sources":["../../src/utils/llm-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,sGAAsG;AACtG,iEAAiE;AACjE,OAAO,8DAA8D,CAAC;AAEtE;;GAEG;AACH,MAAM,wBAAwB,GAA2B;IACvD,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,WAAW;IACrB,WAAW,EAAE,cAAc;IAC3B,MAAM,EAAE,SAAS;IACjB,SAAS,EAAE,YAAY;IACvB,QAAQ,EAAE,WAAW;IACrB,OAAO,EAAE,UAAU;IACnB,UAAU,EAAE,aAAa;IACzB,YAAY,EAAE,eAAe;IAC7B,KAAK,EAAE,QAAQ;IACf,SAAS,EAAE,YAAY;CACxB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,MAAc;IAChE,MAAM,WAAW,GAAG,wBAAwB,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAErE,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5E,MAAM,IAAI,KAAK,CACb,qBAAqB,QAAQ,0BAA0B,kBAAkB,EAAE,CAC5E,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,cAAc,CACvD,OAAO,EACP,WAAW,EACX,MAAM,CACP,CAAC;IAEF,qGAAqG;IACrG,qEAAqE;IACrE,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,SAAS,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,+CAA+C,QAAQ,mBAAmB,WAAW,0CAA0C,CAChI,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,MAAc;IAChE,OAAO,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,wBAAwB,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;AAC/C,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,qBAAqB;IACnC,OAAO,qBAAqB,EAAE,CAAC;AACjC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/db-auto-doc",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "6.2.0-edge.
|
|
4
|
+
"version": "6.2.0-edge.5",
|
|
5
5
|
"description": "AI-powered database documentation generator for SQL Server, MySQL, and PostgreSQL. Analyzes your database structure, uses AI to generate comprehensive descriptions, and saves them as metadata. Works standalone - no MemberJunction runtime required.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -64,10 +64,10 @@
|
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"@inquirer/prompts": "^8.2.0",
|
|
67
|
-
"@memberjunction/ai": "6.2.0-edge.
|
|
68
|
-
"@memberjunction/server-bootstrap-lite": "6.2.0-edge.
|
|
69
|
-
"@memberjunction/core": "6.2.0-edge.
|
|
70
|
-
"@memberjunction/global": "6.2.0-edge.
|
|
67
|
+
"@memberjunction/ai": "6.2.0-edge.5",
|
|
68
|
+
"@memberjunction/server-bootstrap-lite": "6.2.0-edge.5",
|
|
69
|
+
"@memberjunction/core": "6.2.0-edge.5",
|
|
70
|
+
"@memberjunction/global": "6.2.0-edge.5",
|
|
71
71
|
"@oclif/core": "^3.27.0",
|
|
72
72
|
"@oclif/plugin-help": "^6.2.37",
|
|
73
73
|
"chalk": "^5.6.2",
|
|
@@ -14,9 +14,21 @@ These FKs were identified by statistical analysis and/or LLM analysis. Some are
|
|
|
14
14
|
**NOTE**: FKs marked as **[LOCKED]** have very high confidence and CANNOT be removed. Only evaluate the unlocked ones.
|
|
15
15
|
|
|
16
16
|
{% for fk in candidates %}
|
|
17
|
-
{{ loop.index }}. {% if fk.locked %}**[LOCKED]** {% endif %}**{{ fk.sourceColumn }}** → {{ fk.targetSchema }}.{{ fk.targetTable }}.{{ fk.targetColumn }} (confidence: {{ fk.confidence }}%)
|
|
17
|
+
{{ loop.index }}. {% if fk.locked %}**[LOCKED]** {% endif %}**{{ fk.sourceColumn }}** → {{ fk.targetSchema }}.{{ fk.targetTable }}.{{ fk.targetColumn }} (confidence: {{ fk.confidence }}%{% if fk.targetUniquelyIndexed === true %}; target column has a unique index{% elif fk.targetUniquelyIndexed === false %}; target column has no unique index{% endif %})
|
|
18
18
|
{% endfor %}
|
|
19
19
|
|
|
20
|
+
{% if existingIndexes and existingIndexes.length > 0 %}
|
|
21
|
+
## Existing Indexes
|
|
22
|
+
These indexes exist on this table in the database. Developers index the columns they join and filter on, so indexes are clues to keys even when none are declared:
|
|
23
|
+
{% for ix in existingIndexes %}
|
|
24
|
+
- {{ ix }}
|
|
25
|
+
{% endfor %}
|
|
26
|
+
|
|
27
|
+
*A UNIQUE index or PRIMARY KEY on non-null columns is strong evidence of the primary key (or an alternate key). A non-unique index led by an ID- or code-like column often marks a foreign key. Indexes are evidence, not proof — weigh them with names, statistics and value overlap. "(expression)" is a computed key part.*
|
|
28
|
+
{% endif %}
|
|
29
|
+
|
|
30
|
+
*A real FK target is normally unique. A target column with a unique index or primary key supports the FK; one without is weaker evidence (but the database may simply not declare it).*
|
|
31
|
+
|
|
20
32
|
## What to look for when proposing removals:
|
|
21
33
|
|
|
22
34
|
1. **Reverse direction**: FK goes from parent→child instead of child→parent. Example: `Department.DepartmentID → EmployeeDepartmentHistory.DepartmentID` is backwards — the history table should reference Department, not the other way around.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
You are a database performance expert reviewing index recommendations for one table on {{ platform }}.
|
|
2
|
+
|
|
3
|
+
## Table: {{ table.schema }}.{{ table.name }} ({{ table.rowCount }} rows)
|
|
4
|
+
{% if table.description %}**Description**: {{ table.description }}{% endif %}
|
|
5
|
+
|
|
6
|
+
## Columns
|
|
7
|
+
{% for c in columns %}
|
|
8
|
+
- **{{ c.name }}** {{ c.dataType }}{% if c.distinctCount != null %}, {{ c.distinctCount }} distinct{% endif %}{% if c.nullPercentage != null %}, {{ c.nullPercentage }}% null{% endif %}{% if c.description %} — {{ c.description }}{% endif %}
|
|
9
|
+
{% endfor %}
|
|
10
|
+
|
|
11
|
+
## Existing indexes
|
|
12
|
+
{% if existing.length %}{% for ix in existing %}
|
|
13
|
+
- {{ ix.name }} ({{ ix.columns | join(", ") }}){% if ix.include.length %} INCLUDE ({{ ix.include | join(", ") }}){% endif %}{% if ix.isPrimaryKey %} [primary key]{% elif ix.isUnique %} [unique]{% endif %}{% if ix.filter %} WHERE {{ ix.filter }}{% endif %}
|
|
14
|
+
{% endfor %}{% else %}
|
|
15
|
+
(none)
|
|
16
|
+
{% endif %}
|
|
17
|
+
|
|
18
|
+
## Proposed indexes (from deterministic rules)
|
|
19
|
+
{% if proposals.length %}{% for p in proposals %}
|
|
20
|
+
{{ loop.index }}. ({{ p.columns | join(", ") }}) — {{ p.reason }}
|
|
21
|
+
{% endfor %}{% else %}
|
|
22
|
+
(none)
|
|
23
|
+
{% endif %}
|
|
24
|
+
|
|
25
|
+
{% if sampleQueries.length %}## Queries that use this table
|
|
26
|
+
{% for q in sampleQueries %}
|
|
27
|
+
### {{ q.name }}
|
|
28
|
+
```sql
|
|
29
|
+
{{ q.sql }}
|
|
30
|
+
```
|
|
31
|
+
{% endfor %}{% endif %}
|
|
32
|
+
|
|
33
|
+
## Your task
|
|
34
|
+
|
|
35
|
+
1. For each proposed index, decide **keep**, **drop** (not worth it: e.g. the column is rarely used to join or filter, or another index does the job) or **modify** (better as a composite index, or with INCLUDE columns that make it covering for the queries above).
|
|
36
|
+
2. Suggest **additional** indexes only when there is clear evidence: columns the queries above filter, join, group or sort on, or obvious lookup columns (codes, emails, external IDs) on a large table. Prefer few, high-value indexes; every index slows writes.
|
|
37
|
+
|
|
38
|
+
Rules:
|
|
39
|
+
- Use only column names listed above, spelled exactly.
|
|
40
|
+
- Put the most selective / equality-filtered column first in a composite index.
|
|
41
|
+
- Do not suggest an index that an existing index already starts with.
|
|
42
|
+
- Do not lead an index with a column that has very few distinct values or a large text/JSON type.
|
|
43
|
+
- At most 5 key columns per index.
|
|
44
|
+
|
|
45
|
+
## Response format
|
|
46
|
+
|
|
47
|
+
Return only JSON, exactly in this shape (use empty arrays when you have nothing):
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"Decisions": [
|
|
52
|
+
{ "Proposal": 1, "Action": "keep", "Reason": "…" },
|
|
53
|
+
{ "Proposal": 2, "Action": "modify", "Columns": ["ColA", "ColB"], "IncludeColumns": ["ColC"], "Reason": "…" },
|
|
54
|
+
{ "Proposal": 3, "Action": "drop", "Reason": "…" }
|
|
55
|
+
],
|
|
56
|
+
"Additions": [
|
|
57
|
+
{ "Columns": ["ColX"], "IncludeColumns": [], "Reason": "…" }
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
```
|
|
@@ -8,6 +8,16 @@ You are evaluating primary key candidates for a database table.
|
|
|
8
8
|
{{ loop.index }}. Columns: {{ pk.columns | join(", ") }} (confidence: {{ pk.confidence }}%{% if pk.locked %}, LOCKED - do not modify{% endif %})
|
|
9
9
|
{% endfor %}
|
|
10
10
|
|
|
11
|
+
{% if existingIndexes and existingIndexes.length > 0 %}
|
|
12
|
+
## Existing Indexes
|
|
13
|
+
These indexes exist on this table in the database. Developers index the columns they join and filter on, so indexes are clues to keys even when no primary or foreign key is declared:
|
|
14
|
+
{% for ix in existingIndexes %}
|
|
15
|
+
- {{ ix }}
|
|
16
|
+
{% endfor %}
|
|
17
|
+
|
|
18
|
+
*A UNIQUE index or PRIMARY KEY on non-null columns is strong evidence of the primary key (or an alternate key). A non-unique index led by an ID- or code-like column often marks a foreign key. Indexes are evidence, not proof — weigh them with names, statistics and value overlap. "(expression)" is a computed key part.*
|
|
19
|
+
{% endif %}
|
|
20
|
+
|
|
11
21
|
## All Database Tables (for context):
|
|
12
22
|
{% for tbl in allTables %}
|
|
13
23
|
- {{ tbl.schema }}.{{ tbl.name }}{% if tbl.pk %} (PK: {{ tbl.pk }}){% endif %}
|
|
@@ -96,6 +96,16 @@ The following columns in this table were identified as potential foreign keys by
|
|
|
96
96
|
*Value overlap = % of source values that exist in the target column. 100% = strong FK evidence. Cardinality ratio = source distinct / target distinct — values > 1 suggest child→parent direction.*
|
|
97
97
|
{% endif %}
|
|
98
98
|
|
|
99
|
+
{% if existingIndexes and existingIndexes.length > 0 %}
|
|
100
|
+
## Existing Indexes
|
|
101
|
+
These indexes exist on this table in the database. Developers index the columns they join and filter on, so indexes are clues to keys even when no primary or foreign key is declared:
|
|
102
|
+
{% for ix in existingIndexes %}
|
|
103
|
+
- {{ ix }}
|
|
104
|
+
{% endfor %}
|
|
105
|
+
|
|
106
|
+
*A UNIQUE index or PRIMARY KEY on non-null columns is strong evidence of the primary key (or an alternate key). A non-unique index led by an ID- or code-like column often marks a foreign key. Indexes are evidence, not proof — weigh them with names, statistics and value overlap. "(expression)" is a computed key part.*
|
|
107
|
+
{% endif %}
|
|
108
|
+
|
|
99
109
|
{% if allTables %}
|
|
100
110
|
## All Database Tables
|
|
101
111
|
**IMPORTANT**: When referring to foreign key relationships, you MUST use one of these exact table names:
|
|
@@ -168,6 +178,7 @@ Based on the evidence above, generate a JSON response with this exact structure:
|
|
|
168
178
|
- Use `"columns": ["Col1", "Col2"]` for composite keys
|
|
169
179
|
- Confidence should reflect how certain you are (0-1 scale)
|
|
170
180
|
- If a PK is already marked in the column list above, you may confirm it or propose a different one
|
|
181
|
+
- A UNIQUE index on non-null column(s) under "Existing Indexes" is strong evidence for those columns as the key
|
|
171
182
|
6. **Foreign Keys**: **CRITICAL** - Use structured format for ALL foreign key relationships:
|
|
172
183
|
- Include EVERY column that references another table
|
|
173
184
|
- Use EXACT schema and table names from the "All Database Tables" list above
|