devmind 1.0.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/LICENSE +191 -0
- package/README.md +148 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +232 -0
- package/dist/cli.js.map +1 -0
- package/dist/codebase/generators/architecture.d.ts +4 -0
- package/dist/codebase/generators/architecture.js +33 -0
- package/dist/codebase/generators/architecture.js.map +1 -0
- package/dist/codebase/generators/modules.d.ts +9 -0
- package/dist/codebase/generators/modules.js +46 -0
- package/dist/codebase/generators/modules.js.map +1 -0
- package/dist/codebase/generators/overview.d.ts +5 -0
- package/dist/codebase/generators/overview.js +34 -0
- package/dist/codebase/generators/overview.js.map +1 -0
- package/dist/codebase/generators/skeleton.d.ts +8 -0
- package/dist/codebase/generators/skeleton.js +57 -0
- package/dist/codebase/generators/skeleton.js.map +1 -0
- package/dist/codebase/index.d.ts +24 -0
- package/dist/codebase/index.js +50 -0
- package/dist/codebase/index.js.map +1 -0
- package/dist/codebase/parsers/typescript.d.ts +14 -0
- package/dist/codebase/parsers/typescript.js +145 -0
- package/dist/codebase/parsers/typescript.js.map +1 -0
- package/dist/codebase/scanners/filesystem.d.ts +17 -0
- package/dist/codebase/scanners/filesystem.js +152 -0
- package/dist/codebase/scanners/filesystem.js.map +1 -0
- package/dist/codebase/utils/hashing.d.ts +15 -0
- package/dist/codebase/utils/hashing.js +50 -0
- package/dist/codebase/utils/hashing.js.map +1 -0
- package/dist/codebase/utils/stats.d.ts +12 -0
- package/dist/codebase/utils/stats.js +55 -0
- package/dist/codebase/utils/stats.js.map +1 -0
- package/dist/codebase/utils/tree.d.ts +10 -0
- package/dist/codebase/utils/tree.js +22 -0
- package/dist/codebase/utils/tree.js.map +1 -0
- package/dist/commands/analyze.d.ts +6 -0
- package/dist/commands/analyze.js +97 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/context.d.ts +4 -0
- package/dist/commands/context.js +54 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/core/config.d.ts +20 -0
- package/dist/core/config.js +40 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/errors.d.ts +18 -0
- package/dist/core/errors.js +53 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/fileio.d.ts +10 -0
- package/dist/core/fileio.js +57 -0
- package/dist/core/fileio.js.map +1 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +15 -0
- package/dist/core/logger.js +40 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/types.d.ts +106 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/database/cli.d.ts +7 -0
- package/dist/database/cli.js +132 -0
- package/dist/database/cli.js.map +1 -0
- package/dist/database/commands/checkpoint.d.ts +13 -0
- package/dist/database/commands/checkpoint.js +136 -0
- package/dist/database/commands/checkpoint.js.map +1 -0
- package/dist/database/commands/generate.d.ts +21 -0
- package/dist/database/commands/generate.js +269 -0
- package/dist/database/commands/generate.js.map +1 -0
- package/dist/database/commands/handoff.d.ts +15 -0
- package/dist/database/commands/handoff.js +332 -0
- package/dist/database/commands/handoff.js.map +1 -0
- package/dist/database/commands/history.d.ts +13 -0
- package/dist/database/commands/history.js +148 -0
- package/dist/database/commands/history.js.map +1 -0
- package/dist/database/commands/init.d.ts +10 -0
- package/dist/database/commands/init.js +28 -0
- package/dist/database/commands/init.js.map +1 -0
- package/dist/database/commands/learn.d.ts +12 -0
- package/dist/database/commands/learn.js +93 -0
- package/dist/database/commands/learn.js.map +1 -0
- package/dist/database/commands/memory.d.ts +90 -0
- package/dist/database/commands/memory.js +353 -0
- package/dist/database/commands/memory.js.map +1 -0
- package/dist/database/commands/show.d.ts +9 -0
- package/dist/database/commands/show.js +136 -0
- package/dist/database/commands/show.js.map +1 -0
- package/dist/database/commands/validate.d.ts +9 -0
- package/dist/database/commands/validate.js +200 -0
- package/dist/database/commands/validate.js.map +1 -0
- package/dist/database/commands/watch.d.ts +9 -0
- package/dist/database/commands/watch.js +77 -0
- package/dist/database/commands/watch.js.map +1 -0
- package/dist/database/extractors/drizzle.d.ts +62 -0
- package/dist/database/extractors/drizzle.js +251 -0
- package/dist/database/extractors/drizzle.js.map +1 -0
- package/dist/database/extractors/firebase.d.ts +39 -0
- package/dist/database/extractors/firebase.js +192 -0
- package/dist/database/extractors/firebase.js.map +1 -0
- package/dist/database/extractors/index.d.ts +69 -0
- package/dist/database/extractors/index.js +345 -0
- package/dist/database/extractors/index.js.map +1 -0
- package/dist/database/extractors/mongodb.d.ts +44 -0
- package/dist/database/extractors/mongodb.js +198 -0
- package/dist/database/extractors/mongodb.js.map +1 -0
- package/dist/database/extractors/mysql.d.ts +61 -0
- package/dist/database/extractors/mysql.js +173 -0
- package/dist/database/extractors/mysql.js.map +1 -0
- package/dist/database/extractors/postgres.d.ts +47 -0
- package/dist/database/extractors/postgres.js +141 -0
- package/dist/database/extractors/postgres.js.map +1 -0
- package/dist/database/extractors/prisma.d.ts +71 -0
- package/dist/database/extractors/prisma.js +270 -0
- package/dist/database/extractors/prisma.js.map +1 -0
- package/dist/database/extractors/sqlite.d.ts +50 -0
- package/dist/database/extractors/sqlite.js +148 -0
- package/dist/database/extractors/sqlite.js.map +1 -0
- package/dist/database/generators/learning-generator.d.ts +48 -0
- package/dist/database/generators/learning-generator.js +221 -0
- package/dist/database/generators/learning-generator.js.map +1 -0
- package/dist/database/generators/templates.d.ts +103 -0
- package/dist/database/generators/templates.js +1557 -0
- package/dist/database/generators/templates.js.map +1 -0
- package/dist/database/index.d.ts +15 -0
- package/dist/database/index.js +16 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/utils/json-output.d.ts +26 -0
- package/dist/database/utils/json-output.js +37 -0
- package/dist/database/utils/json-output.js.map +1 -0
- package/dist/generators/unified.d.ts +1 -0
- package/dist/generators/unified.js +173 -0
- package/dist/generators/unified.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config-detector.d.ts +1 -0
- package/dist/utils/config-detector.js +40 -0
- package/dist/utils/config-detector.js.map +1 -0
- package/dist/utils/config-loader.d.ts +16 -0
- package/dist/utils/config-loader.js +20 -0
- package/dist/utils/config-loader.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Schema Extractor
|
|
3
|
+
* Extracts database schema information from SQLite databases
|
|
4
|
+
*/
|
|
5
|
+
import sqlite3 from 'sqlite3';
|
|
6
|
+
export class SQLiteExtractor {
|
|
7
|
+
dbPath;
|
|
8
|
+
constructor(dbPath) {
|
|
9
|
+
this.dbPath = dbPath;
|
|
10
|
+
}
|
|
11
|
+
async extract() {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const db = new sqlite3.Database(this.dbPath, (err) => {
|
|
14
|
+
if (err) {
|
|
15
|
+
reject(err);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
db.serialize(async () => {
|
|
20
|
+
try {
|
|
21
|
+
const tables = await this.extractTables(db);
|
|
22
|
+
const tablesWithDetails = await Promise.all(tables.map((table) => this.enrichTable(db, table)));
|
|
23
|
+
db.close();
|
|
24
|
+
resolve({
|
|
25
|
+
tables: tablesWithDetails,
|
|
26
|
+
databaseType: 'sqlite',
|
|
27
|
+
databasePath: this.dbPath,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
db.close();
|
|
32
|
+
reject(error);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
extractTables(db) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
db.all(`
|
|
40
|
+
SELECT
|
|
41
|
+
name,
|
|
42
|
+
sql
|
|
43
|
+
FROM sqlite_master
|
|
44
|
+
WHERE type = 'table'
|
|
45
|
+
AND name NOT LIKE 'sqlite_%'
|
|
46
|
+
ORDER BY name
|
|
47
|
+
`, (err, rows) => {
|
|
48
|
+
if (err) {
|
|
49
|
+
reject(err);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const tables = rows.map((row) => {
|
|
53
|
+
const sql = row.sql || '';
|
|
54
|
+
const withoutRowId = sql.toUpperCase().includes('WITHOUT ROWID');
|
|
55
|
+
return {
|
|
56
|
+
name: row.name,
|
|
57
|
+
columns: [],
|
|
58
|
+
indexes: [],
|
|
59
|
+
foreignKeys: [],
|
|
60
|
+
primaryKey: [],
|
|
61
|
+
withoutRowId,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
resolve(tables);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
enrichTable(db, table) {
|
|
69
|
+
return new Promise((resolve, reject) => {
|
|
70
|
+
const tableName = table.name;
|
|
71
|
+
db.all(`PRAGMA table_info("${tableName}")`, (err, rows) => {
|
|
72
|
+
if (err) {
|
|
73
|
+
reject(err);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const columns = rows.map((row) => ({
|
|
77
|
+
name: row.name,
|
|
78
|
+
type: row.type || 'TEXT',
|
|
79
|
+
nullable: row.notnull === 0,
|
|
80
|
+
default: row.dflt_value,
|
|
81
|
+
primaryKey: row.pk === 1,
|
|
82
|
+
}));
|
|
83
|
+
const primaryKey = columns.filter((c) => c.primaryKey).map((c) => c.name);
|
|
84
|
+
// Get indexes
|
|
85
|
+
db.all(`PRAGMA index_list("${tableName}")`, (err, indexRows) => {
|
|
86
|
+
if (err) {
|
|
87
|
+
reject(err);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const indexesPromises = indexRows
|
|
91
|
+
.filter((idx) => idx.name !== 'sqlite_autoindex_' + tableName)
|
|
92
|
+
.map((index) => {
|
|
93
|
+
return new Promise((resolveIdx, rejectIdx) => {
|
|
94
|
+
db.all(`PRAGMA index_info("${index.name}")`, (err, colRows) => {
|
|
95
|
+
if (err) {
|
|
96
|
+
rejectIdx(err);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const columnsList = colRows.map((r) => r.name);
|
|
100
|
+
const isAutoIncrement = index.origin === 'u' && columnsList.length === 1 && columnsList[0] === 'id';
|
|
101
|
+
resolveIdx({
|
|
102
|
+
name: index.name,
|
|
103
|
+
table: tableName,
|
|
104
|
+
columns: columnsList,
|
|
105
|
+
unique: index.unique === 1,
|
|
106
|
+
isPrimaryKey: index.origin === 'pk',
|
|
107
|
+
isAutoIncrement,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
Promise.all(indexesPromises)
|
|
113
|
+
.then((indexes) => {
|
|
114
|
+
// Get foreign keys
|
|
115
|
+
db.all(`PRAGMA foreign_key_list("${tableName}")`, (err, fkRows) => {
|
|
116
|
+
if (err) {
|
|
117
|
+
reject(err);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const foreignKeys = fkRows.map((row) => ({
|
|
121
|
+
id: row.id,
|
|
122
|
+
seq: row.seq,
|
|
123
|
+
table: row.table,
|
|
124
|
+
from: row.from,
|
|
125
|
+
to: row.to,
|
|
126
|
+
onUpdate: row.on_update,
|
|
127
|
+
onDelete: row.on_delete,
|
|
128
|
+
match: row.match,
|
|
129
|
+
}));
|
|
130
|
+
resolve({
|
|
131
|
+
...table,
|
|
132
|
+
columns,
|
|
133
|
+
indexes,
|
|
134
|
+
foreignKeys,
|
|
135
|
+
primaryKey,
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
})
|
|
139
|
+
.catch(reject);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
async close() {
|
|
145
|
+
return Promise.resolve();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/database/extractors/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learning Generator
|
|
3
|
+
* Converts schema analysis into accumulated learnings
|
|
4
|
+
*/
|
|
5
|
+
import { UnifiedSchemaInfo } from '../extractors/index.js';
|
|
6
|
+
export interface DetectedPattern {
|
|
7
|
+
type: 'multi-tenancy' | 'soft-delete' | 'audit-trail' | 'polymorphic' | 'enum-usage';
|
|
8
|
+
confidence: number;
|
|
9
|
+
description: string;
|
|
10
|
+
tables: string[];
|
|
11
|
+
recommendation: string;
|
|
12
|
+
example?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class LearningGenerator {
|
|
15
|
+
/**
|
|
16
|
+
* Analyze schema and generate learnings
|
|
17
|
+
*/
|
|
18
|
+
generateLearnings(schema: UnifiedSchemaInfo): DetectedPattern[];
|
|
19
|
+
/**
|
|
20
|
+
* Detect multi-tenancy pattern (organization_id, tenant_id, etc.)
|
|
21
|
+
*/
|
|
22
|
+
private detectMultiTenancy;
|
|
23
|
+
/**
|
|
24
|
+
* Detect soft delete pattern (deleted_at, is_deleted)
|
|
25
|
+
*/
|
|
26
|
+
private detectSoftDelete;
|
|
27
|
+
/**
|
|
28
|
+
* Detect audit trail pattern (created_at, updated_at)
|
|
29
|
+
*/
|
|
30
|
+
private detectAuditTrail;
|
|
31
|
+
/**
|
|
32
|
+
* Detect polymorphic associations (resource_type + resource_id)
|
|
33
|
+
*/
|
|
34
|
+
private detectPolymorphic;
|
|
35
|
+
/**
|
|
36
|
+
* Detect enum column usage
|
|
37
|
+
*/
|
|
38
|
+
private detectEnumUsage;
|
|
39
|
+
/**
|
|
40
|
+
* Helper: Find most common column name
|
|
41
|
+
*/
|
|
42
|
+
private getMostCommonColumn;
|
|
43
|
+
/**
|
|
44
|
+
* Format learnings as markdown
|
|
45
|
+
*/
|
|
46
|
+
formatLearnings(patterns: DetectedPattern[]): string;
|
|
47
|
+
private patternTitle;
|
|
48
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learning Generator
|
|
3
|
+
* Converts schema analysis into accumulated learnings
|
|
4
|
+
*/
|
|
5
|
+
export class LearningGenerator {
|
|
6
|
+
/**
|
|
7
|
+
* Analyze schema and generate learnings
|
|
8
|
+
*/
|
|
9
|
+
generateLearnings(schema) {
|
|
10
|
+
const patterns = [];
|
|
11
|
+
// Detect multi-tenancy
|
|
12
|
+
const multiTenancy = this.detectMultiTenancy(schema);
|
|
13
|
+
if (multiTenancy)
|
|
14
|
+
patterns.push(multiTenancy);
|
|
15
|
+
// Detect soft delete
|
|
16
|
+
const softDelete = this.detectSoftDelete(schema);
|
|
17
|
+
if (softDelete)
|
|
18
|
+
patterns.push(softDelete);
|
|
19
|
+
// Detect audit trail
|
|
20
|
+
const auditTrail = this.detectAuditTrail(schema);
|
|
21
|
+
if (auditTrail)
|
|
22
|
+
patterns.push(auditTrail);
|
|
23
|
+
// Detect polymorphic associations
|
|
24
|
+
const polymorphic = this.detectPolymorphic(schema);
|
|
25
|
+
if (polymorphic)
|
|
26
|
+
patterns.push(polymorphic);
|
|
27
|
+
// Detect enum usage
|
|
28
|
+
const enums = this.detectEnumUsage(schema);
|
|
29
|
+
patterns.push(...enums);
|
|
30
|
+
return patterns;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Detect multi-tenancy pattern (organization_id, tenant_id, etc.)
|
|
34
|
+
*/
|
|
35
|
+
detectMultiTenancy(schema) {
|
|
36
|
+
const tenantColumns = ['organization_id', 'tenant_id', 'account_id', 'workspace_id'];
|
|
37
|
+
const tablesWithTenant = [];
|
|
38
|
+
for (const table of schema.tables) {
|
|
39
|
+
for (const column of table.columns) {
|
|
40
|
+
if (tenantColumns.includes(column.name.toLowerCase())) {
|
|
41
|
+
tablesWithTenant.push(table.name);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (tablesWithTenant.length >= 3) {
|
|
47
|
+
const tenantColumn = this.getMostCommonColumn(schema.tables, tenantColumns);
|
|
48
|
+
return {
|
|
49
|
+
type: 'multi-tenancy',
|
|
50
|
+
confidence: tablesWithTenant.length / schema.tables.length,
|
|
51
|
+
description: `Multi-tenancy pattern detected: ${tablesWithTenant.length} tables have ${tenantColumn}`,
|
|
52
|
+
tables: tablesWithTenant,
|
|
53
|
+
recommendation: `ALWAYS include \`${tenantColumn}\` in WHERE clauses for data isolation`,
|
|
54
|
+
example: `SELECT * FROM users WHERE ${tenantColumn} = ? AND id = ?`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Detect soft delete pattern (deleted_at, is_deleted)
|
|
61
|
+
*/
|
|
62
|
+
detectSoftDelete(schema) {
|
|
63
|
+
const softDeleteColumns = ['deleted_at', 'is_deleted', 'deleted'];
|
|
64
|
+
const tablesWithSoftDelete = [];
|
|
65
|
+
for (const table of schema.tables) {
|
|
66
|
+
for (const column of table.columns) {
|
|
67
|
+
if (softDeleteColumns.includes(column.name.toLowerCase())) {
|
|
68
|
+
tablesWithSoftDelete.push(table.name);
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (tablesWithSoftDelete.length >= 2) {
|
|
74
|
+
const deleteColumn = this.getMostCommonColumn(schema.tables, softDeleteColumns);
|
|
75
|
+
const isTimestamp = deleteColumn.includes('_at');
|
|
76
|
+
return {
|
|
77
|
+
type: 'soft-delete',
|
|
78
|
+
confidence: tablesWithSoftDelete.length / schema.tables.length,
|
|
79
|
+
description: `Soft delete pattern: ${tablesWithSoftDelete.length} tables use ${deleteColumn}`,
|
|
80
|
+
tables: tablesWithSoftDelete,
|
|
81
|
+
recommendation: `Filter out soft-deleted records by default`,
|
|
82
|
+
example: isTimestamp
|
|
83
|
+
? `SELECT * FROM users WHERE ${deleteColumn} IS NULL`
|
|
84
|
+
: `SELECT * FROM users WHERE ${deleteColumn} = false`,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Detect audit trail pattern (created_at, updated_at)
|
|
91
|
+
*/
|
|
92
|
+
detectAuditTrail(schema) {
|
|
93
|
+
const auditColumns = ['created_at', 'updated_at', 'modified_at'];
|
|
94
|
+
let tablesWithAudit = 0;
|
|
95
|
+
for (const table of schema.tables) {
|
|
96
|
+
const hasCreated = table.columns.some((c) => c.name.toLowerCase() === 'created_at');
|
|
97
|
+
const hasUpdated = table.columns.some((c) => c.name.toLowerCase() === 'updated_at' || c.name.toLowerCase() === 'modified_at');
|
|
98
|
+
if (hasCreated && hasUpdated) {
|
|
99
|
+
tablesWithAudit++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (tablesWithAudit >= schema.tables.length * 0.5) {
|
|
103
|
+
return {
|
|
104
|
+
type: 'audit-trail',
|
|
105
|
+
confidence: tablesWithAudit / schema.tables.length,
|
|
106
|
+
description: `Audit trail: ${tablesWithAudit} tables track created_at and updated_at`,
|
|
107
|
+
tables: [],
|
|
108
|
+
recommendation: 'Use timestamp columns for debugging, rollback, and audit purposes',
|
|
109
|
+
example: "SELECT * FROM users WHERE updated_at > NOW() - INTERVAL '1 day'",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Detect polymorphic associations (resource_type + resource_id)
|
|
116
|
+
*/
|
|
117
|
+
detectPolymorphic(schema) {
|
|
118
|
+
const polymorphicTables = [];
|
|
119
|
+
for (const table of schema.tables) {
|
|
120
|
+
const hasTypeColumn = table.columns.some((c) => c.name.toLowerCase().includes('_type') || c.name.toLowerCase() === 'type');
|
|
121
|
+
const hasIdColumn = table.columns.some((c) => c.name.toLowerCase().includes('_id') && !c.name.toLowerCase().includes('user_id'));
|
|
122
|
+
if (hasTypeColumn && hasIdColumn) {
|
|
123
|
+
polymorphicTables.push(table.name);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (polymorphicTables.length > 0) {
|
|
127
|
+
return {
|
|
128
|
+
type: 'polymorphic',
|
|
129
|
+
confidence: 0.8,
|
|
130
|
+
description: `Polymorphic associations detected in: ${polymorphicTables.join(', ')}`,
|
|
131
|
+
tables: polymorphicTables,
|
|
132
|
+
recommendation: 'Use type + id pattern for flexible associations',
|
|
133
|
+
example: "SELECT * FROM comments WHERE resource_type = 'Post' AND resource_id = ?",
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Detect enum column usage
|
|
140
|
+
*/
|
|
141
|
+
detectEnumUsage(schema) {
|
|
142
|
+
const patterns = [];
|
|
143
|
+
for (const table of schema.tables) {
|
|
144
|
+
for (const column of table.columns) {
|
|
145
|
+
// Check if column type suggests enum
|
|
146
|
+
if (column.type.toLowerCase().includes('enum') ||
|
|
147
|
+
column.name.toLowerCase().includes('status') ||
|
|
148
|
+
column.name.toLowerCase().includes('role') ||
|
|
149
|
+
column.name.toLowerCase().includes('type')) {
|
|
150
|
+
patterns.push({
|
|
151
|
+
type: 'enum-usage',
|
|
152
|
+
confidence: 0.9,
|
|
153
|
+
description: `${table.name}.${column.name} appears to be an enum/status field`,
|
|
154
|
+
tables: [table.name],
|
|
155
|
+
recommendation: `Use specific values, avoid SELECT * to reduce overhead`,
|
|
156
|
+
example: `SELECT id, ${column.name} FROM ${table.name} WHERE ${column.name} = 'active'`,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return patterns;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Helper: Find most common column name
|
|
165
|
+
*/
|
|
166
|
+
getMostCommonColumn(tables, candidates) {
|
|
167
|
+
const counts = {};
|
|
168
|
+
for (const table of tables) {
|
|
169
|
+
for (const column of table.columns) {
|
|
170
|
+
const name = column.name.toLowerCase();
|
|
171
|
+
if (candidates.includes(name)) {
|
|
172
|
+
counts[name] = (counts[name] || 0) + 1;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
let maxCount = 0;
|
|
177
|
+
let mostCommon = candidates[0];
|
|
178
|
+
for (const [name, count] of Object.entries(counts)) {
|
|
179
|
+
if (count > maxCount) {
|
|
180
|
+
maxCount = count;
|
|
181
|
+
mostCommon = name;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return mostCommon;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Format learnings as markdown
|
|
188
|
+
*/
|
|
189
|
+
formatLearnings(patterns) {
|
|
190
|
+
let markdown = '# Business Logic Learnings\n\n';
|
|
191
|
+
markdown += `> Auto-generated from schema analysis on ${new Date().toISOString()}\n\n`;
|
|
192
|
+
for (const pattern of patterns) {
|
|
193
|
+
markdown += `## ${this.patternTitle(pattern.type)}\n\n`;
|
|
194
|
+
markdown += `**Confidence:** ${(pattern.confidence * 100).toFixed(0)}%\n\n`;
|
|
195
|
+
markdown += `**Description:** ${pattern.description}\n\n`;
|
|
196
|
+
if (pattern.tables.length > 0 && pattern.tables.length <= 10) {
|
|
197
|
+
markdown += `**Affected Tables:** ${pattern.tables.join(', ')}\n\n`;
|
|
198
|
+
}
|
|
199
|
+
else if (pattern.tables.length > 10) {
|
|
200
|
+
markdown += `**Affected Tables:** ${pattern.tables.length} tables\n\n`;
|
|
201
|
+
}
|
|
202
|
+
markdown += `**Recommendation:** ${pattern.recommendation}\n\n`;
|
|
203
|
+
if (pattern.example) {
|
|
204
|
+
markdown += `**Example:**\n\`\`\`sql\n${pattern.example}\n\`\`\`\n\n`;
|
|
205
|
+
}
|
|
206
|
+
markdown += '---\n\n';
|
|
207
|
+
}
|
|
208
|
+
return markdown;
|
|
209
|
+
}
|
|
210
|
+
patternTitle(type) {
|
|
211
|
+
const titles = {
|
|
212
|
+
'multi-tenancy': 'Multi-Tenancy Pattern',
|
|
213
|
+
'soft-delete': 'Soft Delete Pattern',
|
|
214
|
+
'audit-trail': 'Audit Trail Pattern',
|
|
215
|
+
polymorphic: 'Polymorphic Associations',
|
|
216
|
+
'enum-usage': 'Enum/Status Field',
|
|
217
|
+
};
|
|
218
|
+
return titles[type] || type;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=learning-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-generator.js","sourceRoot":"","sources":["../../../src/database/generators/learning-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Generator - Enhanced Version
|
|
3
|
+
* Generates CLAUDE.md and AGENTS.md from schema information with full relationship support
|
|
4
|
+
*/
|
|
5
|
+
import { PostgresSchemaInfo, MySQLSchemaInfo, SQLiteSchemaInfo, PrismaSchemaInfo, DrizzleSchemaInfo } from '../extractors/index.js';
|
|
6
|
+
export interface UnifiedColumnInfo {
|
|
7
|
+
name: string;
|
|
8
|
+
type: string;
|
|
9
|
+
nullable: boolean;
|
|
10
|
+
default: string | null;
|
|
11
|
+
isPrimaryKey: boolean;
|
|
12
|
+
isUnique: boolean;
|
|
13
|
+
isForeignKey: boolean;
|
|
14
|
+
referencesTable?: string;
|
|
15
|
+
referencesColumn?: string;
|
|
16
|
+
onDelete?: string;
|
|
17
|
+
onUpdate?: string;
|
|
18
|
+
description?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface UnifiedIndexInfo {
|
|
21
|
+
name: string;
|
|
22
|
+
columns: string[];
|
|
23
|
+
unique: boolean;
|
|
24
|
+
isPrimaryKey: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface UnifiedRelationInfo {
|
|
27
|
+
fromTable: string;
|
|
28
|
+
fromColumn: string;
|
|
29
|
+
toTable: string;
|
|
30
|
+
toColumn: string;
|
|
31
|
+
cardinality: '1:1' | '1:N' | 'N:1' | 'N:M';
|
|
32
|
+
onDelete?: string;
|
|
33
|
+
onUpdate?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface UnifiedTableInfo {
|
|
36
|
+
name: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
columns: UnifiedColumnInfo[];
|
|
39
|
+
indexes: UnifiedIndexInfo[];
|
|
40
|
+
relations: UnifiedRelationInfo[];
|
|
41
|
+
primaryKey: string[];
|
|
42
|
+
}
|
|
43
|
+
export interface UnifiedSchemaInfo {
|
|
44
|
+
tables: UnifiedTableInfo[];
|
|
45
|
+
databaseType: 'postgresql' | 'mysql' | 'sqlite' | 'prisma' | 'drizzle' | 'mongodb' | 'firebase';
|
|
46
|
+
schemaName?: string;
|
|
47
|
+
source?: string;
|
|
48
|
+
}
|
|
49
|
+
export declare class UnifiedSchemaConverter {
|
|
50
|
+
static fromPostgres(schema: PostgresSchemaInfo): UnifiedSchemaInfo;
|
|
51
|
+
static fromMySQL(schema: MySQLSchemaInfo): UnifiedSchemaInfo;
|
|
52
|
+
static fromSQLite(schema: SQLiteSchemaInfo): UnifiedSchemaInfo;
|
|
53
|
+
static fromPrisma(schema: PrismaSchemaInfo): UnifiedSchemaInfo;
|
|
54
|
+
static fromDrizzle(schema: DrizzleSchemaInfo): UnifiedSchemaInfo;
|
|
55
|
+
}
|
|
56
|
+
export declare class TemplateGenerator {
|
|
57
|
+
private templateDir;
|
|
58
|
+
private outputDir;
|
|
59
|
+
constructor(templateDir?: string, outputDir?: string);
|
|
60
|
+
generate(schema: UnifiedSchemaInfo): {
|
|
61
|
+
claudeMd: string;
|
|
62
|
+
agentsMd: string;
|
|
63
|
+
queries: Record<string, string>;
|
|
64
|
+
edgeCasesMd: string;
|
|
65
|
+
constraintsMd: string;
|
|
66
|
+
testTemplates: Record<string, string>;
|
|
67
|
+
memoryPatterns: Record<string, string>;
|
|
68
|
+
handoffTemplates: Record<string, string>;
|
|
69
|
+
decisionTemplates: Record<string, string>;
|
|
70
|
+
};
|
|
71
|
+
save(outputPath: string, schema: UnifiedSchemaInfo): Promise<void>;
|
|
72
|
+
private buildTemplateData;
|
|
73
|
+
private buildRelationships;
|
|
74
|
+
private getCardinalitySummary;
|
|
75
|
+
private getIndexPurpose;
|
|
76
|
+
private getRelationshipDescription;
|
|
77
|
+
private getUsagePattern;
|
|
78
|
+
private getBusinessRules;
|
|
79
|
+
private getConventions;
|
|
80
|
+
private getOwnershipRules;
|
|
81
|
+
private getPerformanceTips;
|
|
82
|
+
private renderClaudeMd;
|
|
83
|
+
private renderAgentsMd;
|
|
84
|
+
private generateAllQueryTemplates;
|
|
85
|
+
private generateQueryTemplate;
|
|
86
|
+
private generateTransactionPatterns;
|
|
87
|
+
private renderEdgeCasesMd;
|
|
88
|
+
private renderConstraintsMd;
|
|
89
|
+
private generateTestTemplates;
|
|
90
|
+
private generateEdgeCasesTest;
|
|
91
|
+
private generateCRUDEdgeCases;
|
|
92
|
+
private generateSingleTableTests;
|
|
93
|
+
private generateMemoryPatterns;
|
|
94
|
+
private generateCheckpointPatterns;
|
|
95
|
+
private generateSessionTemplate;
|
|
96
|
+
private generateEmptyLearnings;
|
|
97
|
+
private generateHandoffTemplates;
|
|
98
|
+
private generateHandoffTemplate;
|
|
99
|
+
private generateMultiAgentProtocol;
|
|
100
|
+
private generateDecisionTemplates;
|
|
101
|
+
private generateDecisionTemplate;
|
|
102
|
+
private generateDecisionLog;
|
|
103
|
+
}
|