@defai.digital/automatosx 5.6.19 → 5.6.21

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/CHANGELOG.md CHANGED
@@ -2,6 +2,72 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [5.6.20](https://github.com/defai-digital/automatosx/compare/v5.6.19...v5.6.20) (2025-10-25)
6
+
7
+ ### Bug Fixes
8
+
9
+ * **fix(critical):** Fix 3 resource lifecycle bugs and 1 test infrastructure bug (Ultrathink Review #7) 🐛 CRITICAL
10
+
11
+ **Summary**: Fixed 3 critical resource leaks + 1 test infrastructure issue discovered via systematic ultrathink analysis
12
+ - **Total Bugs Fixed**: 4 (3 CRITICAL resource leaks + 1 CRITICAL test issue)
13
+ - **Impact**: Eliminates memory leaks, improves worker pool stability, fixes failing tests
14
+ - **Pattern Match**: 100% (all fixes follow established patterns from Reviews #4-#6)
15
+ - **Test Results**: graceful-shutdown tests 13/13 passing (was 10/13 with 3 timeouts)
16
+
17
+ **Bug #1: InFlightTracker setInterval Leak** (CRITICAL)
18
+ - File: `src/utils/graceful-shutdown.ts:278-300`
19
+ - Problem: setInterval not cleared if Promise rejected externally
20
+ - Root Cause: External timeout in parent shutdown process
21
+ - Fix:
22
+ - Clear interval in callback (normal path: resolve/reject)
23
+ - Use .finally() as safety net (external cancellation path)
24
+ - Fix timeout comparison logic (>= instead of >)
25
+ - Pattern: ProgressChannel setTimeout leak (v5.6.19 Review #6)
26
+ - Impact: Eliminates memory leak in long-running processes
27
+
28
+ **Bug #2: WorkerPool setTimeout Leak on Worker Exit** (CRITICAL)
29
+ - File: `src/core/worker-pool.ts:252-281`
30
+ - Problem: Task timeout not cleared when worker exits unexpectedly without error event
31
+ - Root Cause: Exit handler didn't clear timeout or fail pending task
32
+ - Fix:
33
+ - Clear task timeout in exit handler before cleanup
34
+ - Fail pending task with proper error message
35
+ - Spawn replacement worker if below minimum
36
+ - Process next queued task
37
+ - Pattern: ProcessManager Promise.race leak (v5.6.17 Review #5)
38
+ - Impact: Prevents orphaned timeouts and ensures task failure notification
39
+
40
+ **Bug #3: WorkerPool idleCheckInterval Leak on Init Failure** (MEDIUM)
41
+ - File: `src/core/worker-pool.ts:83-100, 177-199`
42
+ - Problem: setInterval for idle cleanup not cleared if initialization fails
43
+ - Root Cause: Constructor started interval before validating initialization
44
+ - Fix:
45
+ - Wrap initialization in try-catch
46
+ - Add cleanup() method to clear interval and terminate workers
47
+ - Throw error after cleanup to maintain error propagation
48
+ - Pattern: AdaptiveCache cleanupInterval leak (v5.6.19 Review #6)
49
+ - Impact: Prevents memory leak when WorkerPool initialization fails
50
+
51
+ **Bug #4: Vitest Fake Timers Preventing Test Execution** (CRITICAL - Test Infrastructure)
52
+ - File: `tests/unit/graceful-shutdown.test.ts:91-95`
53
+ - Problem: Global vi.useFakeTimers() prevented real setInterval/setTimeout from executing
54
+ - Root Cause: vitest.setup.ts:31 enables fake timers globally
55
+ - Symptom: 3 InFlightTracker tests timing out after 60s (callbacks never executed)
56
+ - Fix: Use vi.useRealTimers() in InFlightTracker test beforeEach hook
57
+ - Result: Tests 10/13 → 13/13 passing, duration 180s → 310ms
58
+ - Impact: Reliable test suite, faster test execution
59
+
60
+ **Testing**:
61
+ - TypeScript compilation: ✅ PASSED
62
+ - graceful-shutdown tests: ✅ 13/13 PASSED (310ms, was 10/13 with 3x 60s timeouts)
63
+ - Pattern match: ✅ 100% (all fixes follow established patterns)
64
+ - Risk: 🟢 LOW (defensive cleanup, no behavioral changes)
65
+
66
+ **Documentation**:
67
+ - `tmp/ultrathink-review-7-bug-report.md` - Detailed analysis
68
+ - `tmp/v5.6.20-implementation-summary.md` - Implementation details
69
+ - `tmp/v5.6.20-final-summary.md` - Final summary and commit message
70
+
5
71
  ## [5.6.18](https://github.com/defai-digital/automatosx/compare/v5.6.17...v5.6.18) (2025-10-25)
6
72
 
7
73
  ### Performance Improvements
package/README.md CHANGED
@@ -13,7 +13,7 @@ AutomatosX is a CLI-first orchestration tool that transforms stateless AI assist
13
13
  [![Windows](https://img.shields.io/badge/Windows-10+-blue.svg)](https://www.microsoft.com/windows)
14
14
  [![Ubuntu](https://img.shields.io/badge/Ubuntu-24.04-orange.svg)](https://ubuntu.com)
15
15
 
16
- **Status**: ✅ Production Ready · **v5.6.19** · October 2025 · 24 Specialized Agents · 100% Resource Leak Free · Production Stability
16
+ **Status**: ✅ Production Ready · **v5.6.21** · October 2025 · 24 Specialized Agents · 100% Resource Leak Free · Production Stability
17
17
 
18
18
  ---
19
19
 
@@ -137,7 +137,7 @@ AutomatosX comes with a pre-built team of 24 agents, each with a specific role a
137
137
  - **Security** (Audits, threat modeling)
138
138
  - **Data Science** (ML strategy, statistical analysis)
139
139
  - **ML Engineer** (PyTorch/TensorFlow, CNN/Transformer, LLM fine-tuning)
140
- - **Best Practices** (SOLID, design patterns, clean code, refactoring, architecture)
140
+ - **Best Practices - Stan** (SOLID, design patterns, clean code, refactoring, architecture) ✨ NEW in v5.6.21
141
141
  - **ERP Integration** (SAP, Oracle, Dynamics 365, enterprise integration patterns)
142
142
  - **Figma Expert** (Figma API, design tokens, design-to-code, MCP integration) ✨ NEW in v5.6.10
143
143
  - **IoT/Embedded Engineer** (MQTT, ROS2, FreeRTOS, edge computing, robotics) ✨ NEW in v5.6.10
package/dist/index.js CHANGED
@@ -11383,12 +11383,14 @@ var ParallelAgentExecutor = class {
11383
11383
  totalAgents: plan.totalAgents,
11384
11384
  maxConcurrency: plan.maxConcurrency
11385
11385
  });
11386
+ let abortHandler;
11386
11387
  if (options.signal) {
11387
11388
  this.abortController = new AbortController();
11388
- options.signal.addEventListener("abort", () => {
11389
+ abortHandler = () => {
11389
11390
  logger.warn("Execution cancellation requested");
11390
11391
  this.abortController?.abort();
11391
- });
11392
+ };
11393
+ options.signal.addEventListener("abort", abortHandler);
11392
11394
  }
11393
11395
  const results = /* @__PURE__ */ new Map();
11394
11396
  const continueOnFailure = options.continueOnFailure ?? true;
@@ -11430,6 +11432,10 @@ var ParallelAgentExecutor = class {
11430
11432
  } catch (error) {
11431
11433
  logger.error("Execution failed", { error: error.message });
11432
11434
  throw error;
11435
+ } finally {
11436
+ if (abortHandler && options.signal) {
11437
+ options.signal.removeEventListener("abort", abortHandler);
11438
+ }
11433
11439
  }
11434
11440
  const totalDuration = Date.now() - startTime;
11435
11441
  const result = this.buildResult(graph, timeline, totalDuration);
@@ -11481,10 +11487,18 @@ var ParallelAgentExecutor = class {
11481
11487
  return null;
11482
11488
  }
11483
11489
  });
11484
- const timelineEntries = await Promise.all(promises);
11485
- const entriesToAdd = timelineEntries.filter((entry) => entry !== null);
11486
- if (entriesToAdd.length > 0) {
11487
- timeline.push(...entriesToAdd);
11490
+ try {
11491
+ const timelineEntries = await Promise.all(promises);
11492
+ const entriesToAdd = timelineEntries.filter((entry) => entry !== null);
11493
+ if (entriesToAdd.length > 0) {
11494
+ timeline.push(...entriesToAdd);
11495
+ }
11496
+ } catch (error) {
11497
+ logger.error("Unhandled error in parallel batch execution", {
11498
+ batch,
11499
+ error: error.message
11500
+ });
11501
+ throw error;
11488
11502
  }
11489
11503
  }
11490
11504
  /**
@@ -1,7 +1,13 @@
1
1
  # AutomatosX Agent Directory
2
2
 
3
+ **v5.6.21 Update - Stan Agent Implementation**:
4
+ - ✨ **New Best Practices Agent**: Stan (Software Engineering Standards Expert) - SOLID, design patterns, clean code, refactoring, software architecture
5
+ - 📚 **5 New Best Practices Abilities**: solid-principles, design-patterns, clean-code, refactoring, software-architecture (~8,200 lines)
6
+ - 🔧 **Enhanced Queenie**: Added base-level best-practices ability with delegation pattern to Stan
7
+ - 🤝 **Collaboration Model**: Queenie (quality/bugs/tests) ↔ Stan (standards/patterns/architecture)
8
+ - 🤖 **24 Total Agents**: Stan fills critical ownership gap for SOLID principles and architecture standards
9
+
3
10
  **v5.6.10 Update - Four New Specialist Agents (Completed in One Release)**:
4
- - ✨ **New Best Practices Agent**: Stan (Software Engineering Standards Expert) - SOLID, design patterns, clean code, refactoring, architecture
5
11
  - ✨ **New ERP Integration Agent**: Emma (ERP Integration Specialist) - SAP, Oracle, Dynamics 365, enterprise integration patterns
6
12
  - ✨ **New Figma Expert**: Fiona (Design-to-Code Specialist) - Figma API, design tokens, design-to-code automation, MCP integration
7
13
  - ✨ **New IoT/Embedded/Robotics Engineer**: Ivy (IoT Specialist) - MQTT, ROS2, FreeRTOS, K3s edge computing
@@ -190,7 +196,7 @@ Bob (Backend): "Optimize database queries"
190
196
  | Team | Depth 3 | Depth 2 | Depth 1 | Depth 0 |
191
197
  |------|---------|---------|---------|---------|
192
198
  | **Engineering** | Oliver, Dana | - | Felix, Maya, **Bob**, **Frank**, **Quinn**, **Astrid**, **Mira**, **Ivy** ✨ | Steve |
193
- | **Core/Quality** | - | **Queenie** | - | - |
199
+ | **Core/Quality** | - | **Queenie** | **Stan** | - |
194
200
  | **Business** | Tony | - | Paris, Eric | - |
195
201
  | **Design/Content** | - | - | **Fiona** ✨ | Debbee, Wendy |
196
202
  | **Data** | Dana | - | - | Daisy |
@@ -201,7 +207,7 @@ Bob (Backend): "Optimize database queries"
201
207
 
202
208
  - **3 Strategic Coordinators** (Depth 3): Tony, Oliver, Dana
203
209
  - **6 Tactical Coordinators** (Depth 1-2): Queenie (2), Paris, Felix, Maya, Eric, Cynthia
204
- - **9 Tactical Implementers** (Depth 1): Bob, Frank, Quinn (v5.6.9), Astrid (v5.6.9), Mira (v5.6.10), Stan (v5.6.10), Emma (v5.6.10), **Fiona** (v5.6.11), **Ivy** (v5.6.11)
210
+ - **9 Tactical Implementers** (Depth 1): Bob, Frank, Quinn (v5.6.9), Astrid (v5.6.9), Mira (v5.6.10), **Stan** (v5.6.21), Emma (v5.6.10), Fiona (v5.6.11), Ivy (v5.6.11)
205
211
  - **6 Pure Implementers** (Depth 0): Steve, Daisy, Debbee, Wendy, Rodman
206
212
 
207
213
  ---
@@ -416,17 +422,17 @@ Bob (Backend): "Optimize database queries"
416
422
 
417
423
  | Name | Agent | Expertise | Best For | Delegation Capability |
418
424
  |------|-------|-----------|----------|-----------------------|
419
- | **Queenie** | quality | **SOLE OWNER** of code-review & debugging | Multi-layer QA workflows, test coordination | 2 layers (QA → Implementation → Specialist) |
425
+ | **Queenie** | quality | **SHARED code-review** with Stan & **SOLE OWNER** of debugging/testing | Multi-layer QA workflows, test coordination | 2 layers (QA → Implementation → Specialist) |
420
426
 
421
427
  **Why Depth 2?**: Quality assurance requires coordinating complex workflows where implementers need to delegate to specialists (e.g., Backend implements tests → Security audits security aspects).
422
428
 
423
- #### Tactical Implementers (Depth 1) ⭐ NEW in v5.6.10
429
+ #### Tactical Implementers (Depth 1) ⭐ UPDATED in v5.6.21
424
430
 
425
431
  | Name | Agent | Expertise | Best For | Delegation Capability |
426
432
  |------|-------|-----------|----------|-----------------------|
427
- | **Stan** | best-practices | **Software engineering standards** - SOLID principles, design patterns (Gang of Four), clean code, refactoring techniques, software architecture (Layered, Microservices, Hexagonal, Event-Driven) ⭐ v5.6.10 | Code reviews, architecture validation, refactoring guidance, pattern recommendations | 1 layer (can consult implementers for code validation) |
433
+ | **Stan** | best-practices | **Software engineering standards** - SOLID principles, design patterns (Gang of Four), clean code, refactoring techniques, software architecture (Layered, Microservices, Hexagonal, Event-Driven) ⭐ v5.6.21 | Code reviews, architecture validation, refactoring guidance, pattern recommendations | 1 layer (can consult implementers for code validation) |
428
434
 
429
- **Stan's Best Practices Expertise (v5.6.10)**:
435
+ **Stan's Best Practices Expertise (v5.6.21)**:
430
436
  - **SOLID Principles**: SRP (Single Responsibility), OCP (Open/Closed), LSP (Liskov Substitution), ISP (Interface Segregation), DIP (Dependency Inversion)
431
437
  - **Design Patterns**: Creational (Singleton, Factory, Builder), Structural (Adapter, Decorator, Facade), Behavioral (Strategy, Observer, Command, Template Method)
432
438
  - **Clean Code**: Meaningful naming, small functions, DRY (Don't Repeat Yourself), YAGNI (You Aren't Gonna Need It), KISS (Keep It Simple)
@@ -0,0 +1,398 @@
1
+ # Clean Code Ability
2
+
3
+ Expert knowledge and application of clean code principles for writing maintainable, readable, and high-quality software.
4
+
5
+ ## Overview
6
+
7
+ Clean code is code that is easy to read, understand, and modify. It communicates intent clearly and minimizes cognitive load for future developers (including yourself).
8
+
9
+ ## Fundamental Principles
10
+
11
+ ### 1. Meaningful Names
12
+
13
+ **Rule**: Names should reveal intent without requiring comments
14
+
15
+ **Guidelines**:
16
+ - Use intention-revealing names
17
+ - Avoid disinformation and encodings
18
+ - Make meaningful distinctions
19
+ - Use pronounceable and searchable names
20
+ - Avoid mental mapping
21
+
22
+ **Examples**:
23
+ ```typescript
24
+ // ❌ BAD: Cryptic names
25
+ const d = new Date(); // elapsed time in days
26
+ const arr = ['Bob', 'Alice'];
27
+
28
+ // ✅ GOOD: Intention-revealing
29
+ const elapsedTimeInDays = new Date();
30
+ const userNames = ['Bob', 'Alice'];
31
+
32
+ // ❌ BAD: Hungarian notation, noise words
33
+ const strName = 'Bob';
34
+ const userData = { name: 'Bob' };
35
+ const userInfo = { name: 'Bob' }; // What's the difference?
36
+
37
+ // ✅ GOOD: Clean, semantic names
38
+ const userName = 'Bob';
39
+ const user = { name: 'Bob' };
40
+ const userProfile = { name: 'Bob', bio: '...' };
41
+ ```
42
+
43
+ **Variable Naming**:
44
+ - Use nouns or noun phrases
45
+ - Boolean: `isActive`, `hasPermission`, `canEdit`
46
+ - Collections: Use plural (`users`, `orders`, `products`)
47
+
48
+ **Function Naming**:
49
+ - Use verbs or verb phrases
50
+ - `getUser()`, `calculateTotal()`, `validateInput()`
51
+ - Boolean returning: `isValid()`, `hasErrors()`, `canProceed()`
52
+
53
+ **Class Naming**:
54
+ - Use nouns
55
+ - Avoid "Manager", "Processor", "Data" suffixes
56
+ - `UserRepository`, `EmailService`, `OrderValidator`
57
+
58
+ ### 2. Functions
59
+
60
+ **Rule**: Functions should do one thing, do it well, and do it only
61
+
62
+ **Small Functions**:
63
+ - Keep functions small (< 20 lines ideal)
64
+ - Each function should be one level of abstraction
65
+ - Functions should not have side effects
66
+
67
+ **Single Responsibility**:
68
+ ```typescript
69
+ // ❌ BAD: Multiple responsibilities
70
+ function processUser(user: User) {
71
+ validateUser(user);
72
+ saveToDatabase(user);
73
+ sendEmail(user);
74
+ logAudit(user);
75
+ updateCache(user);
76
+ }
77
+
78
+ // ✅ GOOD: Single responsibility
79
+ function registerUser(user: User) {
80
+ const validated = validateUser(user);
81
+ return userRepository.save(validated);
82
+ }
83
+
84
+ function notifyUserRegistered(user: User) {
85
+ emailService.sendWelcome(user);
86
+ auditLogger.log('USER_REGISTERED', user.id);
87
+ }
88
+ ```
89
+
90
+ **Function Arguments**:
91
+ - Zero arguments (niladic) is ideal
92
+ - One argument (monadic) is good
93
+ - Two arguments (dyadic) are okay
94
+ - Three+ arguments (triadic+) require justification
95
+ - Avoid flag arguments (split into two functions)
96
+
97
+ **Examples**:
98
+ ```typescript
99
+ // ❌ BAD: Too many arguments
100
+ function createUser(name: string, email: string, age: number, role: string, active: boolean) {}
101
+
102
+ // ✅ GOOD: Use object parameter
103
+ function createUser(userData: UserData) {}
104
+
105
+ // ❌ BAD: Flag argument
106
+ function saveUser(user: User, validate: boolean) {}
107
+
108
+ // ✅ GOOD: Separate functions
109
+ function saveUser(user: User) {}
110
+ function saveUserWithoutValidation(user: User) {}
111
+ ```
112
+
113
+ **Command Query Separation**:
114
+ - Functions should either DO something or ANSWER something, not both
115
+ - Commands modify state, queries return values
116
+
117
+ ```typescript
118
+ // ❌ BAD: Does both
119
+ function setAndReturn(value: string): boolean {
120
+ this.value = value; // Command
121
+ return this.value === value; // Query
122
+ }
123
+
124
+ // ✅ GOOD: Separated
125
+ function setValue(value: string): void {
126
+ this.value = value;
127
+ }
128
+
129
+ function getValue(): string {
130
+ return this.value;
131
+ }
132
+ ```
133
+
134
+ ### 3. Comments
135
+
136
+ **Rule**: Good code mostly documents itself; use comments wisely
137
+
138
+ **When to Comment**:
139
+ - Explain WHY, not WHAT
140
+ - Clarify complex business rules
141
+ - Warn of consequences
142
+ - TODO/FIXME notes (with tickets)
143
+ - Legal comments (copyright, license)
144
+ - API documentation (JSDoc, docstrings)
145
+
146
+ **When NOT to Comment**:
147
+ - Don't comment bad code, rewrite it
148
+ - Avoid redundant comments
149
+ - Don't comment out code (use version control)
150
+ - Avoid journal comments
151
+ - Avoid position markers
152
+
153
+ **Examples**:
154
+ ```typescript
155
+ // ❌ BAD: Redundant comments
156
+ // Get the user by ID
157
+ function getUserById(id: string): User {
158
+ // Return the user
159
+ return users.find(u => u.id === id);
160
+ }
161
+
162
+ // ✅ GOOD: Self-documenting code
163
+ function getUserById(id: string): User {
164
+ return users.find(u => u.id === id);
165
+ }
166
+
167
+ // ❌ BAD: Commented-out code
168
+ function processOrder(order: Order) {
169
+ // validateOrder(order);
170
+ // checkInventory(order);
171
+ saveOrder(order);
172
+ }
173
+
174
+ // ✅ GOOD: Clear intent without noise
175
+ /**
176
+ * Processes order for payment and fulfillment.
177
+ * NOTE: Validation and inventory check are handled upstream.
178
+ */
179
+ function processOrder(order: Order) {
180
+ saveOrder(order);
181
+ }
182
+ ```
183
+
184
+ ### 4. Formatting
185
+
186
+ **Rule**: Code formatting is about communication
187
+
188
+ **Vertical Formatting**:
189
+ - Small files are better (< 500 lines)
190
+ - Blank lines separate concepts
191
+ - Related code should be close together
192
+ - Declare variables close to usage
193
+ - Dependent functions should be close
194
+
195
+ **Horizontal Formatting**:
196
+ - Keep lines short (< 120 characters)
197
+ - Use whitespace to associate related things
198
+ - Indent to show hierarchy
199
+
200
+ **Example**:
201
+ ```typescript
202
+ // ✅ GOOD: Well-formatted
203
+ class UserService {
204
+ constructor(
205
+ private userRepository: UserRepository,
206
+ private emailService: EmailService
207
+ ) {}
208
+
209
+ async registerUser(userData: UserData): Promise<User> {
210
+ const validated = this.validateUserData(userData);
211
+ const user = await this.userRepository.create(validated);
212
+ await this.sendWelcomeEmail(user);
213
+ return user;
214
+ }
215
+
216
+ private validateUserData(userData: UserData): UserData {
217
+ if (!userData.email) throw new Error('Email required');
218
+ if (!userData.name) throw new Error('Name required');
219
+ return userData;
220
+ }
221
+
222
+ private async sendWelcomeEmail(user: User): Promise<void> {
223
+ await this.emailService.send(user.email, 'Welcome!');
224
+ }
225
+ }
226
+ ```
227
+
228
+ ### 5. Objects and Data Structures
229
+
230
+ **Rule**: Objects hide data, expose behavior. Data structures expose data, have no behavior.
231
+
232
+ **Law of Demeter**:
233
+ - Don't talk to strangers
234
+ - Method should only call methods on:
235
+ - Itself
236
+ - Its parameters
237
+ - Objects it creates
238
+ - Its direct dependencies
239
+
240
+ ```typescript
241
+ // ❌ BAD: Violates Law of Demeter (train wreck)
242
+ const street = user.getAddress().getStreet().getName();
243
+
244
+ // ✅ GOOD: Tell, don't ask
245
+ const street = user.getStreetName();
246
+
247
+ // Inside User class:
248
+ getStreetName(): string {
249
+ return this.address.street.name;
250
+ }
251
+ ```
252
+
253
+ ### 6. Error Handling
254
+
255
+ **Rule**: Error handling is important, but it shouldn't obscure logic
256
+
257
+ **Use Exceptions**:
258
+ ```typescript
259
+ // ❌ BAD: Error codes
260
+ function processPayment(amount: number): number {
261
+ if (amount <= 0) return -1;
262
+ if (insufficientFunds()) return -2;
263
+ return 0; // success
264
+ }
265
+
266
+ // ✅ GOOD: Exceptions
267
+ function processPayment(amount: number): void {
268
+ if (amount <= 0) {
269
+ throw new InvalidAmountError('Amount must be positive');
270
+ }
271
+ if (insufficientFunds()) {
272
+ throw new InsufficientFundsError('Not enough balance');
273
+ }
274
+ // Process payment
275
+ }
276
+ ```
277
+
278
+ **Don't Return Null**:
279
+ ```typescript
280
+ // ❌ BAD: Null checks everywhere
281
+ const users = getUsers();
282
+ if (users !== null) {
283
+ for (const user of users) {
284
+ if (user !== null) {
285
+ // ...
286
+ }
287
+ }
288
+ }
289
+
290
+ // ✅ GOOD: Return empty collection
291
+ function getUsers(): User[] {
292
+ return users ?? [];
293
+ }
294
+
295
+ // Or use Optional/Maybe pattern
296
+ function getUserById(id: string): User | undefined {
297
+ return users.find(u => u.id === id);
298
+ }
299
+ ```
300
+
301
+ ### 7. DRY (Don't Repeat Yourself)
302
+
303
+ **Rule**: Every piece of knowledge should have a single representation in the system
304
+
305
+ ```typescript
306
+ // ❌ BAD: Duplication
307
+ function calculateOrderTotal(order: Order): number {
308
+ let total = 0;
309
+ for (const item of order.items) {
310
+ total += item.price * item.quantity;
311
+ }
312
+ total += total * 0.1; // Tax
313
+ total += 5; // Shipping
314
+ return total;
315
+ }
316
+
317
+ function calculateInvoiceTotal(invoice: Invoice): number {
318
+ let total = 0;
319
+ for (const item of invoice.items) {
320
+ total += item.price * item.quantity;
321
+ }
322
+ total += total * 0.1; // Tax
323
+ total += 5; // Shipping
324
+ return total;
325
+ }
326
+
327
+ // ✅ GOOD: Extract common logic
328
+ function calculateSubtotal(items: Item[]): number {
329
+ return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
330
+ }
331
+
332
+ function addTaxAndShipping(subtotal: number): number {
333
+ const tax = subtotal * 0.1;
334
+ const shipping = 5;
335
+ return subtotal + tax + shipping;
336
+ }
337
+
338
+ function calculateTotal(items: Item[]): number {
339
+ const subtotal = calculateSubtotal(items);
340
+ return addTaxAndShipping(subtotal);
341
+ }
342
+ ```
343
+
344
+ ## Code Quality Checklist
345
+
346
+ **Naming**:
347
+ - [ ] All names reveal intent
348
+ - [ ] No abbreviations or encodings
349
+ - [ ] Boolean names start with is/has/can
350
+ - [ ] Collections are plural
351
+ - [ ] Functions are verbs, classes are nouns
352
+
353
+ **Functions**:
354
+ - [ ] Functions are small (< 20 lines)
355
+ - [ ] Functions do one thing
356
+ - [ ] One level of abstraction per function
357
+ - [ ] Few arguments (prefer 0-2)
358
+ - [ ] No flag arguments
359
+ - [ ] No side effects
360
+
361
+ **Comments**:
362
+ - [ ] Comments explain WHY, not WHAT
363
+ - [ ] No commented-out code
364
+ - [ ] No redundant comments
365
+ - [ ] API documentation present where needed
366
+
367
+ **Formatting**:
368
+ - [ ] Consistent indentation
369
+ - [ ] Lines < 120 characters
370
+ - [ ] Blank lines separate concepts
371
+ - [ ] Related code is together
372
+
373
+ **Error Handling**:
374
+ - [ ] Use exceptions, not error codes
375
+ - [ ] Don't return null (use empty collections or Optional)
376
+ - [ ] Exceptions are specific and meaningful
377
+
378
+ **General**:
379
+ - [ ] No duplication (DRY)
380
+ - [ ] Code is self-documenting
381
+ - [ ] Tests exist and pass
382
+ - [ ] No dead code
383
+
384
+ ## The Boy Scout Rule
385
+
386
+ **"Leave the code better than you found it."**
387
+
388
+ - Clean up small messes when you see them
389
+ - Improve names, extract functions, add tests
390
+ - Continuous improvement over time
391
+ - Don't need permission for small improvements
392
+
393
+ ## Further Reading
394
+
395
+ - "Clean Code" by Robert C. Martin
396
+ - "Code Complete" by Steve McConnell
397
+ - "The Pragmatic Programmer" by Hunt and Thomas
398
+ - "Refactoring" by Martin Fowler