@emaenriquez/projectmanager-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +98 -0
- package/dist/application/ConfigManager.d.ts +73 -0
- package/dist/application/ConfigManager.d.ts.map +1 -0
- package/dist/application/ConfigManager.js +253 -0
- package/dist/application/ConfigManager.js.map +1 -0
- package/dist/application/errors/ErrorHandler.d.ts +27 -0
- package/dist/application/errors/ErrorHandler.d.ts.map +1 -0
- package/dist/application/errors/ErrorHandler.js +88 -0
- package/dist/application/errors/ErrorHandler.js.map +1 -0
- package/dist/application/state/StateManager.d.ts +26 -0
- package/dist/application/state/StateManager.d.ts.map +1 -0
- package/dist/application/state/StateManager.js +114 -0
- package/dist/application/state/StateManager.js.map +1 -0
- package/dist/application/use_cases/AddProjectUseCase.d.ts +9 -0
- package/dist/application/use_cases/AddProjectUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/AddProjectUseCase.js +85 -0
- package/dist/application/use_cases/AddProjectUseCase.js.map +1 -0
- package/dist/application/use_cases/ListProjectsUseCase.d.ts +7 -0
- package/dist/application/use_cases/ListProjectsUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/ListProjectsUseCase.js +14 -0
- package/dist/application/use_cases/ListProjectsUseCase.js.map +1 -0
- package/dist/application/use_cases/OpenProjectUseCase.d.ts +10 -0
- package/dist/application/use_cases/OpenProjectUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/OpenProjectUseCase.js +168 -0
- package/dist/application/use_cases/OpenProjectUseCase.js.map +1 -0
- package/dist/application/use_cases/RemoveProjectUseCase.d.ts +7 -0
- package/dist/application/use_cases/RemoveProjectUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/RemoveProjectUseCase.js +24 -0
- package/dist/application/use_cases/RemoveProjectUseCase.js.map +1 -0
- package/dist/application/use_cases/ScanProjectsUseCase.d.ts +13 -0
- package/dist/application/use_cases/ScanProjectsUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/ScanProjectsUseCase.js +57 -0
- package/dist/application/use_cases/ScanProjectsUseCase.js.map +1 -0
- package/dist/application/use_cases/SyncProjectsUseCase.d.ts +12 -0
- package/dist/application/use_cases/SyncProjectsUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/SyncProjectsUseCase.js +74 -0
- package/dist/application/use_cases/SyncProjectsUseCase.js.map +1 -0
- package/dist/application/use_cases/SystemDiagnostics.d.ts +16 -0
- package/dist/application/use_cases/SystemDiagnostics.d.ts.map +1 -0
- package/dist/application/use_cases/SystemDiagnostics.js +35 -0
- package/dist/application/use_cases/SystemDiagnostics.js.map +1 -0
- package/dist/application/use_cases/TagProjectUseCase.d.ts +9 -0
- package/dist/application/use_cases/TagProjectUseCase.d.ts.map +1 -0
- package/dist/application/use_cases/TagProjectUseCase.js +41 -0
- package/dist/application/use_cases/TagProjectUseCase.js.map +1 -0
- package/dist/domain/patterns/ProjectPatterns.d.ts +47 -0
- package/dist/domain/patterns/ProjectPatterns.d.ts.map +1 -0
- package/dist/domain/patterns/ProjectPatterns.js +200 -0
- package/dist/domain/patterns/ProjectPatterns.js.map +1 -0
- package/dist/domain/services/GitService.d.ts +23 -0
- package/dist/domain/services/GitService.d.ts.map +1 -0
- package/dist/domain/services/GitService.js +155 -0
- package/dist/domain/services/GitService.js.map +1 -0
- package/dist/domain/services/IgnoreFileParser.d.ts +55 -0
- package/dist/domain/services/IgnoreFileParser.d.ts.map +1 -0
- package/dist/domain/services/IgnoreFileParser.js +200 -0
- package/dist/domain/services/IgnoreFileParser.js.map +1 -0
- package/dist/domain/services/ProjectScanner.d.ts +65 -0
- package/dist/domain/services/ProjectScanner.d.ts.map +1 -0
- package/dist/domain/services/ProjectScanner.js +207 -0
- package/dist/domain/services/ProjectScanner.js.map +1 -0
- package/dist/domain/services/TechnologyDetector.d.ts +78 -0
- package/dist/domain/services/TechnologyDetector.d.ts.map +1 -0
- package/dist/domain/services/TechnologyDetector.js +633 -0
- package/dist/domain/services/TechnologyDetector.js.map +1 -0
- package/dist/domain/services/ToolDetector.d.ts +74 -0
- package/dist/domain/services/ToolDetector.d.ts.map +1 -0
- package/dist/domain/services/ToolDetector.js +344 -0
- package/dist/domain/services/ToolDetector.js.map +1 -0
- package/dist/domain/services/index.d.ts +5 -0
- package/dist/domain/services/index.d.ts.map +1 -0
- package/dist/domain/services/index.js +12 -0
- package/dist/domain/services/index.js.map +1 -0
- package/dist/domain/types/Config.d.ts +37 -0
- package/dist/domain/types/Config.d.ts.map +1 -0
- package/dist/domain/types/Config.js +6 -0
- package/dist/domain/types/Config.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/database/DatabaseConnection.d.ts +88 -0
- package/dist/infrastructure/database/DatabaseConnection.d.ts.map +1 -0
- package/dist/infrastructure/database/DatabaseConnection.js +318 -0
- package/dist/infrastructure/database/DatabaseConnection.js.map +1 -0
- package/dist/infrastructure/database/DatabaseValidator.d.ts +154 -0
- package/dist/infrastructure/database/DatabaseValidator.d.ts.map +1 -0
- package/dist/infrastructure/database/DatabaseValidator.js +583 -0
- package/dist/infrastructure/database/DatabaseValidator.js.map +1 -0
- package/dist/infrastructure/database/index.d.ts +8 -0
- package/dist/infrastructure/database/index.d.ts.map +1 -0
- package/dist/infrastructure/database/index.js +14 -0
- package/dist/infrastructure/database/index.js.map +1 -0
- package/dist/infrastructure/database/migrations/001_initial.d.ts +24 -0
- package/dist/infrastructure/database/migrations/001_initial.d.ts.map +1 -0
- package/dist/infrastructure/database/migrations/001_initial.js +109 -0
- package/dist/infrastructure/database/migrations/001_initial.js.map +1 -0
- package/dist/infrastructure/database/migrations/Migration.d.ts +27 -0
- package/dist/infrastructure/database/migrations/Migration.d.ts.map +1 -0
- package/dist/infrastructure/database/migrations/Migration.js +3 -0
- package/dist/infrastructure/database/migrations/Migration.js.map +1 -0
- package/dist/infrastructure/database/migrations/MigrationRunner.d.ts +52 -0
- package/dist/infrastructure/database/migrations/MigrationRunner.d.ts.map +1 -0
- package/dist/infrastructure/database/migrations/MigrationRunner.js +167 -0
- package/dist/infrastructure/database/migrations/MigrationRunner.js.map +1 -0
- package/dist/infrastructure/database/migrations/index.d.ts +10 -0
- package/dist/infrastructure/database/migrations/index.d.ts.map +1 -0
- package/dist/infrastructure/database/migrations/index.js +22 -0
- package/dist/infrastructure/database/migrations/index.js.map +1 -0
- package/dist/infrastructure/filesystem/DirectoryManager.d.ts +50 -0
- package/dist/infrastructure/filesystem/DirectoryManager.d.ts.map +1 -0
- package/dist/infrastructure/filesystem/DirectoryManager.js +143 -0
- package/dist/infrastructure/filesystem/DirectoryManager.js.map +1 -0
- package/dist/infrastructure/filesystem/index.d.ts +2 -0
- package/dist/infrastructure/filesystem/index.d.ts.map +1 -0
- package/dist/infrastructure/filesystem/index.js +6 -0
- package/dist/infrastructure/filesystem/index.js.map +1 -0
- package/dist/infrastructure/logging/LogRotator.d.ts +43 -0
- package/dist/infrastructure/logging/LogRotator.d.ts.map +1 -0
- package/dist/infrastructure/logging/LogRotator.js +172 -0
- package/dist/infrastructure/logging/LogRotator.js.map +1 -0
- package/dist/infrastructure/logging/Logger.d.ts +59 -0
- package/dist/infrastructure/logging/Logger.d.ts.map +1 -0
- package/dist/infrastructure/logging/Logger.js +182 -0
- package/dist/infrastructure/logging/Logger.js.map +1 -0
- package/dist/infrastructure/logging/index.d.ts +3 -0
- package/dist/infrastructure/logging/index.d.ts.map +1 -0
- package/dist/infrastructure/logging/index.js +8 -0
- package/dist/infrastructure/logging/index.js.map +1 -0
- package/dist/infrastructure/repositories/ProjectRepository.d.ts +20 -0
- package/dist/infrastructure/repositories/ProjectRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/ProjectRepository.js +61 -0
- package/dist/infrastructure/repositories/ProjectRepository.js.map +1 -0
- package/dist/infrastructure/repositories/QueryBuilder.d.ts +24 -0
- package/dist/infrastructure/repositories/QueryBuilder.d.ts.map +1 -0
- package/dist/infrastructure/repositories/QueryBuilder.js +92 -0
- package/dist/infrastructure/repositories/QueryBuilder.js.map +1 -0
- package/dist/infrastructure/repositories/TagRepository.d.ts +18 -0
- package/dist/infrastructure/repositories/TagRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/TagRepository.js +66 -0
- package/dist/infrastructure/repositories/TagRepository.js.map +1 -0
- package/dist/infrastructure/repositories/TechnologyRepository.d.ts +16 -0
- package/dist/infrastructure/repositories/TechnologyRepository.d.ts.map +1 -0
- package/dist/infrastructure/repositories/TechnologyRepository.js +46 -0
- package/dist/infrastructure/repositories/TechnologyRepository.js.map +1 -0
- package/dist/infrastructure/repositories/TransactionManager.d.ts +11 -0
- package/dist/infrastructure/repositories/TransactionManager.d.ts.map +1 -0
- package/dist/infrastructure/repositories/TransactionManager.js +21 -0
- package/dist/infrastructure/repositories/TransactionManager.js.map +1 -0
- package/dist/infrastructure/ui/ScreenManager.d.ts +11 -0
- package/dist/infrastructure/ui/ScreenManager.d.ts.map +1 -0
- package/dist/infrastructure/ui/ScreenManager.js +69 -0
- package/dist/infrastructure/ui/ScreenManager.js.map +1 -0
- package/dist/ui/cli/CLI.d.ts +9 -0
- package/dist/ui/cli/CLI.d.ts.map +1 -0
- package/dist/ui/cli/CLI.js +211 -0
- package/dist/ui/cli/CLI.js.map +1 -0
- package/dist/ui/components/DetailsPanel.d.ts +11 -0
- package/dist/ui/components/DetailsPanel.d.ts.map +1 -0
- package/dist/ui/components/DetailsPanel.js +181 -0
- package/dist/ui/components/DetailsPanel.js.map +1 -0
- package/dist/ui/components/ProjectListView.d.ts +15 -0
- package/dist/ui/components/ProjectListView.d.ts.map +1 -0
- package/dist/ui/components/ProjectListView.js +122 -0
- package/dist/ui/components/ProjectListView.js.map +1 -0
- package/dist/ui/tui/TUIApplication.d.ts +17 -0
- package/dist/ui/tui/TUIApplication.d.ts.map +1 -0
- package/dist/ui/tui/TUIApplication.js +532 -0
- package/dist/ui/tui/TUIApplication.js.map +1 -0
- package/dist/ui/tui/Theme.d.ts +25 -0
- package/dist/ui/tui/Theme.d.ts.map +1 -0
- package/dist/ui/tui/Theme.js +62 -0
- package/dist/ui/tui/Theme.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseValidator = void 0;
|
|
4
|
+
const DatabaseConnection_1 = require("./DatabaseConnection");
|
|
5
|
+
/**
|
|
6
|
+
* DatabaseValidator provides comprehensive database integrity checking and repair capabilities
|
|
7
|
+
* Validates schema consistency, foreign key constraints, and data integrity
|
|
8
|
+
*/
|
|
9
|
+
class DatabaseValidator {
|
|
10
|
+
constructor() {
|
|
11
|
+
/**
|
|
12
|
+
* Expected database schema definition
|
|
13
|
+
*/
|
|
14
|
+
this.expectedSchema = {
|
|
15
|
+
projects: {
|
|
16
|
+
columns: {
|
|
17
|
+
id: 'TEXT',
|
|
18
|
+
name: 'TEXT',
|
|
19
|
+
path: 'TEXT',
|
|
20
|
+
created_at: 'DATETIME',
|
|
21
|
+
last_opened: 'DATETIME',
|
|
22
|
+
is_favorite: 'BOOLEAN',
|
|
23
|
+
default_tool: 'TEXT',
|
|
24
|
+
notes: 'TEXT'
|
|
25
|
+
},
|
|
26
|
+
primaryKey: 'id',
|
|
27
|
+
uniqueConstraints: ['path']
|
|
28
|
+
},
|
|
29
|
+
tags: {
|
|
30
|
+
columns: {
|
|
31
|
+
id: 'TEXT',
|
|
32
|
+
name: 'TEXT',
|
|
33
|
+
created_at: 'DATETIME'
|
|
34
|
+
},
|
|
35
|
+
primaryKey: 'id',
|
|
36
|
+
uniqueConstraints: ['name']
|
|
37
|
+
},
|
|
38
|
+
project_tags: {
|
|
39
|
+
columns: {
|
|
40
|
+
project_id: 'TEXT',
|
|
41
|
+
tag_id: 'TEXT',
|
|
42
|
+
added_at: 'DATETIME'
|
|
43
|
+
},
|
|
44
|
+
primaryKey: ['project_id', 'tag_id'],
|
|
45
|
+
foreignKeys: [
|
|
46
|
+
{ column: 'project_id', references: 'projects(id)', onDelete: 'CASCADE' },
|
|
47
|
+
{ column: 'tag_id', references: 'tags(id)', onDelete: 'CASCADE' }
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
technologies: {
|
|
51
|
+
columns: {
|
|
52
|
+
id: 'TEXT',
|
|
53
|
+
project_id: 'TEXT',
|
|
54
|
+
name: 'TEXT',
|
|
55
|
+
version: 'TEXT',
|
|
56
|
+
category: 'TEXT',
|
|
57
|
+
detected_at: 'DATETIME'
|
|
58
|
+
},
|
|
59
|
+
primaryKey: 'id',
|
|
60
|
+
foreignKeys: [{ column: 'project_id', references: 'projects(id)', onDelete: 'CASCADE' }]
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Expected indexes
|
|
65
|
+
*/
|
|
66
|
+
this.expectedIndexes = [
|
|
67
|
+
'idx_projects_name',
|
|
68
|
+
'idx_projects_path',
|
|
69
|
+
'idx_project_tags_project_id',
|
|
70
|
+
'idx_project_tags_tag_id',
|
|
71
|
+
'idx_technologies_project_id',
|
|
72
|
+
'idx_technologies_name'
|
|
73
|
+
];
|
|
74
|
+
this.db = DatabaseConnection_1.DatabaseConnection.getInstance();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Run comprehensive database validation
|
|
78
|
+
* @returns ValidationReport with complete validation results
|
|
79
|
+
*/
|
|
80
|
+
validate() {
|
|
81
|
+
const report = {
|
|
82
|
+
isValid: true,
|
|
83
|
+
schema: { isValid: true, missingTables: [], invalidColumns: [], invalidIndexes: [] },
|
|
84
|
+
constraints: { isValid: true, orphanRecords: [], violatedConstraints: [] },
|
|
85
|
+
errors: [],
|
|
86
|
+
warnings: [],
|
|
87
|
+
repairAttempted: false,
|
|
88
|
+
repairSuccessful: false
|
|
89
|
+
};
|
|
90
|
+
// Validate schema
|
|
91
|
+
const schemaResult = this.validateSchema();
|
|
92
|
+
report.schema = schemaResult;
|
|
93
|
+
if (!schemaResult.isValid) {
|
|
94
|
+
report.isValid = false;
|
|
95
|
+
schemaResult.missingTables.forEach((table) => {
|
|
96
|
+
report.errors.push(`Missing table: ${table}`);
|
|
97
|
+
});
|
|
98
|
+
schemaResult.invalidColumns.forEach((col) => {
|
|
99
|
+
report.errors.push(`Invalid column in ${col.table}.${col.column}: ${col.issue}`);
|
|
100
|
+
});
|
|
101
|
+
schemaResult.invalidIndexes.forEach((idx) => {
|
|
102
|
+
report.warnings.push(`Missing index: ${idx}`);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// Validate constraints
|
|
106
|
+
const constraintsResult = this.validateConstraints();
|
|
107
|
+
report.constraints = constraintsResult;
|
|
108
|
+
if (!constraintsResult.isValid) {
|
|
109
|
+
report.isValid = false;
|
|
110
|
+
constraintsResult.orphanRecords.forEach((orphan) => {
|
|
111
|
+
report.errors.push(`Orphan records in ${orphan.table}.${orphan.foreignKeyColumn}: ` +
|
|
112
|
+
`${orphan.recordCount} records referencing non-existent ${orphan.referencedTable}`);
|
|
113
|
+
});
|
|
114
|
+
constraintsResult.violatedConstraints.forEach((violation) => {
|
|
115
|
+
const messageType = violation.severity === 'critical' ? 'ERROR' : 'WARNING';
|
|
116
|
+
report[violation.severity === 'critical' ? 'errors' : 'warnings'].push(`${messageType} in ${violation.table}: ${violation.constraint} - ${violation.description}`);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return report;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Validate database schema
|
|
123
|
+
* Checks that all required tables exist with correct columns and structure
|
|
124
|
+
*/
|
|
125
|
+
validateSchema() {
|
|
126
|
+
const result = {
|
|
127
|
+
isValid: true,
|
|
128
|
+
missingTables: [],
|
|
129
|
+
invalidColumns: [],
|
|
130
|
+
invalidIndexes: []
|
|
131
|
+
};
|
|
132
|
+
try {
|
|
133
|
+
// Check all tables exist
|
|
134
|
+
for (const tableName of Object.keys(this.expectedSchema)) {
|
|
135
|
+
const tableExists = this.tableExists(tableName);
|
|
136
|
+
if (!tableExists) {
|
|
137
|
+
result.missingTables.push(tableName);
|
|
138
|
+
result.isValid = false;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
// Validate columns in existing table
|
|
142
|
+
const tableInfo = this.getTableInfo(tableName);
|
|
143
|
+
const expectedColumns = this.expectedSchema[tableName].columns;
|
|
144
|
+
for (const [columnName, expectedType] of Object.entries(expectedColumns)) {
|
|
145
|
+
const actualColumn = tableInfo.find((col) => col.name === columnName);
|
|
146
|
+
if (!actualColumn) {
|
|
147
|
+
result.invalidColumns.push({
|
|
148
|
+
table: tableName,
|
|
149
|
+
column: columnName,
|
|
150
|
+
expectedType: expectedType,
|
|
151
|
+
actualType: 'MISSING',
|
|
152
|
+
issue: `Column does not exist, expected type: ${expectedType}`
|
|
153
|
+
});
|
|
154
|
+
result.isValid = false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// Check indexes
|
|
159
|
+
const existingIndexes = this.getExistingIndexes();
|
|
160
|
+
for (const indexName of this.expectedIndexes) {
|
|
161
|
+
if (!existingIndexes.includes(indexName)) {
|
|
162
|
+
result.invalidIndexes.push(indexName);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
throw new Error(`Schema validation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Validate database constraints
|
|
173
|
+
* Checks for orphan records and constraint violations
|
|
174
|
+
*/
|
|
175
|
+
validateConstraints() {
|
|
176
|
+
const result = {
|
|
177
|
+
isValid: true,
|
|
178
|
+
orphanRecords: [],
|
|
179
|
+
violatedConstraints: []
|
|
180
|
+
};
|
|
181
|
+
try {
|
|
182
|
+
// Check for orphan records in project_tags
|
|
183
|
+
const orphanProjectTags = this.checkOrphanRecords('project_tags', 'project_id', 'projects', 'id');
|
|
184
|
+
if (orphanProjectTags > 0) {
|
|
185
|
+
result.orphanRecords.push({
|
|
186
|
+
table: 'project_tags',
|
|
187
|
+
foreignKeyColumn: 'project_id',
|
|
188
|
+
recordCount: orphanProjectTags,
|
|
189
|
+
referencedTable: 'projects'
|
|
190
|
+
});
|
|
191
|
+
result.isValid = false;
|
|
192
|
+
}
|
|
193
|
+
const orphanTagRecords = this.checkOrphanRecords('project_tags', 'tag_id', 'tags', 'id');
|
|
194
|
+
if (orphanTagRecords > 0) {
|
|
195
|
+
result.orphanRecords.push({
|
|
196
|
+
table: 'project_tags',
|
|
197
|
+
foreignKeyColumn: 'tag_id',
|
|
198
|
+
recordCount: orphanTagRecords,
|
|
199
|
+
referencedTable: 'tags'
|
|
200
|
+
});
|
|
201
|
+
result.isValid = false;
|
|
202
|
+
}
|
|
203
|
+
// Check for orphan records in technologies
|
|
204
|
+
const orphanTechnologies = this.checkOrphanRecords('technologies', 'project_id', 'projects', 'id');
|
|
205
|
+
if (orphanTechnologies > 0) {
|
|
206
|
+
result.orphanRecords.push({
|
|
207
|
+
table: 'technologies',
|
|
208
|
+
foreignKeyColumn: 'project_id',
|
|
209
|
+
recordCount: orphanTechnologies,
|
|
210
|
+
referencedTable: 'projects'
|
|
211
|
+
});
|
|
212
|
+
result.isValid = false;
|
|
213
|
+
}
|
|
214
|
+
// Check for duplicate paths in projects (UNIQUE constraint)
|
|
215
|
+
const duplicatePaths = this.checkDuplicateUniqueConstraint('projects', 'path');
|
|
216
|
+
if (duplicatePaths > 0) {
|
|
217
|
+
result.violatedConstraints.push({
|
|
218
|
+
table: 'projects',
|
|
219
|
+
constraint: 'UNIQUE(path)',
|
|
220
|
+
description: `${duplicatePaths} duplicate project paths found`,
|
|
221
|
+
severity: 'critical'
|
|
222
|
+
});
|
|
223
|
+
result.isValid = false;
|
|
224
|
+
}
|
|
225
|
+
// Check for duplicate tag names
|
|
226
|
+
const duplicateTagNames = this.checkDuplicateUniqueConstraint('tags', 'name');
|
|
227
|
+
if (duplicateTagNames > 0) {
|
|
228
|
+
result.violatedConstraints.push({
|
|
229
|
+
table: 'tags',
|
|
230
|
+
constraint: 'UNIQUE(name)',
|
|
231
|
+
description: `${duplicateTagNames} duplicate tag names found`,
|
|
232
|
+
severity: 'critical'
|
|
233
|
+
});
|
|
234
|
+
result.isValid = false;
|
|
235
|
+
}
|
|
236
|
+
// Check for NULL values in NOT NULL columns
|
|
237
|
+
const nullInProjects = this.checkNullConstraints('projects', ['id', 'name', 'path']);
|
|
238
|
+
if (nullInProjects.length > 0) {
|
|
239
|
+
nullInProjects.forEach((column) => {
|
|
240
|
+
result.violatedConstraints.push({
|
|
241
|
+
table: 'projects',
|
|
242
|
+
constraint: `NOT NULL(${column})`,
|
|
243
|
+
description: `Found NULL values in NOT NULL column: ${column}`,
|
|
244
|
+
severity: 'critical'
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
result.isValid = false;
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
throw new Error(`Constraint validation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Attempt to repair database integrity issues
|
|
257
|
+
* Returns report of repair attempts
|
|
258
|
+
*/
|
|
259
|
+
repair() {
|
|
260
|
+
const report = this.validate();
|
|
261
|
+
report.repairAttempted = true;
|
|
262
|
+
try {
|
|
263
|
+
// Repair schema issues
|
|
264
|
+
if (report.schema.missingTables.length > 0) {
|
|
265
|
+
this.repairMissingTables(report.schema.missingTables);
|
|
266
|
+
}
|
|
267
|
+
if (report.schema.invalidColumns.length > 0) {
|
|
268
|
+
this.repairInvalidColumns(report.schema.invalidColumns);
|
|
269
|
+
}
|
|
270
|
+
if (report.schema.invalidIndexes.length > 0) {
|
|
271
|
+
this.repairMissingIndexes(report.schema.invalidIndexes);
|
|
272
|
+
}
|
|
273
|
+
// Repair constraint violations
|
|
274
|
+
if (report.constraints.orphanRecords.length > 0) {
|
|
275
|
+
this.repairOrphanRecords(report.constraints.orphanRecords);
|
|
276
|
+
}
|
|
277
|
+
if (report.constraints.violatedConstraints.length > 0) {
|
|
278
|
+
this.repairConstraintViolations(report.constraints.violatedConstraints);
|
|
279
|
+
}
|
|
280
|
+
// Re-validate after repairs
|
|
281
|
+
const revalidationReport = this.validate();
|
|
282
|
+
if (revalidationReport.isValid) {
|
|
283
|
+
report.repairSuccessful = true;
|
|
284
|
+
report.errors = [];
|
|
285
|
+
report.warnings = [];
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
report.repairSuccessful = false;
|
|
289
|
+
report.errors.push('Some issues could not be automatically repaired');
|
|
290
|
+
}
|
|
291
|
+
return report;
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
report.repairSuccessful = false;
|
|
295
|
+
report.errors.push(`Repair failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
296
|
+
return report;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Recreate missing tables
|
|
301
|
+
*/
|
|
302
|
+
repairMissingTables(missingTables) {
|
|
303
|
+
for (const tableName of missingTables) {
|
|
304
|
+
if (tableName === 'projects') {
|
|
305
|
+
this.db.execute(`
|
|
306
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
307
|
+
id TEXT PRIMARY KEY,
|
|
308
|
+
name TEXT NOT NULL,
|
|
309
|
+
path TEXT NOT NULL UNIQUE,
|
|
310
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
311
|
+
last_opened DATETIME,
|
|
312
|
+
is_favorite BOOLEAN DEFAULT 0,
|
|
313
|
+
default_tool TEXT,
|
|
314
|
+
notes TEXT
|
|
315
|
+
)
|
|
316
|
+
`);
|
|
317
|
+
}
|
|
318
|
+
else if (tableName === 'tags') {
|
|
319
|
+
this.db.execute(`
|
|
320
|
+
CREATE TABLE IF NOT EXISTS tags (
|
|
321
|
+
id TEXT PRIMARY KEY,
|
|
322
|
+
name TEXT NOT NULL UNIQUE,
|
|
323
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
324
|
+
)
|
|
325
|
+
`);
|
|
326
|
+
}
|
|
327
|
+
else if (tableName === 'project_tags') {
|
|
328
|
+
this.db.execute(`
|
|
329
|
+
CREATE TABLE IF NOT EXISTS project_tags (
|
|
330
|
+
project_id TEXT NOT NULL,
|
|
331
|
+
tag_id TEXT NOT NULL,
|
|
332
|
+
added_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
333
|
+
PRIMARY KEY (project_id, tag_id),
|
|
334
|
+
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
|
335
|
+
FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE
|
|
336
|
+
)
|
|
337
|
+
`);
|
|
338
|
+
}
|
|
339
|
+
else if (tableName === 'technologies') {
|
|
340
|
+
this.db.execute(`
|
|
341
|
+
CREATE TABLE IF NOT EXISTS technologies (
|
|
342
|
+
id TEXT PRIMARY KEY,
|
|
343
|
+
project_id TEXT NOT NULL,
|
|
344
|
+
name TEXT NOT NULL,
|
|
345
|
+
version TEXT,
|
|
346
|
+
category TEXT,
|
|
347
|
+
detected_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
348
|
+
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
|
349
|
+
)
|
|
350
|
+
`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Add missing columns to tables
|
|
356
|
+
*/
|
|
357
|
+
repairInvalidColumns(invalidColumns) {
|
|
358
|
+
// Group by table
|
|
359
|
+
const columnsByTable = invalidColumns.reduce((acc, col) => {
|
|
360
|
+
if (!acc[col.table])
|
|
361
|
+
acc[col.table] = [];
|
|
362
|
+
acc[col.table].push(col);
|
|
363
|
+
return acc;
|
|
364
|
+
}, {});
|
|
365
|
+
// Add missing columns
|
|
366
|
+
for (const [tableName, columns] of Object.entries(columnsByTable)) {
|
|
367
|
+
for (const col of columns) {
|
|
368
|
+
try {
|
|
369
|
+
const defaultValue = this.getDefaultValueForType(col.expectedType);
|
|
370
|
+
this.db.execute(`ALTER TABLE ${tableName} ADD COLUMN ${col.column} ${col.expectedType} DEFAULT ${defaultValue}`);
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
// Column might already exist, skip
|
|
374
|
+
console.warn(`Could not add column ${col.column} to ${tableName}: ${error}`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Recreate missing indexes
|
|
381
|
+
*/
|
|
382
|
+
repairMissingIndexes(missingIndexes) {
|
|
383
|
+
const indexDefinitions = {
|
|
384
|
+
idx_projects_name: 'CREATE INDEX IF NOT EXISTS idx_projects_name ON projects(name)',
|
|
385
|
+
idx_projects_path: 'CREATE INDEX IF NOT EXISTS idx_projects_path ON projects(path)',
|
|
386
|
+
idx_project_tags_project_id: 'CREATE INDEX IF NOT EXISTS idx_project_tags_project_id ON project_tags(project_id)',
|
|
387
|
+
idx_project_tags_tag_id: 'CREATE INDEX IF NOT EXISTS idx_project_tags_tag_id ON project_tags(tag_id)',
|
|
388
|
+
idx_technologies_project_id: 'CREATE INDEX IF NOT EXISTS idx_technologies_project_id ON technologies(project_id)',
|
|
389
|
+
idx_technologies_name: 'CREATE INDEX IF NOT EXISTS idx_technologies_name ON technologies(name)'
|
|
390
|
+
};
|
|
391
|
+
for (const indexName of missingIndexes) {
|
|
392
|
+
if (indexDefinitions[indexName]) {
|
|
393
|
+
this.db.execute(indexDefinitions[indexName]);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Remove orphan records
|
|
399
|
+
*/
|
|
400
|
+
repairOrphanRecords(orphanRecords) {
|
|
401
|
+
for (const orphan of orphanRecords) {
|
|
402
|
+
// Delete orphan records
|
|
403
|
+
const sql = `
|
|
404
|
+
DELETE FROM ${orphan.table}
|
|
405
|
+
WHERE ${orphan.foreignKeyColumn} NOT IN (
|
|
406
|
+
SELECT id FROM ${orphan.referencedTable}
|
|
407
|
+
)
|
|
408
|
+
`;
|
|
409
|
+
this.db.execute(sql);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Repair constraint violations
|
|
414
|
+
*/
|
|
415
|
+
repairConstraintViolations(violations) {
|
|
416
|
+
for (const violation of violations) {
|
|
417
|
+
if (violation.constraint.includes('UNIQUE')) {
|
|
418
|
+
// Handle duplicate unique values
|
|
419
|
+
if (violation.table === 'projects' && violation.constraint === 'UNIQUE(path)') {
|
|
420
|
+
this.removeDuplicateUniqueValues('projects', 'path');
|
|
421
|
+
}
|
|
422
|
+
else if (violation.table === 'tags' && violation.constraint === 'UNIQUE(name)') {
|
|
423
|
+
this.removeDuplicateUniqueValues('tags', 'name');
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
else if (violation.constraint.includes('NOT NULL')) {
|
|
427
|
+
// Handle NULL values in NOT NULL columns
|
|
428
|
+
const columnMatch = violation.constraint.match(/NOT NULL\((\w+)\)/);
|
|
429
|
+
if (columnMatch) {
|
|
430
|
+
const column = columnMatch[1];
|
|
431
|
+
this.removeRecordsWithNullColumn(violation.table, column);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Helper: Check if table exists
|
|
438
|
+
*/
|
|
439
|
+
tableExists(tableName) {
|
|
440
|
+
try {
|
|
441
|
+
const result = this.db.queryOne("SELECT COUNT(*) as count FROM sqlite_master WHERE type='table' AND name=?", [tableName]);
|
|
442
|
+
return result ? result.count > 0 : false;
|
|
443
|
+
}
|
|
444
|
+
catch {
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Helper: Get table info (columns)
|
|
450
|
+
*/
|
|
451
|
+
getTableInfo(tableName) {
|
|
452
|
+
try {
|
|
453
|
+
return this.db.query(`PRAGMA table_info(${tableName})`);
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
return [];
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Helper: Get existing indexes
|
|
461
|
+
*/
|
|
462
|
+
getExistingIndexes() {
|
|
463
|
+
try {
|
|
464
|
+
const result = this.db.query("SELECT name FROM sqlite_master WHERE type='index' AND name NOT LIKE 'sqlite_%'");
|
|
465
|
+
return result.map((idx) => idx.name);
|
|
466
|
+
}
|
|
467
|
+
catch {
|
|
468
|
+
return [];
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Helper: Check for orphan records
|
|
473
|
+
*/
|
|
474
|
+
checkOrphanRecords(table, foreignKeyColumn, referencedTable, referencedColumn) {
|
|
475
|
+
try {
|
|
476
|
+
const result = this.db.queryOne(`
|
|
477
|
+
SELECT COUNT(*) as count FROM ${table}
|
|
478
|
+
WHERE ${foreignKeyColumn} NOT IN (
|
|
479
|
+
SELECT ${referencedColumn} FROM ${referencedTable}
|
|
480
|
+
)
|
|
481
|
+
`);
|
|
482
|
+
return result?.count || 0;
|
|
483
|
+
}
|
|
484
|
+
catch {
|
|
485
|
+
return 0;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Helper: Check for duplicate unique constraint values
|
|
490
|
+
*/
|
|
491
|
+
checkDuplicateUniqueConstraint(table, column) {
|
|
492
|
+
try {
|
|
493
|
+
const result = this.db.queryOne(`
|
|
494
|
+
SELECT COUNT(*) - COUNT(DISTINCT ${column}) as count FROM ${table}
|
|
495
|
+
`);
|
|
496
|
+
return result?.count || 0;
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
return 0;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Helper: Check for NULL values in columns
|
|
504
|
+
*/
|
|
505
|
+
checkNullConstraints(table, columns) {
|
|
506
|
+
const nullColumns = [];
|
|
507
|
+
for (const column of columns) {
|
|
508
|
+
try {
|
|
509
|
+
const result = this.db.queryOne(`SELECT COUNT(*) as count FROM ${table} WHERE ${column} IS NULL`);
|
|
510
|
+
if (result && result.count > 0) {
|
|
511
|
+
nullColumns.push(column);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
catch {
|
|
515
|
+
// Skip if column doesn't exist
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return nullColumns;
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Helper: Get default value for a column type
|
|
522
|
+
*/
|
|
523
|
+
getDefaultValueForType(type) {
|
|
524
|
+
if (type.includes('TEXT') || type.includes('VARCHAR'))
|
|
525
|
+
return "''";
|
|
526
|
+
if (type.includes('DATETIME'))
|
|
527
|
+
return 'CURRENT_TIMESTAMP';
|
|
528
|
+
if (type.includes('BOOLEAN') || type.includes('INT'))
|
|
529
|
+
return '0';
|
|
530
|
+
return 'NULL';
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Helper: Remove duplicate unique values (keep first, delete rest)
|
|
534
|
+
*/
|
|
535
|
+
removeDuplicateUniqueValues(table, column) {
|
|
536
|
+
this.db.execute(`
|
|
537
|
+
DELETE FROM ${table}
|
|
538
|
+
WHERE rowid NOT IN (
|
|
539
|
+
SELECT MIN(rowid) FROM ${table}
|
|
540
|
+
GROUP BY ${column}
|
|
541
|
+
)
|
|
542
|
+
`);
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Helper: Remove records with NULL in specified column
|
|
546
|
+
*/
|
|
547
|
+
removeRecordsWithNullColumn(table, column) {
|
|
548
|
+
this.db.execute(`
|
|
549
|
+
DELETE FROM ${table}
|
|
550
|
+
WHERE ${column} IS NULL
|
|
551
|
+
`);
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Get a detailed validation summary as formatted string
|
|
555
|
+
*/
|
|
556
|
+
getValidationSummary(report) {
|
|
557
|
+
let summary = 'Database Validation Report\n';
|
|
558
|
+
summary += '===========================\n\n';
|
|
559
|
+
summary += `Status: ${report.isValid ? '✓ VALID' : '✗ INVALID'}\n`;
|
|
560
|
+
summary += `Errors: ${report.errors.length}\n`;
|
|
561
|
+
summary += `Warnings: ${report.warnings.length}\n\n`;
|
|
562
|
+
if (report.errors.length > 0) {
|
|
563
|
+
summary += 'Errors:\n';
|
|
564
|
+
report.errors.forEach((error) => {
|
|
565
|
+
summary += ` - ${error}\n`;
|
|
566
|
+
});
|
|
567
|
+
summary += '\n';
|
|
568
|
+
}
|
|
569
|
+
if (report.warnings.length > 0) {
|
|
570
|
+
summary += 'Warnings:\n';
|
|
571
|
+
report.warnings.forEach((warning) => {
|
|
572
|
+
summary += ` - ${warning}\n`;
|
|
573
|
+
});
|
|
574
|
+
summary += '\n';
|
|
575
|
+
}
|
|
576
|
+
if (report.repairAttempted) {
|
|
577
|
+
summary += `Repair Attempted: ${report.repairSuccessful ? '✓ Successful' : '✗ Failed'}\n`;
|
|
578
|
+
}
|
|
579
|
+
return summary;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
exports.DatabaseValidator = DatabaseValidator;
|
|
583
|
+
//# sourceMappingURL=DatabaseValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DatabaseValidator.js","sourceRoot":"","sources":["../../../src/infrastructure/database/DatabaseValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Infrastructure Module
|
|
3
|
+
* Exports database connection and related utilities
|
|
4
|
+
*/
|
|
5
|
+
export { DatabaseConnection } from './DatabaseConnection';
|
|
6
|
+
export type { default as Database } from 'better-sqlite3';
|
|
7
|
+
export { Migration, MigrationRunner, InitialMigration, getAllMigrations } from './migrations';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/database/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Database Infrastructure Module
|
|
4
|
+
* Exports database connection and related utilities
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getAllMigrations = exports.InitialMigration = exports.MigrationRunner = exports.DatabaseConnection = void 0;
|
|
8
|
+
var DatabaseConnection_1 = require("./DatabaseConnection");
|
|
9
|
+
Object.defineProperty(exports, "DatabaseConnection", { enumerable: true, get: function () { return DatabaseConnection_1.DatabaseConnection; } });
|
|
10
|
+
var migrations_1 = require("./migrations");
|
|
11
|
+
Object.defineProperty(exports, "MigrationRunner", { enumerable: true, get: function () { return migrations_1.MigrationRunner; } });
|
|
12
|
+
Object.defineProperty(exports, "InitialMigration", { enumerable: true, get: function () { return migrations_1.InitialMigration; } });
|
|
13
|
+
Object.defineProperty(exports, "getAllMigrations", { enumerable: true, get: function () { return migrations_1.getAllMigrations; } });
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/infrastructure/database/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAE3B,2CAA8F;AAA1E,6GAAA,eAAe,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AAAE,8GAAA,gBAAgB,OAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Migration } from './Migration';
|
|
2
|
+
/**
|
|
3
|
+
* Initial migration: Creates all base tables for Project Hub
|
|
4
|
+
* - projects: Stores project information
|
|
5
|
+
* - tags: Stores available tags
|
|
6
|
+
* - project_tags: Join table for many-to-many relationship between projects and tags
|
|
7
|
+
* - technologies: Stores detected technologies for projects
|
|
8
|
+
*/
|
|
9
|
+
export declare class InitialMigration implements Migration {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
private db;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Create all necessary tables
|
|
16
|
+
*/
|
|
17
|
+
up(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Drop all tables created by this migration
|
|
20
|
+
* WARNING: This will delete all data
|
|
21
|
+
*/
|
|
22
|
+
down(): void;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=001_initial.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"001_initial.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/database/migrations/001_initial.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,SAAS;IAChD,EAAE,SAAS;IACX,IAAI,SAAa;IACjB,OAAO,CAAC,EAAE,CAAqB;;IAM/B;;OAEG;IACH,EAAE,IAAI,IAAI;IA+EV;;;OAGG;IACH,IAAI,IAAI,IAAI;CAWb"}
|