oh-my-ag 1.2.0

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/.agent/skills/_shared/api-contracts/README.md +56 -0
  2. package/.agent/skills/_shared/api-contracts/template.md +88 -0
  3. package/.agent/skills/_shared/clarification-protocol.md +217 -0
  4. package/.agent/skills/_shared/common-checklist.md +31 -0
  5. package/.agent/skills/_shared/context-budget.md +118 -0
  6. package/.agent/skills/_shared/context-loading.md +105 -0
  7. package/.agent/skills/_shared/difficulty-guide.md +55 -0
  8. package/.agent/skills/_shared/lessons-learned.md +113 -0
  9. package/.agent/skills/_shared/memory-protocol.md +79 -0
  10. package/.agent/skills/_shared/reasoning-templates.md +161 -0
  11. package/.agent/skills/_shared/skill-routing.md +80 -0
  12. package/.agent/skills/_shared/verify.sh +252 -0
  13. package/.agent/skills/backend-agent/SKILL.md +47 -0
  14. package/.agent/skills/backend-agent/resources/api-template.py +326 -0
  15. package/.agent/skills/backend-agent/resources/checklist.md +36 -0
  16. package/.agent/skills/backend-agent/resources/error-playbook.md +98 -0
  17. package/.agent/skills/backend-agent/resources/examples.md +85 -0
  18. package/.agent/skills/backend-agent/resources/execution-protocol.md +45 -0
  19. package/.agent/skills/backend-agent/resources/snippets.md +197 -0
  20. package/.agent/skills/backend-agent/resources/tech-stack.md +39 -0
  21. package/.agent/skills/commit/SKILL.md +121 -0
  22. package/.agent/skills/commit/config/commit-config.yaml +55 -0
  23. package/.agent/skills/commit/resources/conventional-commits.md +166 -0
  24. package/.agent/skills/debug-agent/SKILL.md +51 -0
  25. package/.agent/skills/debug-agent/resources/bug-report-template.md +332 -0
  26. package/.agent/skills/debug-agent/resources/checklist.md +30 -0
  27. package/.agent/skills/debug-agent/resources/common-patterns.md +734 -0
  28. package/.agent/skills/debug-agent/resources/debugging-checklist.md +362 -0
  29. package/.agent/skills/debug-agent/resources/error-playbook.md +94 -0
  30. package/.agent/skills/debug-agent/resources/examples.md +87 -0
  31. package/.agent/skills/debug-agent/resources/execution-protocol.md +51 -0
  32. package/.agent/skills/frontend-agent/SKILL.md +48 -0
  33. package/.agent/skills/frontend-agent/resources/checklist.md +38 -0
  34. package/.agent/skills/frontend-agent/resources/component-template.tsx +92 -0
  35. package/.agent/skills/frontend-agent/resources/error-playbook.md +108 -0
  36. package/.agent/skills/frontend-agent/resources/examples.md +77 -0
  37. package/.agent/skills/frontend-agent/resources/execution-protocol.md +49 -0
  38. package/.agent/skills/frontend-agent/resources/snippets.md +205 -0
  39. package/.agent/skills/frontend-agent/resources/tailwind-rules.md +343 -0
  40. package/.agent/skills/frontend-agent/resources/tech-stack.md +36 -0
  41. package/.agent/skills/mobile-agent/SKILL.md +46 -0
  42. package/.agent/skills/mobile-agent/resources/checklist.md +35 -0
  43. package/.agent/skills/mobile-agent/resources/error-playbook.md +106 -0
  44. package/.agent/skills/mobile-agent/resources/examples.md +79 -0
  45. package/.agent/skills/mobile-agent/resources/execution-protocol.md +49 -0
  46. package/.agent/skills/mobile-agent/resources/screen-template.dart +298 -0
  47. package/.agent/skills/mobile-agent/resources/snippets.md +235 -0
  48. package/.agent/skills/mobile-agent/resources/tech-stack.md +45 -0
  49. package/.agent/skills/orchestrator/SKILL.md +99 -0
  50. package/.agent/skills/orchestrator/config/cli-config.yaml +78 -0
  51. package/.agent/skills/orchestrator/resources/memory-schema.md +212 -0
  52. package/.agent/skills/orchestrator/resources/subagent-prompt-template.md +153 -0
  53. package/.agent/skills/orchestrator/scripts/parallel-run.sh +330 -0
  54. package/.agent/skills/orchestrator/scripts/spawn-agent.sh +263 -0
  55. package/.agent/skills/orchestrator/templates/backend-task.md +18 -0
  56. package/.agent/skills/orchestrator/templates/debug-task.md +16 -0
  57. package/.agent/skills/orchestrator/templates/frontend-task.md +17 -0
  58. package/.agent/skills/orchestrator/templates/mobile-task.md +17 -0
  59. package/.agent/skills/orchestrator/templates/qa-task.md +16 -0
  60. package/.agent/skills/orchestrator/templates/tasks-example.yaml +15 -0
  61. package/.agent/skills/pm-agent/SKILL.md +47 -0
  62. package/.agent/skills/pm-agent/resources/error-playbook.md +75 -0
  63. package/.agent/skills/pm-agent/resources/examples.md +121 -0
  64. package/.agent/skills/pm-agent/resources/execution-protocol.md +46 -0
  65. package/.agent/skills/pm-agent/resources/task-template.json +57 -0
  66. package/.agent/skills/qa-agent/SKILL.md +43 -0
  67. package/.agent/skills/qa-agent/resources/checklist.md +294 -0
  68. package/.agent/skills/qa-agent/resources/error-playbook.md +95 -0
  69. package/.agent/skills/qa-agent/resources/examples.md +100 -0
  70. package/.agent/skills/qa-agent/resources/execution-protocol.md +50 -0
  71. package/.agent/skills/qa-agent/resources/self-check.md +27 -0
  72. package/.agent/skills/workflow-guide/SKILL.md +57 -0
  73. package/.agent/skills/workflow-guide/resources/examples.md +68 -0
  74. package/README.ko.md +459 -0
  75. package/README.md +563 -0
  76. package/bin/cli.js +205 -0
  77. package/package.json +75 -0
