@sun-asterisk/impact-analyzer 1.0.6 → 1.0.7

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,59 @@
1
+ # BUG-004 Fix Summary
2
+
3
+ ## Status
4
+ ✅ **FIXED**
5
+
6
+ ## What Was Fixed
7
+ Raw SQL detection now correctly identifies database changes even when modifications are deep inside multi-line template literals.
8
+
9
+ ## Root Cause
10
+ The original implementation processed diff lines without accessing the full file content. This meant it couldn't see the `.query()` method call when the change was in the SQL string body.
11
+
12
+ ## Solution
13
+ Refactored to use **full file content** instead of diff-only approach:
14
+
15
+ ### New Flow
16
+ ```
17
+ 1. Read full file from disk
18
+ 2. Parse diff → get changed line numbers
19
+ 3. For each changed line:
20
+ - Search backwards for `.query(` or `.execute(`
21
+ - Search forward for statement end (`;`)
22
+ - Extract complete statement
23
+ - Parse SQL from template literal
24
+ - Report tables/fields
25
+ ```
26
+
27
+ ## Key Changes
28
+ | Method | Change | Purpose |
29
+ |--------|--------|---------|
30
+ | `detectRawSQLQueries()` | Added `filePath` param | Read full file content |
31
+ | `extractChangedLineNumbers()` | New method | Parse diff hunks |
32
+ | `findQueryStatementContainingLine()` | New method | Find parent SQL statement |
33
+ | `extractSQLFromStatement()` | Simplified | Extract SQL from template |
34
+
35
+ ## Test Case
36
+ ```typescript
37
+ // Before: ❌ Not detected
38
+ // After: ✅ Detected
39
+
40
+ const [result] = await queryRunner.manager.query<Array<{ count: string }>>(
41
+ `
42
+ SELECT COUNT(*) as count
43
+ FROM t003
44
+ WHERE t003.field_1 = $1
45
+ AND t003.field_3 = ANY($3) // <- Change here
46
+ `,
47
+ [var1, var2, [1, 2, 3]],
48
+ );
49
+ ```
50
+
51
+ **Result**: ✅ Detects `t003` table, `field_3` field, `SELECT` operation
52
+
53
+ ## Files Modified
54
+ - `core/detectors/database-detector.js` (~180 lines changed)
55
+
56
+ ## Verified
57
+ ✅ Syntax check passed
58
+ ✅ No breaking changes to existing API
59
+ ✅ Maintains backward compatibility
@@ -0,0 +1,158 @@
1
+ # BUG-004: Raw SQL Detection in Database Changes
2
+
3
+ **Bug ID:** BUG-004
4
+ **Status:** ✅ Fixed
5
+ **Priority:** High
6
+ **Component:** `core/detectors/database-detector.js`
7
+ **Created:** 2025-01-29
8
+ **Fixed:** 2025-01-30
9
+
10
+ ---
11
+
12
+ ## Problem
13
+
14
+ Database detector fails to detect changes in raw SQL queries when:
15
+ 1. SQL queries span multiple lines (template literals)
16
+ 2. Changes occur in WHERE conditions (e.g., `= $1` → `= ANY($1)`)
17
+ 3. SQL is in `queryRunner.manager.query()` or similar methods
18
+
19
+ **Example:**
20
+ ```typescript
21
+ await queryRunner.manager.query(`
22
+ SELECT COUNT(*) as count
23
+ FROM user
24
+ WHERE user.id = $1
25
+ - AND user.name = $2
26
+ + AND user.name = ANY($2) // <- change not detected
27
+ `)
28
+ ```
29
+
30
+ **Expected:** Detect `user` table and `name` field
31
+ **Actual:** No detection or incomplete detection
32
+
33
+ ---
34
+
35
+ ## Root Cause
36
+
37
+ Current `detectRawSQLQueries()` processes diff **line-by-line**:
38
+
39
+ ```javascript
40
+ for (const line of lines) {
41
+ if (line.startsWith('+')) {
42
+ if (added.includes('.query(')) {
43
+ const sqlMatch = added.match(/`([^`]+)`/);
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ **Problems:**
50
+ 1. ❌ Cannot capture multi-line SQL (template literals span multiple lines)
51
+ 2. ❌ Only checks added lines (`+`), misses modified/context lines
52
+ 3. ❌ Assumes SQL starts and ends on same line
53
+ 4. ❌ Fragile pattern matching - breaks with formatting changes
54
+
55
+ ---
56
+
57
+ ## Fix Strategy
58
+
59
+ ### Change Detection Approach
60
+
61
+ **From:** Line-by-line iteration → **To:** Block-based detection
62
+
63
+ **New Algorithm:**
64
+ 1. Extract full file content (not just diff)
65
+ 2. Find all SQL query blocks using regex (template literals, .query() calls)
66
+ 3. Match changed line numbers to SQL block ranges
67
+ 4. Parse affected SQL blocks to extract tables/fields
68
+
69
+ ### Implementation Steps
70
+
71
+ **Step 1:** Add `extractSQLBlocks(fileContent)` - Find all SQL blocks with line ranges
72
+
73
+ **Step 2:** Add `findAffectedSQLBlocks(sqlBlocks, diff)` - Match diff changes to blocks
74
+
75
+ **Step 3:** Improve `parseSQLForSchema(sql)` - Extract tables/fields from full SQL
76
+
77
+ **Step 4:** Refactor `detectRawSQLQueries(file, diff)` - Use block-based approach
78
+
79
+ ---
80
+
81
+ ## Test Cases
82
+
83
+ **Test 1:** Multi-line WHERE condition change
84
+ ```sql
85
+ WHERE user.id = $1
86
+ - AND user.name = $2
87
+ + AND user.name = ANY($2)
88
+ ```
89
+ Expected: Detect `user.name` field change
90
+
91
+ **Test 2:** JOIN type change
92
+ ```typescript
93
+ - .innerJoin('orders', 'orders.user_id = user.id')
94
+ + .leftJoin('orders', 'orders.user_id = user.id')
95
+ ```
96
+ Expected: Detect JOIN operation change on `orders`, `user` tables
97
+
98
+ **Test 3:** SELECT field addition
99
+ ```sql
100
+ - SELECT user.id, user.name FROM user
101
+ + SELECT user.id, user.name, user.email FROM user
102
+ ```
103
+ Expected: Detect new `user.email` field
104
+
105
+ ---
106
+
107
+ ## Checklist
108
+
109
+ - [x] Implement changed-line-first approach instead of pattern-first
110
+ - [x] Implement `findParentSQLBlock()` - find parent block containing SQL method
111
+ - [x] Implement `extractSQLFromBlock()` - extract SQL from code block
112
+ - [x] Refactor `detectRawSQLQueries()` to use new approach
113
+ - [x] Remove old `extractSQLFromMethodCall()` and `extractStringLiteral()` methods
114
+ - [ ] Add tests for multi-line SQL changes
115
+ - [ ] Verify no regression
116
+
117
+ ---
118
+
119
+ ## Fix Applied
120
+
121
+ **Date:** 2025-01-30
122
+
123
+ **Approach Changed:**
124
+ - **OLD (Incorrect):** Pattern-first → Find all `.query()` in file → Check if overlaps with changes
125
+ - **NEW (Correct):** Change-first → Start from changed lines → Find parent block → Check if contains `.query()`
126
+
127
+ **Implementation:**
128
+
129
+ 1. **`detectRawSQLQueries()`** - New change-driven approach:
130
+ - Parse diff to find all changed line numbers (+ or -)
131
+ - For each changed line, find parent SQL block
132
+ - Extract SQL only from blocks that changed
133
+
134
+ 2. **`findParentSQLBlock()`** - Find parent function containing SQL:
135
+ - Search backward from changed line for `.query()` or `.execute()`
136
+ - Search forward to find statement end (handle parentheses depth)
137
+ - Return complete block with boundaries
138
+
139
+ 3. **`extractSQLFromBlock()`** - Extract SQL string:
140
+ - Find string literal after `.query()` or `.execute()`
141
+ - Handle template literals, single/double quotes
142
+ - Return cleaned SQL content
143
+
144
+ **Why This Works:**
145
+ - Starts from **what changed** (diff lines), not patterns
146
+ - Finds **context around changes** (parent block)
147
+ - Only processes **blocks that actually changed**
148
+ - Handles multi-line statements correctly
149
+
150
+ ---
151
+
152
+ ## Impact
153
+
154
+ - **Severity:** High - Missing critical database changes
155
+ - **Files Affected:** `core/detectors/database-detector.js` (~150-200 lines)
156
+ - **Related:** BUG-001, BUG-002, BUG-003
157
+
158
+ **Key Insight:** Need to parse full code structure first, then identify affected regions - not analyze line-by-line diffs.
@@ -0,0 +1,197 @@
1
+ # BUG-005: Queue Processor Endpoint Detection Missing
2
+
3
+ **Bug ID:** BUG-005
4
+ **Created:** 2025-12-30
5
+ **Status:** Fixed
6
+ **Severity:** Medium
7
+ **Component:** endpoint-detector.js, method-call-graph.js
8
+
9
+ ---
10
+
11
+ ## Problem
12
+
13
+ **Current behavior:**
14
+ Queue processors using `@nestjs/bull` pattern are not detected as endpoints.
15
+
16
+ **Example pattern not detected:**
17
+ ```typescript
18
+ // Processor (worker)
19
+ @Processor('update-queue')
20
+ export class UpdateFactoryProcessor {
21
+ constructor(
22
+ @InjectRepository(UserEntity)
23
+ private readonly userRepository: Repository<UserEntity>,
24
+ ) {}
25
+
26
+ @Process('update-task')
27
+ async handleUpdateTask(job: Job) {
28
+ // This method is not detected as endpoint
29
+ const result = await this.userRepository.update(...);
30
+ return result;
31
+ }
32
+ }
33
+
34
+ // Controller (producer)
35
+ @Controller('users')
36
+ export class UserController {
37
+ constructor(
38
+ @InjectQueue('update-queue')
39
+ private readonly updateQueue: Queue,
40
+ ) {}
41
+
42
+ @Post('trigger-update')
43
+ async triggerUpdate() {
44
+ await this.updateQueue.add('update-task', { ... });
45
+ return { message: 'Job queued' };
46
+ }
47
+ }
48
+ ```
49
+
50
+ **Expected:** Should detect both:
51
+ - Queue processor method `handleUpdateTask` as async endpoint
52
+ - Controller method `triggerUpdate` that triggers the queue
53
+
54
+ ---
55
+
56
+ ## Root Cause
57
+
58
+ **Location:** `core/detectors/endpoint-detector.js`
59
+
60
+ 1. **Only detects HTTP decorators** - Current implementation only looks for `@Get`, `@Post`, `@Put`, `@Delete`, `@Patch`
61
+ 2. **Ignores queue patterns** - Does not recognize `@Processor()` and `@Process()` decorators
62
+ 3. **Missing queue linkage** - Does not connect controller `@InjectQueue()` to processor `@Processor()`
63
+
64
+ ---
65
+
66
+ ## Impact
67
+
68
+ - **Missing queue-based endpoints** in impact analysis
69
+ - **Incomplete call chains** when changes affect queue processors
70
+ - **False negatives** for async job handlers
71
+
72
+ ---
73
+
74
+ ## Fix Strategy
75
+
76
+ ### Step 1: Detect Queue Processors
77
+ Add pattern detection in `methodCallGraph` or `endpoint-detector`:
78
+
79
+ ```javascript
80
+ // Detect @Processor('queue-name')
81
+ const processorPattern = /@Processor\(['"`]([^'"`]+)['"`]\)/;
82
+
83
+ // Detect @Process('job-name') methods
84
+ const processPattern = /@Process\(['"`]([^'"`]+)['"`]\)/;
85
+ ```
86
+
87
+ ### Step 2: Detect Queue Injection
88
+ ```javascript
89
+ // Detect @InjectQueue('queue-name') in controllers
90
+ const injectQueuePattern = /@InjectQueue\(['"`]([^'"`]+)['"`]\)/;
91
+ ```
92
+
93
+ ### Step 3: Link Controller to Processor
94
+ ```javascript
95
+ // When controller has @InjectQueue('update-queue')
96
+ // and calls this.updateQueue.add('update-task', ...)
97
+ // Link to @Processor('update-queue') @Process('update-task')
98
+ ```
99
+
100
+ ### Step 4: Report Format
101
+ ```javascript
102
+ {
103
+ method: 'QUEUE',
104
+ path: '/queue/update-queue/update-task',
105
+ handler: 'UpdateFactoryProcessor.handleUpdateTask',
106
+ triggeredBy: 'UserController.triggerUpdate (POST /users/trigger-update)',
107
+ layers: ['Controller', 'Queue', 'Processor', 'Repository']
108
+ }
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Checklist
114
+
115
+ - [x] Add queue processor detection patterns
116
+ - [x] Add queue injection detection in controllers
117
+ - [x] Link queue producers to consumers
118
+ - [x] Update report to show queue-based endpoints
119
+ - [ ] Test with @nestjs/bull examples
120
+ - [ ] Update documentation
121
+
122
+ ---
123
+
124
+ ## Fix Implementation
125
+
126
+ ### Changes Made (2025-12-30)
127
+
128
+ **File:** `core/utils/method-call-graph.js`
129
+
130
+ **Change 1:** Detect queue dispatches in ALL methods (line ~128-134)
131
+ ```javascript
132
+ // OLD: Only in endpoint methods
133
+ if (httpDecorator) {
134
+ this.detectCommandDispatches(method, fullMethodName);
135
+ this.detectQueueDispatches(method, fullMethodName);
136
+ }
137
+
138
+ // NEW: In all methods (endpoints + services)
139
+ this.detectCommandDispatches(method, fullMethodName);
140
+ this.detectQueueDispatches(method, fullMethodName);
141
+ ```
142
+
143
+ **Change 2:** Enhanced `findEndpointsByQueue()` method (line ~867-941)
144
+ - **Pattern 1 (Direct)**: Controller → Queue.add() → Processor
145
+ - **Pattern 2 (Indirect)**: Controller → Service → Queue.add() → Processor
146
+
147
+ When a service method triggers a queue:
148
+ 1. Find which controllers call that service
149
+ 2. Build full call chain: Processor ← Queue ← Service ← Controller
150
+ 3. Report controller endpoints
151
+
152
+ ### How It Works
153
+
154
+ ```
155
+ 1. Processor file changes
156
+ └─> Extract changed method: UpdateProcessor.handleJob
157
+
158
+ 2. Check if queue processor
159
+ └─> Found @Process decorator → queue: 'update-queue'
160
+
161
+ 3. Find methods calling queue.add('update-queue')
162
+ └─> Found: UpdateService.triggerUpdate
163
+
164
+ 4. Trace service callers
165
+ └─> Found: UpdateController.update
166
+
167
+ 5. Report endpoint
168
+ └─> POST /api/update is affected
169
+ ```
170
+
171
+ ---
172
+
173
+ ## Checklist
174
+
175
+ - [ ] Add queue processor detection patterns
176
+ - [ ] Add queue injection detection in controllers
177
+ - [ ] Link queue producers to consumers
178
+ - [ ] Update report to show queue-based endpoints
179
+ - [ ] Test with @nestjs/bull examples
180
+ - [ ] Update documentation
181
+
182
+ ---
183
+
184
+ ## References
185
+
186
+ - NestJS Bull Documentation: https://docs.nestjs.com/techniques/queues
187
+ - Current implementation: `core/detectors/endpoint-detector.js`
188
+ - Call graph: `core/analyzers/method-call-graph.js`
189
+ - API Impact Detection Spec: `.specify/specs/features/api-impact-detection.md`
190
+ - Architecture Doc: `.specify/plans/architecture.md`
191
+ - Code Rules: `.github/copilot-instructions.md`
192
+
193
+ ---
194
+
195
+ ## Notes
196
+
197
+ Queue-based patterns are common in microservices and async processing. Missing these endpoints leads to incomplete impact analysis for background job changes.
@@ -0,0 +1,284 @@
1
+ # TASK-005: CLI Optimization & Default Configuration
2
+
3
+ **Status:** 📋 TODO
4
+ **Priority:** Medium
5
+ **Estimated Effort:** 2-3 hours
6
+
7
+ ---
8
+
9
+ ## 📋 Overview
10
+
11
+ Improve CLI usability by adding default configurations and comprehensive usage documentation. Make the tool easier to use with sensible defaults while maintaining flexibility.
12
+
13
+ ---
14
+
15
+ ## 🎯 Objectives
16
+
17
+ 1. ✅ Add default values for optional CLI arguments
18
+ 2. ✅ Improve help text and usage documentation
19
+ 3. ✅ Add validation and better error messages
20
+ 4. ✅ Support config file (`.impactrc.json`)
21
+ 5. ✅ Update README with complete usage guide
22
+
23
+ ---
24
+
25
+ ## 📝 Requirements
26
+
27
+ ### 1. CLI Argument Defaults
28
+
29
+ **Current behavior:**
30
+ - `--base` is required
31
+ - Other args require explicit values
32
+ - No fallback configuration
33
+
34
+ **Expected behavior:**
35
+ ```bash
36
+ # Minimal command (use defaults for base)
37
+ npx impact-analyzer
38
+
39
+ # Full command (override defaults)
40
+ npx impact-analyzer --input=src --base=HEAD~1 --head=HEAD --output=report.md --json=report.json --verbose
41
+ ```
42
+
43
+ **Default values:**
44
+ - `--input`: `src` (or auto-detect from `package.json` or `tsconfig.json`)
45
+ - `--base`: `HEAD~1` (NEW: no longer required, use HEAD~1 as default)
46
+ - `--head`: `HEAD`
47
+ - `--output`: No default (console only)
48
+ - `--json`: No default (console only)
49
+ - `--verbose`: `false`
50
+
51
+ ### 2. Config File Support
52
+
53
+ Support `.impactrc.json` for project-level defaults:
54
+
55
+ ```json
56
+ {
57
+ "input": "src",
58
+ "excludePaths": ["node_modules", "dist", "**/*.test.ts"],
59
+ "verbose": false,
60
+ "severity": {
61
+ "low": 20,
62
+ "medium": 50,
63
+ "high": 100
64
+ }
65
+ }
66
+ ```
67
+
68
+ **Priority:** CLI args > `.impactrc.json` > built-in defaults
69
+
70
+ ### 3. Help Command
71
+
72
+ Add `--help` or `-h` flag:
73
+
74
+ ```bash
75
+ npx impact-analyzer --help
76
+ ```
77
+
78
+ **Output:**
79
+ ```
80
+ Impact Analyzer - Code change impact analysis tool
81
+
82
+ USAGE:
83
+ npx impact-analyzer [options]
84
+
85
+ OPTIONS:
86
+ --input=<path> Source directory (default: src)
87
+ --base=<ref> Git base reference (default: HEAD~1)
88
+ --head=<ref> Git head reference (default: HEAD)
89
+ --output=<path> Markdown report output path
90
+ --json=<path> JSON report output path
91
+ --verbose Enable verbose logging
92
+ --help, -h Show this help message
93
+
94
+ EXAMPLES:
95
+ # Basic analysis (compare HEAD~1 to HEAD)
96
+ npx impact-analyzer
97
+
98
+ # Compare with specific branch
99
+ npx impact-analyzer --base=origin/main
100
+
101
+ # With custom input directory
102
+ npx impact-analyzer --input=backend/src --base=origin/develop
103
+
104
+ # Generate reports
105
+ npx impact-analyzer --output=impact.md --json=impact.json
106
+
107
+ # Verbose mode
108
+ npx impact-analyzer --verbose
109
+
110
+ MORE INFO:
111
+ Documentation: https://github.com/sun-asterisk/impact-analyzer
112
+ Report issues: https://github.com/sun-asterisk/impact-analyzer/issues
113
+ ```
114
+
115
+ ### 4. Validation & Error Messages
116
+
117
+ **Validate:**
118
+ - ✅ `--input` directory exists
119
+ - ✅ Git repository is valid
120
+ - ✅ Base/head refs exist
121
+
122
+ **Error messages:**
123
+ ```bash
124
+ # Invalid path
125
+ ❌ Error: Input directory not found: 'invalid/path'
126
+ Please provide a valid directory path with --input
127
+
128
+ # Invalid git ref
129
+ ❌ Error: Git reference not found: 'origin/invalid'
130
+ Run 'git fetch' or verify the branch exists
131
+
132
+ # Not in git repository
133
+ ❌ Error: Not a git repository
134
+ Please run this tool inside a git repository
135
+ ```
136
+
137
+ ---
138
+
139
+ ## 🔧 Implementation Plan
140
+
141
+ ### Phase 1: Add Default Configuration
142
+
143
+ **File:** `cli.js`
144
+
145
+ 1. Add default values to `CLI` class:
146
+ ```javascript
147
+ const DEFAULTS = {
148
+ input: 'src',
149
+ base: 'HEAD~1',
150
+ head: 'HEAD',
151
+ verbose: false
152
+ };
153
+ ```
154
+
155
+ 2. Update `getArg()` method:
156
+ ```javascript
157
+ getArg(key, defaultValue = DEFAULTS[key] || '') {
158
+ return this.args.get(key) || defaultValue;
159
+ }
160
+ ```
161
+
162
+ ### Phase 2: Add Config File Support
163
+
164
+ **File:** `config/config-loader.js` (new)
165
+
166
+ ```javascript
167
+ export class ConfigLoader {
168
+ static load(cwd = process.cwd()) {
169
+ // Try .impactrc.json
170
+ // Try package.json "impact" field
171
+ // Return defaults
172
+ }
173
+ }
174
+ ```
175
+
176
+ ### Phase 3: Add Help Command
177
+
178
+ **File:** `cli.js`
179
+
180
+ Add method:
181
+ ```javascript
182
+ showHelp() {
183
+ console.log(`
184
+ Impact Analyzer - Code change impact analysis tool
185
+
186
+ USAGE: ...
187
+ `);
188
+ }
189
+ ```
190
+
191
+ Check in `index.js`:
192
+ ```javascript
193
+ if (cli.hasArg('help') || cli.hasArg('h')) {
194
+ cli.showHelp();
195
+ process.exit(0);
196
+ }
197
+ ```
198
+
199
+ ### Phase 4: Add Validation
200
+
201
+ **File:** `core/validator.js` (new)
202
+
203
+ ```javascript
204
+ export class CLIValidator {
205
+ static validate(args) {
206
+ // Check required args
207
+ // Check paths exist
208
+ // Check git refs
209
+ // Return { valid: true/false, errors: [] }
210
+ }
211
+ }
212
+ ```
213
+
214
+ ### Phase 5: Update Documentation
215
+
216
+ **File:** `README.md`
217
+
218
+ Add sections:
219
+ - ✅ Configuration file usage
220
+ - ✅ Default values table
221
+ - ✅ Troubleshooting guide
222
+ - ✅ More examples
223
+
224
+ ---
225
+
226
+ ## ✅ Acceptance Criteria
227
+
228
+ - [ ] NO required arguments (all have defaults)
229
+ - [ ] `--base` defaults to `HEAD~1`
230
+ - [ ] `--input` defaults to `src` directory
231
+ - [ ] `--head` defaults to `HEAD`
232
+ - [ ] `--help` displays usage information
233
+ - [ ] `.impactrc.json` config file is supported
234
+ - [ ] Clear validation error messages
235
+ - [ ] README documentation is complete
236
+ - [ ] Works without any args: `npx impact-analyzer`
237
+
238
+ ---
239
+
240
+ ## 🧪 Testing
241
+
242
+ ```bash
243
+ # Test defaults (should work with no args)
244
+ npx impact-analyzer
245
+
246
+ # Test with base ref
247
+ npx impact-analyzer --base=origin/main
248
+
249
+ # Test help
250
+ npx impact-analyzer --help
251
+
252
+ # Test validation
253
+ npx impact-analyzer --base=invalid-ref # Should show error
254
+ npx impact-analyzer --input=invalid-path # Should show error
255
+
256
+ # Test config file
257
+ echo '{"input":"backend/src","base":"origin/develop"}' > .impactrc.json
258
+ npx impact-analyzer
259
+
260
+ # Test override
261
+ npx impact-analyzer --base=origin/main --input=custom/path
262
+ ```
263
+
264
+ ---
265
+
266
+ ## 📚 References
267
+
268
+ ### External Resources
269
+ - CLI best practices: https://clig.dev/
270
+ - Commander.js (if we want to use a library): https://github.com/tj/commander.js
271
+ - Yargs (alternative): https://yargs.js.org/
272
+
273
+ ### Internal Coding Standards
274
+ Follow these coding rules from `.github/copilot-instructions.md`:
275
+ - **Rule C005** – Each function should do one thing only
276
+ - **Rule C006** – Function names must be verb/verb-noun
277
+ - **Rule C007** – Avoid comments that just describe the code
278
+ - **Rule C012** – Separate Command and Query (CQS principle)
279
+ - **Rule C014** – Use Dependency Injection instead of direct `new` in logic
280
+ - **Rule C015** – Use domain language in class/function names
281
+ - **Rule C031** – Data validation logic must be separated
282
+ - **Rule C035** – When handling errors, log full context information
283
+ - **Rule C037** – API handlers should return standard response objects
284
+ - **Rule C040** – Don't scatter validation logic across multiple classes