@tinkcarlos/skillora 0.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.
- package/.claude/skills/.temp-skill-index.md +245 -0
- package/.claude/skills/SKILL.md +264 -0
- package/.claude/skills/api-scaffolding/SKILL.md +431 -0
- package/.claude/skills/api-scaffolding/agents/backend-architect.md +282 -0
- package/.claude/skills/api-scaffolding/agents/django-pro.md +144 -0
- package/.claude/skills/api-scaffolding/agents/fastapi-pro.md +156 -0
- package/.claude/skills/api-scaffolding/agents/graphql-architect.md +146 -0
- package/.claude/skills/api-scaffolding/skills/fastapi-templates/SKILL.md +171 -0
- package/.claude/skills/api-testing-observability/SKILL.md +583 -0
- package/.claude/skills/api-testing-observability/agents/api-documenter.md +146 -0
- package/.claude/skills/api-testing-observability/commands/api-mock.md +1320 -0
- package/.claude/skills/brainstorming/SKILL.md +283 -0
- package/.claude/skills/bug-fixing/SKILL.md +382 -0
- package/.claude/skills/bug-fixing/references/backend-guide.md +132 -0
- package/.claude/skills/bug-fixing/references/bug-guide.md +354 -0
- package/.claude/skills/bug-fixing/references/bug-record-template.md +134 -0
- package/.claude/skills/bug-fixing/references/bug-records.md +88 -0
- package/.claude/skills/bug-fixing/references/code-review-gate.md +81 -0
- package/.claude/skills/bug-fixing/references/common-bugs.md +140 -0
- package/.claude/skills/bug-fixing/references/complete-workflow.md +361 -0
- package/.claude/skills/bug-fixing/references/config-driven-fixes.md +136 -0
- package/.claude/skills/bug-fixing/references/context-isolation-protocol.md +268 -0
- package/.claude/skills/bug-fixing/references/cross-surface-regression.md +120 -0
- package/.claude/skills/bug-fixing/references/database-investigation.md +129 -0
- package/.claude/skills/bug-fixing/references/dependency-and-integrity-protocol.md +369 -0
- package/.claude/skills/bug-fixing/references/fix-completeness-checklist.md +239 -0
- package/.claude/skills/bug-fixing/references/frontend-guide.md +219 -0
- package/.claude/skills/bug-fixing/references/fullstack-joint-guide.md +123 -0
- package/.claude/skills/bug-fixing/references/functional-breakage.md +117 -0
- package/.claude/skills/bug-fixing/references/ide-lint-errors-guide.md +176 -0
- package/.claude/skills/bug-fixing/references/impact-analysis.md +511 -0
- package/.claude/skills/bug-fixing/references/investigation-checklist.md +263 -0
- package/.claude/skills/bug-fixing/references/knowledge-extraction-guide.md +531 -0
- package/.claude/skills/bug-fixing/references/knowledge-workflow.md +212 -0
- package/.claude/skills/bug-fixing/references/post-edit-quality-gate.md +30 -0
- package/.claude/skills/bug-fixing/references/python-env-and-testing.md +126 -0
- package/.claude/skills/bug-fixing/references/rca-guide.md +428 -0
- package/.claude/skills/bug-fixing/references/similar-bug-patterns.md +113 -0
- package/.claude/skills/bug-fixing/references/skill-delegation-guide.md +350 -0
- package/.claude/skills/bug-fixing/references/skill-orchestration.md +155 -0
- package/.claude/skills/bug-fixing/references/testing-strategy.md +350 -0
- package/.claude/skills/bug-fixing/references/tooling-build-scripts.md +162 -0
- package/.claude/skills/bug-fixing/references/user-input-validation.md +77 -0
- package/.claude/skills/bug-fixing/references/ux-patterns.md +158 -0
- package/.claude/skills/bug-fixing/references/windows-terminal-hygiene.md +106 -0
- package/.claude/skills/bug-fixing/references/zero-regression-matrix.md +239 -0
- package/.claude/skills/bug-fixing/references/zero-risk-protocol.md +102 -0
- package/.claude/skills/bug-fixing/scripts/format_code.py +611 -0
- package/.claude/skills/bug-fixing/scripts/generate_report_template.py +74 -0
- package/.claude/skills/bug-fixing/scripts/lint_check.py +816 -0
- package/.claude/skills/bug-fixing/scripts/requirements.txt +36 -0
- package/.claude/skills/cicd-pipeline/SKILL.md +300 -0
- package/.claude/skills/code-review/SKILL.md +535 -0
- package/.claude/skills/code-review/references/anti-pattern-scan.md +102 -0
- package/.claude/skills/code-review/references/automated-analysis.md +456 -0
- package/.claude/skills/code-review/references/backend-common-issues.md +589 -0
- package/.claude/skills/code-review/references/backend-expert-guide.md +415 -0
- package/.claude/skills/code-review/references/backend-review.md +868 -0
- package/.claude/skills/code-review/references/batch-processing-strategy.md +198 -0
- package/.claude/skills/code-review/references/call-chain-analysis-protocol.md +166 -0
- package/.claude/skills/code-review/references/common-patterns.md +321 -0
- package/.claude/skills/code-review/references/configuration-review.md +425 -0
- package/.claude/skills/code-review/references/control-flow-completeness.md +114 -0
- package/.claude/skills/code-review/references/database-review.md +298 -0
- package/.claude/skills/code-review/references/dependency-and-integrity-protocol.md +313 -0
- package/.claude/skills/code-review/references/external-standards.md +51 -0
- package/.claude/skills/code-review/references/feature-review.md +329 -0
- package/.claude/skills/code-review/references/file-review-template.md +326 -0
- package/.claude/skills/code-review/references/frontend-advanced.md +654 -0
- package/.claude/skills/code-review/references/frontend-common-issues.md +482 -0
- package/.claude/skills/code-review/references/frontend-expert-guide.md +342 -0
- package/.claude/skills/code-review/references/frontend-review.md +783 -0
- package/.claude/skills/code-review/references/fullstack-consistency.md +418 -0
- package/.claude/skills/code-review/references/fullstack-review.md +477 -0
- package/.claude/skills/code-review/references/functional-completeness.md +386 -0
- package/.claude/skills/code-review/references/hidden-bugs-detection.md +473 -0
- package/.claude/skills/code-review/references/ide-lint-errors-guide.md +173 -0
- package/.claude/skills/code-review/references/infrastructure-review.md +453 -0
- package/.claude/skills/code-review/references/iteration-review.md +264 -0
- package/.claude/skills/code-review/references/job-review.md +335 -0
- package/.claude/skills/code-review/references/layered-checklist-protocol.md +157 -0
- package/.claude/skills/code-review/references/logic-completeness.md +535 -0
- package/.claude/skills/code-review/references/mandatory-checklist.md +288 -0
- package/.claude/skills/code-review/references/multi-language-guide.md +800 -0
- package/.claude/skills/code-review/references/new-project-review.md +226 -0
- package/.claude/skills/code-review/references/non-code-files-review.md +451 -0
- package/.claude/skills/code-review/references/overlooked-issues.md +657 -0
- package/.claude/skills/code-review/references/platform-specific-review.md +195 -0
- package/.claude/skills/code-review/references/precision-analysis-protocol.md +260 -0
- package/.claude/skills/code-review/references/python-patterns.md +494 -0
- package/.claude/skills/code-review/references/rca-techniques.md +362 -0
- package/.claude/skills/code-review/references/report-template.md +430 -0
- package/.claude/skills/code-review/references/resource-limits-and-degradation.md +137 -0
- package/.claude/skills/code-review/references/review-dimensions.md +311 -0
- package/.claude/skills/code-review/references/review-guide.md +202 -0
- package/.claude/skills/code-review/references/review-knowledge-workflow.md +257 -0
- package/.claude/skills/code-review/references/review-progress-tracker-protocol.md +172 -0
- package/.claude/skills/code-review/references/review-record-template.md +195 -0
- package/.claude/skills/code-review/references/skill-orchestration.md +143 -0
- package/.claude/skills/code-review/references/ui-ux-review.md +470 -0
- package/.claude/skills/containerization/SKILL.md +313 -0
- package/.claude/skills/database-migrations/agents/database-admin.md +142 -0
- package/.claude/skills/database-migrations/agents/database-optimizer.md +144 -0
- package/.claude/skills/database-migrations/commands/migration-observability.md +408 -0
- package/.claude/skills/database-migrations/commands/sql-migrations.md +492 -0
- package/.claude/skills/finishing-a-development-branch/SKILL.md +319 -0
- package/.claude/skills/frontend-design/LICENSE.txt +177 -0
- package/.claude/skills/frontend-design/SKILL.md +587 -0
- package/.claude/skills/frontend-design/references/color-consistency.md +487 -0
- package/.claude/skills/frontend-design/references/color-palettes-full.md +657 -0
- package/.claude/skills/frontend-design/references/design-system-generator.md +285 -0
- package/.claude/skills/frontend-design/references/font-pairings-full.md +705 -0
- package/.claude/skills/frontend-design/references/industry-anti-patterns.md +281 -0
- package/.claude/skills/frontend-design/references/layout-anti-patterns.md +582 -0
- package/.claude/skills/frontend-design/references/motion-patterns.md +659 -0
- package/.claude/skills/frontend-design/references/pre-delivery-checklist.md +153 -0
- package/.claude/skills/frontend-design/references/responsive-design.md +555 -0
- package/.claude/skills/frontend-design/references/style-modification-rules.md +335 -0
- package/.claude/skills/frontend-design/references/ui-styles-full.md +383 -0
- package/.claude/skills/frontend-design/references/ui-styles-rating.md +191 -0
- package/.claude/skills/frontend-design/references/ux-guidelines.md +640 -0
- package/.claude/skills/fullstack-developer/SKILL.md +512 -0
- package/.claude/skills/fullstack-developer/references/api-contract-guide.md +312 -0
- package/.claude/skills/fullstack-developer/references/api-response-patterns.md +223 -0
- package/.claude/skills/fullstack-developer/references/async-patterns.md +220 -0
- package/.claude/skills/fullstack-developer/references/bug-prevention.md +914 -0
- package/.claude/skills/fullstack-developer/references/code-quality-checklist.md +271 -0
- package/.claude/skills/fullstack-developer/references/complete-development-workflow.md +278 -0
- package/.claude/skills/fullstack-developer/references/context-isolation-protocol.md +256 -0
- package/.claude/skills/fullstack-developer/references/database-migration.md +331 -0
- package/.claude/skills/fullstack-developer/references/dependency-and-integrity-protocol.md +390 -0
- package/.claude/skills/fullstack-developer/references/development-phases.md +333 -0
- package/.claude/skills/fullstack-developer/references/expert-guide.md +214 -0
- package/.claude/skills/fullstack-developer/references/file-import-patterns.md +114 -0
- package/.claude/skills/fullstack-developer/references/graceful-degradation-patterns.md +78 -0
- package/.claude/skills/fullstack-developer/references/ide-lint-errors-guide.md +183 -0
- package/.claude/skills/fullstack-developer/references/integration-testing.md +301 -0
- package/.claude/skills/fullstack-developer/references/mock-api-patterns.md +307 -0
- package/.claude/skills/fullstack-developer/references/phase-gate-template.md +249 -0
- package/.claude/skills/fullstack-developer/references/post-edit-quality-gate.md +30 -0
- package/.claude/skills/fullstack-developer/references/python-engineering.md +79 -0
- package/.claude/skills/fullstack-developer/references/skill-orchestration.md +214 -0
- package/.claude/skills/fullstack-developer/references/skill-router-table.md +304 -0
- package/.claude/skills/fullstack-developer/references/state-sync.md +217 -0
- package/.claude/skills/fullstack-developer/references/ui-testing-checklist.md +292 -0
- package/.claude/skills/fullstack-developer/scripts/format_code.py +611 -0
- package/.claude/skills/fullstack-developer/scripts/lint_check.py +816 -0
- package/.claude/skills/fullstack-developer/scripts/requirements.txt +36 -0
- package/.claude/skills/performance-optimization/SKILL.md +250 -0
- package/.claude/skills/product-requirements/SKILL.md +357 -0
- package/.claude/skills/product-requirements/references/acceptance-criteria.md +335 -0
- package/.claude/skills/product-requirements/references/answer-first-questioning-protocol.md +299 -0
- package/.claude/skills/product-requirements/references/competitive-analysis-guide.md +183 -0
- package/.claude/skills/product-requirements/references/document-accuracy-protocol.md +253 -0
- package/.claude/skills/product-requirements/references/document-management-protocol.md +278 -0
- package/.claude/skills/product-requirements/references/external-standards.md +62 -0
- package/.claude/skills/product-requirements/references/feature-spec-template.md +359 -0
- package/.claude/skills/product-requirements/references/knowledge-acquisition-protocol.md +251 -0
- package/.claude/skills/product-requirements/references/plan-execution-protocol.md +334 -0
- package/.claude/skills/product-requirements/references/plan-generation-protocol.md +264 -0
- package/.claude/skills/product-requirements/references/prioritization-frameworks.md +80 -0
- package/.claude/skills/product-requirements/references/requirement-decomposition-protocol.md +291 -0
- package/.claude/skills/product-requirements/references/user-story-examples.md +297 -0
- package/.claude/skills/product-requirements/references/workflow-templates.md +266 -0
- package/.claude/skills/react-best-practices/SKILL.md +198 -0
- package/.claude/skills/react-best-practices/references/advanced-patterns.md +94 -0
- package/.claude/skills/react-best-practices/references/bundle-optimization.md +182 -0
- package/.claude/skills/react-best-practices/references/client-data-fetching.md +112 -0
- package/.claude/skills/react-best-practices/references/complete-guide.md +2249 -0
- package/.claude/skills/react-best-practices/references/eliminating-waterfalls.md +169 -0
- package/.claude/skills/react-best-practices/references/javascript-performance.md +256 -0
- package/.claude/skills/react-best-practices/references/rendering-performance.md +230 -0
- package/.claude/skills/react-best-practices/references/rerender-optimization.md +214 -0
- package/.claude/skills/react-best-practices/references/server-performance.md +182 -0
- package/.claude/skills/security-audit/SKILL.md +226 -0
- package/.claude/skills/shared-references/advanced-debugging-techniques.md +186 -0
- package/.claude/skills/shared-references/code-quality-checklist.md +218 -0
- package/.claude/skills/shared-references/code-review-efficiency-guide.md +125 -0
- package/.claude/skills/shared-references/mcp-dependency-compatibility-protocol.md +276 -0
- package/.claude/skills/shared-references/skill-call-graph.md +230 -0
- package/.claude/skills/shared-references/skill-orchestration-protocol.md +281 -0
- package/.claude/skills/shared-references/subagent-dispatch-templates.md +199 -0
- package/.claude/skills/skill-expert-skills/LICENSE.txt +204 -0
- package/.claude/skills/skill-expert-skills/QUICK_NAVIGATION.md +374 -0
- package/.claude/skills/skill-expert-skills/SKILL.md +247 -0
- package/.claude/skills/skill-expert-skills/docs/_index.md +91 -0
- package/.claude/skills/skill-expert-skills/references/deep-research-methodology.md +389 -0
- package/.claude/skills/skill-expert-skills/references/docs-generation-workflow.md +398 -0
- package/.claude/skills/skill-expert-skills/references/domain-expertise-protocol.md +343 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/_index.md +54 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/backend-expertise.md +517 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/bug-fixing-expertise.md +363 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/code-review-expertise.md +392 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge/frontend-expertise.md +410 -0
- package/.claude/skills/skill-expert-skills/references/domain-knowledge-template.md +503 -0
- package/.claude/skills/skill-expert-skills/references/examples.md +782 -0
- package/.claude/skills/skill-expert-skills/references/integration-examples.md +655 -0
- package/.claude/skills/skill-expert-skills/references/knowledge-validation-checklist.md +246 -0
- package/.claude/skills/skill-expert-skills/references/latest-knowledge-acquisition.md +461 -0
- package/.claude/skills/skill-expert-skills/references/mcp-tools-guide.md +439 -0
- package/.claude/skills/skill-expert-skills/references/official-best-practices.md +616 -0
- package/.claude/skills/skill-expert-skills/references/patterns.md +218 -0
- package/.claude/skills/skill-expert-skills/references/plugin-skills-guide.md +432 -0
- package/.claude/skills/skill-expert-skills/references/requirement-elicitation-protocol.md +290 -0
- package/.claude/skills/skill-expert-skills/references/skill-creator-SKILL.md +353 -0
- package/.claude/skills/skill-expert-skills/references/skill-templates.md +583 -0
- package/.claude/skills/skill-expert-skills/references/skills-knowledge-base.md +561 -0
- package/.claude/skills/skill-expert-skills/references/tools-guide.md +379 -0
- package/.claude/skills/skill-expert-skills/references/troubleshooting.md +378 -0
- package/.claude/skills/skill-expert-skills/references/universality-guide.md +205 -0
- package/.claude/skills/skill-expert-skills/references/writing-style-guide.md +466 -0
- package/.claude/skills/skill-expert-skills/scripts/__pycache__/quick_validate.cpython-313.pyc +0 -0
- package/.claude/skills/skill-expert-skills/scripts/__pycache__/universal_validate.cpython-313.pyc +0 -0
- package/.claude/skills/skill-expert-skills/scripts/analyze_trigger.py +425 -0
- package/.claude/skills/skill-expert-skills/scripts/diff_with_official.py +188 -0
- package/.claude/skills/skill-expert-skills/scripts/init_skill.py +349 -0
- package/.claude/skills/skill-expert-skills/scripts/package_skill.py +156 -0
- package/.claude/skills/skill-expert-skills/scripts/quick_validate.py +493 -0
- package/.claude/skills/skill-expert-skills/scripts/requirements.txt +2 -0
- package/.claude/skills/skill-expert-skills/scripts/universal_validate.py +182 -0
- package/.claude/skills/skill-expert-skills/scripts/upgrade_skill.py +431 -0
- package/.claude/skills/subagent-driven-development/SKILL.md +268 -0
- package/.claude/skills/test-driven-development/SKILL.md +246 -0
- package/.claude/skills/test-driven-development/references/testing-anti-patterns.md +192 -0
- package/.claude/skills/using-git-worktrees/SKILL.md +266 -0
- package/.claude/skills/using-skillstack/SKILL.md +127 -0
- package/.claude/skills/vercel-deploy/SKILL.md +166 -0
- package/.claude/skills/vercel-deploy/scripts/deploy.sh +249 -0
- package/.claude/skills/verification-before-completion/SKILL.md +305 -0
- package/.claude/skills/writing-plans/SKILL.md +259 -0
- package/README.md +69 -0
- package/bin/cli.js +468 -0
- package/lib/init.js +333 -0
- package/package.json +29 -0
|
@@ -0,0 +1,914 @@
|
|
|
1
|
+
# Bug Prevention & Detection Guide
|
|
2
|
+
|
|
3
|
+
> Prevention is cheaper than debugging. This guide integrates patterns from bug-fixing and code-review skills.
|
|
4
|
+
|
|
5
|
+
## 🔴 Universal Prevention Rules (All Languages/Frameworks)
|
|
6
|
+
|
|
7
|
+
These six patterns cause bugs across **any** tech stack. Check them before every code submission.
|
|
8
|
+
|
|
9
|
+
### 1. Batch Callback Processing
|
|
10
|
+
|
|
11
|
+
**Problem**: Processing items one-by-one in event callbacks causes UI freeze or resource exhaustion.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
❌ Bad: on_item_received(item) → immediately update UI
|
|
15
|
+
✅ Good: on_item_received(item) → add to buffer → timer flushes buffer every N ms
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Detection**: "If 1000 events arrive in 1 second, will the UI freeze?"
|
|
19
|
+
|
|
20
|
+
### 2. Resource Release Completeness
|
|
21
|
+
|
|
22
|
+
**Problem**: Timeout alone doesn't guarantee resource release.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
❌ Bad: resource.stop(); wait(2000); // assume released
|
|
26
|
+
✅ Good: resource.stop(); if (!wait(2000)) { force_terminate(); wait(); }
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Detection**: "If the operation times out, is the resource truly released?"
|
|
30
|
+
|
|
31
|
+
### 3. Exception Granularity
|
|
32
|
+
|
|
33
|
+
**Problem**: Outer try-catch aborts entire operation on single failure.
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
❌ Bad: try { for item in items: process(item) } catch: pass // entire loop aborts
|
|
37
|
+
✅ Good: for item in items: try { process(item) } catch: continue // only skip failed item
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Detection**: "If one iteration fails, will the entire loop abort?"
|
|
41
|
+
|
|
42
|
+
### 4. Idempotent Creation
|
|
43
|
+
|
|
44
|
+
**Problem**: Creating entities without existence check causes duplicates.
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
❌ Bad: create_entity(name, data)
|
|
48
|
+
✅ Good: existing = find_by_name(name); if existing: return existing; else: create_entity(unique_name, data)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Detection**: "If this function is called twice with the same input, will it create duplicates?"
|
|
52
|
+
|
|
53
|
+
### 5. Shared State in Concurrent Code
|
|
54
|
+
|
|
55
|
+
**Problem**: Direct read/write of shared variables without synchronization.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
❌ Bad: self.cancelled = True // in thread A, read in thread B
|
|
59
|
+
✅ Good: with lock: self.cancelled = True // or use atomic/thread-safe primitive
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Detection**: "If two threads read/write this variable, is there a race condition?"
|
|
63
|
+
|
|
64
|
+
### 6. Cleanup on Close/Destroy
|
|
65
|
+
|
|
66
|
+
**Problem**: Assuming child resources auto-cleanup when parent closes.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
❌ Bad: on_close() { /* nothing, assume GC handles it */ }
|
|
70
|
+
✅ Good: on_close() { stop_timer(); cancel_thread(); close_connection(); }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Detection**: "When the window/connection/process closes, are all child resources stopped?"
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Core Principles (From bug-fixing)
|
|
78
|
+
|
|
79
|
+
1. **Never fix what you don't understand** — A fix without understanding is a landmine
|
|
80
|
+
2. **Fix root cause, not symptoms** — Symptoms resurface elsewhere
|
|
81
|
+
3. **Configuration over hardcode** — Avoid hardcoded lists, use dynamic detection
|
|
82
|
+
4. **Hunt similar bugs** — After finding one bug, search entire project for same pattern
|
|
83
|
+
5. **Full-scope investigation** — Code, DB, configs, migrations, environment files
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 🔥 Most Common Issues (80/20 Rule)
|
|
88
|
+
|
|
89
|
+
| Issue | Frequency | Impact |
|
|
90
|
+
|-------|-----------|--------|
|
|
91
|
+
| **CORS errors** | Very High | Blocks all API calls |
|
|
92
|
+
| **Field name mismatch** (camelCase/snake_case) | Very High | Data not displayed |
|
|
93
|
+
| **Missing error handling** | High | Silent failures |
|
|
94
|
+
| **useEffect cleanup missing** | High | Memory leaks |
|
|
95
|
+
| **Input validation gaps** | High | Security + crashes |
|
|
96
|
+
| **N+1 queries** | High | Performance |
|
|
97
|
+
| **Auth token issues** | Medium | 401 errors |
|
|
98
|
+
| **Type mismatch** (string vs number) | Medium | Runtime errors |
|
|
99
|
+
| **Missing loading states** | Medium | Bad UX |
|
|
100
|
+
| **Database migration missing** | Medium | Column not found |
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Hidden Bug Categories (Most Dangerous)
|
|
105
|
+
|
|
106
|
+
| Category | Characteristics | Difficulty | Severity |
|
|
107
|
+
|----------|----------------|------------|----------|
|
|
108
|
+
| **Data Races** | Only occurs under concurrency | 🔴 Very Hard | 🔴 Critical |
|
|
109
|
+
| **Memory Leaks** | Only exposed after long runtime | 🔴 Very Hard | 🟠 High |
|
|
110
|
+
| **State Inconsistency** | Triggered by specific operation sequence | 🟠 Hard | 🔴 Critical |
|
|
111
|
+
| **Timing Issues** | Depends on execution order | 🟠 Hard | 🟠 High |
|
|
112
|
+
| **Resource Leaks** | Uncleared on exception paths | 🟡 Medium | 🟠 High |
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 1. Data Race Prevention
|
|
117
|
+
|
|
118
|
+
### Shared State Modification (Most Dangerous)
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
# 🔴 BUG: Modifying shared singleton state
|
|
122
|
+
class ChatService:
|
|
123
|
+
def __init__(self):
|
|
124
|
+
self.agent = load_agent() # Shared singleton
|
|
125
|
+
|
|
126
|
+
async def chat(self, user_input, llm_id=None):
|
|
127
|
+
if llm_id:
|
|
128
|
+
self.agent.llm_provider_id = llm_id # 💀 Affects ALL users!
|
|
129
|
+
await self.executor.run(self.agent, user_input)
|
|
130
|
+
|
|
131
|
+
# ✅ CORRECT: Pass through parameters
|
|
132
|
+
async def chat(self, user_input, llm_id=None):
|
|
133
|
+
await self.executor.run(
|
|
134
|
+
self.agent, user_input,
|
|
135
|
+
override_llm_id=llm_id # Pass as parameter
|
|
136
|
+
)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Detection Commands
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Python: State modification in async functions
|
|
143
|
+
grep -rn "self\.[a-z_]* = " --include="*.py" | grep -v "__init__"
|
|
144
|
+
|
|
145
|
+
# Module-level mutable objects (dangerous)
|
|
146
|
+
grep -rn "^[a-z_]* = \[\]\|^[a-z_]* = {}" --include="*.py"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## 2. Memory & Resource Leak Prevention
|
|
152
|
+
|
|
153
|
+
### Frontend Event Listener Leak
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// 🔴 BUG: No cleanup
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
window.addEventListener('resize', handleResize);
|
|
159
|
+
}, []);
|
|
160
|
+
|
|
161
|
+
// ✅ CORRECT: Cleanup on unmount
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
window.addEventListener('resize', handleResize);
|
|
164
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
165
|
+
}, []);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Backend Connection Leak
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
# 🔴 BUG: Connection not closed on exception
|
|
172
|
+
async def query():
|
|
173
|
+
conn = await pool.acquire()
|
|
174
|
+
result = await conn.fetch("SELECT ...") # Exception here = leak
|
|
175
|
+
await pool.release(conn)
|
|
176
|
+
|
|
177
|
+
# ✅ CORRECT: Context manager
|
|
178
|
+
async def query():
|
|
179
|
+
async with pool.acquire() as conn:
|
|
180
|
+
return await conn.fetch("SELECT ...")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Detection Commands
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# useEffect without cleanup
|
|
187
|
+
grep -rn "useEffect" --include="*.tsx" -A 8 | grep -B 6 "}, \[\])" | grep -v "return () =>"
|
|
188
|
+
|
|
189
|
+
# Unclosed connections
|
|
190
|
+
grep -rn "\.acquire()\|\.open(" --include="*.py" | grep -v "with\|async with"
|
|
191
|
+
|
|
192
|
+
# setInterval without clear
|
|
193
|
+
grep -rn "setInterval\|setTimeout" --include="*.ts" -A 5 | grep -v "clearInterval\|clearTimeout"
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## 3. State Inconsistency Prevention
|
|
199
|
+
|
|
200
|
+
### Optimistic Update Without Rollback
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// 🔴 BUG: No proper rollback
|
|
204
|
+
async function deleteItem(id) {
|
|
205
|
+
setItems(items.filter(i => i.id !== id)); // Optimistic
|
|
206
|
+
try {
|
|
207
|
+
await api.delete(id);
|
|
208
|
+
} catch (e) {
|
|
209
|
+
// 💀 Other operations may have modified items
|
|
210
|
+
setItems(backup); // Stale backup
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// ✅ CORRECT: Use functional update
|
|
215
|
+
async function deleteItem(id) {
|
|
216
|
+
const previousItems = items;
|
|
217
|
+
setItems(prev => prev.filter(i => i.id !== id));
|
|
218
|
+
try {
|
|
219
|
+
await api.delete(id);
|
|
220
|
+
} catch (e) {
|
|
221
|
+
setItems(previousItems);
|
|
222
|
+
showError('Delete failed');
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Cache & Database Inconsistency
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
# 🔴 BUG: Delete cache first = stale data cached
|
|
231
|
+
await cache.delete(f"user:{user_id}")
|
|
232
|
+
await db.update(user_id, data) # Read request may cache old data
|
|
233
|
+
|
|
234
|
+
# ✅ CORRECT: Update DB first, then delete cache
|
|
235
|
+
await db.update(user_id, data)
|
|
236
|
+
await cache.delete(f"user:{user_id}")
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## 4. Timing & Concurrency Prevention
|
|
242
|
+
|
|
243
|
+
### Missing Await
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// 🔴 BUG: Not awaited = race condition
|
|
247
|
+
async function loadData() {
|
|
248
|
+
fetchUserProfile(); // 💀 Fire and forget
|
|
249
|
+
fetchUserOrders();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// ✅ CORRECT: Await or Promise.all
|
|
253
|
+
async function loadData() {
|
|
254
|
+
const [profile, orders] = await Promise.all([
|
|
255
|
+
fetchUserProfile(),
|
|
256
|
+
fetchUserOrders()
|
|
257
|
+
]);
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Token Refresh Race
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// 🔴 BUG: Multiple refresh calls
|
|
265
|
+
async function apiCall(url) {
|
|
266
|
+
if (isTokenExpired()) {
|
|
267
|
+
await refreshToken(); // 💀 Multiple calls = multiple refreshes
|
|
268
|
+
}
|
|
269
|
+
return fetch(url);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// ✅ CORRECT: Singleton refresh promise
|
|
273
|
+
let refreshPromise = null;
|
|
274
|
+
async function apiCall(url) {
|
|
275
|
+
if (isTokenExpired()) {
|
|
276
|
+
if (!refreshPromise) {
|
|
277
|
+
refreshPromise = refreshToken().finally(() => refreshPromise = null);
|
|
278
|
+
}
|
|
279
|
+
await refreshPromise;
|
|
280
|
+
}
|
|
281
|
+
return fetch(url);
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## 5. Frontend-Backend-Database Sync Prevention
|
|
288
|
+
|
|
289
|
+
### Contract Mismatch Detection
|
|
290
|
+
|
|
291
|
+
| Symptom | Cause | Fix |
|
|
292
|
+
|---------|-------|-----|
|
|
293
|
+
| UI shows success, action failed | Not reading response status | Check response handling |
|
|
294
|
+
| Data not updating | Wrong response field | Compare schemas |
|
|
295
|
+
| Field undefined | Naming convention differs | camelCase vs snake_case |
|
|
296
|
+
| **Column not found** | Missing migration | Create and run migration |
|
|
297
|
+
| **Null constraint error** | Required field missing | Check nullable settings |
|
|
298
|
+
| **Type conversion error** | DB type ≠ code type | Align types across layers |
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# Compare validation rules
|
|
302
|
+
grep -rn "maxLength\|max:" --include="*.ts" # Frontend
|
|
303
|
+
grep -rn "max_length\|MaxLength" --include="*.py" # Backend
|
|
304
|
+
|
|
305
|
+
# Compare model with database schema
|
|
306
|
+
alembic check # Python/Alembic
|
|
307
|
+
npx prisma migrate status # Node/Prisma
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Database-Model Mismatch
|
|
311
|
+
|
|
312
|
+
```python
|
|
313
|
+
# 🔴 BUG: Model has field, database doesn't
|
|
314
|
+
class User(Base):
|
|
315
|
+
avatar_url = Column(String) # 💀 Not in database!
|
|
316
|
+
|
|
317
|
+
# Error: column "avatar_url" does not exist
|
|
318
|
+
|
|
319
|
+
# ✅ CORRECT: Always create migration first
|
|
320
|
+
# 1. alembic revision --autogenerate -m "add avatar_url"
|
|
321
|
+
# 2. alembic upgrade head
|
|
322
|
+
# 3. Then add to model
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Field Alignment Checklist
|
|
326
|
+
|
|
327
|
+
```markdown
|
|
328
|
+
| Layer | Field Name | Type | Nullable |
|
|
329
|
+
|-------|------------|------|----------|
|
|
330
|
+
| Database | created_at | TIMESTAMP | NO |
|
|
331
|
+
| ORM Model | created_at | DateTime | NO |
|
|
332
|
+
| API Schema | createdAt | string | NO |
|
|
333
|
+
| Frontend | createdAt | string | NO |
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Common Sync Issues
|
|
337
|
+
|
|
338
|
+
```typescript
|
|
339
|
+
// 🔴 BUG: Field name mismatch
|
|
340
|
+
// Frontend expects: response.userId
|
|
341
|
+
// Backend sends: response.user_id
|
|
342
|
+
|
|
343
|
+
// ✅ CORRECT: Transform or match exactly
|
|
344
|
+
const user = {
|
|
345
|
+
userId: response.user_id, // Transform
|
|
346
|
+
...response
|
|
347
|
+
};
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
→ Complete database guide: `database-migration.md`
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## 6. CORS Errors (Most Frustrating)
|
|
355
|
+
|
|
356
|
+
### Why It Happens
|
|
357
|
+
|
|
358
|
+
```
|
|
359
|
+
Frontend (localhost:3000) → API (localhost:8000)
|
|
360
|
+
Browser blocks because different origins!
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Common Symptoms
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
// Console error
|
|
367
|
+
Access to fetch at 'http://api.example.com/users' from origin
|
|
368
|
+
'http://localhost:3000' has been blocked by CORS policy
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Backend Fixes
|
|
372
|
+
|
|
373
|
+
```python
|
|
374
|
+
# Python FastAPI
|
|
375
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
376
|
+
|
|
377
|
+
app.add_middleware(
|
|
378
|
+
CORSMiddleware,
|
|
379
|
+
allow_origins=["http://localhost:3000"], # Not "*" in production!
|
|
380
|
+
allow_credentials=True,
|
|
381
|
+
allow_methods=["*"],
|
|
382
|
+
allow_headers=["*"],
|
|
383
|
+
)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
```javascript
|
|
387
|
+
// Node.js Express
|
|
388
|
+
const cors = require('cors');
|
|
389
|
+
app.use(cors({
|
|
390
|
+
origin: 'http://localhost:3000',
|
|
391
|
+
credentials: true
|
|
392
|
+
}));
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Checklist
|
|
396
|
+
|
|
397
|
+
- [ ] Backend has CORS middleware configured
|
|
398
|
+
- [ ] Allowed origins include frontend URL
|
|
399
|
+
- [ ] Credentials setting matches frontend fetch options
|
|
400
|
+
- [ ] Preflight OPTIONS requests handled
|
|
401
|
+
- [ ] Custom headers allowed if using them
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## 7. UI Boundary Detection (MANDATORY for Popups)
|
|
406
|
+
|
|
407
|
+
### Why This Matters
|
|
408
|
+
|
|
409
|
+
Popup elements (context menus, tooltips, dropdowns, popovers) positioned with raw click coordinates will be clipped/hidden when triggered near viewport edges. This is a **high-frequency bug** that affects user experience.
|
|
410
|
+
|
|
411
|
+
### Detection Questions (Ask Before Every Popup Implementation)
|
|
412
|
+
|
|
413
|
+
1. "If user clicks near viewport bottom, will the popup be fully visible?"
|
|
414
|
+
2. "If user clicks near viewport right edge, will content overflow?"
|
|
415
|
+
3. "Does the component have boundary flip logic?"
|
|
416
|
+
|
|
417
|
+
### Universal Rule
|
|
418
|
+
|
|
419
|
+
```
|
|
420
|
+
❌ Bad: style={{ left: clientX, top: clientY }} // Direct coordinates
|
|
421
|
+
✅ Good: useLayoutEffect → measure → clamp/flip → adjustedPosition
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
### Standard Implementation Pattern
|
|
425
|
+
|
|
426
|
+
```tsx
|
|
427
|
+
const [adjustedPos, setAdjustedPos] = useState({ x: 0, y: 0 });
|
|
428
|
+
const menuRef = useRef<HTMLDivElement>(null);
|
|
429
|
+
|
|
430
|
+
useLayoutEffect(() => {
|
|
431
|
+
if (!isOpen || !menuRef.current) return;
|
|
432
|
+
|
|
433
|
+
const rect = menuRef.current.getBoundingClientRect();
|
|
434
|
+
const vh = window.innerHeight;
|
|
435
|
+
const vw = window.innerWidth;
|
|
436
|
+
const margin = 10; // Safety margin from edge
|
|
437
|
+
|
|
438
|
+
let x = position.x;
|
|
439
|
+
let y = position.y;
|
|
440
|
+
|
|
441
|
+
// Bottom boundary: flip upward
|
|
442
|
+
if (y + rect.height > vh - margin) {
|
|
443
|
+
y = y - rect.height;
|
|
444
|
+
if (y < margin) y = margin;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Right boundary: flip leftward
|
|
448
|
+
if (x + rect.width > vw - margin) {
|
|
449
|
+
x = x - rect.width;
|
|
450
|
+
if (x < margin) x = margin;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
setAdjustedPos({ x, y });
|
|
454
|
+
}, [isOpen, position]);
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Component Types Requiring Boundary Detection
|
|
458
|
+
|
|
459
|
+
| Component | Bottom Edge | Right Edge | Top Edge | Left Edge |
|
|
460
|
+
|-----------|-------------|------------|----------|-----------|
|
|
461
|
+
| Context Menu | Flip up | Flip left | Clamp | Clamp |
|
|
462
|
+
| Tooltip | Flip up | Flip left | Flip down | Flip right |
|
|
463
|
+
| Dropdown | Flip to "dropup" | Scroll/truncate | N/A | N/A |
|
|
464
|
+
| Popover | Auto-flip | Auto-flip | Auto-flip | Auto-flip |
|
|
465
|
+
| Autocomplete | Flip up | Scroll | N/A | N/A |
|
|
466
|
+
|
|
467
|
+
### Pre-Implementation Checklist
|
|
468
|
+
|
|
469
|
+
- [ ] Does the component use `fixed` or `absolute` positioning?
|
|
470
|
+
- [ ] Is the position calculated from mouse coordinates (`clientX/Y`)?
|
|
471
|
+
- [ ] Is there a `useLayoutEffect` for boundary detection?
|
|
472
|
+
- [ ] Are all four edges (top/bottom/left/right) handled?
|
|
473
|
+
- [ ] Is there a safety margin (8-10px) from viewport edges?
|
|
474
|
+
|
|
475
|
+
### Hunt Similar Issues
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
# Find all popup positioning without boundary check
|
|
479
|
+
grep -rn "clientX\|clientY\|pageX\|pageY" --include="*.tsx" -A 8 | \
|
|
480
|
+
grep -v "innerHeight\|innerWidth\|getBoundingClientRect"
|
|
481
|
+
|
|
482
|
+
# Find fixed position elements
|
|
483
|
+
grep -rn "position: fixed\|position: 'fixed'" --include="*.tsx" | \
|
|
484
|
+
grep -i "menu\|popup\|tooltip\|dropdown\|popover\|context"
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Recommended Libraries
|
|
488
|
+
|
|
489
|
+
If implementing from scratch is complex, use battle-tested libraries:
|
|
490
|
+
- **Floating UI** (`@floating-ui/react`) - Best flexibility
|
|
491
|
+
- **Radix UI** - Built-in boundary handling
|
|
492
|
+
- **Headless UI** - Accessible with boundary logic
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
## 8. React Hooks Common Mistakes
|
|
497
|
+
|
|
498
|
+
### useEffect Mistakes (7 Critical)
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
// ❌ 1. Missing dependency
|
|
502
|
+
useEffect(() => {
|
|
503
|
+
fetchData(userId); // userId not in deps
|
|
504
|
+
}, []); // 💀 Stale userId
|
|
505
|
+
|
|
506
|
+
// ✅ Fix
|
|
507
|
+
useEffect(() => {
|
|
508
|
+
fetchData(userId);
|
|
509
|
+
}, [userId]);
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
```typescript
|
|
513
|
+
// ❌ 2. Object/Array in deps (infinite loop)
|
|
514
|
+
useEffect(() => {
|
|
515
|
+
doSomething();
|
|
516
|
+
}, [{ id: 1 }]); // 💀 New object every render
|
|
517
|
+
|
|
518
|
+
// ✅ Fix: Use primitive or useMemo
|
|
519
|
+
useEffect(() => {
|
|
520
|
+
doSomething();
|
|
521
|
+
}, [id]);
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
// ❌ 3. Async function directly
|
|
526
|
+
useEffect(async () => { // 💀 Returns Promise, not cleanup
|
|
527
|
+
await fetchData();
|
|
528
|
+
}, []);
|
|
529
|
+
|
|
530
|
+
// ✅ Fix: Define async inside
|
|
531
|
+
useEffect(() => {
|
|
532
|
+
const load = async () => {
|
|
533
|
+
await fetchData();
|
|
534
|
+
};
|
|
535
|
+
load();
|
|
536
|
+
}, []);
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
```typescript
|
|
540
|
+
// ❌ 4. Missing cleanup
|
|
541
|
+
useEffect(() => {
|
|
542
|
+
const timer = setInterval(tick, 1000);
|
|
543
|
+
// 💀 Timer runs forever
|
|
544
|
+
}, []);
|
|
545
|
+
|
|
546
|
+
// ✅ Fix
|
|
547
|
+
useEffect(() => {
|
|
548
|
+
const timer = setInterval(tick, 1000);
|
|
549
|
+
return () => clearInterval(timer);
|
|
550
|
+
}, []);
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
```typescript
|
|
554
|
+
// ❌ 5. Race condition
|
|
555
|
+
useEffect(() => {
|
|
556
|
+
fetchData(id).then(setData); // 💀 Old request may finish after new
|
|
557
|
+
}, [id]);
|
|
558
|
+
|
|
559
|
+
// ✅ Fix: Cancel flag
|
|
560
|
+
useEffect(() => {
|
|
561
|
+
let cancelled = false;
|
|
562
|
+
fetchData(id).then(data => {
|
|
563
|
+
if (!cancelled) setData(data);
|
|
564
|
+
});
|
|
565
|
+
return () => { cancelled = true; };
|
|
566
|
+
}, [id]);
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### useState Mistakes
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
// ❌ 1. Wrong initial type
|
|
573
|
+
const [count, setCount] = useState(0);
|
|
574
|
+
setCount("1"); // 💀 Type error
|
|
575
|
+
|
|
576
|
+
// ❌ 2. Not using functional update
|
|
577
|
+
setCount(count + 1); // 💀 Stale if called multiple times
|
|
578
|
+
setCount(prev => prev + 1); // ✅
|
|
579
|
+
|
|
580
|
+
// ❌ 3. Mutating state directly
|
|
581
|
+
const [items, setItems] = useState([]);
|
|
582
|
+
items.push(newItem); // 💀 Mutation
|
|
583
|
+
setItems([...items, newItem]); // ✅
|
|
584
|
+
|
|
585
|
+
// ❌ 4. Object mutation
|
|
586
|
+
const [user, setUser] = useState({ name: '' });
|
|
587
|
+
user.name = 'John'; // 💀 Mutation
|
|
588
|
+
setUser({ ...user, name: 'John' }); // ✅
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## 8. API Error Handling (RFC 9457)
|
|
594
|
+
|
|
595
|
+
### Standard Error Response Format
|
|
596
|
+
|
|
597
|
+
```json
|
|
598
|
+
{
|
|
599
|
+
"type": "https://api.example.com/errors/validation",
|
|
600
|
+
"title": "Validation Error",
|
|
601
|
+
"status": 422,
|
|
602
|
+
"detail": "The email field is invalid",
|
|
603
|
+
"instance": "/api/users/123",
|
|
604
|
+
"errors": {
|
|
605
|
+
"email": ["Invalid email format"],
|
|
606
|
+
"password": ["Must be at least 8 characters"]
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
### HTTP Status Code Usage
|
|
612
|
+
|
|
613
|
+
| Code | Meaning | When to Use |
|
|
614
|
+
|------|---------|-------------|
|
|
615
|
+
| 400 | Bad Request | Malformed JSON, missing required field |
|
|
616
|
+
| 401 | Unauthorized | No token, invalid token |
|
|
617
|
+
| 403 | Forbidden | Valid token, but no permission |
|
|
618
|
+
| 404 | Not Found | Resource doesn't exist |
|
|
619
|
+
| 409 | Conflict | Duplicate entry, version conflict |
|
|
620
|
+
| 422 | Unprocessable | Valid syntax, invalid semantics (validation) |
|
|
621
|
+
| 429 | Too Many Requests | Rate limited |
|
|
622
|
+
| 500 | Server Error | Unexpected backend error |
|
|
623
|
+
|
|
624
|
+
### Frontend Error Handling Pattern
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
async function apiCall<T>(url: string): Promise<T> {
|
|
628
|
+
const response = await fetch(url);
|
|
629
|
+
|
|
630
|
+
if (!response.ok) {
|
|
631
|
+
const error = await response.json();
|
|
632
|
+
|
|
633
|
+
switch (response.status) {
|
|
634
|
+
case 401:
|
|
635
|
+
// Token expired, redirect to login
|
|
636
|
+
redirectToLogin();
|
|
637
|
+
throw new AuthError(error.detail);
|
|
638
|
+
|
|
639
|
+
case 403:
|
|
640
|
+
throw new ForbiddenError(error.detail);
|
|
641
|
+
|
|
642
|
+
case 404:
|
|
643
|
+
throw new NotFoundError(error.detail);
|
|
644
|
+
|
|
645
|
+
case 422:
|
|
646
|
+
// Validation errors - show to user
|
|
647
|
+
throw new ValidationError(error.errors);
|
|
648
|
+
|
|
649
|
+
case 429:
|
|
650
|
+
// Rate limited - retry after
|
|
651
|
+
throw new RateLimitError(response.headers.get('Retry-After'));
|
|
652
|
+
|
|
653
|
+
default:
|
|
654
|
+
throw new ApiError(error.detail || 'Something went wrong');
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
return response.json();
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
---
|
|
663
|
+
|
|
664
|
+
## 9. Input Validation (Security Critical)
|
|
665
|
+
|
|
666
|
+
### Backend Validation (NEVER Trust Frontend)
|
|
667
|
+
|
|
668
|
+
```python
|
|
669
|
+
# ❌ BAD: Trust user input
|
|
670
|
+
@app.post("/users")
|
|
671
|
+
def create_user(data: dict):
|
|
672
|
+
db.execute(f"INSERT INTO users VALUES ('{data['email']}')") # SQL Injection!
|
|
673
|
+
|
|
674
|
+
# ✅ GOOD: Validate with schema
|
|
675
|
+
from pydantic import BaseModel, EmailStr, Field
|
|
676
|
+
|
|
677
|
+
class UserCreate(BaseModel):
|
|
678
|
+
email: EmailStr
|
|
679
|
+
password: str = Field(min_length=8, max_length=100)
|
|
680
|
+
name: str = Field(min_length=2, max_length=50)
|
|
681
|
+
|
|
682
|
+
@app.post("/users")
|
|
683
|
+
def create_user(data: UserCreate): # Pydantic validates
|
|
684
|
+
db.add(User(**data.dict()))
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Frontend Validation (UX, not Security)
|
|
688
|
+
|
|
689
|
+
```typescript
|
|
690
|
+
// Validate before submit
|
|
691
|
+
const validateForm = (data: FormData) => {
|
|
692
|
+
const errors: Record<string, string> = {};
|
|
693
|
+
|
|
694
|
+
if (!data.email) {
|
|
695
|
+
errors.email = 'Email is required';
|
|
696
|
+
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
|
|
697
|
+
errors.email = 'Invalid email format';
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
if (!data.password) {
|
|
701
|
+
errors.password = 'Password is required';
|
|
702
|
+
} else if (data.password.length < 8) {
|
|
703
|
+
errors.password = 'Password must be at least 8 characters';
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
return errors;
|
|
707
|
+
};
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
### Validation Alignment Checklist
|
|
711
|
+
|
|
712
|
+
```markdown
|
|
713
|
+
| Field | Frontend Rule | Backend Rule | Match? |
|
|
714
|
+
|-------|---------------|--------------|--------|
|
|
715
|
+
| email | Required, email format | Required, EmailStr | ✅ |
|
|
716
|
+
| password | Min 8 chars | Min 8 chars | ✅ |
|
|
717
|
+
| name | Max 100 chars | Max 50 chars | ❌ FE too lenient! |
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
---
|
|
721
|
+
|
|
722
|
+
## 10. Backend Common Mistakes
|
|
723
|
+
|
|
724
|
+
### Skipping Input Validation
|
|
725
|
+
|
|
726
|
+
```python
|
|
727
|
+
# 🔴 BUG: Direct user input to query
|
|
728
|
+
query = f"SELECT * FROM users WHERE id = {request.id}" # SQL Injection!
|
|
729
|
+
|
|
730
|
+
# ✅ FIX: Parameterized query
|
|
731
|
+
query = "SELECT * FROM users WHERE id = ?"
|
|
732
|
+
db.execute(query, [request.id])
|
|
733
|
+
```
|
|
734
|
+
|
|
735
|
+
### Missing Rate Limiting
|
|
736
|
+
|
|
737
|
+
```python
|
|
738
|
+
# 🔴 BUG: No rate limiting
|
|
739
|
+
@app.post("/login")
|
|
740
|
+
def login(data: LoginRequest):
|
|
741
|
+
return authenticate(data) # 💀 Brute force possible
|
|
742
|
+
|
|
743
|
+
# ✅ FIX: Add rate limiter
|
|
744
|
+
from slowapi import Limiter
|
|
745
|
+
limiter = Limiter(key_func=get_remote_address)
|
|
746
|
+
|
|
747
|
+
@app.post("/login")
|
|
748
|
+
@limiter.limit("5/minute")
|
|
749
|
+
def login(data: LoginRequest):
|
|
750
|
+
return authenticate(data)
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
### Exposing Sensitive Data in Logs
|
|
754
|
+
|
|
755
|
+
```python
|
|
756
|
+
# 🔴 BUG: Logging sensitive data
|
|
757
|
+
logger.info(f"User login: {email}, password: {password}") # 💀
|
|
758
|
+
|
|
759
|
+
# ✅ FIX: Mask sensitive data
|
|
760
|
+
logger.info(f"User login: {email}")
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
### Not Handling Concurrent Requests
|
|
764
|
+
|
|
765
|
+
```python
|
|
766
|
+
# 🔴 BUG: Race condition on balance update
|
|
767
|
+
def withdraw(user_id, amount):
|
|
768
|
+
balance = get_balance(user_id)
|
|
769
|
+
if balance >= amount:
|
|
770
|
+
set_balance(user_id, balance - amount) # 💀 Two requests can both pass
|
|
771
|
+
|
|
772
|
+
# ✅ FIX: Use database transaction with lock
|
|
773
|
+
async with db.transaction():
|
|
774
|
+
await db.execute("SELECT balance FROM accounts WHERE id = ? FOR UPDATE", [user_id])
|
|
775
|
+
# Now locked, proceed safely
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
---
|
|
779
|
+
|
|
780
|
+
## 11. Solution Design Hierarchy (From bug-fixing)
|
|
781
|
+
|
|
782
|
+
**Prefer top to bottom when fixing issues:**
|
|
783
|
+
|
|
784
|
+
| Priority | Approach | When to Use |
|
|
785
|
+
|----------|----------|-------------|
|
|
786
|
+
| 1️⃣ | **Database field** | Feature can be configured per-entity |
|
|
787
|
+
| 2️⃣ | **Runtime detection** | Feature can be probed at runtime |
|
|
788
|
+
| 3️⃣ | **Config file** | Setting applies environment-wide |
|
|
789
|
+
| 4️⃣ | **Pattern matching** | Fallback when detection impossible |
|
|
790
|
+
| 5️⃣ | **Hardcoded list** | Last resort, document why |
|
|
791
|
+
|
|
792
|
+
```python
|
|
793
|
+
# ❌ BAD: Hardcoded list
|
|
794
|
+
UNSUPPORTED = ["model-a", "model-b"]
|
|
795
|
+
if name in UNSUPPORTED: fallback()
|
|
796
|
+
|
|
797
|
+
# ✅ GOOD: Config-driven
|
|
798
|
+
if not config.supports_feature: fallback()
|
|
799
|
+
|
|
800
|
+
# ✅ GOOD: Runtime detection
|
|
801
|
+
if not await detect_support(model): fallback()
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
---
|
|
805
|
+
|
|
806
|
+
## 12. Similar Bug Hunt (MANDATORY After Any Fix)
|
|
807
|
+
|
|
808
|
+
After fixing ANY bug, search the entire project:
|
|
809
|
+
|
|
810
|
+
```bash
|
|
811
|
+
# Extract the pattern that caused the bug
|
|
812
|
+
grep -rn "PATTERN" --include="*.EXT" .
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
### Hunt Patterns
|
|
816
|
+
|
|
817
|
+
| Bug Type | What to Search |
|
|
818
|
+
|----------|----------------|
|
|
819
|
+
| Hardcoded data | The exact hardcoded value |
|
|
820
|
+
| Placeholder code | `TODO`, `FIXME`, empty handlers |
|
|
821
|
+
| Missing integration | `handle*` functions without API calls |
|
|
822
|
+
| Contract mismatch | Field name in both FE and BE |
|
|
823
|
+
| State not synced | State init without fetch |
|
|
824
|
+
|
|
825
|
+
### Report Format
|
|
826
|
+
|
|
827
|
+
```markdown
|
|
828
|
+
## Similar Bug Hunt
|
|
829
|
+
|
|
830
|
+
**Pattern**: [What caused the bug]
|
|
831
|
+
**Search**: `grep -rn "xxx" --include="*.ts"`
|
|
832
|
+
|
|
833
|
+
| File | Line | Issue | Status |
|
|
834
|
+
|------|------|-------|--------|
|
|
835
|
+
| a.ts | 123 | Same pattern | ✅ Fixed |
|
|
836
|
+
| b.ts | 45 | False positive | ⏭️ Skip |
|
|
837
|
+
|
|
838
|
+
**Conclusion**: Found N similar issues, all fixed.
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
---
|
|
842
|
+
|
|
843
|
+
## 13. Quick Detection Script
|
|
844
|
+
|
|
845
|
+
```bash
|
|
846
|
+
#!/bin/bash
|
|
847
|
+
# Run before every commit
|
|
848
|
+
|
|
849
|
+
echo "=== CORS Check ==="
|
|
850
|
+
grep -rn "CORSMiddleware\|cors(" --include="*.py" --include="*.js" --include="*.ts"
|
|
851
|
+
|
|
852
|
+
echo "=== Data Race Detection ==="
|
|
853
|
+
grep -rn "self\.[a-z_]* = " --include="*.py" | grep -v "__init__"
|
|
854
|
+
|
|
855
|
+
echo "=== Resource Leak Detection ==="
|
|
856
|
+
grep -rn "useEffect" --include="*.tsx" -A 8 | grep -B 6 "}, \[\])" | grep -v "return () =>"
|
|
857
|
+
|
|
858
|
+
echo "=== Missing Await ==="
|
|
859
|
+
grep -rn "async function" --include="*.ts" -A 10 | grep -E "\([a-zA-Z]+\)\s*;" | grep -v await
|
|
860
|
+
|
|
861
|
+
echo "=== Hardcoded Secrets ==="
|
|
862
|
+
grep -rn "password\s*=\|api_key\s*=\|secret\s*=" --include="*.py" --include="*.ts" | grep -v "env\|config\|\.example"
|
|
863
|
+
|
|
864
|
+
echo "=== SQL Injection Risk ==="
|
|
865
|
+
grep -rn "execute.*f\"\|query.*\+" --include="*.py" --include="*.ts"
|
|
866
|
+
|
|
867
|
+
echo "=== Missing Input Validation ==="
|
|
868
|
+
grep -rn "@app\.\(post\|put\|patch\)" --include="*.py" -A 3 | grep -v "BaseModel\|Schema"
|
|
869
|
+
|
|
870
|
+
echo "=== Done ==="
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
---
|
|
874
|
+
|
|
875
|
+
## 14. Pre-Commit Checklist
|
|
876
|
+
|
|
877
|
+
```markdown
|
|
878
|
+
### Before Every Commit
|
|
879
|
+
|
|
880
|
+
**🔴 Critical (Block Merge)**
|
|
881
|
+
- [ ] CORS configured for frontend origin
|
|
882
|
+
- [ ] All API inputs validated (Pydantic/Zod)
|
|
883
|
+
- [ ] No SQL injection (parameterized queries)
|
|
884
|
+
- [ ] No hardcoded secrets
|
|
885
|
+
- [ ] Auth checked on protected endpoints
|
|
886
|
+
|
|
887
|
+
**🟠 High Priority**
|
|
888
|
+
- [ ] All useEffect have cleanup functions
|
|
889
|
+
- [ ] All async operations awaited
|
|
890
|
+
- [ ] No connection/timer leaks
|
|
891
|
+
- [ ] Error boundaries for React components
|
|
892
|
+
- [ ] Database migration created for schema changes
|
|
893
|
+
|
|
894
|
+
**🟡 Medium Priority**
|
|
895
|
+
- [ ] Field names match (FE/BE/DB)
|
|
896
|
+
- [ ] All HTTP status codes handled (401, 403, 404, 422, 500)
|
|
897
|
+
- [ ] Loading/error/empty states implemented
|
|
898
|
+
- [ ] Form validation before submit
|
|
899
|
+
- [ ] Double-submit prevention on forms
|
|
900
|
+
|
|
901
|
+
**🟢 Good Practice**
|
|
902
|
+
- [ ] No console.log/print debugging
|
|
903
|
+
- [ ] Types on all functions
|
|
904
|
+
- [ ] Similar bug hunt completed
|
|
905
|
+
- [ ] API documented in Swagger
|
|
906
|
+
|
|
907
|
+
### Quick Self-Test
|
|
908
|
+
|
|
909
|
+
1. Does the feature work end-to-end? (smoke test)
|
|
910
|
+
2. What happens on error? (error handling)
|
|
911
|
+
3. What happens with no data? (empty state)
|
|
912
|
+
4. What happens with slow network? (loading state)
|
|
913
|
+
5. Can a user break it? (edge cases)
|
|
914
|
+
```
|