@sun-asterisk/impact-analyzer 1.0.3 → 1.0.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.
@@ -0,0 +1,593 @@
1
+ # Task 002: Database Impact Detector - Spec-Driven Implementation
2
+
3
+ **Status:** 📋 TODO
4
+ **Priority:** 🔴 HIGH
5
+ **Assignee:** AI Agent
6
+ **Created:** 2025-12-25
7
+
8
+ ---
9
+
10
+ ## 📝 Overview
11
+
12
+ Implement a **spec-driven database impact detector** that identifies affected database tables and operations from code changes. This task focuses on **table change detection** using the existing specification as the single source of truth.
13
+
14
+ ## 🎯 What is Spec-Driven Development?
15
+
16
+ **Spec-Driven Development (SDD)** is a methodology where:
17
+
18
+ 1. **Specification First** - Write detailed functional requirements BEFORE coding
19
+ 2. **Spec as Contract** - The spec defines expected behavior, inputs, outputs
20
+ 3. **Code Follows Spec** - Implementation must match spec exactly
21
+ 4. **Spec as Test Oracle** - Verification checks if code meets spec requirements
22
+
23
+ ### Why Spec-Driven?
24
+
25
+ ✅ **Clarity** - Everyone knows what to build
26
+ ✅ **Quality** - Requirements are clear before coding
27
+ ✅ **Testability** - Spec defines expected outputs
28
+ ✅ **Maintainability** - Spec documents intent
29
+ ✅ **AI-Friendly** - LLMs can generate code from clear specs
30
+
31
+ ### SDD Workflow
32
+
33
+ ```
34
+ ┌─────────────────┐
35
+ │ 1. Read Spec │ ← Start here
36
+ └────────┬────────┘
37
+
38
+ ┌─────────────────┐
39
+ │ 2. Understand │ ← What's required?
40
+ │ Requirements │
41
+ └────────┬────────┘
42
+
43
+ ┌─────────────────┐
44
+ │ 3. Design Code │ ← Plan implementation
45
+ │ Structure │
46
+ └────────┬────────┘
47
+
48
+ ┌─────────────────┐
49
+ │ 4. Implement │ ← Code according to spec
50
+ │ Features │
51
+ └────────┬────────┘
52
+
53
+ ┌─────────────────┐
54
+ │ 5. Verify │ ← Check against spec
55
+ │ Against Spec │
56
+ └────────┬────────┘
57
+
58
+ ┌─────────────────┐
59
+ │ 6. Update Spec │ ← If requirements change
60
+ │ if Needed │
61
+ └─────────────────┘
62
+ ```
63
+
64
+ ## 📚 Reference Specification
65
+
66
+ **Location:** `.specify/specs/features/database-impact-detection.md`
67
+
68
+ **Key Requirements from Spec:**
69
+
70
+ | Requirement | Description | Priority |
71
+ |------------|-------------|----------|
72
+ | **FR-001** | Detect Entity/Model Changes | CRITICAL |
73
+ | **FR-002** | Extract Table Names | CRITICAL |
74
+ | **FR-003** | Detect Repository/DAO Changes | HIGH |
75
+ | **FR-004** | Classify Impact Type | HIGH |
76
+ | **FR-005** | Identify CRUD Operations | MEDIUM |
77
+ | **FR-006** | Generate Database Report | CRITICAL |
78
+
79
+ ## 🎯 Goals - Table Change Detection Focus
80
+
81
+ ### Primary Goal
82
+ **Detect which database tables are affected when code changes occur**
83
+
84
+ ### Specific Detection Targets
85
+
86
+ 1. **Entity Definition Changes** (FR-001)
87
+ - New columns added to entity
88
+ - Existing columns modified
89
+ - Relations added/removed
90
+ - Entity class renamed
91
+
92
+ 2. **Table Name Identification** (FR-002)
93
+ - Extract from `@Entity('table_name')`
94
+ - Extract from `@Entity({ name: 'table_name' })`
95
+ - Convert class name to snake_case if not specified
96
+
97
+ 3. **Repository Method Changes** (FR-003)
98
+ - Changes in repository files
99
+ - Changes in methods that call repository
100
+ - Track call chain: Service → Repository → Table
101
+
102
+ 4. **Operation Detection** (FR-005)
103
+ - Identify INSERT operations (save, create, insert)
104
+ - Identify UPDATE operations (update, merge)
105
+ - Identify DELETE operations (delete, remove, softDelete)
106
+ - Identify SELECT operations (find, findOne, findBy)
107
+
108
+ ## 📋 Implementation Tasks
109
+
110
+ ### Phase 1: Spec Analysis ✅
111
+
112
+ - [x] Read database impact detection spec
113
+ - [x] Understand all functional requirements
114
+ - [x] Identify output schema requirements
115
+ - [x] List all ORM patterns to support (TypeORM, Sequelize)
116
+
117
+ ### Phase 2: Current Implementation Review
118
+
119
+ - [ ] Audit existing `core/detectors/database-detector.js`
120
+ - [ ] List what's already implemented
121
+ - [ ] Identify gaps vs. specification
122
+ - [ ] Document what needs to be added/changed
123
+
124
+ **Audit Checklist:**
125
+ ```javascript
126
+ // Check if current code implements:
127
+ ✓ Entity change detection
128
+ ✓ Table name extraction
129
+ ✓ Repository method tracking
130
+ ✓ CRUD operation identification
131
+ ? Output matches spec schema
132
+ ? Severity classification
133
+ ? All ORM patterns supported
134
+ ```
135
+
136
+ ### Phase 3: Implement Table Detection (Core Feature)
137
+
138
+ #### 3.1 Entity Change Detection
139
+
140
+ **Spec Requirement:** FR-001
141
+
142
+ **Implementation:**
143
+ ```javascript
144
+ /**
145
+ * Detect changes to entity/model files
146
+ * @param {ChangedFile[]} changedFiles
147
+ * @returns {EntityChange[]}
148
+ */
149
+ detectEntityChanges(changedFiles) {
150
+ const entityChanges = [];
151
+
152
+ for (const file of changedFiles) {
153
+ // Check if file is an entity
154
+ if (this.isEntityFile(file)) {
155
+ const change = this.analyzeEntityChange(file);
156
+ entityChanges.push(change);
157
+ }
158
+ }
159
+
160
+ return entityChanges;
161
+ }
162
+
163
+ isEntityFile(file) {
164
+ // Check for:
165
+ // - @Entity() decorator
166
+ // - extends Model
167
+ // - .entity.ts extension
168
+ // - /entities/ in path
169
+ }
170
+ ```
171
+
172
+ **Acceptance Criteria:**
173
+ - [ ] Detects TypeORM entities with @Entity decorator
174
+ - [ ] Detects Sequelize models with @Table decorator
175
+ - [ ] Identifies entity files by naming convention
176
+ - [ ] Extracts changed properties/columns
177
+
178
+ #### 3.2 Table Name Extraction
179
+
180
+ **Spec Requirement:** FR-002
181
+
182
+ **Implementation:**
183
+ ```javascript
184
+ /**
185
+ * Extract database table name from entity
186
+ * @param {string} entityCode - Entity class code
187
+ * @param {string} className - Entity class name
188
+ * @returns {string} Table name in snake_case
189
+ */
190
+ extractTableName(entityCode, className) {
191
+ // Priority order:
192
+ // 1. Explicit: @Entity('users')
193
+ // 2. Options: @Entity({ name: 'users' })
194
+ // 3. Convert className to snake_case
195
+
196
+ const explicitMatch = entityCode.match(/@Entity\s*\(\s*['"](\w+)['"]/);
197
+ if (explicitMatch) return explicitMatch[1];
198
+
199
+ const optionsMatch = entityCode.match(/@Entity\s*\(\s*\{.*name:\s*['"](\w+)['"]/);
200
+ if (optionsMatch) return optionsMatch[1];
201
+
202
+ return this.classNameToTableName(className);
203
+ }
204
+
205
+ classNameToTableName(className) {
206
+ // Convert: UserProfile → user_profile
207
+ return className
208
+ .replace(/Entity$/, '') // Remove "Entity" suffix
209
+ .replace(/([A-Z])/g, '_$1') // Add underscore before capitals
210
+ .toLowerCase()
211
+ .replace(/^_/, ''); // Remove leading underscore
212
+ }
213
+ ```
214
+
215
+ **Acceptance Criteria:**
216
+ - [ ] Extracts explicit table names from @Entity('name')
217
+ - [ ] Extracts from @Entity({ name: 'name' })
218
+ - [ ] Converts class names correctly: UserProfile → user_profile
219
+ - [ ] Handles Entity suffix removal
220
+
221
+ #### 3.3 Repository Method Detection
222
+
223
+ **Spec Requirement:** FR-003
224
+
225
+ **Implementation:**
226
+ ```javascript
227
+ /**
228
+ * Find repository methods affected by changes
229
+ * Uses method call graph to trace: Change → Service → Repository
230
+ * @param {MethodChange[]} changedMethods
231
+ * @returns {RepositoryMethod[]}
232
+ */
233
+ findAffectedRepositoryMethods(changedMethods) {
234
+ const repoMethods = [];
235
+ const visited = new Set();
236
+
237
+ for (const method of changedMethods) {
238
+ // Traverse call graph upward
239
+ const repos = this.traceToRepository(method, visited);
240
+ repoMethods.push(...repos);
241
+ }
242
+
243
+ return this.deduplicateRepositoryMethods(repoMethods);
244
+ }
245
+
246
+ traceToRepository(method, visited, depth = 0) {
247
+ if (depth > 10 || visited.has(method.key)) return [];
248
+ visited.add(method.key);
249
+
250
+ // Check if this is a repository
251
+ if (this.isRepositoryMethod(method)) {
252
+ return [method];
253
+ }
254
+
255
+ // Get callers and continue tracing
256
+ const callers = this.methodCallGraph.getCallers(method);
257
+ const repos = [];
258
+
259
+ for (const caller of callers) {
260
+ repos.push(...this.traceToRepository(caller, visited, depth + 1));
261
+ }
262
+
263
+ return repos;
264
+ }
265
+
266
+ isRepositoryMethod(method) {
267
+ return (
268
+ method.file?.includes('/repository/') ||
269
+ method.file?.includes('.repository.') ||
270
+ method.className?.includes('Repository')
271
+ );
272
+ }
273
+ ```
274
+
275
+ **Acceptance Criteria:**
276
+ - [ ] Traces changes to repository methods
277
+ - [ ] Handles deep call chains (Service → Service → Repository)
278
+ - [ ] Prevents infinite loops with visited tracking
279
+ - [ ] Identifies repository by file path and class name
280
+
281
+ #### 3.4 CRUD Operation Detection
282
+
283
+ **Spec Requirement:** FR-005
284
+
285
+ **Implementation:**
286
+ ```javascript
287
+ /**
288
+ * Identify database operations from code changes
289
+ * @param {string} diff - Git diff of changed code
290
+ * @returns {DbOperation[]}
291
+ */
292
+ detectOperations(diff) {
293
+ const operations = [];
294
+
295
+ // TypeORM operation patterns
296
+ const operationMap = {
297
+ 'insert': 'INSERT',
298
+ 'save': 'INSERT/UPDATE',
299
+ 'create': 'INSERT',
300
+ 'update': 'UPDATE',
301
+ 'merge': 'UPDATE',
302
+ 'delete': 'DELETE',
303
+ 'remove': 'DELETE',
304
+ 'softDelete': 'SOFT_DELETE',
305
+ 'find': 'SELECT',
306
+ 'findOne': 'SELECT',
307
+ 'findBy': 'SELECT',
308
+ };
309
+
310
+ // Scan added lines for operations
311
+ const addedLines = this.extractAddedLines(diff);
312
+
313
+ for (const line of addedLines) {
314
+ for (const [method, opType] of Object.entries(operationMap)) {
315
+ if (line.includes(`.${method}(`)) {
316
+ operations.push({
317
+ type: opType,
318
+ method: method,
319
+ line: line.trim()
320
+ });
321
+ }
322
+ }
323
+ }
324
+
325
+ return operations;
326
+ }
327
+ ```
328
+
329
+ **Acceptance Criteria:**
330
+ - [ ] Detects INSERT operations (save, create, insert)
331
+ - [ ] Detects UPDATE operations (update, merge)
332
+ - [ ] Detects DELETE operations (delete, remove)
333
+ - [ ] Detects SELECT operations (find, findOne)
334
+ - [ ] Only analyzes added lines (+) in diff
335
+
336
+ ### Phase 4: Output Format (Match Spec)
337
+
338
+ **Spec Requirement:** FR-006
339
+
340
+ **Required Output Schema:**
341
+ ```javascript
342
+ {
343
+ tableName: string, // snake_case table name
344
+ modelName: string, // Entity class name
345
+ modelPath: string, // File path to entity
346
+ impactType: 'schema' | 'query' | 'relation' | 'migration',
347
+ operations: ('SELECT'|'INSERT'|'UPDATE'|'DELETE')[],
348
+ changeSource: FileChange,
349
+ severity: 'low' | 'medium' | 'high' | 'critical'
350
+ }
351
+ ```
352
+
353
+ **Implementation:**
354
+ ```javascript
355
+ /**
356
+ * Format database impact according to spec
357
+ * @param {Object} databaseChanges - Raw detected changes
358
+ * @returns {DatabaseImpact[]} - Spec-compliant output
359
+ */
360
+ formatDatabaseImpact(databaseChanges) {
361
+ const impacts = [];
362
+
363
+ for (const table of databaseChanges.tables) {
364
+ impacts.push({
365
+ tableName: table.name,
366
+ modelName: table.entity,
367
+ modelPath: table.file,
368
+ impactType: this.classifyImpactType(table),
369
+ operations: Array.from(table.operations),
370
+ changeSource: table.changeSource,
371
+ severity: this.calculateSeverity(table)
372
+ });
373
+ }
374
+
375
+ return impacts;
376
+ }
377
+
378
+ classifyImpactType(table) {
379
+ // Schema: entity file changed
380
+ if (table.isEntityFile) return 'schema';
381
+
382
+ // Relation: relation decorators changed
383
+ if (table.hasRelationChange) return 'relation';
384
+
385
+ // Migration: migration file changed
386
+ if (table.isMigrationFile) return 'migration';
387
+
388
+ // Query: repository changed
389
+ return 'query';
390
+ }
391
+
392
+ calculateSeverity(table) {
393
+ // Per spec: Section 6
394
+ if (table.impactType === 'schema') return 'critical';
395
+ if (table.impactType === 'relation') return 'high';
396
+ if (table.operations.includes('DELETE')) return 'high';
397
+ if (table.operations.includes('UPDATE')) return 'medium';
398
+ if (table.operations.includes('INSERT')) return 'medium';
399
+ return 'low'; // SELECT only
400
+ }
401
+ ```
402
+
403
+ **Acceptance Criteria:**
404
+ - [ ] Output matches spec schema exactly
405
+ - [ ] All required fields present
406
+ - [ ] Severity follows spec rules
407
+ - [ ] Impact type classification correct
408
+
409
+ ### Phase 5: Logging & Verbose Mode
410
+
411
+ **Apply same pattern as Task 001:**
412
+
413
+ ```javascript
414
+ import { createLogger } from '../utils/logger.js';
415
+
416
+ export class DatabaseDetector {
417
+ constructor(methodCallGraph, config) {
418
+ this.methodCallGraph = methodCallGraph;
419
+ this.config = config;
420
+ this.logger = createLogger(config.verbose);
421
+ }
422
+
423
+ async detect(changedFiles) {
424
+ this.logger.info('🔍 Analyzing database impacts...');
425
+ this.logger.verbose('DatabaseDetector', `Processing ${changedFiles.length} files`);
426
+
427
+ const startTime = Date.now();
428
+
429
+ // ... detection logic
430
+
431
+ const duration = Date.now() - startTime;
432
+ this.logger.verbose('DatabaseDetector', `Completed in ${duration}ms`);
433
+
434
+ return impacts;
435
+ }
436
+ }
437
+ ```
438
+
439
+ **Acceptance Criteria:**
440
+ - [ ] Normal mode: clean output only
441
+ - [ ] Verbose mode: detailed tracing with [DatabaseDetector] prefix
442
+ - [ ] Performance timing shown in verbose mode
443
+
444
+ ## ✅ Verification Against Spec
445
+
446
+ ### Checklist
447
+
448
+ Compare implementation against spec requirements:
449
+
450
+ **Functional Requirements:**
451
+ - [ ] FR-001: Entity/Model changes detected ✓
452
+ - [ ] FR-002: Table names extracted correctly ✓
453
+ - [ ] FR-003: Repository changes tracked ✓
454
+ - [ ] FR-004: Impact type classified ✓
455
+ - [ ] FR-005: CRUD operations identified ✓
456
+ - [ ] FR-006: Report format matches spec ✓
457
+
458
+ **Output Schema:**
459
+ - [ ] `tableName` field present and correct
460
+ - [ ] `modelName` field present
461
+ - [ ] `modelPath` field present
462
+ - [ ] `impactType` enum matches spec
463
+ - [ ] `operations` array present
464
+ - [ ] `severity` classification correct
465
+
466
+ **ORM Support:**
467
+ - [ ] TypeORM @Entity detection
468
+ - [ ] TypeORM @Column detection
469
+ - [ ] Repository pattern detection
470
+ - [ ] Method call tracing
471
+
472
+ ## 🧪 Testing
473
+
474
+ ### Manual Test Cases
475
+
476
+ **Test 1: Entity Column Change**
477
+ ```bash
478
+ # Modify an entity column
479
+ echo "Test scenario from spec Section 8"
480
+
481
+ # Expected:
482
+ # - tableName: "users"
483
+ # - impactType: "schema"
484
+ # - severity: "critical"
485
+ ```
486
+
487
+ **Test 2: Repository Method Change**
488
+ ```bash
489
+ # Modify a repository method
490
+
491
+ # Expected:
492
+ # - tableName: extracted from repository
493
+ # - impactType: "query"
494
+ # - operations: detected from method
495
+ ```
496
+
497
+ **Test 3: Service Change Affecting Database**
498
+ ```bash
499
+ # Change a service that calls repository
500
+
501
+ # Expected:
502
+ # - Call graph traced to repository
503
+ # - Table identified
504
+ # - Operations detected
505
+ ```
506
+
507
+ ### Verbose Mode Test
508
+ ```bash
509
+ node cli.js --input=src --base=origin/main --verbose
510
+ ```
511
+
512
+ **Expected Output:**
513
+ ```
514
+ 🔍 Step 2: Analyzing impact...
515
+ [DatabaseDetector] Processing 3 files
516
+ [DatabaseDetector] Analyzing entity: UserEntity
517
+ [DatabaseDetector] Extracted table name: users
518
+ [DatabaseDetector] Detected operations: INSERT, UPDATE
519
+ [DatabaseDetector] Tracing call chain: UserService → UserRepository
520
+ [DatabaseDetector] Completed in 85ms
521
+
522
+ 📊 Database Impact:
523
+ ✓ Affected tables: 2
524
+ • users (schema change, critical)
525
+ • posts (query change, medium)
526
+ ```
527
+
528
+ ## 📊 Success Metrics
529
+
530
+ - [ ] Detects >95% of entity changes (per NFR-002)
531
+ - [ ] Detects >85% of repository changes (per NFR-002)
532
+ - [ ] Analysis time <5 seconds (per NFR-001)
533
+ - [ ] Zero crashes on valid code
534
+ - [ ] Output validates against spec schema
535
+
536
+ ## 🔗 References
537
+
538
+ - **Spec**: `.specify/specs/features/database-impact-detection.md`
539
+ - **Current Code**: `core/detectors/database-detector.js`
540
+ - **Task 001**: `.specify/tasks/task-001-refactor-api-detector.md`
541
+ - **Logger Pattern**: `core/utils/logger.js`
542
+ - **Code Rules**: `.github/copilot-instructions.md`
543
+
544
+ ## 📝 Notes
545
+
546
+ ### Spec-Driven Best Practices
547
+
548
+ 1. **Read spec first, code second** - Always check spec before coding
549
+ 2. **Question discrepancies** - If code doesn't match spec, ask why
550
+ 3. **Update spec if requirements change** - Keep spec as source of truth
551
+ 4. **Use spec for testing** - Test cases come from spec examples
552
+ 5. **Reference spec in code comments** - Link requirements to implementation
553
+
554
+ ### Table Detection Strategy
555
+
556
+ ```
557
+ ┌─────────────────┐
558
+ │ Changed File │
559
+ └────────┬────────┘
560
+
561
+ ┌────────────┐
562
+ │ Is Entity? │──Yes──> Extract table name → Return
563
+ └─────┬──────┘
564
+ │ No
565
+
566
+ ┌──────────────────┐
567
+ │ Has DB calls in │──Yes──> Extract operations → Return
568
+ │ changed lines? │
569
+ └─────┬────────────┘
570
+ │ No
571
+
572
+ ┌──────────────────┐
573
+ │ Trace call graph │──Repo found──> Extract table → Return
574
+ │ to repository │
575
+ └──────────────────┘
576
+ ```
577
+
578
+ ## 🎯 Definition of Done
579
+
580
+ - [ ] All Phase 2-5 tasks completed
581
+ - [ ] Code matches spec requirements exactly
582
+ - [ ] Output schema matches spec
583
+ - [ ] Verbose mode implemented
584
+ - [ ] Manual tests pass
585
+ - [ ] Performance targets met
586
+ - [ ] Documentation updated
587
+ - [ ] Code reviewed for compliance with code rules
588
+
589
+ ---
590
+
591
+ **Last Updated:** 2025-12-25
592
+ **Spec Version:** 1.0
593
+ **Implementation Status:** TODO
File without changes