@defai.digital/automatosx 5.0.1

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +2877 -0
  2. package/CONTRIBUTING.md +357 -0
  3. package/FAQ.md +604 -0
  4. package/FIXES.md +277 -0
  5. package/LICENSE +190 -0
  6. package/README.md +603 -0
  7. package/REVIEW-REPORT.md +278 -0
  8. package/TROUBLESHOOTING.md +612 -0
  9. package/automatosx.config.json +219 -0
  10. package/dist/index.d.ts +2 -0
  11. package/dist/index.js +11806 -0
  12. package/dist/index.js.map +1 -0
  13. package/docs/README.md +227 -0
  14. package/docs/guide/core-concepts.md +568 -0
  15. package/docs/guide/installation.md +406 -0
  16. package/docs/guide/introduction.md +199 -0
  17. package/docs/guide/quick-start.md +387 -0
  18. package/docs/index.md +132 -0
  19. package/docs/reference/cli-commands.md +894 -0
  20. package/docs/tutorials/first-agent.md +691 -0
  21. package/docs/tutorials/memory-management.md +785 -0
  22. package/examples/AGENTS_INFO.md +293 -0
  23. package/examples/README.md +434 -0
  24. package/examples/abilities/best-practices.md +102 -0
  25. package/examples/abilities/code-generation.md +1035 -0
  26. package/examples/abilities/code-review.md +42 -0
  27. package/examples/abilities/content-creation.md +97 -0
  28. package/examples/abilities/debugging.md +43 -0
  29. package/examples/abilities/documentation.md +54 -0
  30. package/examples/abilities/error-analysis.md +107 -0
  31. package/examples/abilities/general-assistance.md +26 -0
  32. package/examples/abilities/our-architecture-decisions.md +242 -0
  33. package/examples/abilities/our-code-review-checklist.md +217 -0
  34. package/examples/abilities/our-coding-standards.md +389 -0
  35. package/examples/abilities/our-project-structure.md +502 -0
  36. package/examples/abilities/performance-analysis.md +56 -0
  37. package/examples/abilities/problem-solving.md +50 -0
  38. package/examples/abilities/refactoring.md +49 -0
  39. package/examples/abilities/security-audit.md +65 -0
  40. package/examples/abilities/task-planning.md +65 -0
  41. package/examples/abilities/technical-writing.md +77 -0
  42. package/examples/abilities/testing.md +47 -0
  43. package/examples/abilities/troubleshooting.md +80 -0
  44. package/examples/agents/assistant.yaml +45 -0
  45. package/examples/agents/backend.yaml +60 -0
  46. package/examples/agents/ceo.yaml +47 -0
  47. package/examples/agents/coder.yaml +388 -0
  48. package/examples/agents/cto.yaml +47 -0
  49. package/examples/agents/data.yaml +47 -0
  50. package/examples/agents/debugger.yaml +59 -0
  51. package/examples/agents/design.yaml +46 -0
  52. package/examples/agents/devops.yaml +47 -0
  53. package/examples/agents/frontend.yaml +61 -0
  54. package/examples/agents/product.yaml +47 -0
  55. package/examples/agents/quality.yaml +47 -0
  56. package/examples/agents/reviewer.yaml +49 -0
  57. package/examples/agents/security.yaml +47 -0
  58. package/examples/agents/writer.yaml +66 -0
  59. package/examples/claude/commands/ax:agent.md +37 -0
  60. package/examples/claude/commands/ax:clear.md +22 -0
  61. package/examples/claude/commands/ax:init.md +25 -0
  62. package/examples/claude/commands/ax:list.md +19 -0
  63. package/examples/claude/commands/ax:memory.md +25 -0
  64. package/examples/claude/commands/ax:status.md +24 -0
  65. package/examples/claude/commands/ax:update.md +28 -0
  66. package/examples/claude/mcp/automatosx.json +74 -0
  67. package/examples/templates/analyst.yaml +60 -0
  68. package/examples/templates/basic-agent.yaml +28 -0
  69. package/examples/templates/designer.yaml +69 -0
  70. package/examples/templates/developer.yaml +60 -0
  71. package/examples/templates/qa-specialist.yaml +71 -0
  72. package/examples/use-cases/01-web-app-development.md +374 -0
  73. package/package.json +86 -0
  74. package/scripts/check-release.js +128 -0
  75. package/scripts/real-provider-test.sh +357 -0
  76. package/scripts/smoke-test.sh +286 -0
  77. package/tsup.config.ts +16 -0