@@ -0,0 +1,734 @@
1
+ # Common Bug Patterns & Solutions
2
+
3
+ Quick reference guide for frequently encountered bugs and their fixes.
4
+
5
+ ---
6
+
7
+ ## 🔴 Frontend Bugs
8
+
9
+ ### 1. Undefined/Null Errors
10
+
11
+ **❌ Problem**: `Cannot read property 'X' of undefined`
12
+
13
+ ```typescript
14
+ // Crash when data not loaded yet
15
+ const name = user.profile.name;
16
+ ```
17
+
18
+ **✅ Solutions**:
19
+
20
+ ```typescript
21
+ // Option 1: Optional chaining + nullish coalescing
22
+ const name = user?.profile?.name ?? 'Unknown';
23
+
24
+ // Option 2: Conditional rendering
25
+ {user?.profile && <div>{user.profile.name}</div>}
26
+
27
+ // Option 3: Early return
28
+ if (!user?.profile) return <div>Loading...</div>;
29
+ ```
30
+
31
+ ---
32
+
33
+ ### 2. Stale Closures in useEffect
34
+
35
+ **❌ Problem**: Event handlers/callbacks use old state values
36
+
37
+ ```typescript
38
+ function Counter() {
39
+ const [count, setCount] = useState(0);
40
+
41
+ useEffect(() => {
42
+ const interval = setInterval(() => {
43
+ console.log(count); // Always logs 0!
44
+ }, 1000);
45
+ return () => clearInterval(interval);
46
+ }, []); // Missing dependency
47
+
48
+ return <button onClick={() => setCount(c => c + 1)}>+</button>;
49
+ }
50
+ ```
51
+
52
+ **✅ Solutions**:
53
+
54
+ ```typescript
55
+ // Option 1: Include dependency
56
+ useEffect(() => {
57
+ const interval = setInterval(() => {
58
+ console.log(count); // Now updates!
59
+ }, 1000);
60
+ return () => clearInterval(interval);
61
+ }, [count]); // Dependency added
62
+
63
+ // Option 2: Use functional update
64
+ useEffect(() => {
65
+ const interval = setInterval(() => {
66
+ setCount(c => {
67
+ console.log(c); // Current value
68
+ return c;
69
+ });
70
+ }, 1000);
71
+ return () => clearInterval(interval);
72
+ }, []); // Can stay empty
73
+
74
+ // Option 3: Use ref for latest value
75
+ const countRef = useRef(count);
76
+ countRef.current = count;
77
+
78
+ useEffect(() => {
79
+ const interval = setInterval(() => {
80
+ console.log(countRef.current); // Latest value
81
+ }, 1000);
82
+ return () => clearInterval(interval);
83
+ }, []);
84
+ ```
85
+
86
+ ---
87
+
88
+ ### 3. Missing Cleanup in useEffect
89
+
90
+ **❌ Problem**: Memory leaks from subscriptions/listeners
91
+
92
+ ```typescript
93
+ useEffect(() => {
94
+ const subscription = api.subscribe(data => setData(data));
95
+ // Missing cleanup!
96
+ }, []);
97
+ ```
98
+
99
+ **✅ Solution**:
100
+
101
+ ```typescript
102
+ useEffect(() => {
103
+ const subscription = api.subscribe(data => setData(data));
104
+
105
+ return () => {
106
+ subscription.unsubscribe(); // Cleanup
107
+ };
108
+ }, []);
109
+ ```
110
+
111
+ **Common things that need cleanup**:
112
+ - Event listeners (`addEventListener`)
113
+ - Intervals (`setInterval`)
114
+ - Timeouts (`setTimeout`)
115
+ - Subscriptions (WebSockets, observables)
116
+ - API requests (cancellation tokens)
117
+
118
+ ---
119
+
120
+ ### 4. Race Conditions in Async Effects
121
+
122
+ **❌ Problem**: Old requests overwrite new ones
123
+
124
+ ```typescript
125
+ useEffect(() => {
126
+ fetchUser(userId).then(setUser);
127
+ // If userId changes quickly, old responses arrive after new ones
128
+ }, [userId]);
129
+ ```
130
+
131
+ **✅ Solution**:
132
+
133
+ ```typescript
134
+ useEffect(() => {
135
+ let cancelled = false;
136
+
137
+ fetchUser(userId).then(user => {
138
+ if (!cancelled) {
139
+ setUser(user);
140
+ }
141
+ });
142
+
143
+ return () => {
144
+ cancelled = true;
145
+ };
146
+ }, [userId]);
147
+ ```
148
+
149
+ ---
150
+
151
+ ### 5. Infinite Re-render Loops
152
+
153
+ **❌ Problem**: Component re-renders infinitely
154
+
155
+ ```typescript
156
+ function Component() {
157
+ const [data, setData] = useState([]);
158
+
159
+ useEffect(() => {
160
+ setData([...data, 'new']); // Triggers effect again!
161
+ }, [data]); // Dependency causes loop
162
+
163
+ return <div>{data.length}</div>;
164
+ }
165
+ ```
166
+
167
+ **✅ Solutions**:
168
+
169
+ ```typescript
170
+ // Option 1: Remove problematic dependency
171
+ useEffect(() => {
172
+ setData(prevData => [...prevData, 'new']);
173
+ }, []); // Empty deps - runs once
174
+
175
+ // Option 2: Use ref instead of state
176
+ const dataRef = useRef([]);
177
+
178
+ useEffect(() => {
179
+ dataRef.current = [...dataRef.current, 'new'];
180
+ }, []);
181
+
182
+ // Option 3: Add condition
183
+ useEffect(() => {
184
+ if (data.length === 0) { // Only run when empty
185
+ setData(['new']);
186
+ }
187
+ }, [data]);
188
+ ```
189
+
190
+ ---
191
+
192
+ ### 6. Key Prop Issues in Lists
193
+
194
+ **❌ Problem**: List items reordering incorrectly
195
+
196
+ ```typescript
197
+ // Using index as key
198
+ {todos.map((todo, index) => (
199
+ <TodoItem key={index} todo={todo} />
200
+ ))}
201
+ ```
202
+
203
+ **✅ Solution**:
204
+
205
+ ```typescript
206
+ // Use stable, unique ID
207
+ {todos.map(todo => (
208
+ <TodoItem key={todo.id} todo={todo} />
209
+ ))}
210
+
211
+ // If no ID, generate stable key
212
+ {todos.map((todo, index) => (
213
+ <TodoItem key={`${todo.title}-${index}`} todo={todo} />
214
+ ))}
215
+ ```
216
+
217
+ ---
218
+
219
+ ### 7. Form Input Controlled/Uncontrolled Switch
220
+
221
+ **❌ Problem**: `Warning: A component is changing an uncontrolled input to be controlled`
222
+
223
+ ```typescript
224
+ const [value, setValue] = useState(); // undefined initially
225
+
226
+ <input value={value} onChange={e => setValue(e.target.value)} />
227
+ ```
228
+
229
+ **✅ Solution**:
230
+
231
+ ```typescript
232
+ // Initialize with empty string
233
+ const [value, setValue] = useState('');
234
+
235
+ <input value={value} onChange={e => setValue(e.target.value)} />
236
+
237
+ // Or use defaultValue for uncontrolled
238
+ <input defaultValue="" onChange={e => console.log(e.target.value)} />
239
+ ```
240
+
241
+ ---
242
+
243
+ ## 🔴 Backend Bugs
244
+
245
+ ### 1. SQL Injection
246
+
247
+ **❌ Problem**: User input directly in SQL query
248
+
249
+ ```python
250
+ # DANGEROUS!
251
+ email = request.args.get('email')
252
+ query = f"SELECT * FROM users WHERE email = '{email}'"
253
+ db.execute(query)
254
+ # User can input: ' OR '1'='1
255
+ ```
256
+
257
+ **✅ Solution**:
258
+
259
+ ```python
260
+ # Use parameterized queries
261
+ from sqlalchemy import text
262
+
263
+ email = request.args.get('email')
264
+ query = text("SELECT * FROM users WHERE email = :email")
265
+ result = db.execute(query, {"email": email})
266
+
267
+ # Or use ORM
268
+ user = db.query(User).filter(User.email == email).first()
269
+ ```
270
+
271
+ ---
272
+
273
+ ### 2. N+1 Query Problem
274
+
275
+ **❌ Problem**: One query per item in a loop
276
+
277
+ ```python
278
+ # 1 query to get todos
279
+ todos = db.query(Todo).all()
280
+
281
+ # N queries (one per todo)
282
+ for todo in todos:
283
+ user = db.query(User).filter(User.id == todo.user_id).first()
284
+ print(f"{todo.title} by {user.name}")
285
+ ```
286
+
287
+ **✅ Solution**:
288
+
289
+ ```python
290
+ # Use JOIN - single query
291
+ from sqlalchemy.orm import joinedload
292
+
293
+ todos = db.query(Todo).options(joinedload(Todo.user)).all()
294
+
295
+ for todo in todos:
296
+ print(f"{todo.title} by {todo.user.name}") # No extra query
297
+ ```
298
+
299
+ ---
300
+
301
+ ### 3. Missing Authentication Check
302
+
303
+ **❌ Problem**: Protected endpoint accessible without auth
304
+
305
+ ```python
306
+ @app.get("/api/admin/users")
307
+ async def get_all_users(db: DatabaseDep):
308
+ return db.query(User).all() # Anyone can access!
309
+ ```
310
+
311
+ **✅ Solution**:
312
+
313
+ ```python
314
+ @app.get("/api/admin/users")
315
+ async def get_all_users(
316
+ db: DatabaseDep,
317
+ current_user: User = Depends(get_current_user) # Require auth
318
+ ):
319
+ if current_user.role != "admin": # Check role
320
+ raise HTTPException(403, "Admin only")
321
+ return db.query(User).all()
322
+ ```
323
+
324
+ ---
325
+
326
+ ### 4. Missing Input Validation
327
+
328
+ **❌ Problem**: Invalid data causes errors
329
+
330
+ ```python
331
+ @app.post("/api/users")
332
+ async def create_user(email: str, age: int):
333
+ # No validation!
334
+ user = User(email=email, age=age)
335
+ db.add(user)
336
+ db.commit()
337
+ ```
338
+
339
+ **✅ Solution**:
340
+
341
+ ```python
342
+ from pydantic import BaseModel, EmailStr, Field
343
+
344
+ class UserCreate(BaseModel):
345
+ email: EmailStr # Validates email format
346
+ age: int = Field(ge=0, le=150) # Must be 0-150
347
+
348
+ @app.post("/api/users")
349
+ async def create_user(user: UserCreate):
350
+ # Pydantic validates automatically
351
+ db_user = User(**user.model_dump())
352
+ db.add(db_user)
353
+ db.commit()
354
+ ```
355
+
356
+ ---
357
+
358
+ ### 5. Unhandled Exceptions
359
+
360
+ **❌ Problem**: Server crashes on error
361
+
362
+ ```python
363
+ @app.post("/api/todos")
364
+ async def create_todo(todo: TodoCreate, user: User = Depends(get_current_user)):
365
+ db_todo = Todo(**todo.model_dump(), user_id=user.id)
366
+ db.add(db_todo)
367
+ db.commit() # Could fail!
368
+ return db_todo
369
+ ```
370
+
371
+ **✅ Solution**:
372
+
373
+ ```python
374
+ from fastapi import HTTPException
375
+
376
+ @app.post("/api/todos")
377
+ async def create_todo(todo: TodoCreate, user: User = Depends(get_current_user)):
378
+ try:
379
+ db_todo = Todo(**todo.model_dump(), user_id=user.id)
380
+ db.add(db_todo)
381
+ db.commit()
382
+ db.refresh(db_todo)
383
+ return db_todo
384
+ except IntegrityError as e:
385
+ db.rollback()
386
+ raise HTTPException(409, "Duplicate entry")
387
+ except Exception as e:
388
+ db.rollback()
389
+ logger.error(f"Failed to create todo: {e}")
390
+ raise HTTPException(500, "Internal server error")
391
+ ```
392
+
393
+ ---
394
+
395
+ ### 6. Missing CORS Configuration
396
+
397
+ **❌ Problem**: Frontend can't call API
398
+
399
+ ```
400
+ Access to fetch at 'http://localhost:8000/api/todos' from origin
401
+ 'http://localhost:3000' has been blocked by CORS policy
402
+ ```
403
+
404
+ **✅ Solution**:
405
+
406
+ ```python
407
+ from fastapi.middleware.cors import CORSMiddleware
408
+
409
+ app.add_middleware(
410
+ CORSMiddleware,
411
+ allow_origins=["http://localhost:3000"], # Frontend URL
412
+ allow_credentials=True,
413
+ allow_methods=["*"],
414
+ allow_headers=["*"],
415
+ )
416
+
417
+ # For production, be specific:
418
+ # allow_origins=["https://yourdomain.com"]
419
+ ```
420
+
421
+ ---
422
+
423
+ ### 7. Password Storage
424
+
425
+ **❌ Problem**: Passwords stored in plain text
426
+
427
+ ```python
428
+ user = User(email=email, password=password) # NEVER DO THIS!
429
+ ```
430
+
431
+ **✅ Solution**:
432
+
433
+ ```python
434
+ from passlib.context import CryptContext
435
+
436
+ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
437
+
438
+ # Hash before storing
439
+ password_hash = pwd_context.hash(password)
440
+ user = User(email=email, password_hash=password_hash)
441
+
442
+ # Verify on login
443
+ if not pwd_context.verify(plain_password, user.password_hash):
444
+ raise HTTPException(401, "Invalid credentials")
445
+ ```
446
+
447
+ ---
448
+
449
+ ## 🔴 Mobile Bugs
450
+
451
+ ### 1. Memory Leaks in Flutter
452
+
453
+ **❌ Problem**: Controllers not disposed
454
+
455
+ ```dart
456
+ class MyWidget extends StatefulWidget {
457
+ @override
458
+ _MyWidgetState createState() => _MyWidgetState();
459
+ }
460
+
461
+ class _MyWidgetState extends State<MyWidget> {
462
+ final controller = TextEditingController();
463
+
464
+ @override
465
+ Widget build(BuildContext context) {
466
+ return TextField(controller: controller);
467
+ }
468
+ // Missing dispose!
469
+ }
470
+ ```
471
+
472
+ **✅ Solution**:
473
+
474
+ ```dart
475
+ class _MyWidgetState extends State<MyWidget> {
476
+ final controller = TextEditingController();
477
+
478
+ @override
479
+ void dispose() {
480
+ controller.dispose(); // Clean up
481
+ super.dispose();
482
+ }
483
+
484
+ @override
485
+ Widget build(BuildContext context) {
486
+ return TextField(controller: controller);
487
+ }
488
+ }
489
+ ```
490
+
491
+ ---
492
+
493
+ ### 2. Platform-Specific Code Not Checked
494
+
495
+ **❌ Problem**: iOS-specific code crashes on Android
496
+
497
+ ```dart
498
+ // Crashes on Android
499
+ import 'dart:io' show Platform;
500
+
501
+ final deviceName = Platform.isIOS ? 'iPhone' : 'Unknown';
502
+ ```
503
+
504
+ **✅ Solution**:
505
+
506
+ ```dart
507
+ import 'dart:io' show Platform;
508
+
509
+ final deviceName = Platform.isIOS
510
+ ? 'iPhone'
511
+ : Platform.isAndroid
512
+ ? 'Android'
513
+ : 'Unknown';
514
+
515
+ // Or use conditional imports
516
+ if (Platform.isIOS) {
517
+ // iOS-specific code
518
+ } else if (Platform.isAndroid) {
519
+ // Android-specific code
520
+ }
521
+ ```
522
+
523
+ ---
524
+
525
+ ## 🔴 Performance Bugs
526
+
527
+ ### 1. Unnecessary Re-renders (React)
528
+
529
+ **❌ Problem**: Component re-renders on every parent render
530
+
531
+ ```typescript
532
+ function Parent() {
533
+ const [count, setCount] = useState(0);
534
+
535
+ return (
536
+ <div>
537
+ <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
538
+ <ExpensiveChild data={someData} /> {/* Re-renders every time! */}
539
+ </div>
540
+ );
541
+ }
542
+ ```
543
+
544
+ **✅ Solution**:
545
+
546
+ ```typescript
547
+ // Memoize the expensive component
548
+ const ExpensiveChild = React.memo(function ExpensiveChild({ data }) {
549
+ // Only re-renders when data changes
550
+ return <div>{/* expensive computation */}</div>;
551
+ });
552
+
553
+ // Or memoize the props
554
+ function Parent() {
555
+ const [count, setCount] = useState(0);
556
+ const memoizedData = useMemo(() => computeData(), []);
557
+
558
+ return (
559
+ <div>
560
+ <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
561
+ <ExpensiveChild data={memoizedData} />
562
+ </div>
563
+ );
564
+ }
565
+ ```
566
+
567
+ ---
568
+
569
+ ### 2. Large Bundle Size
570
+
571
+ **❌ Problem**: Importing entire library
572
+
573
+ ```typescript
574
+ // Imports all of lodash (~70KB)
575
+ import _ from 'lodash';
576
+
577
+ const unique = _.uniq(array);
578
+ ```
579
+
580
+ **✅ Solution**:
581
+
582
+ ```typescript
583
+ // Import only what you need
584
+ import uniq from 'lodash/uniq'; // ~2KB
585
+
586
+ const unique = uniq(array);
587
+
588
+ // Or use native methods
589
+ const unique = [...new Set(array)];
590
+ ```
591
+
592
+ ---
593
+
594
+ ## 🔴 Security Bugs
595
+
596
+ ### 1. XSS (Cross-Site Scripting)
597
+
598
+ **❌ Problem**: User input rendered as HTML
599
+
600
+ ```typescript
601
+ // Dangerous!
602
+ <div dangerouslySetInnerHTML={{ __html: userComment }} />
603
+ ```
604
+
605
+ **✅ Solution**:
606
+
607
+ ```typescript
608
+ // React escapes by default
609
+ <div>{userComment}</div>
610
+
611
+ // If HTML needed, sanitize first
612
+ import DOMPurify from 'dompurify';
613
+
614
+ <div dangerouslySetInnerHTML={{
615
+ __html: DOMPurify.sanitize(userComment)
616
+ }} />
617
+ ```
618
+
619
+ ---
620
+
621
+ ### 2. Missing Rate Limiting
622
+
623
+ **❌ Problem**: API can be abused
624
+
625
+ ```python
626
+ @app.post("/api/auth/login")
627
+ async def login(credentials: LoginRequest):
628
+ # No rate limiting - brute force possible!
629
+ ...
630
+ ```
631
+
632
+ **✅ Solution**:
633
+
634
+ ```python
635
+ from slowapi import Limiter
636
+ from slowapi.util import get_remote_address
637
+
638
+ limiter = Limiter(key_func=get_remote_address)
639
+
640
+ @app.post("/api/auth/login")
641
+ @limiter.limit("5/minute") # Max 5 attempts per minute
642
+ async def login(request: Request, credentials: LoginRequest):
643
+ ...
644
+ ```
645
+
646
+ ---
647
+
648
+ ## 📊 Common Error Messages & Solutions
649
+
650
+ | Error | Likely Cause | Solution |
651
+ |-------|--------------|----------|
652
+ | `Cannot read property 'X' of undefined` | Accessing property before data loads | Add null check or optional chaining |
653
+ | `Maximum update depth exceeded` | Infinite re-render loop | Check useEffect dependencies |
654
+ | `Warning: Each child should have unique key` | Missing/duplicate keys in list | Use unique, stable IDs as keys |
655
+ | `401 Unauthorized` | Missing/invalid auth token | Check token in request headers |
656
+ | `403 Forbidden` | Insufficient permissions | Verify user role/permissions |
657
+ | `404 Not Found` | Wrong URL or resource doesn't exist | Check endpoint path and resource ID |
658
+ | `500 Internal Server Error` | Backend exception | Check server logs for stack trace |
659
+ | `CORS Error` | Cross-origin request blocked | Configure CORS middleware |
660
+ | `ERR_CONNECTION_REFUSED` | Server not running | Start the backend server |
661
+
662
+ ---
663
+
664
+ ## 🎯 Quick Debugging Commands
665
+
666
+ ### Frontend
667
+ ```bash
668
+ # Check for errors
669
+ npm run lint
670
+
671
+ # Run tests
672
+ npm test
673
+
674
+ # Build and check bundle size
675
+ npm run build
676
+ npm run analyze
677
+
678
+ # Check for unused dependencies
679
+ npx depcheck
680
+ ```
681
+
682
+ ### Backend
683
+ ```bash
684
+ # Check for security issues
685
+ pip install safety
686
+ safety check
687
+
688
+ # Run tests with coverage
689
+ pytest --cov=app
690
+
691
+ # Check for SQL injection
692
+ bandit -r app/
693
+ ```
694
+
695
+ ### Mobile
696
+ ```bash
697
+ # Check for issues
698
+ flutter analyze
699
+
700
+ # Run tests
701
+ flutter test
702
+
703
+ # Check app size
704
+ flutter build apk --analyze-size
705
+ ```
706
+
707
+ ---
708
+
709
+ ## 🔍 When to Use Each Agent
710
+
711
+ | Bug Type | Best Agent | Reason |
712
+ |----------|-----------|---------|
713
+ | Frontend crash | debug-agent | Specializes in bug diagnosis |
714
+ | Backend API error | debug-agent | Can trace through stack |
715
+ | Complex multi-domain | workflow-guide | Coordinates multiple agents |
716
+ | Security vulnerability | qa-agent | Security expertise |
717
+ | Performance issue | qa-agent | Performance profiling tools |
718
+ | New feature needed | Specialist agent | Not a bug, it's a feature |
719
+
720
+ ---
721
+
722
+ ## 💡 Prevention Tips
723
+
724
+ 1. **Write tests first** - Catch bugs before they ship
725
+ 2. **Use TypeScript** - Catch type errors at compile time
726
+ 3. **Enable strict mode** - More safety checks
727
+ 4. **Code review** - Second pair of eyes
728
+ 5. **Automated linting** - Enforce best practices
729
+ 6. **Error monitoring** - Sentry, LogRocket, etc.
730
+ 7. **User testing** - Real users find real bugs
731
+
732
+ ---
733
+
734
+ **Remember**: The best bug is the one that never happens. Write defensive code, test thoroughly, and document lessons learned!