vibecodingmachine-core 2026.1.23-1010 ā 2026.1.29-1432
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/package.json +10 -1
- package/src/database/user-database-client.js +8 -3
- package/.babelrc +0 -13
- package/ERROR_REPORTING_API.md +0 -212
- package/ERROR_REPORTING_USAGE.md +0 -380
- package/__tests__/applescript-manager-claude-fix.test.js +0 -286
- package/__tests__/provider-manager-fallback.test.js +0 -43
- package/__tests__/provider-manager-rate-limit.test.js +0 -61
- package/__tests__/requirement-2-auto-start-looping.test.js +0 -69
- package/__tests__/requirement-3-auto-start-looping.test.js +0 -69
- package/__tests__/requirement-4-auto-start-looping.test.js +0 -69
- package/__tests__/requirement-6-auto-start-looping.test.js +0 -73
- package/__tests__/requirement-7-status-tracking.test.js +0 -332
- package/__tests__/utils/git-branch-manager.test.js +0 -61
- package/jest.config.js +0 -18
- package/jest.setup.js +0 -12
- package/scripts/setup-database.js +0 -108
- package/src/health-tracking/__tests__/ide-health-tracker.test.js +0 -420
- package/src/health-tracking/__tests__/interaction-recorder.test.js +0 -392
- package/src/ide-integration/__tests__/applescript-manager-thread-closure.test.js +0 -227
- package/src/ui/StateManager.test.js +0 -0
- package/test-quota-system.js +0 -67
- package/test-requirement-stats.js +0 -66
- package/tests/health-tracking/health-reporter.test.js +0 -329
- package/tests/health-tracking/ide-health-tracker.test.js +0 -368
- package/tests/health-tracking/interaction-recorder.test.js +0 -309
|
@@ -1,332 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test suite for Requirement 7: Status tracking and logging improvements
|
|
3
|
-
*
|
|
4
|
-
* This test verifies that the file watcher properly tracks status changes
|
|
5
|
-
* and only logs requirement completion when status changes from "IN PROGRESS" to "DONE"
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
describe('Requirement 7: Status Tracking and Logging', () => {
|
|
12
|
-
let mockRequirementsContent;
|
|
13
|
-
let mockFilePath;
|
|
14
|
-
let mockMainWindow;
|
|
15
|
-
let consoleSpy;
|
|
16
|
-
|
|
17
|
-
beforeEach(() => {
|
|
18
|
-
// Mock console methods to capture logs
|
|
19
|
-
consoleSpy = {
|
|
20
|
-
log: jest.spyOn(console, 'log').mockImplementation(() => {}),
|
|
21
|
-
error: jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// Mock file system
|
|
25
|
-
jest.spyOn(fs, 'readFileSync').mockImplementation((filePath) => {
|
|
26
|
-
if (filePath === mockFilePath) {
|
|
27
|
-
return mockRequirementsContent;
|
|
28
|
-
}
|
|
29
|
-
return '';
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
jest.spyOn(fs, 'existsSync').mockReturnValue(true);
|
|
33
|
-
|
|
34
|
-
// Mock main window
|
|
35
|
-
mockMainWindow = {
|
|
36
|
-
isDestroyed: jest.fn().mockReturnValue(false),
|
|
37
|
-
webContents: {
|
|
38
|
-
send: jest.fn()
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
mockFilePath = '/test/requirements.md';
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
afterEach(() => {
|
|
46
|
-
jest.restoreAllMocks();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
describe('Status Parsing Functions', () => {
|
|
50
|
-
test('parseCurrentStatus should extract status from Current Status section', () => {
|
|
51
|
-
// Import the function (we'll need to mock the module)
|
|
52
|
-
const { parseCurrentStatus } = require('../../electron-app/src/main/file-watcher');
|
|
53
|
-
|
|
54
|
-
const content = `
|
|
55
|
-
# Requirements
|
|
56
|
-
|
|
57
|
-
## š¦ Current Status
|
|
58
|
-
|
|
59
|
-
IN PROGRESS
|
|
60
|
-
|
|
61
|
-
## Other Section
|
|
62
|
-
Some other content
|
|
63
|
-
`;
|
|
64
|
-
|
|
65
|
-
const status = parseCurrentStatus(content);
|
|
66
|
-
expect(status).toBe('IN PROGRESS');
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test('parseCurrentStatus should handle empty status section', () => {
|
|
70
|
-
const { parseCurrentStatus } = require('../../electron-app/src/main/file-watcher');
|
|
71
|
-
|
|
72
|
-
const content = `
|
|
73
|
-
# Requirements
|
|
74
|
-
|
|
75
|
-
## š¦ Current Status
|
|
76
|
-
|
|
77
|
-
## Other Section
|
|
78
|
-
Some other content
|
|
79
|
-
`;
|
|
80
|
-
|
|
81
|
-
const status = parseCurrentStatus(content);
|
|
82
|
-
expect(status).toBe('');
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
test('extractCurrentRequirementDetails should extract requirement from Current In Progress section', () => {
|
|
86
|
-
const { extractCurrentRequirementDetails } = require('../../electron-app/src/main/file-watcher');
|
|
87
|
-
|
|
88
|
-
const content = `
|
|
89
|
-
# Requirements
|
|
90
|
-
|
|
91
|
-
## šØ Current In Progress Requirement
|
|
92
|
-
|
|
93
|
-
7: Update PROCESSES.md and the electron app if needed so that when the electron app is watching for REQUIREMENTS file updates, it does not log that a requirement was done until it is done, at which time the REQUIREMENT file "Current Status" changes from "IN PROGRESS" to "DONE".
|
|
94
|
-
|
|
95
|
-
## Other Section
|
|
96
|
-
Some other content
|
|
97
|
-
`;
|
|
98
|
-
|
|
99
|
-
const details = extractCurrentRequirementDetails(content);
|
|
100
|
-
expect(details).toContain('7: Update PROCESSES.md');
|
|
101
|
-
expect(details).toContain('IN PROGRESS');
|
|
102
|
-
expect(details).toContain('DONE');
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
describe('Status Change Detection', () => {
|
|
107
|
-
test('should log requirement completion when status changes from IN PROGRESS to DONE', () => {
|
|
108
|
-
const { handleRequirementsFileChange } = require('../../electron-app/src/main/file-watcher');
|
|
109
|
-
|
|
110
|
-
// First call - IN PROGRESS status
|
|
111
|
-
mockRequirementsContent = `
|
|
112
|
-
# Requirements
|
|
113
|
-
|
|
114
|
-
## š¦ Current Status
|
|
115
|
-
|
|
116
|
-
IN PROGRESS
|
|
117
|
-
|
|
118
|
-
## šØ Current In Progress Requirement
|
|
119
|
-
|
|
120
|
-
7: Update PROCESSES.md and the electron app if needed so that when the electron app is watching for REQUIREMENTS file updates, it does not log that a requirement was done until it is done, at which time the REQUIREMENT file "Current Status" changes from "IN PROGRESS" to "DONE".
|
|
121
|
-
|
|
122
|
-
## Other Section
|
|
123
|
-
Some other content
|
|
124
|
-
`;
|
|
125
|
-
|
|
126
|
-
// Mock the module's internal state
|
|
127
|
-
const fileWatcherModule = require('../../electron-app/src/main/file-watcher');
|
|
128
|
-
fileWatcherModule.lastRequirementsContent = '';
|
|
129
|
-
fileWatcherModule.lastStatus = '';
|
|
130
|
-
fileWatcherModule.progressDots = '';
|
|
131
|
-
|
|
132
|
-
// First call - should set up initial state
|
|
133
|
-
handleRequirementsFileChange(mockFilePath, mockMainWindow);
|
|
134
|
-
|
|
135
|
-
// Second call - DONE status
|
|
136
|
-
mockRequirementsContent = `
|
|
137
|
-
# Requirements
|
|
138
|
-
|
|
139
|
-
## š¦ Current Status
|
|
140
|
-
|
|
141
|
-
DONE
|
|
142
|
-
|
|
143
|
-
## šØ Current In Progress Requirement
|
|
144
|
-
|
|
145
|
-
7: Update PROCESSES.md and the electron app if needed so that when the electron app is watching for REQUIREMENTS file updates, it does not log that a requirement was done until it is done, at which time the REQUIREMENT file "Current Status" changes from "IN PROGRESS" to "DONE".
|
|
146
|
-
|
|
147
|
-
## Other Section
|
|
148
|
-
Some other content
|
|
149
|
-
`;
|
|
150
|
-
|
|
151
|
-
// Second call - should detect status change and log completion
|
|
152
|
-
handleRequirementsFileChange(mockFilePath, mockMainWindow);
|
|
153
|
-
|
|
154
|
-
// Verify that completion was logged
|
|
155
|
-
expect(consoleSpy.log).toHaveBeenCalledWith('š ===== REQUIREMENT COMPLETED =====');
|
|
156
|
-
expect(consoleSpy.log).toHaveBeenCalledWith('šÆ Status changed from "IN PROGRESS" to "DONE" - logging requirement completion');
|
|
157
|
-
expect(consoleSpy.log).toHaveBeenCalledWith('š ===== COMPLETED REQUIREMENT DETAILS =====');
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
test('should show progress dots for IN PROGRESS status', () => {
|
|
161
|
-
const { handleRequirementsFileChange } = require('../../electron-app/src/main/file-watcher');
|
|
162
|
-
|
|
163
|
-
mockRequirementsContent = `
|
|
164
|
-
# Requirements
|
|
165
|
-
|
|
166
|
-
## š¦ Current Status
|
|
167
|
-
|
|
168
|
-
IN PROGRESS
|
|
169
|
-
|
|
170
|
-
## Other Section
|
|
171
|
-
Some other content
|
|
172
|
-
`;
|
|
173
|
-
|
|
174
|
-
// Mock the module's internal state
|
|
175
|
-
const fileWatcherModule = require('../../electron-app/src/main/file-watcher');
|
|
176
|
-
fileWatcherModule.lastRequirementsContent = '';
|
|
177
|
-
fileWatcherModule.lastStatus = '';
|
|
178
|
-
fileWatcherModule.progressDots = '';
|
|
179
|
-
|
|
180
|
-
handleRequirementsFileChange(mockFilePath, mockMainWindow);
|
|
181
|
-
|
|
182
|
-
expect(consoleSpy.log).toHaveBeenCalledWith('ā³ Progress update: .');
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test('should show progress dots for other status changes', () => {
|
|
186
|
-
const { handleRequirementsFileChange } = require('../../electron-app/src/main/file-watcher');
|
|
187
|
-
|
|
188
|
-
mockRequirementsContent = `
|
|
189
|
-
# Requirements
|
|
190
|
-
|
|
191
|
-
## š¦ Current Status
|
|
192
|
-
|
|
193
|
-
READY FOR NEXT REQUIREMENT
|
|
194
|
-
|
|
195
|
-
## Other Section
|
|
196
|
-
Some other content
|
|
197
|
-
`;
|
|
198
|
-
|
|
199
|
-
// Mock the module's internal state
|
|
200
|
-
const fileWatcherModule = require('../../electron-app/src/main/file-watcher');
|
|
201
|
-
fileWatcherModule.lastRequirementsContent = '';
|
|
202
|
-
fileWatcherModule.lastStatus = '';
|
|
203
|
-
fileWatcherModule.progressDots = '';
|
|
204
|
-
|
|
205
|
-
handleRequirementsFileChange(mockFilePath, mockMainWindow);
|
|
206
|
-
|
|
207
|
-
expect(consoleSpy.log).toHaveBeenCalledWith('š File update: .');
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
describe('Integration with Existing Functionality', () => {
|
|
212
|
-
test('should still send requirements-response event to UI', () => {
|
|
213
|
-
const { handleRequirementsFileChange } = require('../../electron-app/src/main/file-watcher');
|
|
214
|
-
|
|
215
|
-
mockRequirementsContent = `
|
|
216
|
-
# Requirements
|
|
217
|
-
|
|
218
|
-
## RESPONSE FROM LAST CHAT
|
|
219
|
-
|
|
220
|
-
### ONE LINE STATUS: Test status
|
|
221
|
-
### ONE LINE SUMMARY: Test summary
|
|
222
|
-
### MULTILINE DETAILS:
|
|
223
|
-
Test details
|
|
224
|
-
|
|
225
|
-
## š¦ Current Status
|
|
226
|
-
|
|
227
|
-
IN PROGRESS
|
|
228
|
-
|
|
229
|
-
## Other Section
|
|
230
|
-
Some other content
|
|
231
|
-
`;
|
|
232
|
-
|
|
233
|
-
// Mock the module's internal state
|
|
234
|
-
const fileWatcherModule = require('../../electron-app/src/main/file-watcher');
|
|
235
|
-
fileWatcherModule.lastRequirementsContent = '';
|
|
236
|
-
fileWatcherModule.lastStatus = '';
|
|
237
|
-
fileWatcherModule.progressDots = '';
|
|
238
|
-
|
|
239
|
-
handleRequirementsFileChange(mockFilePath, mockMainWindow);
|
|
240
|
-
|
|
241
|
-
// Verify that the UI event was still sent
|
|
242
|
-
expect(mockMainWindow.webContents.send).toHaveBeenCalledWith('requirements-response', expect.objectContaining({
|
|
243
|
-
content: expect.any(String),
|
|
244
|
-
timestamp: expect.any(String),
|
|
245
|
-
filePath: mockFilePath,
|
|
246
|
-
parsedResponse: expect.any(Object)
|
|
247
|
-
}));
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
test('should still send requirements-file-changed event for auto mode', () => {
|
|
251
|
-
const { handleRequirementsFileChange } = require('../../electron-app/src/main/file-watcher');
|
|
252
|
-
|
|
253
|
-
mockRequirementsContent = `
|
|
254
|
-
# Requirements
|
|
255
|
-
|
|
256
|
-
## š¦ Current Status
|
|
257
|
-
|
|
258
|
-
IN PROGRESS
|
|
259
|
-
|
|
260
|
-
## Other Section
|
|
261
|
-
Some other content
|
|
262
|
-
`;
|
|
263
|
-
|
|
264
|
-
// Mock the module's internal state
|
|
265
|
-
const fileWatcherModule = require('../../electron-app/src/main/file-watcher');
|
|
266
|
-
fileWatcherModule.lastRequirementsContent = '';
|
|
267
|
-
fileWatcherModule.lastStatus = '';
|
|
268
|
-
fileWatcherModule.progressDots = '';
|
|
269
|
-
|
|
270
|
-
handleRequirementsFileChange(mockFilePath, mockMainWindow);
|
|
271
|
-
|
|
272
|
-
// Verify that the auto mode event was still sent
|
|
273
|
-
expect(mockMainWindow.webContents.send).toHaveBeenCalledWith('requirements-file-changed');
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
describe('Error Handling', () => {
|
|
278
|
-
test('should handle errors in status parsing gracefully', () => {
|
|
279
|
-
const { parseCurrentStatus } = require('../../electron-app/src/main/file-watcher');
|
|
280
|
-
|
|
281
|
-
// Test with malformed content
|
|
282
|
-
const malformedContent = 'Invalid content without proper sections';
|
|
283
|
-
|
|
284
|
-
const status = parseCurrentStatus(malformedContent);
|
|
285
|
-
expect(status).toBe('');
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
test('should handle errors in requirement details extraction gracefully', () => {
|
|
289
|
-
const { extractCurrentRequirementDetails } = require('../../electron-app/src/main/file-watcher');
|
|
290
|
-
|
|
291
|
-
// Test with malformed content
|
|
292
|
-
const malformedContent = 'Invalid content without proper sections';
|
|
293
|
-
|
|
294
|
-
const details = extractCurrentRequirementDetails(malformedContent);
|
|
295
|
-
expect(details).toBe('');
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
describe('Progress Dots Management', () => {
|
|
300
|
-
test('should reset progress dots when requirement is completed', () => {
|
|
301
|
-
const { handleRequirementsFileChange } = require('../../electron-app/src/main/file-watcher');
|
|
302
|
-
|
|
303
|
-
// Mock the module's internal state with existing progress dots
|
|
304
|
-
const fileWatcherModule = require('../../electron-app/src/main/file-watcher');
|
|
305
|
-
fileWatcherModule.lastRequirementsContent = 'previous content';
|
|
306
|
-
fileWatcherModule.lastStatus = 'IN PROGRESS';
|
|
307
|
-
fileWatcherModule.progressDots = '...';
|
|
308
|
-
|
|
309
|
-
// Change to DONE status
|
|
310
|
-
mockRequirementsContent = `
|
|
311
|
-
# Requirements
|
|
312
|
-
|
|
313
|
-
## š¦ Current Status
|
|
314
|
-
|
|
315
|
-
DONE
|
|
316
|
-
|
|
317
|
-
## šØ Current In Progress Requirement
|
|
318
|
-
|
|
319
|
-
7: Test requirement
|
|
320
|
-
|
|
321
|
-
## Other Section
|
|
322
|
-
Some other content
|
|
323
|
-
`;
|
|
324
|
-
|
|
325
|
-
handleRequirementsFileChange(mockFilePath, mockMainWindow);
|
|
326
|
-
|
|
327
|
-
// Verify that progress dots were reset
|
|
328
|
-
expect(consoleSpy.log).toHaveBeenCalledWith('š ===== REQUIREMENT COMPLETED =====');
|
|
329
|
-
// The progress dots should be reset internally (we can't directly test this without exposing the variable)
|
|
330
|
-
});
|
|
331
|
-
});
|
|
332
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const { execSync } = require('child_process');
|
|
2
|
-
const fs = require('fs-extra');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const os = require('os');
|
|
5
|
-
const { isGitRepo, getCurrentBranch, hasUncommittedChanges } = require('../../src/utils/git-branch-manager');
|
|
6
|
-
|
|
7
|
-
describe('git-branch-manager', () => {
|
|
8
|
-
let tempRepoPath;
|
|
9
|
-
|
|
10
|
-
beforeEach(async () => {
|
|
11
|
-
tempRepoPath = path.join(os.tmpdir(), `vcm-test-repo-${Date.now()}`);
|
|
12
|
-
await fs.ensureDir(tempRepoPath);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterEach(async () => {
|
|
16
|
-
await fs.remove(tempRepoPath);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const initRepo = () => {
|
|
20
|
-
execSync('git init', { cwd: tempRepoPath, stdio: 'ignore' });
|
|
21
|
-
execSync('git config user.email "test@example.com"', { cwd: tempRepoPath, stdio: 'ignore' });
|
|
22
|
-
execSync('git config user.name "Test User"', { cwd: tempRepoPath, stdio: 'ignore' });
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
test('isGitRepo identifies git repositories', () => {
|
|
26
|
-
expect(isGitRepo(tempRepoPath)).toBe(false);
|
|
27
|
-
initRepo();
|
|
28
|
-
expect(isGitRepo(tempRepoPath)).toBe(true);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('getCurrentBranch returns the current branch name', async () => {
|
|
32
|
-
initRepo();
|
|
33
|
-
// Must commit something for HEAD to exist
|
|
34
|
-
await fs.writeFile(path.join(tempRepoPath, 'initial.txt'), 'init');
|
|
35
|
-
execSync('git add .', { cwd: tempRepoPath, stdio: 'ignore' });
|
|
36
|
-
execSync('git commit -m "initial commit"', { cwd: tempRepoPath, stdio: 'ignore' });
|
|
37
|
-
|
|
38
|
-
const branch = getCurrentBranch(tempRepoPath);
|
|
39
|
-
expect(branch).toMatch(/^(main|master)$/);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('hasUncommittedChanges detects dirty repository', async () => {
|
|
43
|
-
initRepo();
|
|
44
|
-
// Should be false initially (even if empty)
|
|
45
|
-
expect(hasUncommittedChanges(tempRepoPath)).toBe(false);
|
|
46
|
-
|
|
47
|
-
// Create a file
|
|
48
|
-
await fs.writeFile(path.join(tempRepoPath, 'test.txt'), 'hello');
|
|
49
|
-
// Untracked file counts as uncommitted change
|
|
50
|
-
expect(hasUncommittedChanges(tempRepoPath)).toBe(true);
|
|
51
|
-
|
|
52
|
-
// Commit it
|
|
53
|
-
execSync('git add .', { cwd: tempRepoPath, stdio: 'ignore' });
|
|
54
|
-
execSync('git commit -m "initial commit"', { cwd: tempRepoPath, stdio: 'ignore' });
|
|
55
|
-
expect(hasUncommittedChanges(tempRepoPath)).toBe(false);
|
|
56
|
-
|
|
57
|
-
// Modify it
|
|
58
|
-
await fs.appendFile(path.join(tempRepoPath, 'test.txt'), ' world');
|
|
59
|
-
expect(hasUncommittedChanges(tempRepoPath)).toBe(true);
|
|
60
|
-
});
|
|
61
|
-
});
|
package/jest.config.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
testEnvironment: 'node',
|
|
3
|
-
testMatch: ['**/__tests__/**/*.test.js'],
|
|
4
|
-
collectCoverageFrom: [
|
|
5
|
-
'src/**/*.js',
|
|
6
|
-
'!src/**/*.test.js',
|
|
7
|
-
'!src/**/__tests__/**'
|
|
8
|
-
],
|
|
9
|
-
coverageDirectory: 'coverage',
|
|
10
|
-
coverageReporters: ['text', 'lcov', 'html'],
|
|
11
|
-
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
|
|
12
|
-
moduleNameMapper: {
|
|
13
|
-
'^@/(.*)$': '<rootDir>/src/$1'
|
|
14
|
-
},
|
|
15
|
-
transform: {
|
|
16
|
-
'^.+\\.js$': 'babel-jest'
|
|
17
|
-
}
|
|
18
|
-
};
|
package/jest.setup.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Jest setup file for core package
|
|
2
|
-
// Global test setup and configuration
|
|
3
|
-
|
|
4
|
-
// Mock console methods to reduce noise in tests
|
|
5
|
-
global.console = {
|
|
6
|
-
...console,
|
|
7
|
-
log: jest.fn(),
|
|
8
|
-
debug: jest.fn(),
|
|
9
|
-
info: jest.fn(),
|
|
10
|
-
warn: jest.fn(),
|
|
11
|
-
error: jest.fn()
|
|
12
|
-
};
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Database Setup Script for VibeCodingMachine Enhanced User Tracking
|
|
5
|
-
*
|
|
6
|
-
* This script creates the necessary DynamoDB tables for the enhanced
|
|
7
|
-
* user tracking system.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const DatabaseMigrations = require('../src/database/migrations')
|
|
11
|
-
|
|
12
|
-
async function main() {
|
|
13
|
-
console.log('š VibeCodingMachine Database Setup')
|
|
14
|
-
console.log('=====================================\n')
|
|
15
|
-
|
|
16
|
-
const migrations = new DatabaseMigrations()
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
// Check current table status
|
|
20
|
-
console.log('š Checking current database status...')
|
|
21
|
-
const tableStatuses = await migrations.getAllTableStatus()
|
|
22
|
-
|
|
23
|
-
console.log('\nCurrent Table Status:')
|
|
24
|
-
tableStatuses.forEach(status => {
|
|
25
|
-
const statusIcon = status.status === 'ACTIVE' ? 'ā
' :
|
|
26
|
-
status.status === 'NOT_FOUND' ? 'ā' : 'ā³'
|
|
27
|
-
console.log(` ${statusIcon} ${status.name}: ${status.status}`)
|
|
28
|
-
if (status.itemCount !== undefined) {
|
|
29
|
-
console.log(` Items: ${status.itemCount}, Size: ${Math.round(status.sizeBytes / 1024)} KB`)
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
console.log('\nš Running database migrations...')
|
|
34
|
-
await migrations.runMigrations()
|
|
35
|
-
|
|
36
|
-
// Check final status
|
|
37
|
-
console.log('\nš Final database status...')
|
|
38
|
-
const finalStatuses = await migrations.getAllTableStatus()
|
|
39
|
-
|
|
40
|
-
console.log('\nFinal Table Status:')
|
|
41
|
-
finalStatuses.forEach(status => {
|
|
42
|
-
const statusIcon = status.status === 'ACTIVE' ? 'ā
' :
|
|
43
|
-
status.status === 'CREATING' ? 'ā³' : 'ā'
|
|
44
|
-
console.log(` ${statusIcon} ${status.name}: ${status.status}`)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
console.log('\nš Database setup completed successfully!')
|
|
48
|
-
console.log('\nNext steps:')
|
|
49
|
-
console.log('1. Update your application environment variables with AWS credentials')
|
|
50
|
-
console.log('2. Test the user registration flow')
|
|
51
|
-
console.log('3. Deploy the admin dashboard')
|
|
52
|
-
console.log('4. Configure compliance policies')
|
|
53
|
-
|
|
54
|
-
} catch (error) {
|
|
55
|
-
console.error('\nā Database setup failed:', error.message)
|
|
56
|
-
console.error('\nTroubleshooting:')
|
|
57
|
-
console.error('1. Check your AWS credentials and permissions')
|
|
58
|
-
console.error('2. Ensure you have DynamoDB access in your AWS region')
|
|
59
|
-
console.error('3. Verify your AWS region is set correctly')
|
|
60
|
-
console.error('4. Check for any existing tables with the same names')
|
|
61
|
-
process.exit(1)
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Handle command line arguments
|
|
66
|
-
const args = process.argv.slice(2)
|
|
67
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
68
|
-
console.log('VibeCodingMachine Database Setup')
|
|
69
|
-
console.log('')
|
|
70
|
-
console.log('Usage: node setup-database.js [options]')
|
|
71
|
-
console.log('')
|
|
72
|
-
console.log('Options:')
|
|
73
|
-
console.log(' --help, -h Show this help message')
|
|
74
|
-
console.log(' --status Show current table status only')
|
|
75
|
-
console.log('')
|
|
76
|
-
console.log('Environment Variables:')
|
|
77
|
-
console.log(' AWS_REGION AWS region (default: us-east-1)')
|
|
78
|
-
console.log(' AWS_ACCESS_KEY_ID AWS access key')
|
|
79
|
-
console.log(' AWS_SECRET_ACCESS_KEY AWS secret key')
|
|
80
|
-
console.log('')
|
|
81
|
-
console.log('Required AWS Permissions:')
|
|
82
|
-
console.log(' - dynamodb:CreateTable')
|
|
83
|
-
console.log(' - dynamodb:DescribeTable')
|
|
84
|
-
console.log(' - dynamodb:ListTables')
|
|
85
|
-
process.exit(0)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (args.includes('--status')) {
|
|
89
|
-
// Just show status, don't run migrations
|
|
90
|
-
const migrations = new DatabaseMigrations()
|
|
91
|
-
migrations.getAllTableStatus().then(statuses => {
|
|
92
|
-
console.log('Current Table Status:')
|
|
93
|
-
statuses.forEach(status => {
|
|
94
|
-
const statusIcon = status.status === 'ACTIVE' ? 'ā
' :
|
|
95
|
-
status.status === 'NOT_FOUND' ? 'ā' : 'ā³'
|
|
96
|
-
console.log(` ${statusIcon} ${status.name}: ${status.status}`)
|
|
97
|
-
if (status.itemCount !== undefined) {
|
|
98
|
-
console.log(` Items: ${status.itemCount}, Size: ${Math.round(status.sizeBytes / 1024)} KB`)
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
}).catch(error => {
|
|
102
|
-
console.error('Error checking table status:', error.message)
|
|
103
|
-
process.exit(1)
|
|
104
|
-
})
|
|
105
|
-
} else {
|
|
106
|
-
// Run full setup
|
|
107
|
-
main()
|
|
108
|
-
}
|