@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.
Files changed (177) hide show
  1. package/README.md +200 -3
  2. package/dist/commands/analyze.d.ts +1 -0
  3. package/dist/commands/analyze.d.ts.map +1 -1
  4. package/dist/commands/analyze.js +6 -0
  5. package/dist/commands/analyze.js.map +1 -1
  6. package/dist/commands/export.d.ts +32 -15
  7. package/dist/commands/export.d.ts.map +1 -1
  8. package/dist/commands/export.js +144 -14
  9. package/dist/commands/export.js.map +1 -1
  10. package/dist/commands/init.js +1 -1
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/core/AnalysisEngine.d.ts +15 -6
  13. package/dist/core/AnalysisEngine.d.ts.map +1 -1
  14. package/dist/core/AnalysisEngine.js +41 -40
  15. package/dist/core/AnalysisEngine.js.map +1 -1
  16. package/dist/core/AnalysisOrchestrator.d.ts +25 -1
  17. package/dist/core/AnalysisOrchestrator.d.ts.map +1 -1
  18. package/dist/core/AnalysisOrchestrator.js +163 -27
  19. package/dist/core/AnalysisOrchestrator.js.map +1 -1
  20. package/dist/core/PKProposalGate.d.ts +22 -0
  21. package/dist/core/PKProposalGate.d.ts.map +1 -0
  22. package/dist/core/PKProposalGate.js +52 -0
  23. package/dist/core/PKProposalGate.js.map +1 -0
  24. package/dist/database/Database.d.ts +8 -0
  25. package/dist/database/Database.d.ts.map +1 -1
  26. package/dist/database/Database.js +23 -1
  27. package/dist/database/Database.js.map +1 -1
  28. package/dist/discovery/EnumCandidateGate.d.ts +19 -0
  29. package/dist/discovery/EnumCandidateGate.d.ts.map +1 -1
  30. package/dist/discovery/EnumCandidateGate.js +47 -5
  31. package/dist/discovery/EnumCandidateGate.js.map +1 -1
  32. package/dist/discovery/FKGraphWalker.d.ts +35 -0
  33. package/dist/discovery/FKGraphWalker.d.ts.map +1 -1
  34. package/dist/discovery/FKGraphWalker.js +113 -12
  35. package/dist/discovery/FKGraphWalker.js.map +1 -1
  36. package/dist/discovery/LLMDiscoveryValidator.d.ts +2 -0
  37. package/dist/discovery/LLMDiscoveryValidator.d.ts.map +1 -1
  38. package/dist/discovery/LLMDiscoveryValidator.js +20 -9
  39. package/dist/discovery/LLMDiscoveryValidator.js.map +1 -1
  40. package/dist/discovery/OrganicKeyDetector.d.ts.map +1 -1
  41. package/dist/discovery/OrganicKeyDetector.js +8 -2
  42. package/dist/discovery/OrganicKeyDetector.js.map +1 -1
  43. package/dist/discovery/StructuralPhase.d.ts +27 -5
  44. package/dist/discovery/StructuralPhase.d.ts.map +1 -1
  45. package/dist/discovery/StructuralPhase.js +42 -9
  46. package/dist/discovery/StructuralPhase.js.map +1 -1
  47. package/dist/discovery/TransitiveBridgeDetector.d.ts +5 -1
  48. package/dist/discovery/TransitiveBridgeDetector.d.ts.map +1 -1
  49. package/dist/discovery/TransitiveBridgeDetector.js +25 -3
  50. package/dist/discovery/TransitiveBridgeDetector.js.map +1 -1
  51. package/dist/drivers/BaseAutoDocDriver.d.ts +6 -1
  52. package/dist/drivers/BaseAutoDocDriver.d.ts.map +1 -1
  53. package/dist/drivers/BaseAutoDocDriver.js +3 -5
  54. package/dist/drivers/BaseAutoDocDriver.js.map +1 -1
  55. package/dist/drivers/IndexCatalog.d.ts +54 -0
  56. package/dist/drivers/IndexCatalog.d.ts.map +1 -0
  57. package/dist/drivers/IndexCatalog.js +145 -0
  58. package/dist/drivers/IndexCatalog.js.map +1 -0
  59. package/dist/drivers/MySQLDriver.d.ts +5 -1
  60. package/dist/drivers/MySQLDriver.d.ts.map +1 -1
  61. package/dist/drivers/MySQLDriver.js +15 -6
  62. package/dist/drivers/MySQLDriver.js.map +1 -1
  63. package/dist/drivers/PostgreSQLDriver.d.ts +14 -2
  64. package/dist/drivers/PostgreSQLDriver.d.ts.map +1 -1
  65. package/dist/drivers/PostgreSQLDriver.js +52 -19
  66. package/dist/drivers/PostgreSQLDriver.js.map +1 -1
  67. package/dist/drivers/SQLServerDriver.d.ts +5 -1
  68. package/dist/drivers/SQLServerDriver.d.ts.map +1 -1
  69. package/dist/drivers/SQLServerDriver.js +13 -1
  70. package/dist/drivers/SQLServerDriver.js.map +1 -1
  71. package/dist/generators/AdditionalSchemaInfoGenerator.d.ts +34 -0
  72. package/dist/generators/AdditionalSchemaInfoGenerator.d.ts.map +1 -1
  73. package/dist/generators/AdditionalSchemaInfoGenerator.js +85 -4
  74. package/dist/generators/AdditionalSchemaInfoGenerator.js.map +1 -1
  75. package/dist/generators/ErdClusterGenerator.d.ts +44 -0
  76. package/dist/generators/ErdClusterGenerator.d.ts.map +1 -0
  77. package/dist/generators/ErdClusterGenerator.js +216 -0
  78. package/dist/generators/ErdClusterGenerator.js.map +1 -0
  79. package/dist/generators/ErdClusterer.d.ts +130 -0
  80. package/dist/generators/ErdClusterer.d.ts.map +1 -0
  81. package/dist/generators/ErdClusterer.js +308 -0
  82. package/dist/generators/ErdClusterer.js.map +1 -0
  83. package/dist/generators/HTMLGenerator.d.ts +6 -0
  84. package/dist/generators/HTMLGenerator.d.ts.map +1 -1
  85. package/dist/generators/HTMLGenerator.js +41 -6
  86. package/dist/generators/HTMLGenerator.js.map +1 -1
  87. package/dist/generators/MermaidGenerator.d.ts +3 -0
  88. package/dist/generators/MermaidGenerator.d.ts.map +1 -1
  89. package/dist/generators/MermaidGenerator.js +4 -0
  90. package/dist/generators/MermaidGenerator.js.map +1 -1
  91. package/dist/generators/index.d.ts +2 -0
  92. package/dist/generators/index.d.ts.map +1 -1
  93. package/dist/generators/index.js +2 -0
  94. package/dist/generators/index.js.map +1 -1
  95. package/dist/index.d.ts +1 -0
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +2 -0
  98. package/dist/index.js.map +1 -1
  99. package/dist/plugins/BaseAutoDocPlugin.d.ts +33 -0
  100. package/dist/plugins/BaseAutoDocPlugin.d.ts.map +1 -0
  101. package/dist/plugins/BaseAutoDocPlugin.js +70 -0
  102. package/dist/plugins/BaseAutoDocPlugin.js.map +1 -0
  103. package/dist/plugins/PluginManager.d.ts +54 -0
  104. package/dist/plugins/PluginManager.d.ts.map +1 -0
  105. package/dist/plugins/PluginManager.js +115 -0
  106. package/dist/plugins/PluginManager.js.map +1 -0
  107. package/dist/plugins/builtins.d.ts +13 -0
  108. package/dist/plugins/builtins.d.ts.map +1 -0
  109. package/dist/plugins/builtins.js +12 -0
  110. package/dist/plugins/builtins.js.map +1 -0
  111. package/dist/plugins/index-advisor/IndexAdvisorPlugin.d.ts +25 -0
  112. package/dist/plugins/index-advisor/IndexAdvisorPlugin.d.ts.map +1 -0
  113. package/dist/plugins/index-advisor/IndexAdvisorPlugin.js +128 -0
  114. package/dist/plugins/index-advisor/IndexAdvisorPlugin.js.map +1 -0
  115. package/dist/plugins/index-advisor/IndexAdvisorTypes.d.ts +111 -0
  116. package/dist/plugins/index-advisor/IndexAdvisorTypes.d.ts.map +1 -0
  117. package/dist/plugins/index-advisor/IndexAdvisorTypes.js +5 -0
  118. package/dist/plugins/index-advisor/IndexAdvisorTypes.js.map +1 -0
  119. package/dist/plugins/index-advisor/IndexLLMReview.d.ts +48 -0
  120. package/dist/plugins/index-advisor/IndexLLMReview.d.ts.map +1 -0
  121. package/dist/plugins/index-advisor/IndexLLMReview.js +181 -0
  122. package/dist/plugins/index-advisor/IndexLLMReview.js.map +1 -0
  123. package/dist/plugins/index-advisor/IndexMigrationGenerator.d.ts +28 -0
  124. package/dist/plugins/index-advisor/IndexMigrationGenerator.d.ts.map +1 -0
  125. package/dist/plugins/index-advisor/IndexMigrationGenerator.js +98 -0
  126. package/dist/plugins/index-advisor/IndexMigrationGenerator.js.map +1 -0
  127. package/dist/plugins/index-advisor/IndexRules.d.ts +19 -0
  128. package/dist/plugins/index-advisor/IndexRules.d.ts.map +1 -0
  129. package/dist/plugins/index-advisor/IndexRules.js +154 -0
  130. package/dist/plugins/index-advisor/IndexRules.js.map +1 -0
  131. package/dist/plugins/index.d.ts +13 -0
  132. package/dist/plugins/index.d.ts.map +1 -0
  133. package/dist/plugins/index.js +13 -0
  134. package/dist/plugins/index.js.map +1 -0
  135. package/dist/plugins/types.d.ts +82 -0
  136. package/dist/plugins/types.d.ts.map +1 -0
  137. package/dist/plugins/types.js +9 -0
  138. package/dist/plugins/types.js.map +1 -0
  139. package/dist/types/analysis.d.ts +2 -0
  140. package/dist/types/analysis.d.ts.map +1 -1
  141. package/dist/types/config.d.ts +52 -0
  142. package/dist/types/config.d.ts.map +1 -1
  143. package/dist/types/config.js +7 -4
  144. package/dist/types/config.js.map +1 -1
  145. package/dist/types/discovery.d.ts +2 -0
  146. package/dist/types/discovery.d.ts.map +1 -1
  147. package/dist/types/driver.d.ts +30 -0
  148. package/dist/types/driver.d.ts.map +1 -1
  149. package/dist/types/driver.js +5 -1
  150. package/dist/types/driver.js.map +1 -1
  151. package/dist/types/index.d.ts +1 -0
  152. package/dist/types/index.d.ts.map +1 -1
  153. package/dist/types/index.js +1 -0
  154. package/dist/types/index.js.map +1 -1
  155. package/dist/types/state.d.ts +36 -0
  156. package/dist/types/state.d.ts.map +1 -1
  157. package/dist/utils/config-loader.d.ts +5 -0
  158. package/dist/utils/config-loader.d.ts.map +1 -1
  159. package/dist/utils/config-loader.js +38 -1
  160. package/dist/utils/config-loader.js.map +1 -1
  161. package/dist/utils/index-hints.d.ts +36 -0
  162. package/dist/utils/index-hints.d.ts.map +1 -0
  163. package/dist/utils/index-hints.js +65 -0
  164. package/dist/utils/index-hints.js.map +1 -0
  165. package/dist/utils/index.d.ts +1 -0
  166. package/dist/utils/index.d.ts.map +1 -1
  167. package/dist/utils/index.js +1 -0
  168. package/dist/utils/index.js.map +1 -1
  169. package/dist/utils/llm-factory.d.ts +1 -0
  170. package/dist/utils/llm-factory.d.ts.map +1 -1
  171. package/dist/utils/llm-factory.js +6 -1
  172. package/dist/utils/llm-factory.js.map +1 -1
  173. package/package.json +5 -5
  174. package/prompts/fk-pruning-table.md +13 -1
  175. package/prompts/index-review.md +60 -0
  176. package/prompts/pk-pruning-table.md +10 -0
  177. 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-preview',
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":"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"}
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":"AAAA;;;;;;;GAOG;AAeH,2DAA2D;AAC3D,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAE5C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAmD,EAAE,GAAG,GAAG,yBAAyB;IAClH,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,EAAE,CAAC;IACrC,OAAO,CAAC,GAAG,OAAO,CAAC;SAChB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;SACzC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;SACb,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACZ,OAAO,EAAE,EAAE,CAAC,OAAO;QACnB,cAAc,EAAE,EAAE,CAAC,cAAc;QACjC,QAAQ,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,YAAY;QACxC,YAAY,EAAE,EAAE,CAAC,YAAY;QAC7B,MAAM,EAAE,EAAE,CAAC,gBAAgB,IAAI,SAAS;KACzC,CAAC,CAAC,CAAC;AACR,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,eAAe,CAAC,IAAe;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IACpF,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACjG,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAmD,EAAE,MAAc;IACnG,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACpB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CACvB,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CACtI,CAAC;AACJ,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,qBAAqB,CAAC,MAAyB,EAAE,OAAuB;IACtF,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAChD,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACd,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IACvF,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACtF,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,EAAgB;IAChC,OAAO,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC"}
@@ -2,4 +2,5 @@
2
2
  * Exports for utils module
3
3
  */
4
4
  export { ConfigLoader } from './config-loader.js';
5
+ export * from './index-hints.js';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -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"}
@@ -2,4 +2,5 @@
2
2
  * Exports for utils module
3
3
  */
4
4
  export { ConfigLoader } from './config-loader.js';
5
+ export * from './index-hints.js';
5
6
  //# sourceMappingURL=index.js.map
@@ -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"}
@@ -5,6 +5,7 @@
5
5
  * across PromptEngine and LLMSanityChecker.
6
6
  */
7
7
  import { BaseLLM } from '@memberjunction/ai';
8
+ import '@memberjunction/server-bootstrap-lite/mj-class-registrations';
8
9
  /**
9
10
  * Create an LLM instance from a provider name
10
11
  *
@@ -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;AAoB7C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAuB3E;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"}
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
- if (!llm) {
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;AAElD;;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,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,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"}
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.3",
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.3",
68
- "@memberjunction/server-bootstrap-lite": "6.2.0-edge.3",
69
- "@memberjunction/core": "6.2.0-edge.3",
70
- "@memberjunction/global": "6.2.0-edge.3",
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