@@ -0,0 +1,1035 @@
1
+ # Code Generation Mastery
2
+
3
+ Master the art of generating high-quality, production-ready code across multiple languages and paradigms. This ability covers language-specific patterns, best practices, error handling, testing, and real-world code examples.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [TypeScript/JavaScript Patterns](#typescript-javascript-patterns)
8
+ 2. [Python Best Practices](#python-best-practices)
9
+ 3. [Error Handling Strategies](#error-handling-strategies)
10
+ 4. [API Design Patterns](#api-design-patterns)
11
+ 5. [Testing Code Generation](#testing-code-generation)
12
+ 6. [Common Pitfalls](#common-pitfalls)
13
+ 7. [Quick Reference](#quick-reference)
14
+
15
+ ---
16
+
17
+ ## TypeScript/JavaScript Patterns
18
+
19
+ ### Type-Safe Function Design
20
+
21
+ ```typescript
22
+ // ✅ Good: Type-safe with proper error handling
23
+ async function fetchUser(id: string): Promise<User> {
24
+ if (!id || id.trim() === '') {
25
+ throw new Error('User ID is required');
26
+ }
27
+
28
+ try {
29
+ const response = await fetch(`/api/users/${id}`);
30
+
31
+ if (!response.ok) {
32
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
33
+ }
34
+
35
+ const data = await response.json();
36
+ return validateUser(data); // Validate response structure
37
+ } catch (error) {
38
+ console.error('Failed to fetch user:', error);
39
+ throw new Error(`Failed to fetch user ${id}: ${(error as Error).message}`);
40
+ }
41
+ }
42
+
43
+ // ❌ Bad: No types, poor error handling, no validation
44
+ async function fetchUser(id) {
45
+ return await fetch(`/api/users/${id}`).then(r => r.json());
46
+ }
47
+ ```
48
+
49
+ **💡 Why the good example is better:**
50
+
51
+ - ✅ Type safety: `Promise<User>` ensures return type
52
+ - ✅ Input validation: Checks for empty/invalid ID
53
+ - ✅ Error handling: Try-catch with specific error messages
54
+ - ✅ HTTP status check: Validates response before parsing
55
+ - ✅ Data validation: `validateUser()` ensures correct structure
56
+ - ✅ Error context: Logs and wraps errors with context
57
+
58
+ ---
59
+
60
+ ### Interface and Type Design
61
+
62
+ ```typescript
63
+ // ✅ Good: Well-designed types with documentation
64
+ /**
65
+ * User profile data
66
+ */
67
+ interface User {
68
+ id: string;
69
+ email: string;
70
+ name: string;
71
+ role: UserRole;
72
+ createdAt: Date;
73
+ updatedAt: Date;
74
+ metadata?: Record<string, unknown>;
75
+ }
76
+
77
+ /**
78
+ * User role enumeration
79
+ */
80
+ enum UserRole {
81
+ ADMIN = 'admin',
82
+ USER = 'user',
83
+ GUEST = 'guest'
84
+ }
85
+
86
+ /**
87
+ * Create user request payload
88
+ */
89
+ interface CreateUserRequest {
90
+ email: string;
91
+ name: string;
92
+ role?: UserRole; // Optional, defaults to USER
93
+ }
94
+
95
+ /**
96
+ * Update user request payload
97
+ */
98
+ type UpdateUserRequest = Partial<Omit<User, 'id' | 'createdAt'>>;
99
+
100
+ // ❌ Bad: Vague types, no documentation
101
+ interface UserData {
102
+ data: any;
103
+ stuff: object;
104
+ things?: string[];
105
+ }
106
+ ```
107
+
108
+ **💡 Best Practices:**
109
+
110
+ - ✅ Use descriptive interface names (User, not UserData)
111
+ - ✅ Document with JSDoc comments
112
+ - ✅ Use enums for fixed values (UserRole)
113
+ - ✅ Use utility types (Partial, Omit, Pick) for variations
114
+ - ✅ Avoid `any` and `object` - be specific
115
+ - ✅ Mark optional fields explicitly with `?`
116
+
117
+ ---
118
+
119
+ ### Class Design with SOLID Principles
120
+
121
+ ```typescript
122
+ // ✅ Good: Single Responsibility, Dependency Injection
123
+ /**
124
+ * User repository for database operations
125
+ */
126
+ class UserRepository {
127
+ constructor(private db: Database) {}
128
+
129
+ async findById(id: string): Promise<User | null> {
130
+ const row = await this.db.query(
131
+ 'SELECT * FROM users WHERE id = ?',
132
+ [id]
133
+ );
134
+ return row ? this.mapToUser(row) : null;
135
+ }
136
+
137
+ async create(data: CreateUserRequest): Promise<User> {
138
+ const now = new Date();
139
+ const user: User = {
140
+ id: generateId(),
141
+ email: data.email,
142
+ name: data.name,
143
+ role: data.role ?? UserRole.USER,
144
+ createdAt: now,
145
+ updatedAt: now
146
+ };
147
+
148
+ await this.db.query(
149
+ 'INSERT INTO users (id, email, name, role, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)',
150
+ [user.id, user.email, user.name, user.role, user.createdAt, user.updatedAt]
151
+ );
152
+
153
+ return user;
154
+ }
155
+
156
+ private mapToUser(row: DatabaseRow): User {
157
+ return {
158
+ id: row.id,
159
+ email: row.email,
160
+ name: row.name,
161
+ role: row.role as UserRole,
162
+ createdAt: new Date(row.created_at),
163
+ updatedAt: new Date(row.updated_at)
164
+ };
165
+ }
166
+ }
167
+
168
+ /**
169
+ * User service for business logic
170
+ */
171
+ class UserService {
172
+ constructor(
173
+ private userRepo: UserRepository,
174
+ private emailService: EmailService
175
+ ) {}
176
+
177
+ async registerUser(data: CreateUserRequest): Promise<User> {
178
+ // Validation
179
+ if (!this.isValidEmail(data.email)) {
180
+ throw new Error('Invalid email format');
181
+ }
182
+
183
+ // Check if user exists
184
+ const existing = await this.userRepo.findByEmail(data.email);
185
+ if (existing) {
186
+ throw new Error('Email already registered');
187
+ }
188
+
189
+ // Create user
190
+ const user = await this.userRepo.create(data);
191
+
192
+ // Send welcome email (async, don't block)
193
+ this.emailService.sendWelcome(user.email).catch(error => {
194
+ console.error('Failed to send welcome email:', error);
195
+ });
196
+
197
+ return user;
198
+ }
199
+
200
+ private isValidEmail(email: string): boolean {
201
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
202
+ return emailRegex.test(email);
203
+ }
204
+ }
205
+
206
+ // ❌ Bad: God class, tight coupling, mixed concerns
207
+ class UserManager {
208
+ async doEverything(email, name) {
209
+ // Database access mixed with business logic
210
+ const db = new Database();
211
+ const user = db.query('INSERT INTO users...');
212
+
213
+ // Email sending mixed with user creation
214
+ const smtp = new SmtpClient();
215
+ smtp.send(email, 'Welcome');
216
+
217
+ return user;
218
+ }
219
+ }
220
+ ```
221
+
222
+ **💡 SOLID Principles Applied:**
223
+
224
+ - ✅ **S**ingle Responsibility: UserRepository (data), UserService (logic)
225
+ - ✅ **O**pen/Closed: Extensible through interfaces
226
+ - ✅ **L**iskov Substitution: Can swap Database implementations
227
+ - ✅ **I**nterface Segregation: Small, focused interfaces
228
+ - ✅ **D**ependency Inversion: Depend on abstractions (Database interface)
229
+
230
+ ---
231
+
232
+ ## Python Best Practices
233
+
234
+ ### Type Hints and Validation
235
+
236
+ ```python
237
+ # ✅ Good: Type hints with runtime validation
238
+ from typing import Optional, List, Dict, Any
239
+ from dataclasses import dataclass
240
+ from datetime import datetime
241
+ import re
242
+
243
+ @dataclass
244
+ class User:
245
+ """User profile data"""
246
+ id: str
247
+ email: str
248
+ name: str
249
+ role: str
250
+ created_at: datetime
251
+ updated_at: datetime
252
+ metadata: Optional[Dict[str, Any]] = None
253
+
254
+ def __post_init__(self):
255
+ """Validate data after initialization"""
256
+ if not self.id:
257
+ raise ValueError("User ID is required")
258
+ if not self._is_valid_email(self.email):
259
+ raise ValueError(f"Invalid email format: {self.email}")
260
+ if self.role not in ['admin', 'user', 'guest']:
261
+ raise ValueError(f"Invalid role: {self.role}")
262
+
263
+ @staticmethod
264
+ def _is_valid_email(email: str) -> bool:
265
+ """Validate email format"""
266
+ pattern = r'^[^\s@]+@[^\s@]+\.[^\s@]+$'
267
+ return re.match(pattern, email) is not None
268
+
269
+ class UserRepository:
270
+ """User repository for database operations"""
271
+
272
+ def __init__(self, db_connection):
273
+ self._db = db_connection
274
+
275
+ def find_by_id(self, user_id: str) -> Optional[User]:
276
+ """
277
+ Find user by ID
278
+
279
+ Args:
280
+ user_id: User ID to search for
281
+
282
+ Returns:
283
+ User object if found, None otherwise
284
+
285
+ Raises:
286
+ DatabaseError: If database query fails
287
+ """
288
+ try:
289
+ row = self._db.query(
290
+ "SELECT * FROM users WHERE id = ?",
291
+ (user_id,)
292
+ )
293
+ return self._map_to_user(row) if row else None
294
+ except Exception as e:
295
+ raise DatabaseError(f"Failed to find user {user_id}") from e
296
+
297
+ def create(self, email: str, name: str, role: str = 'user') -> User:
298
+ """
299
+ Create new user
300
+
301
+ Args:
302
+ email: User email address
303
+ name: User full name
304
+ role: User role (default: 'user')
305
+
306
+ Returns:
307
+ Created User object
308
+
309
+ Raises:
310
+ ValueError: If validation fails
311
+ DatabaseError: If database insert fails
312
+ """
313
+ now = datetime.utcnow()
314
+ user = User(
315
+ id=self._generate_id(),
316
+ email=email,
317
+ name=name,
318
+ role=role,
319
+ created_at=now,
320
+ updated_at=now
321
+ )
322
+
323
+ try:
324
+ self._db.execute(
325
+ "INSERT INTO users (id, email, name, role, created_at, updated_at) "
326
+ "VALUES (?, ?, ?, ?, ?, ?)",
327
+ (user.id, user.email, user.name, user.role, user.created_at, user.updated_at)
328
+ )
329
+ self._db.commit()
330
+ except Exception as e:
331
+ self._db.rollback()
332
+ raise DatabaseError(f"Failed to create user") from e
333
+
334
+ return user
335
+
336
+ def _map_to_user(self, row: Dict[str, Any]) -> User:
337
+ """Map database row to User object"""
338
+ return User(
339
+ id=row['id'],
340
+ email=row['email'],
341
+ name=row['name'],
342
+ role=row['role'],
343
+ created_at=datetime.fromisoformat(row['created_at']),
344
+ updated_at=datetime.fromisoformat(row['updated_at']),
345
+ metadata=row.get('metadata')
346
+ )
347
+
348
+ @staticmethod
349
+ def _generate_id() -> str:
350
+ """Generate unique user ID"""
351
+ import uuid
352
+ return str(uuid.uuid4())
353
+
354
+ # ❌ Bad: No types, no validation, poor error handling
355
+ class UserRepo:
356
+ def get_user(self, id):
357
+ return self.db.query("SELECT * FROM users WHERE id = " + id) # SQL injection!
358
+
359
+ def add_user(self, data):
360
+ self.db.insert(data) # No validation, no error handling
361
+ ```
362
+
363
+ **💡 Python Best Practices:**
364
+
365
+ - ✅ Type hints for all parameters and returns
366
+ - ✅ Dataclasses for simple data structures
367
+ - ✅ `__post_init__` for validation
368
+ - ✅ Docstrings with Args/Returns/Raises
369
+ - ✅ Use `from ... import Error` for exception chaining
370
+ - ✅ Parameterized queries (prevent SQL injection)
371
+ - ✅ Transaction management (commit/rollback)
372
+
373
+ ---
374
+
375
+ ## Error Handling Strategies
376
+
377
+ ### Explicit Error Handling (TypeScript)
378
+
379
+ ```typescript
380
+ // ✅ Good: Explicit error types with context
381
+ class ValidationError extends Error {
382
+ constructor(
383
+ message: string,
384
+ public field: string,
385
+ public value: any
386
+ ) {
387
+ super(message);
388
+ this.name = 'ValidationError';
389
+ }
390
+ }
391
+
392
+ class NotFoundError extends Error {
393
+ constructor(
394
+ message: string,
395
+ public resource: string,
396
+ public id: string
397
+ ) {
398
+ super(message);
399
+ this.name = 'NotFoundError';
400
+ }
401
+ }
402
+
403
+ class UserService {
404
+ async getUser(id: string): Promise<User> {
405
+ // Input validation
406
+ if (!id || id.trim() === '') {
407
+ throw new ValidationError(
408
+ 'User ID is required',
409
+ 'id',
410
+ id
411
+ );
412
+ }
413
+
414
+ // Fetch user
415
+ const user = await this.userRepo.findById(id);
416
+
417
+ if (!user) {
418
+ throw new NotFoundError(
419
+ `User not found`,
420
+ 'User',
421
+ id
422
+ );
423
+ }
424
+
425
+ return user;
426
+ }
427
+
428
+ async createUser(data: CreateUserRequest): Promise<User> {
429
+ try {
430
+ // Validate email
431
+ if (!this.isValidEmail(data.email)) {
432
+ throw new ValidationError(
433
+ 'Invalid email format',
434
+ 'email',
435
+ data.email
436
+ );
437
+ }
438
+
439
+ // Check for duplicates
440
+ const existing = await this.userRepo.findByEmail(data.email);
441
+ if (existing) {
442
+ throw new ValidationError(
443
+ 'Email already registered',
444
+ 'email',
445
+ data.email
446
+ );
447
+ }
448
+
449
+ // Create user
450
+ return await this.userRepo.create(data);
451
+ } catch (error) {
452
+ // Re-throw known errors
453
+ if (error instanceof ValidationError || error instanceof NotFoundError) {
454
+ throw error;
455
+ }
456
+
457
+ // Wrap unknown errors
458
+ throw new Error(
459
+ `Failed to create user: ${(error as Error).message}`
460
+ );
461
+ }
462
+ }
463
+ }
464
+
465
+ // API layer error handling
466
+ async function handleCreateUser(req: Request, res: Response) {
467
+ try {
468
+ const user = await userService.createUser(req.body);
469
+ res.status(201).json(user);
470
+ } catch (error) {
471
+ if (error instanceof ValidationError) {
472
+ res.status(400).json({
473
+ error: 'Validation failed',
474
+ field: error.field,
475
+ message: error.message
476
+ });
477
+ } else if (error instanceof NotFoundError) {
478
+ res.status(404).json({
479
+ error: 'Not found',
480
+ resource: error.resource,
481
+ message: error.message
482
+ });
483
+ } else {
484
+ console.error('Unexpected error:', error);
485
+ res.status(500).json({
486
+ error: 'Internal server error',
487
+ message: 'An unexpected error occurred'
488
+ });
489
+ }
490
+ }
491
+ }
492
+
493
+ // ❌ Bad: Generic errors with no context
494
+ async function getUser(id) {
495
+ const user = await db.query(...);
496
+ if (!user) {
497
+ throw new Error('Error'); // No context!
498
+ }
499
+ return user;
500
+ }
501
+ ```
502
+
503
+ **💡 Error Handling Principles:**
504
+
505
+ - ✅ Create custom error classes for different scenarios
506
+ - ✅ Include context (field, value, resource, id)
507
+ - ✅ Re-throw known errors, wrap unknown errors
508
+ - ✅ Map errors to appropriate HTTP status codes
509
+ - ✅ Don't expose internal errors to clients
510
+ - ✅ Log unexpected errors for debugging
511
+
512
+ ---
513
+
514
+ ## API Design Patterns
515
+
516
+ ### RESTful API Design
517
+
518
+ ```typescript
519
+ // ✅ Good: RESTful API with proper structure
520
+ import express, { Router } from 'express';
521
+ import { body, param, validationResult } from 'express-validator';
522
+
523
+ const router = Router();
524
+
525
+ /**
526
+ * GET /api/users/:id
527
+ * Get user by ID
528
+ */
529
+ router.get(
530
+ '/users/:id',
531
+ [
532
+ param('id').isUUID().withMessage('Invalid user ID format')
533
+ ],
534
+ async (req, res, next) => {
535
+ try {
536
+ // Validation
537
+ const errors = validationResult(req);
538
+ if (!errors.isEmpty()) {
539
+ return res.status(400).json({ errors: errors.array() });
540
+ }
541
+
542
+ // Fetch user
543
+ const user = await userService.getUser(req.params.id);
544
+
545
+ res.json({
546
+ data: user,
547
+ meta: {
548
+ requestId: req.id,
549
+ timestamp: new Date().toISOString()
550
+ }
551
+ });
552
+ } catch (error) {
553
+ next(error); // Pass to error handler middleware
554
+ }
555
+ }
556
+ );
557
+
558
+ /**
559
+ * POST /api/users
560
+ * Create new user
561
+ */
562
+ router.post(
563
+ '/users',
564
+ [
565
+ body('email').isEmail().withMessage('Invalid email format'),
566
+ body('name').trim().notEmpty().withMessage('Name is required'),
567
+ body('role').optional().isIn(['admin', 'user', 'guest']).withMessage('Invalid role')
568
+ ],
569
+ async (req, res, next) => {
570
+ try {
571
+ // Validation
572
+ const errors = validationResult(req);
573
+ if (!errors.isEmpty()) {
574
+ return res.status(400).json({ errors: errors.array() });
575
+ }
576
+
577
+ // Create user
578
+ const user = await userService.createUser(req.body);
579
+
580
+ res.status(201).json({
581
+ data: user,
582
+ meta: {
583
+ requestId: req.id,
584
+ timestamp: new Date().toISOString()
585
+ }
586
+ });
587
+ } catch (error) {
588
+ next(error);
589
+ }
590
+ }
591
+ );
592
+
593
+ /**
594
+ * PATCH /api/users/:id
595
+ * Update user (partial)
596
+ */
597
+ router.patch(
598
+ '/users/:id',
599
+ [
600
+ param('id').isUUID(),
601
+ body('email').optional().isEmail(),
602
+ body('name').optional().trim().notEmpty(),
603
+ body('role').optional().isIn(['admin', 'user', 'guest'])
604
+ ],
605
+ async (req, res, next) => {
606
+ try {
607
+ const errors = validationResult(req);
608
+ if (!errors.isEmpty()) {
609
+ return res.status(400).json({ errors: errors.array() });
610
+ }
611
+
612
+ const user = await userService.updateUser(req.params.id, req.body);
613
+
614
+ res.json({
615
+ data: user,
616
+ meta: {
617
+ requestId: req.id,
618
+ timestamp: new Date().toISOString()
619
+ }
620
+ });
621
+ } catch (error) {
622
+ next(error);
623
+ }
624
+ }
625
+ );
626
+
627
+ /**
628
+ * DELETE /api/users/:id
629
+ * Delete user
630
+ */
631
+ router.delete(
632
+ '/users/:id',
633
+ [
634
+ param('id').isUUID()
635
+ ],
636
+ async (req, res, next) => {
637
+ try {
638
+ const errors = validationResult(req);
639
+ if (!errors.isEmpty()) {
640
+ return res.status(400).json({ errors: errors.array() });
641
+ }
642
+
643
+ await userService.deleteUser(req.params.id);
644
+
645
+ res.status(204).send(); // No content
646
+ } catch (error) {
647
+ next(error);
648
+ }
649
+ }
650
+ );
651
+
652
+ // Error handler middleware
653
+ router.use((error: Error, req: Request, res: Response, next: NextFunction) => {
654
+ if (error instanceof ValidationError) {
655
+ return res.status(400).json({
656
+ error: {
657
+ type: 'ValidationError',
658
+ message: error.message,
659
+ field: error.field
660
+ }
661
+ });
662
+ }
663
+
664
+ if (error instanceof NotFoundError) {
665
+ return res.status(404).json({
666
+ error: {
667
+ type: 'NotFoundError',
668
+ message: error.message,
669
+ resource: error.resource
670
+ }
671
+ });
672
+ }
673
+
674
+ // Unexpected errors
675
+ console.error('Unexpected error:', error);
676
+ res.status(500).json({
677
+ error: {
678
+ type: 'InternalError',
679
+ message: 'An unexpected error occurred'
680
+ }
681
+ });
682
+ });
683
+
684
+ // ❌ Bad: Inconsistent, no validation, poor error handling
685
+ router.get('/getUser', async (req, res) => {
686
+ const user = await db.query('SELECT * FROM users WHERE id = ' + req.query.id); // SQL injection!
687
+ res.send(user);
688
+ });
689
+
690
+ router.post('/user/create', async (req, res) => {
691
+ const user = await db.insert(req.body); // No validation!
692
+ res.send({ success: true, user });
693
+ });
694
+ ```
695
+
696
+ **💡 RESTful API Best Practices:**
697
+
698
+ - ✅ Use proper HTTP methods (GET, POST, PATCH, DELETE)
699
+ - ✅ Use resource-based URLs (`/users/:id`, not `/getUser`)
700
+ - ✅ Validate all inputs with express-validator
701
+ - ✅ Return appropriate HTTP status codes (200, 201, 400, 404, 500)
702
+ - ✅ Use consistent response structure (`{ data, meta }`)
703
+ - ✅ Centralized error handling middleware
704
+ - ✅ Return 204 No Content for DELETE
705
+
706
+ ---
707
+
708
+ ## Testing Code Generation
709
+
710
+ ### Unit Testing with TDD
711
+
712
+ ```typescript
713
+ // ✅ Good: Comprehensive tests with edge cases
714
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
715
+ import { UserService } from './user-service';
716
+ import { UserRepository } from './user-repository';
717
+ import { ValidationError, NotFoundError } from './errors';
718
+
719
+ describe('UserService', () => {
720
+ let userService: UserService;
721
+ let mockUserRepo: jest.Mocked<UserRepository>;
722
+
723
+ beforeEach(() => {
724
+ // Create mock repository
725
+ mockUserRepo = {
726
+ findById: vi.fn(),
727
+ findByEmail: vi.fn(),
728
+ create: vi.fn(),
729
+ update: vi.fn(),
730
+ delete: vi.fn()
731
+ } as any;
732
+
733
+ userService = new UserService(mockUserRepo);
734
+ });
735
+
736
+ describe('getUser', () => {
737
+ it('should return user when found', async () => {
738
+ // Arrange
739
+ const mockUser = {
740
+ id: '123',
741
+ email: 'test@example.com',
742
+ name: 'Test User',
743
+ role: 'user'
744
+ };
745
+ mockUserRepo.findById.mockResolvedValue(mockUser);
746
+
747
+ // Act
748
+ const result = await userService.getUser('123');
749
+
750
+ // Assert
751
+ expect(result).toEqual(mockUser);
752
+ expect(mockUserRepo.findById).toHaveBeenCalledWith('123');
753
+ });
754
+
755
+ it('should throw NotFoundError when user not found', async () => {
756
+ // Arrange
757
+ mockUserRepo.findById.mockResolvedValue(null);
758
+
759
+ // Act & Assert
760
+ await expect(userService.getUser('999'))
761
+ .rejects
762
+ .toThrow(NotFoundError);
763
+ });
764
+
765
+ it('should throw ValidationError for empty ID', async () => {
766
+ // Act & Assert
767
+ await expect(userService.getUser(''))
768
+ .rejects
769
+ .toThrow(ValidationError);
770
+
771
+ // Should not call repository for invalid input
772
+ expect(mockUserRepo.findById).not.toHaveBeenCalled();
773
+ });
774
+
775
+ it('should throw ValidationError for whitespace ID', async () => {
776
+ await expect(userService.getUser(' '))
777
+ .rejects
778
+ .toThrow(ValidationError);
779
+ });
780
+ });
781
+
782
+ describe('createUser', () => {
783
+ it('should create user with valid data', async () => {
784
+ // Arrange
785
+ const createData = {
786
+ email: 'new@example.com',
787
+ name: 'New User',
788
+ role: 'user'
789
+ };
790
+ const mockCreatedUser = { id: '456', ...createData };
791
+
792
+ mockUserRepo.findByEmail.mockResolvedValue(null); // No duplicate
793
+ mockUserRepo.create.mockResolvedValue(mockCreatedUser);
794
+
795
+ // Act
796
+ const result = await userService.createUser(createData);
797
+
798
+ // Assert
799
+ expect(result).toEqual(mockCreatedUser);
800
+ expect(mockUserRepo.findByEmail).toHaveBeenCalledWith('new@example.com');
801
+ expect(mockUserRepo.create).toHaveBeenCalledWith(createData);
802
+ });
803
+
804
+ it('should throw ValidationError for invalid email', async () => {
805
+ // Arrange
806
+ const invalidData = {
807
+ email: 'not-an-email',
808
+ name: 'Test',
809
+ role: 'user'
810
+ };
811
+
812
+ // Act & Assert
813
+ await expect(userService.createUser(invalidData))
814
+ .rejects
815
+ .toThrow(ValidationError);
816
+
817
+ expect(mockUserRepo.create).not.toHaveBeenCalled();
818
+ });
819
+
820
+ it('should throw ValidationError for duplicate email', async () => {
821
+ // Arrange
822
+ const duplicateData = {
823
+ email: 'existing@example.com',
824
+ name: 'Test',
825
+ role: 'user'
826
+ };
827
+ mockUserRepo.findByEmail.mockResolvedValue({ id: '123' } as any);
828
+
829
+ // Act & Assert
830
+ await expect(userService.createUser(duplicateData))
831
+ .rejects
832
+ .toThrow(ValidationError);
833
+
834
+ expect(mockUserRepo.create).not.toHaveBeenCalled();
835
+ });
836
+
837
+ it('should use default role when not provided', async () => {
838
+ // Arrange
839
+ const dataWithoutRole = {
840
+ email: 'test@example.com',
841
+ name: 'Test User'
842
+ };
843
+ mockUserRepo.findByEmail.mockResolvedValue(null);
844
+ mockUserRepo.create.mockResolvedValue({ id: '123', ...dataWithoutRole, role: 'user' } as any);
845
+
846
+ // Act
847
+ await userService.createUser(dataWithoutRole);
848
+
849
+ // Assert
850
+ expect(mockUserRepo.create).toHaveBeenCalledWith(
851
+ expect.objectContaining({ role: 'user' })
852
+ );
853
+ });
854
+ });
855
+ });
856
+
857
+ // ❌ Bad: Minimal tests, no edge cases
858
+ describe('UserService', () => {
859
+ it('works', async () => {
860
+ const user = await userService.getUser('123');
861
+ expect(user).toBeDefined();
862
+ });
863
+ });
864
+ ```
865
+
866
+ **💡 Testing Best Practices:**
867
+
868
+ - ✅ Use AAA pattern (Arrange, Act, Assert)
869
+ - ✅ Test happy path AND edge cases
870
+ - ✅ Test error conditions
871
+ - ✅ Use descriptive test names (`should ... when ...`)
872
+ - ✅ Mock external dependencies
873
+ - ✅ Verify mock calls with `toHaveBeenCalledWith`
874
+ - ✅ Test default values and optional parameters
875
+
876
+ ---
877
+
878
+ ## Common Pitfalls
879
+
880
+ ### Pitfall 1: Ignoring Edge Cases
881
+
882
+ ```typescript
883
+ // ❌ Bad: No edge case handling
884
+ function divide(a: number, b: number): number {
885
+ return a / b; // What if b is 0?
886
+ }
887
+
888
+ // ✅ Good: Handle edge cases explicitly
889
+ function divide(a: number, b: number): number {
890
+ if (b === 0) {
891
+ throw new Error('Division by zero');
892
+ }
893
+ if (!Number.isFinite(a) || !Number.isFinite(b)) {
894
+ throw new Error('Invalid input: must be finite numbers');
895
+ }
896
+ return a / b;
897
+ }
898
+ ```
899
+
900
+ ### Pitfall 2: Silent Failures
901
+
902
+ ```typescript
903
+ // ❌ Bad: Silent failure
904
+ async function updateUser(id: string, data: any) {
905
+ try {
906
+ await userRepo.update(id, data);
907
+ } catch (error) {
908
+ // Silent failure - error swallowed!
909
+ }
910
+ }
911
+
912
+ // ✅ Good: Fail loudly with context
913
+ async function updateUser(id: string, data: UpdateUserRequest): Promise<User> {
914
+ try {
915
+ const user = await userRepo.update(id, data);
916
+ return user;
917
+ } catch (error) {
918
+ console.error('Failed to update user:', { id, error });
919
+ throw new Error(`Failed to update user ${id}: ${(error as Error).message}`);
920
+ }
921
+ }
922
+ ```
923
+
924
+ ### Pitfall 3: Overly Complex Functions
925
+
926
+ ```typescript
927
+ // ❌ Bad: God function doing everything
928
+ async function handleUserRegistration(email, name, password, address, phone, ...more) {
929
+ // 200 lines of code
930
+ // Validation, hashing, database, email, logging, analytics...
931
+ }
932
+
933
+ // ✅ Good: Single Responsibility - delegate to specialized functions
934
+ async function registerUser(data: RegistrationData): Promise<User> {
935
+ // Validate
936
+ validateRegistrationData(data);
937
+
938
+ // Create user
939
+ const user = await createUser({
940
+ email: data.email,
941
+ name: data.name,
942
+ passwordHash: await hashPassword(data.password)
943
+ });
944
+
945
+ // Send welcome email (async, don't block)
946
+ sendWelcomeEmail(user).catch(handleEmailError);
947
+
948
+ // Track analytics (async, don't block)
949
+ trackUserRegistration(user).catch(handleAnalyticsError);
950
+
951
+ return user;
952
+ }
953
+ ```
954
+
955
+ ### Pitfall 4: Mutation Instead of Immutability
956
+
957
+ ```typescript
958
+ // ❌ Bad: Mutates input
959
+ function addItem(array: any[], item: any) {
960
+ array.push(item); // Mutates!
961
+ return array;
962
+ }
963
+
964
+ // ✅ Good: Returns new array (immutable)
965
+ function addItem<T>(array: T[], item: T): T[] {
966
+ return [...array, item]; // New array
967
+ }
968
+ ```
969
+
970
+ ---
971
+
972
+ ## Quick Reference
973
+
974
+ ### Code Generation Checklist
975
+
976
+ **Type Safety:**
977
+
978
+ - [ ] All function parameters have types
979
+ - [ ] All return types are explicitly defined
980
+ - [ ] No use of `any` or `unknown` without justification
981
+ - [ ] Interfaces and types are well-documented
982
+
983
+ **Error Handling:**
984
+
985
+ - [ ] Input validation for all public functions
986
+ - [ ] Explicit error types (custom error classes)
987
+ - [ ] Try-catch blocks for async operations
988
+ - [ ] Errors include context (field, value, id)
989
+ - [ ] No silent failures (always throw or log)
990
+
991
+ **Testing:**
992
+
993
+ - [ ] Unit tests for all public methods
994
+ - [ ] Tests cover happy path + edge cases
995
+ - [ ] Tests verify error conditions
996
+ - [ ] Mocks for external dependencies
997
+ - [ ] Descriptive test names
998
+
999
+ **Code Quality:**
1000
+
1001
+ - [ ] Functions are small and focused (< 50 lines)
1002
+ - [ ] Descriptive variable and function names
1003
+ - [ ] JSDoc/TSDoc comments for public APIs
1004
+ - [ ] No code duplication (DRY)
1005
+ - [ ] Follows SOLID principles
1006
+
1007
+ **API Design:**
1008
+
1009
+ - [ ] RESTful URLs (resource-based)
1010
+ - [ ] Proper HTTP methods (GET, POST, PATCH, DELETE)
1011
+ - [ ] Input validation (express-validator)
1012
+ - [ ] Appropriate HTTP status codes
1013
+ - [ ] Consistent response structure
1014
+
1015
+ ---
1016
+
1017
+ ## Summary
1018
+
1019
+ Generating high-quality code requires:
1020
+
1021
+ 1. **Type Safety** - Use TypeScript, define all types explicitly
1022
+ 2. **Error Handling** - Explicit errors, no silent failures, include context
1023
+ 3. **Testing** - TDD approach, test happy path + edge cases + errors
1024
+ 4. **Code Quality** - SOLID principles, small functions, DRY, descriptive names
1025
+ 5. **API Design** - RESTful, validated inputs, appropriate status codes
1026
+ 6. **Edge Cases** - Handle division by zero, null/undefined, empty strings, etc.
1027
+
1028
+ **Remember:**
1029
+
1030
+ - Code is read 10x more than written - optimize for readability
1031
+ - Fail fast, fail loudly - explicit errors over silent failures
1032
+ - Tests are documentation that never goes out of date
1033
+ - Simplicity is the ultimate sophistication
1034
+
1035
+ Use this ability to generate production-ready code with proper types, error handling, tests, and documentation.