devflow-kit 0.9.0 → 1.1.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/CHANGELOG.md +197 -29
- package/LICENSE +1 -1
- package/README.md +185 -309
- package/dist/cli.js +7 -1
- package/dist/commands/ambient.d.ts +18 -0
- package/dist/commands/ambient.js +136 -0
- package/dist/commands/init.d.ts +23 -0
- package/dist/commands/init.js +393 -571
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.js +20 -0
- package/dist/commands/memory.d.ts +22 -0
- package/dist/commands/memory.js +175 -0
- package/dist/commands/uninstall.d.ts +10 -0
- package/dist/commands/uninstall.js +418 -78
- package/dist/plugins.d.ts +46 -0
- package/dist/plugins.js +169 -0
- package/dist/utils/cli.d.ts +5 -0
- package/dist/utils/cli.js +14 -0
- package/dist/utils/installer.d.ts +41 -0
- package/dist/utils/installer.js +177 -0
- package/dist/utils/paths.d.ts +10 -0
- package/dist/utils/paths.js +23 -3
- package/dist/utils/post-install.d.ts +80 -0
- package/dist/utils/post-install.js +508 -0
- package/dist/utils/safe-delete-install.d.ts +29 -0
- package/dist/utils/safe-delete-install.js +191 -0
- package/dist/utils/safe-delete.d.ts +12 -0
- package/dist/utils/safe-delete.js +83 -0
- package/package.json +18 -8
- package/plugins/devflow-ambient/.claude-plugin/plugin.json +7 -0
- package/plugins/devflow-ambient/README.md +49 -0
- package/plugins/devflow-ambient/commands/ambient.md +110 -0
- package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +89 -0
- package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +64 -0
- package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +7 -0
- package/plugins/devflow-audit-claude/README.md +46 -0
- package/plugins/devflow-audit-claude/agents/claude-md-auditor.md +134 -0
- package/plugins/devflow-audit-claude/commands/audit-claude.md +85 -0
- package/plugins/devflow-code-review/.claude-plugin/plugin.json +31 -0
- package/plugins/devflow-code-review/README.md +73 -0
- package/plugins/devflow-code-review/agents/git.md +272 -0
- package/plugins/devflow-code-review/agents/reviewer.md +119 -0
- package/plugins/devflow-code-review/agents/synthesizer.md +204 -0
- package/plugins/devflow-code-review/commands/code-review-teams.md +262 -0
- package/plugins/devflow-code-review/commands/code-review.md +141 -0
- package/plugins/devflow-code-review/skills/accessibility/SKILL.md +229 -0
- package/plugins/devflow-code-review/skills/accessibility/references/detection.md +171 -0
- package/plugins/devflow-code-review/skills/accessibility/references/patterns.md +670 -0
- package/plugins/devflow-code-review/skills/accessibility/references/violations.md +419 -0
- package/plugins/devflow-code-review/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-code-review/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-code-review/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-code-review/skills/agent-teams/references/team-patterns.md +217 -0
- package/plugins/devflow-code-review/skills/architecture-patterns/SKILL.md +153 -0
- package/plugins/devflow-code-review/skills/architecture-patterns/references/detection.md +337 -0
- package/plugins/devflow-code-review/skills/architecture-patterns/references/patterns.md +873 -0
- package/plugins/devflow-code-review/skills/architecture-patterns/references/violations.md +575 -0
- package/plugins/devflow-code-review/skills/complexity-patterns/SKILL.md +143 -0
- package/plugins/devflow-code-review/skills/complexity-patterns/references/detection.md +264 -0
- package/plugins/devflow-code-review/skills/complexity-patterns/references/patterns.md +487 -0
- package/plugins/devflow-code-review/skills/complexity-patterns/references/violations.md +361 -0
- package/plugins/devflow-code-review/skills/consistency-patterns/SKILL.md +140 -0
- package/plugins/devflow-code-review/skills/consistency-patterns/references/detection.md +207 -0
- package/plugins/devflow-code-review/skills/consistency-patterns/references/patterns.md +202 -0
- package/plugins/devflow-code-review/skills/consistency-patterns/references/violations.md +213 -0
- package/plugins/devflow-code-review/skills/database-patterns/SKILL.md +134 -0
- package/plugins/devflow-code-review/skills/database-patterns/references/detection.md +208 -0
- package/plugins/devflow-code-review/skills/database-patterns/references/patterns.md +394 -0
- package/plugins/devflow-code-review/skills/database-patterns/references/violations.md +332 -0
- package/plugins/devflow-code-review/skills/dependencies-patterns/SKILL.md +141 -0
- package/plugins/devflow-code-review/skills/dependencies-patterns/references/detection.md +181 -0
- package/plugins/devflow-code-review/skills/dependencies-patterns/references/patterns.md +225 -0
- package/plugins/devflow-code-review/skills/dependencies-patterns/references/violations.md +247 -0
- package/plugins/devflow-code-review/skills/documentation-patterns/SKILL.md +125 -0
- package/plugins/devflow-code-review/skills/documentation-patterns/references/detection.md +190 -0
- package/plugins/devflow-code-review/skills/documentation-patterns/references/patterns.md +189 -0
- package/plugins/devflow-code-review/skills/documentation-patterns/references/violations.md +163 -0
- package/plugins/devflow-code-review/skills/frontend-design/SKILL.md +254 -0
- package/plugins/devflow-code-review/skills/frontend-design/references/detection.md +184 -0
- package/plugins/devflow-code-review/skills/frontend-design/references/patterns.md +511 -0
- package/plugins/devflow-code-review/skills/frontend-design/references/violations.md +453 -0
- package/plugins/devflow-code-review/skills/performance-patterns/SKILL.md +154 -0
- package/plugins/devflow-code-review/skills/performance-patterns/references/detection.md +351 -0
- package/plugins/devflow-code-review/skills/performance-patterns/references/patterns.md +503 -0
- package/plugins/devflow-code-review/skills/performance-patterns/references/violations.md +354 -0
- package/plugins/devflow-code-review/skills/react/SKILL.md +276 -0
- package/plugins/devflow-code-review/skills/react/references/patterns.md +1331 -0
- package/plugins/devflow-code-review/skills/react/references/violations.md +565 -0
- package/plugins/devflow-code-review/skills/regression-patterns/SKILL.md +146 -0
- package/plugins/devflow-code-review/skills/regression-patterns/references/detection.md +237 -0
- package/plugins/devflow-code-review/skills/regression-patterns/references/patterns.md +226 -0
- package/plugins/devflow-code-review/skills/regression-patterns/references/violations.md +225 -0
- package/plugins/devflow-code-review/skills/review-methodology/SKILL.md +119 -0
- package/plugins/devflow-code-review/skills/review-methodology/references/patterns.md +186 -0
- package/plugins/devflow-code-review/skills/review-methodology/references/report-template.md +142 -0
- package/plugins/devflow-code-review/skills/review-methodology/references/violations.md +125 -0
- package/plugins/devflow-code-review/skills/security-patterns/SKILL.md +156 -0
- package/plugins/devflow-code-review/skills/security-patterns/references/detection.md +287 -0
- package/plugins/devflow-code-review/skills/security-patterns/references/patterns.md +507 -0
- package/plugins/devflow-code-review/skills/security-patterns/references/violations.md +237 -0
- package/plugins/devflow-code-review/skills/test-patterns/SKILL.md +183 -0
- package/plugins/devflow-code-review/skills/test-patterns/references/detection.md +149 -0
- package/plugins/devflow-code-review/skills/test-patterns/references/patterns.md +220 -0
- package/plugins/devflow-code-review/skills/test-patterns/references/report-template.md +108 -0
- package/plugins/devflow-code-review/skills/test-patterns/references/violations.md +221 -0
- package/plugins/devflow-core-skills/.claude-plugin/plugin.json +28 -0
- package/plugins/devflow-core-skills/README.md +50 -0
- package/plugins/devflow-core-skills/skills/accessibility/SKILL.md +229 -0
- package/plugins/devflow-core-skills/skills/accessibility/references/detection.md +171 -0
- package/plugins/devflow-core-skills/skills/accessibility/references/patterns.md +670 -0
- package/plugins/devflow-core-skills/skills/accessibility/references/violations.md +419 -0
- package/plugins/devflow-core-skills/skills/core-patterns/SKILL.md +162 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/checklist.md +276 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/code-smell-violations.md +144 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/detection.md +303 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/patterns.md +576 -0
- package/plugins/devflow-core-skills/skills/core-patterns/references/violations.md +369 -0
- package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +138 -0
- package/plugins/devflow-core-skills/skills/docs-framework/references/patterns.md +346 -0
- package/plugins/devflow-core-skills/skills/docs-framework/references/violations.md +221 -0
- package/plugins/devflow-core-skills/skills/frontend-design/SKILL.md +254 -0
- package/plugins/devflow-core-skills/skills/frontend-design/references/detection.md +184 -0
- package/plugins/devflow-core-skills/skills/frontend-design/references/patterns.md +511 -0
- package/plugins/devflow-core-skills/skills/frontend-design/references/violations.md +453 -0
- package/plugins/devflow-core-skills/skills/git-safety/SKILL.md +122 -0
- package/plugins/devflow-core-skills/skills/git-safety/references/detection.md +290 -0
- package/plugins/devflow-core-skills/skills/git-safety/references/patterns.md +289 -0
- package/plugins/devflow-core-skills/skills/git-safety/references/violations.md +18 -0
- package/plugins/devflow-core-skills/skills/git-workflow/SKILL.md +158 -0
- package/plugins/devflow-core-skills/skills/git-workflow/references/commit-patterns.md +115 -0
- package/plugins/devflow-core-skills/skills/git-workflow/references/commit-violations.md +77 -0
- package/plugins/devflow-core-skills/skills/git-workflow/references/pr-patterns.md +127 -0
- package/plugins/devflow-core-skills/skills/git-workflow/references/pr-violations.md +96 -0
- package/plugins/devflow-core-skills/skills/github-patterns/SKILL.md +153 -0
- package/plugins/devflow-core-skills/skills/github-patterns/references/patterns.md +572 -0
- package/plugins/devflow-core-skills/skills/github-patterns/references/violations.md +298 -0
- package/plugins/devflow-core-skills/skills/input-validation/SKILL.md +148 -0
- package/plugins/devflow-core-skills/skills/input-validation/references/detection.md +283 -0
- package/plugins/devflow-core-skills/skills/input-validation/references/patterns.md +361 -0
- package/plugins/devflow-core-skills/skills/input-validation/references/violations.md +224 -0
- package/plugins/devflow-core-skills/skills/react/SKILL.md +276 -0
- package/plugins/devflow-core-skills/skills/react/references/patterns.md +1331 -0
- package/plugins/devflow-core-skills/skills/react/references/violations.md +565 -0
- package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +139 -0
- package/plugins/devflow-core-skills/skills/test-driven-development/references/rationalization-prevention.md +111 -0
- package/plugins/devflow-core-skills/skills/test-patterns/SKILL.md +183 -0
- package/plugins/devflow-core-skills/skills/test-patterns/references/detection.md +149 -0
- package/plugins/devflow-core-skills/skills/test-patterns/references/patterns.md +220 -0
- package/plugins/devflow-core-skills/skills/test-patterns/references/report-template.md +108 -0
- package/plugins/devflow-core-skills/skills/test-patterns/references/violations.md +221 -0
- package/plugins/devflow-core-skills/skills/typescript/SKILL.md +176 -0
- package/plugins/devflow-core-skills/skills/typescript/references/patterns.md +1105 -0
- package/plugins/devflow-core-skills/skills/typescript/references/violations.md +433 -0
- package/plugins/devflow-debug/.claude-plugin/plugin.json +18 -0
- package/plugins/devflow-debug/README.md +65 -0
- package/plugins/devflow-debug/agents/git.md +272 -0
- package/plugins/devflow-debug/commands/debug-teams.md +231 -0
- package/plugins/devflow-debug/commands/debug.md +160 -0
- package/plugins/devflow-debug/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-debug/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-debug/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-debug/skills/agent-teams/references/team-patterns.md +217 -0
- package/plugins/devflow-debug/skills/git-safety/SKILL.md +122 -0
- package/plugins/devflow-debug/skills/git-safety/references/detection.md +290 -0
- package/plugins/devflow-debug/skills/git-safety/references/patterns.md +289 -0
- package/plugins/devflow-debug/skills/git-safety/references/violations.md +18 -0
- package/plugins/devflow-implement/.claude-plugin/plugin.json +21 -0
- package/plugins/devflow-implement/README.md +71 -0
- package/plugins/devflow-implement/agents/coder.md +122 -0
- package/plugins/devflow-implement/agents/git.md +272 -0
- package/plugins/devflow-implement/agents/scrutinizer.md +80 -0
- package/plugins/devflow-implement/agents/shepherd.md +94 -0
- package/plugins/devflow-implement/agents/simplifier.md +62 -0
- package/plugins/devflow-implement/agents/skimmer.md +88 -0
- package/plugins/devflow-implement/agents/synthesizer.md +204 -0
- package/plugins/devflow-implement/agents/validator.md +86 -0
- package/plugins/devflow-implement/commands/implement-teams.md +608 -0
- package/plugins/devflow-implement/commands/implement.md +426 -0
- package/plugins/devflow-implement/skills/accessibility/SKILL.md +229 -0
- package/plugins/devflow-implement/skills/accessibility/references/detection.md +171 -0
- package/plugins/devflow-implement/skills/accessibility/references/patterns.md +670 -0
- package/plugins/devflow-implement/skills/accessibility/references/violations.md +419 -0
- package/plugins/devflow-implement/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-implement/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-implement/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-implement/skills/agent-teams/references/team-patterns.md +217 -0
- package/plugins/devflow-implement/skills/frontend-design/SKILL.md +254 -0
- package/plugins/devflow-implement/skills/frontend-design/references/detection.md +184 -0
- package/plugins/devflow-implement/skills/frontend-design/references/patterns.md +511 -0
- package/plugins/devflow-implement/skills/frontend-design/references/violations.md +453 -0
- package/plugins/devflow-implement/skills/implementation-patterns/SKILL.md +162 -0
- package/plugins/devflow-implement/skills/implementation-patterns/references/patterns.md +1063 -0
- package/plugins/devflow-implement/skills/implementation-patterns/references/violations.md +483 -0
- package/plugins/devflow-implement/skills/self-review/SKILL.md +149 -0
- package/plugins/devflow-implement/skills/self-review/references/patterns.md +405 -0
- package/plugins/devflow-implement/skills/self-review/references/report-template.md +253 -0
- package/plugins/devflow-implement/skills/self-review/references/violations.md +308 -0
- package/plugins/devflow-resolve/.claude-plugin/plugin.json +19 -0
- package/plugins/devflow-resolve/README.md +65 -0
- package/plugins/devflow-resolve/agents/git.md +272 -0
- package/plugins/devflow-resolve/agents/resolver.md +131 -0
- package/plugins/devflow-resolve/agents/simplifier.md +62 -0
- package/plugins/devflow-resolve/commands/resolve-teams.md +298 -0
- package/plugins/devflow-resolve/commands/resolve.md +237 -0
- package/plugins/devflow-resolve/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-resolve/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-resolve/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-resolve/skills/agent-teams/references/team-patterns.md +217 -0
- package/plugins/devflow-resolve/skills/implementation-patterns/SKILL.md +162 -0
- package/plugins/devflow-resolve/skills/implementation-patterns/references/patterns.md +1063 -0
- package/plugins/devflow-resolve/skills/implementation-patterns/references/violations.md +483 -0
- package/plugins/devflow-resolve/skills/security-patterns/SKILL.md +156 -0
- package/plugins/devflow-resolve/skills/security-patterns/references/detection.md +287 -0
- package/plugins/devflow-resolve/skills/security-patterns/references/patterns.md +507 -0
- package/plugins/devflow-resolve/skills/security-patterns/references/violations.md +237 -0
- package/plugins/devflow-self-review/.claude-plugin/plugin.json +7 -0
- package/plugins/devflow-self-review/README.md +38 -0
- package/plugins/devflow-self-review/agents/scrutinizer.md +80 -0
- package/plugins/devflow-self-review/agents/simplifier.md +62 -0
- package/plugins/devflow-self-review/agents/validator.md +86 -0
- package/plugins/devflow-self-review/commands/self-review.md +126 -0
- package/plugins/devflow-self-review/skills/core-patterns/SKILL.md +162 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/checklist.md +276 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/code-smell-violations.md +144 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/detection.md +303 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/patterns.md +576 -0
- package/plugins/devflow-self-review/skills/core-patterns/references/violations.md +369 -0
- package/plugins/devflow-self-review/skills/self-review/SKILL.md +149 -0
- package/plugins/devflow-self-review/skills/self-review/references/patterns.md +405 -0
- package/plugins/devflow-self-review/skills/self-review/references/report-template.md +253 -0
- package/plugins/devflow-self-review/skills/self-review/references/violations.md +308 -0
- package/plugins/devflow-specify/.claude-plugin/plugin.json +15 -0
- package/plugins/devflow-specify/README.md +46 -0
- package/plugins/devflow-specify/agents/skimmer.md +88 -0
- package/plugins/devflow-specify/agents/synthesizer.md +204 -0
- package/plugins/devflow-specify/commands/specify-teams.md +314 -0
- package/plugins/devflow-specify/commands/specify.md +179 -0
- package/plugins/devflow-specify/skills/agent-teams/SKILL.md +124 -0
- package/plugins/devflow-specify/skills/agent-teams/references/cleanup.md +104 -0
- package/plugins/devflow-specify/skills/agent-teams/references/communication.md +122 -0
- package/plugins/devflow-specify/skills/agent-teams/references/team-patterns.md +217 -0
- package/scripts/hooks/ambient-prompt.sh +48 -0
- package/scripts/hooks/background-memory-update.sh +208 -0
- package/scripts/hooks/ensure-memory-gitignore.sh +17 -0
- package/scripts/hooks/pre-compact-memory.sh +87 -0
- package/scripts/hooks/session-start-memory.sh +126 -0
- package/scripts/hooks/stop-update-memory.sh +85 -0
- package/shared/agents/coder.md +122 -0
- package/shared/agents/git.md +272 -0
- package/shared/agents/resolver.md +131 -0
- package/shared/agents/reviewer.md +119 -0
- package/shared/agents/scrutinizer.md +80 -0
- package/shared/agents/shepherd.md +94 -0
- package/shared/agents/simplifier.md +62 -0
- package/shared/agents/skimmer.md +88 -0
- package/shared/agents/synthesizer.md +204 -0
- package/shared/agents/validator.md +86 -0
- package/shared/skills/accessibility/SKILL.md +229 -0
- package/shared/skills/accessibility/references/detection.md +171 -0
- package/shared/skills/accessibility/references/patterns.md +670 -0
- package/shared/skills/accessibility/references/violations.md +419 -0
- package/shared/skills/agent-teams/SKILL.md +124 -0
- package/shared/skills/agent-teams/references/cleanup.md +104 -0
- package/shared/skills/agent-teams/references/communication.md +122 -0
- package/shared/skills/agent-teams/references/team-patterns.md +217 -0
- package/shared/skills/ambient-router/SKILL.md +89 -0
- package/shared/skills/ambient-router/references/skill-catalog.md +64 -0
- package/shared/skills/architecture-patterns/SKILL.md +153 -0
- package/shared/skills/architecture-patterns/references/detection.md +337 -0
- package/shared/skills/architecture-patterns/references/patterns.md +873 -0
- package/shared/skills/architecture-patterns/references/violations.md +575 -0
- package/shared/skills/complexity-patterns/SKILL.md +143 -0
- package/shared/skills/complexity-patterns/references/detection.md +264 -0
- package/shared/skills/complexity-patterns/references/patterns.md +487 -0
- package/shared/skills/complexity-patterns/references/violations.md +361 -0
- package/shared/skills/consistency-patterns/SKILL.md +140 -0
- package/shared/skills/consistency-patterns/references/detection.md +207 -0
- package/shared/skills/consistency-patterns/references/patterns.md +202 -0
- package/shared/skills/consistency-patterns/references/violations.md +213 -0
- package/shared/skills/core-patterns/SKILL.md +162 -0
- package/shared/skills/core-patterns/references/checklist.md +276 -0
- package/shared/skills/core-patterns/references/code-smell-violations.md +144 -0
- package/shared/skills/core-patterns/references/detection.md +303 -0
- package/shared/skills/core-patterns/references/patterns.md +576 -0
- package/shared/skills/core-patterns/references/violations.md +369 -0
- package/shared/skills/database-patterns/SKILL.md +134 -0
- package/shared/skills/database-patterns/references/detection.md +208 -0
- package/shared/skills/database-patterns/references/patterns.md +394 -0
- package/shared/skills/database-patterns/references/violations.md +332 -0
- package/shared/skills/dependencies-patterns/SKILL.md +141 -0
- package/shared/skills/dependencies-patterns/references/detection.md +181 -0
- package/shared/skills/dependencies-patterns/references/patterns.md +225 -0
- package/shared/skills/dependencies-patterns/references/violations.md +247 -0
- package/shared/skills/docs-framework/SKILL.md +138 -0
- package/shared/skills/docs-framework/references/patterns.md +346 -0
- package/shared/skills/docs-framework/references/violations.md +221 -0
- package/shared/skills/documentation-patterns/SKILL.md +125 -0
- package/shared/skills/documentation-patterns/references/detection.md +190 -0
- package/shared/skills/documentation-patterns/references/patterns.md +189 -0
- package/shared/skills/documentation-patterns/references/violations.md +163 -0
- package/shared/skills/frontend-design/SKILL.md +254 -0
- package/shared/skills/frontend-design/references/detection.md +184 -0
- package/shared/skills/frontend-design/references/patterns.md +511 -0
- package/shared/skills/frontend-design/references/violations.md +453 -0
- package/shared/skills/git-safety/SKILL.md +122 -0
- package/shared/skills/git-safety/references/detection.md +290 -0
- package/shared/skills/git-safety/references/patterns.md +289 -0
- package/shared/skills/git-safety/references/violations.md +18 -0
- package/shared/skills/git-workflow/SKILL.md +158 -0
- package/shared/skills/git-workflow/references/commit-patterns.md +115 -0
- package/shared/skills/git-workflow/references/commit-violations.md +77 -0
- package/shared/skills/git-workflow/references/pr-patterns.md +127 -0
- package/shared/skills/git-workflow/references/pr-violations.md +96 -0
- package/shared/skills/github-patterns/SKILL.md +153 -0
- package/shared/skills/github-patterns/references/patterns.md +572 -0
- package/shared/skills/github-patterns/references/violations.md +298 -0
- package/shared/skills/implementation-patterns/SKILL.md +162 -0
- package/shared/skills/implementation-patterns/references/patterns.md +1063 -0
- package/shared/skills/implementation-patterns/references/violations.md +483 -0
- package/shared/skills/input-validation/SKILL.md +148 -0
- package/shared/skills/input-validation/references/detection.md +283 -0
- package/shared/skills/input-validation/references/patterns.md +361 -0
- package/shared/skills/input-validation/references/violations.md +224 -0
- package/shared/skills/performance-patterns/SKILL.md +154 -0
- package/shared/skills/performance-patterns/references/detection.md +351 -0
- package/shared/skills/performance-patterns/references/patterns.md +503 -0
- package/shared/skills/performance-patterns/references/violations.md +354 -0
- package/shared/skills/react/SKILL.md +276 -0
- package/shared/skills/react/references/patterns.md +1331 -0
- package/shared/skills/react/references/violations.md +565 -0
- package/shared/skills/regression-patterns/SKILL.md +146 -0
- package/shared/skills/regression-patterns/references/detection.md +237 -0
- package/shared/skills/regression-patterns/references/patterns.md +226 -0
- package/shared/skills/regression-patterns/references/violations.md +225 -0
- package/shared/skills/review-methodology/SKILL.md +119 -0
- package/shared/skills/review-methodology/references/patterns.md +186 -0
- package/shared/skills/review-methodology/references/report-template.md +142 -0
- package/shared/skills/review-methodology/references/violations.md +125 -0
- package/shared/skills/security-patterns/SKILL.md +156 -0
- package/shared/skills/security-patterns/references/detection.md +287 -0
- package/shared/skills/security-patterns/references/patterns.md +507 -0
- package/shared/skills/security-patterns/references/violations.md +237 -0
- package/shared/skills/self-review/SKILL.md +149 -0
- package/shared/skills/self-review/references/patterns.md +405 -0
- package/shared/skills/self-review/references/report-template.md +253 -0
- package/shared/skills/self-review/references/violations.md +308 -0
- package/shared/skills/test-driven-development/SKILL.md +139 -0
- package/shared/skills/test-driven-development/references/rationalization-prevention.md +111 -0
- package/shared/skills/test-patterns/SKILL.md +183 -0
- package/shared/skills/test-patterns/references/detection.md +149 -0
- package/shared/skills/test-patterns/references/patterns.md +220 -0
- package/shared/skills/test-patterns/references/report-template.md +108 -0
- package/shared/skills/test-patterns/references/violations.md +221 -0
- package/shared/skills/typescript/SKILL.md +176 -0
- package/shared/skills/typescript/references/patterns.md +1105 -0
- package/shared/skills/typescript/references/violations.md +433 -0
- package/src/templates/claudeignore.template +188 -0
- package/src/templates/managed-settings.json +160 -0
- package/src/templates/settings.json +59 -0
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/uninstall.d.ts.map +0 -1
- package/dist/commands/uninstall.js.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/paths.d.ts.map +0 -1
- package/dist/utils/paths.js.map +0 -1
- package/src/claude/CLAUDE.md +0 -400
- package/src/claude/agents/devflow/audit-architecture.md +0 -132
- package/src/claude/agents/devflow/audit-complexity.md +0 -132
- package/src/claude/agents/devflow/audit-database.md +0 -132
- package/src/claude/agents/devflow/audit-dependencies.md +0 -132
- package/src/claude/agents/devflow/audit-documentation.md +0 -132
- package/src/claude/agents/devflow/audit-performance.md +0 -256
- package/src/claude/agents/devflow/audit-security.md +0 -259
- package/src/claude/agents/devflow/audit-tests.md +0 -132
- package/src/claude/agents/devflow/audit-typescript.md +0 -132
- package/src/claude/agents/devflow/brainstorm.md +0 -279
- package/src/claude/agents/devflow/catch-up.md +0 -345
- package/src/claude/agents/devflow/code-review.md +0 -307
- package/src/claude/agents/devflow/commit.md +0 -380
- package/src/claude/agents/devflow/debug.md +0 -476
- package/src/claude/agents/devflow/design.md +0 -491
- package/src/claude/agents/devflow/get-issue.md +0 -286
- package/src/claude/agents/devflow/pr-comments.md +0 -285
- package/src/claude/agents/devflow/project-state.md +0 -419
- package/src/claude/agents/devflow/pull-request.md +0 -493
- package/src/claude/agents/devflow/release.md +0 -1137
- package/src/claude/agents/devflow/tech-debt.md +0 -338
- package/src/claude/commands/devflow/brainstorm.md +0 -68
- package/src/claude/commands/devflow/breakdown.md +0 -125
- package/src/claude/commands/devflow/catch-up.md +0 -29
- package/src/claude/commands/devflow/code-review.md +0 -237
- package/src/claude/commands/devflow/commit.md +0 -17
- package/src/claude/commands/devflow/debug.md +0 -56
- package/src/claude/commands/devflow/design.md +0 -82
- package/src/claude/commands/devflow/devlog.md +0 -408
- package/src/claude/commands/devflow/get-issue.md +0 -16
- package/src/claude/commands/devflow/implement.md +0 -100
- package/src/claude/commands/devflow/plan.md +0 -223
- package/src/claude/commands/devflow/pull-request.md +0 -20
- package/src/claude/commands/devflow/release.md +0 -251
- package/src/claude/commands/devflow/resolve-comments.md +0 -583
- package/src/claude/scripts/statusline.sh +0 -47
- package/src/claude/settings.json +0 -6
- package/src/claude/skills/devflow/code-smell/SKILL.md +0 -428
- package/src/claude/skills/devflow/debug/SKILL.md +0 -119
- package/src/claude/skills/devflow/error-handling/SKILL.md +0 -597
- package/src/claude/skills/devflow/input-validation/SKILL.md +0 -514
- package/src/claude/skills/devflow/pattern-check/SKILL.md +0 -238
- package/src/claude/skills/devflow/research/SKILL.md +0 -138
- package/src/claude/skills/devflow/test-design/SKILL.md +0 -384
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# Database Correct Patterns
|
|
2
|
+
|
|
3
|
+
Extended examples of correct database design and optimization patterns.
|
|
4
|
+
|
|
5
|
+
## Schema Design Patterns
|
|
6
|
+
|
|
7
|
+
### Proper Table Structure
|
|
8
|
+
|
|
9
|
+
```sql
|
|
10
|
+
-- Well-designed table with all essential elements
|
|
11
|
+
CREATE TABLE orders (
|
|
12
|
+
-- Primary key: UUID for distributed systems, SERIAL for simpler cases
|
|
13
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
14
|
+
|
|
15
|
+
-- Foreign keys with appropriate actions
|
|
16
|
+
customer_id UUID NOT NULL REFERENCES customers(id) ON DELETE RESTRICT,
|
|
17
|
+
|
|
18
|
+
-- Appropriate data types
|
|
19
|
+
total DECIMAL(10, 2) NOT NULL CHECK (total >= 0),
|
|
20
|
+
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
|
21
|
+
|
|
22
|
+
-- Timestamps with timezone
|
|
23
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
24
|
+
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
25
|
+
|
|
26
|
+
-- Constraints
|
|
27
|
+
CONSTRAINT valid_status CHECK (status IN ('pending', 'processing', 'completed', 'cancelled'))
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
-- Indexes for common queries
|
|
31
|
+
CREATE INDEX idx_orders_customer ON orders(customer_id);
|
|
32
|
+
CREATE INDEX idx_orders_status ON orders(status) WHERE status != 'completed';
|
|
33
|
+
CREATE INDEX idx_orders_created ON orders(created_at);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Audit Trail Pattern
|
|
37
|
+
|
|
38
|
+
```sql
|
|
39
|
+
-- Audit columns on every table
|
|
40
|
+
CREATE TABLE users (
|
|
41
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
42
|
+
email VARCHAR(255) NOT NULL UNIQUE,
|
|
43
|
+
name VARCHAR(100) NOT NULL,
|
|
44
|
+
|
|
45
|
+
-- Audit trail
|
|
46
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
47
|
+
created_by UUID REFERENCES users(id),
|
|
48
|
+
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
49
|
+
updated_by UUID REFERENCES users(id),
|
|
50
|
+
deleted_at TIMESTAMP WITH TIME ZONE, -- Soft delete
|
|
51
|
+
deleted_by UUID REFERENCES users(id)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
-- Trigger for automatic updated_at
|
|
55
|
+
CREATE OR REPLACE FUNCTION update_updated_at()
|
|
56
|
+
RETURNS TRIGGER AS $$
|
|
57
|
+
BEGIN
|
|
58
|
+
NEW.updated_at = NOW();
|
|
59
|
+
RETURN NEW;
|
|
60
|
+
END;
|
|
61
|
+
$$ LANGUAGE plpgsql;
|
|
62
|
+
|
|
63
|
+
CREATE TRIGGER users_updated_at
|
|
64
|
+
BEFORE UPDATE ON users
|
|
65
|
+
FOR EACH ROW
|
|
66
|
+
EXECUTE FUNCTION update_updated_at();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Enum Pattern (Preferred over VARCHAR)
|
|
70
|
+
|
|
71
|
+
```sql
|
|
72
|
+
-- Create enum type
|
|
73
|
+
CREATE TYPE order_status AS ENUM (
|
|
74
|
+
'pending',
|
|
75
|
+
'processing',
|
|
76
|
+
'shipped',
|
|
77
|
+
'delivered',
|
|
78
|
+
'cancelled'
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
-- Use in table
|
|
82
|
+
CREATE TABLE orders (
|
|
83
|
+
id UUID PRIMARY KEY,
|
|
84
|
+
status order_status NOT NULL DEFAULT 'pending'
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
-- Benefits: type safety, storage efficiency, self-documenting
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Query Optimization Patterns
|
|
93
|
+
|
|
94
|
+
### Efficient Batch Loading
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// Load related data efficiently
|
|
98
|
+
async function getUsersWithOrders(userIds: string[]): Promise<UserWithOrders[]> {
|
|
99
|
+
// Query 1: Get users
|
|
100
|
+
const users = await db.query(
|
|
101
|
+
'SELECT * FROM users WHERE id = ANY($1)',
|
|
102
|
+
[userIds]
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// Query 2: Get all orders for these users in one query
|
|
106
|
+
const orders = await db.query(
|
|
107
|
+
'SELECT * FROM orders WHERE user_id = ANY($1)',
|
|
108
|
+
[userIds]
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// Build lookup map
|
|
112
|
+
const ordersByUser = new Map<string, Order[]>();
|
|
113
|
+
for (const order of orders) {
|
|
114
|
+
const existing = ordersByUser.get(order.user_id) || [];
|
|
115
|
+
existing.push(order);
|
|
116
|
+
ordersByUser.set(order.user_id, existing);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Combine
|
|
120
|
+
return users.map(user => ({
|
|
121
|
+
...user,
|
|
122
|
+
orders: ordersByUser.get(user.id) || []
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
// Total: 2 queries regardless of user count
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Pagination Pattern
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// Cursor-based pagination (efficient for large datasets)
|
|
132
|
+
async function getOrdersPage(
|
|
133
|
+
customerId: string,
|
|
134
|
+
cursor?: string,
|
|
135
|
+
limit: number = 20
|
|
136
|
+
): Promise<{ orders: Order[]; nextCursor: string | null }> {
|
|
137
|
+
const query = cursor
|
|
138
|
+
? `SELECT * FROM orders
|
|
139
|
+
WHERE customer_id = $1 AND created_at < $2
|
|
140
|
+
ORDER BY created_at DESC
|
|
141
|
+
LIMIT $3`
|
|
142
|
+
: `SELECT * FROM orders
|
|
143
|
+
WHERE customer_id = $1
|
|
144
|
+
ORDER BY created_at DESC
|
|
145
|
+
LIMIT $2`;
|
|
146
|
+
|
|
147
|
+
const params = cursor
|
|
148
|
+
? [customerId, new Date(cursor), limit + 1]
|
|
149
|
+
: [customerId, limit + 1];
|
|
150
|
+
|
|
151
|
+
const orders = await db.query(query, params);
|
|
152
|
+
|
|
153
|
+
const hasMore = orders.length > limit;
|
|
154
|
+
if (hasMore) orders.pop();
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
orders,
|
|
158
|
+
nextCursor: hasMore ? orders[orders.length - 1].created_at.toISOString() : null
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Index Strategy
|
|
164
|
+
|
|
165
|
+
```sql
|
|
166
|
+
-- Primary lookup index
|
|
167
|
+
CREATE INDEX idx_orders_customer ON orders(customer_id);
|
|
168
|
+
|
|
169
|
+
-- Composite index for common query pattern
|
|
170
|
+
-- Order matters: most selective first, or match query order
|
|
171
|
+
CREATE INDEX idx_orders_customer_status_date
|
|
172
|
+
ON orders(customer_id, status, created_at DESC);
|
|
173
|
+
|
|
174
|
+
-- Partial index for active records only
|
|
175
|
+
CREATE INDEX idx_orders_pending
|
|
176
|
+
ON orders(customer_id, created_at)
|
|
177
|
+
WHERE status = 'pending';
|
|
178
|
+
|
|
179
|
+
-- Covering index (includes all needed columns)
|
|
180
|
+
CREATE INDEX idx_orders_summary
|
|
181
|
+
ON orders(customer_id, status)
|
|
182
|
+
INCLUDE (total, created_at);
|
|
183
|
+
-- Query can be satisfied entirely from index
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Migration Patterns
|
|
189
|
+
|
|
190
|
+
### Safe Column Addition
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
// Migration: Add new required column safely
|
|
194
|
+
export async function up(db: Database): Promise<void> {
|
|
195
|
+
// Step 1: Add nullable column (instant, no lock)
|
|
196
|
+
await db.query(`
|
|
197
|
+
ALTER TABLE users ADD COLUMN phone VARCHAR(20)
|
|
198
|
+
`);
|
|
199
|
+
|
|
200
|
+
// Step 2: Backfill in batches
|
|
201
|
+
let processed = 0;
|
|
202
|
+
const batchSize = 1000;
|
|
203
|
+
|
|
204
|
+
while (true) {
|
|
205
|
+
const result = await db.query(`
|
|
206
|
+
UPDATE users
|
|
207
|
+
SET phone = 'UNKNOWN'
|
|
208
|
+
WHERE phone IS NULL
|
|
209
|
+
AND id IN (
|
|
210
|
+
SELECT id FROM users WHERE phone IS NULL LIMIT $1
|
|
211
|
+
)
|
|
212
|
+
RETURNING id
|
|
213
|
+
`, [batchSize]);
|
|
214
|
+
|
|
215
|
+
processed += result.rowCount;
|
|
216
|
+
if (result.rowCount < batchSize) break;
|
|
217
|
+
|
|
218
|
+
// Small delay to reduce load
|
|
219
|
+
await sleep(100);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Step 3: Add NOT NULL constraint
|
|
223
|
+
await db.query(`
|
|
224
|
+
ALTER TABLE users ALTER COLUMN phone SET NOT NULL
|
|
225
|
+
`);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export async function down(db: Database): Promise<void> {
|
|
229
|
+
await db.query(`
|
|
230
|
+
ALTER TABLE users DROP COLUMN phone
|
|
231
|
+
`);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Safe Column Rename
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
// Migration: Rename column without downtime
|
|
239
|
+
export async function up(db: Database): Promise<void> {
|
|
240
|
+
// Step 1: Add new column
|
|
241
|
+
await db.query(`
|
|
242
|
+
ALTER TABLE users ADD COLUMN full_name VARCHAR(200)
|
|
243
|
+
`);
|
|
244
|
+
|
|
245
|
+
// Step 2: Copy data
|
|
246
|
+
await db.query(`
|
|
247
|
+
UPDATE users SET full_name = name WHERE full_name IS NULL
|
|
248
|
+
`);
|
|
249
|
+
|
|
250
|
+
// Step 3: Create trigger for dual-write during transition
|
|
251
|
+
await db.query(`
|
|
252
|
+
CREATE OR REPLACE FUNCTION sync_name_columns()
|
|
253
|
+
RETURNS TRIGGER AS $$
|
|
254
|
+
BEGIN
|
|
255
|
+
IF TG_OP = 'INSERT' OR TG_OP = 'UPDATE' THEN
|
|
256
|
+
IF NEW.full_name IS NOT NULL AND NEW.name IS DISTINCT FROM NEW.full_name THEN
|
|
257
|
+
NEW.name = NEW.full_name;
|
|
258
|
+
ELSIF NEW.name IS NOT NULL AND NEW.full_name IS DISTINCT FROM NEW.name THEN
|
|
259
|
+
NEW.full_name = NEW.name;
|
|
260
|
+
END IF;
|
|
261
|
+
END IF;
|
|
262
|
+
RETURN NEW;
|
|
263
|
+
END;
|
|
264
|
+
$$ LANGUAGE plpgsql;
|
|
265
|
+
|
|
266
|
+
CREATE TRIGGER sync_names
|
|
267
|
+
BEFORE INSERT OR UPDATE ON users
|
|
268
|
+
FOR EACH ROW
|
|
269
|
+
EXECUTE FUNCTION sync_name_columns();
|
|
270
|
+
`);
|
|
271
|
+
|
|
272
|
+
// Step 4: Deploy code using new column
|
|
273
|
+
// Step 5: (separate migration) Drop old column and trigger
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Safe Table Restructure
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
// Migration: Restructure table without downtime
|
|
281
|
+
export async function up(db: Database): Promise<void> {
|
|
282
|
+
// Step 1: Create new table structure
|
|
283
|
+
await db.query(`
|
|
284
|
+
CREATE TABLE users_v2 (
|
|
285
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
286
|
+
email VARCHAR(255) NOT NULL UNIQUE,
|
|
287
|
+
-- new structure
|
|
288
|
+
profile JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
289
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
290
|
+
)
|
|
291
|
+
`);
|
|
292
|
+
|
|
293
|
+
// Step 2: Create insert trigger on old table
|
|
294
|
+
await db.query(`
|
|
295
|
+
CREATE OR REPLACE FUNCTION sync_to_users_v2()
|
|
296
|
+
RETURNS TRIGGER AS $$
|
|
297
|
+
BEGIN
|
|
298
|
+
INSERT INTO users_v2 (id, email, profile, created_at)
|
|
299
|
+
VALUES (
|
|
300
|
+
NEW.id,
|
|
301
|
+
NEW.email,
|
|
302
|
+
jsonb_build_object('name', NEW.name, 'phone', NEW.phone),
|
|
303
|
+
NEW.created_at
|
|
304
|
+
)
|
|
305
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
306
|
+
email = EXCLUDED.email,
|
|
307
|
+
profile = EXCLUDED.profile;
|
|
308
|
+
RETURN NEW;
|
|
309
|
+
END;
|
|
310
|
+
$$ LANGUAGE plpgsql;
|
|
311
|
+
|
|
312
|
+
CREATE TRIGGER sync_users
|
|
313
|
+
AFTER INSERT OR UPDATE ON users
|
|
314
|
+
FOR EACH ROW
|
|
315
|
+
EXECUTE FUNCTION sync_to_users_v2();
|
|
316
|
+
`);
|
|
317
|
+
|
|
318
|
+
// Step 3: Backfill existing data
|
|
319
|
+
await db.query(`
|
|
320
|
+
INSERT INTO users_v2 (id, email, profile, created_at)
|
|
321
|
+
SELECT
|
|
322
|
+
id,
|
|
323
|
+
email,
|
|
324
|
+
jsonb_build_object('name', name, 'phone', phone),
|
|
325
|
+
created_at
|
|
326
|
+
FROM users
|
|
327
|
+
ON CONFLICT (id) DO NOTHING
|
|
328
|
+
`);
|
|
329
|
+
|
|
330
|
+
// Step 4: Switch reads to new table (code deployment)
|
|
331
|
+
// Step 5: (separate migration) Drop old table
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Transaction Patterns
|
|
338
|
+
|
|
339
|
+
### Proper Transaction Handling
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
// Transaction with proper error handling and isolation
|
|
343
|
+
async function transferFunds(
|
|
344
|
+
fromAccount: string,
|
|
345
|
+
toAccount: string,
|
|
346
|
+
amount: number
|
|
347
|
+
): Promise<Result<void, TransferError>> {
|
|
348
|
+
const client = await db.pool.connect();
|
|
349
|
+
|
|
350
|
+
try {
|
|
351
|
+
await client.query('BEGIN');
|
|
352
|
+
await client.query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
|
|
353
|
+
|
|
354
|
+
// Lock rows in consistent order to prevent deadlocks
|
|
355
|
+
const accounts = [fromAccount, toAccount].sort();
|
|
356
|
+
|
|
357
|
+
const fromResult = await client.query(
|
|
358
|
+
'SELECT balance FROM accounts WHERE id = $1 FOR UPDATE',
|
|
359
|
+
[accounts[0] === fromAccount ? fromAccount : toAccount]
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
const toResult = await client.query(
|
|
363
|
+
'SELECT balance FROM accounts WHERE id = $1 FOR UPDATE',
|
|
364
|
+
[accounts[0] === fromAccount ? toAccount : fromAccount]
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
const fromBalance = fromResult.rows[0]?.balance;
|
|
368
|
+
if (!fromBalance || fromBalance < amount) {
|
|
369
|
+
await client.query('ROLLBACK');
|
|
370
|
+
return { ok: false, error: { type: 'insufficient_funds' } };
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
await client.query(
|
|
374
|
+
'UPDATE accounts SET balance = balance - $1 WHERE id = $2',
|
|
375
|
+
[amount, fromAccount]
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
await client.query(
|
|
379
|
+
'UPDATE accounts SET balance = balance + $1 WHERE id = $2',
|
|
380
|
+
[amount, toAccount]
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
await client.query('COMMIT');
|
|
384
|
+
return { ok: true, value: undefined };
|
|
385
|
+
|
|
386
|
+
} catch (error) {
|
|
387
|
+
await client.query('ROLLBACK');
|
|
388
|
+
return { ok: false, error: { type: 'transaction_failed', cause: error } };
|
|
389
|
+
|
|
390
|
+
} finally {
|
|
391
|
+
client.release();
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
```
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# Database Violation Examples
|
|
2
|
+
|
|
3
|
+
Extended examples of database anti-patterns and violations.
|
|
4
|
+
|
|
5
|
+
## Schema Design Violations
|
|
6
|
+
|
|
7
|
+
### Missing Foreign Keys - Extended
|
|
8
|
+
|
|
9
|
+
```sql
|
|
10
|
+
-- PROBLEM: No referential integrity
|
|
11
|
+
CREATE TABLE orders (
|
|
12
|
+
id SERIAL PRIMARY KEY,
|
|
13
|
+
customer_id INT, -- No FK constraint!
|
|
14
|
+
total DECIMAL
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
-- SOLUTION: Add foreign key
|
|
18
|
+
CREATE TABLE orders (
|
|
19
|
+
id SERIAL PRIMARY KEY,
|
|
20
|
+
customer_id INT NOT NULL REFERENCES customers(id) ON DELETE RESTRICT,
|
|
21
|
+
total DECIMAL
|
|
22
|
+
);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Why it matters:**
|
|
26
|
+
- Orphaned records accumulate over time
|
|
27
|
+
- Data integrity depends on application code (fragile)
|
|
28
|
+
- Cannot use cascading deletes/updates
|
|
29
|
+
- Database cannot optimize joins
|
|
30
|
+
|
|
31
|
+
### Denormalization Without Justification - Extended
|
|
32
|
+
|
|
33
|
+
```sql
|
|
34
|
+
-- PROBLEM: Unnecessary duplication
|
|
35
|
+
CREATE TABLE orders (
|
|
36
|
+
id SERIAL PRIMARY KEY,
|
|
37
|
+
customer_id INT,
|
|
38
|
+
customer_name VARCHAR(100), -- Duplicated!
|
|
39
|
+
customer_email VARCHAR(100), -- Duplicated!
|
|
40
|
+
customer_address TEXT -- Duplicated!
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
-- SOLUTION: Normalize unless performance requires otherwise
|
|
44
|
+
CREATE TABLE orders (
|
|
45
|
+
id SERIAL PRIMARY KEY,
|
|
46
|
+
customer_id INT REFERENCES customers(id)
|
|
47
|
+
);
|
|
48
|
+
-- Access customer data via JOIN
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**When denormalization IS justified:**
|
|
52
|
+
- Read-heavy workloads with measured performance issues
|
|
53
|
+
- Historical data that must not change when source changes
|
|
54
|
+
- Reporting/analytics tables (materialized views)
|
|
55
|
+
- Document explicitly: `-- DENORMALIZED: Performance requirement, see ticket DB-123`
|
|
56
|
+
|
|
57
|
+
### Poor Data Type Choices - Extended
|
|
58
|
+
|
|
59
|
+
```sql
|
|
60
|
+
-- PROBLEM: Inappropriate types
|
|
61
|
+
CREATE TABLE users (
|
|
62
|
+
id VARCHAR(100), -- Use UUID or SERIAL
|
|
63
|
+
age VARCHAR(10), -- Use INT
|
|
64
|
+
balance VARCHAR(50), -- Use DECIMAL
|
|
65
|
+
is_active VARCHAR(5), -- Use BOOLEAN
|
|
66
|
+
created_at VARCHAR(50) -- Use TIMESTAMP
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
-- SOLUTION: Appropriate types
|
|
70
|
+
CREATE TABLE users (
|
|
71
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
72
|
+
age INT CHECK (age >= 0 AND age < 150),
|
|
73
|
+
balance DECIMAL(10, 2) DEFAULT 0,
|
|
74
|
+
is_active BOOLEAN DEFAULT true,
|
|
75
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
76
|
+
);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Data type guidelines:**
|
|
80
|
+
| Data | Wrong | Correct |
|
|
81
|
+
|------|-------|---------|
|
|
82
|
+
| Money | FLOAT, VARCHAR | DECIMAL(precision, scale) |
|
|
83
|
+
| Boolean | VARCHAR, INT | BOOLEAN |
|
|
84
|
+
| Date/Time | VARCHAR | TIMESTAMP WITH TIME ZONE |
|
|
85
|
+
| IDs | VARCHAR (random) | UUID, SERIAL, BIGSERIAL |
|
|
86
|
+
| Email | TEXT | VARCHAR(255) with CHECK |
|
|
87
|
+
|
|
88
|
+
### Missing Constraints - Extended
|
|
89
|
+
|
|
90
|
+
```sql
|
|
91
|
+
-- PROBLEM: No data validation
|
|
92
|
+
CREATE TABLE products (
|
|
93
|
+
id SERIAL PRIMARY KEY,
|
|
94
|
+
name VARCHAR(100),
|
|
95
|
+
price DECIMAL,
|
|
96
|
+
quantity INT
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
-- SOLUTION: Add constraints
|
|
100
|
+
CREATE TABLE products (
|
|
101
|
+
id SERIAL PRIMARY KEY,
|
|
102
|
+
name VARCHAR(100) NOT NULL,
|
|
103
|
+
price DECIMAL(10, 2) NOT NULL CHECK (price >= 0),
|
|
104
|
+
quantity INT NOT NULL DEFAULT 0 CHECK (quantity >= 0),
|
|
105
|
+
CONSTRAINT name_not_empty CHECK (LENGTH(TRIM(name)) > 0)
|
|
106
|
+
);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Essential constraints:**
|
|
110
|
+
- `NOT NULL` on required fields
|
|
111
|
+
- `CHECK` constraints for business rules
|
|
112
|
+
- `UNIQUE` on natural keys
|
|
113
|
+
- `DEFAULT` values where appropriate
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Query Optimization Violations
|
|
118
|
+
|
|
119
|
+
### N+1 Queries - Extended
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
// PROBLEM: Query per iteration (N+1)
|
|
123
|
+
const users = await db.query('SELECT * FROM users');
|
|
124
|
+
for (const user of users) {
|
|
125
|
+
const orders = await db.query(
|
|
126
|
+
'SELECT * FROM orders WHERE user_id = ?',
|
|
127
|
+
[user.id]
|
|
128
|
+
);
|
|
129
|
+
user.orders = orders;
|
|
130
|
+
}
|
|
131
|
+
// If 100 users: 1 + 100 = 101 queries!
|
|
132
|
+
|
|
133
|
+
// SOLUTION 1: Single query with JOIN
|
|
134
|
+
const users = await db.query(`
|
|
135
|
+
SELECT u.*, json_agg(o.*) as orders
|
|
136
|
+
FROM users u
|
|
137
|
+
LEFT JOIN orders o ON o.user_id = u.id
|
|
138
|
+
GROUP BY u.id
|
|
139
|
+
`);
|
|
140
|
+
|
|
141
|
+
// SOLUTION 2: Two queries with IN (batch)
|
|
142
|
+
const users = await db.query('SELECT * FROM users');
|
|
143
|
+
const userIds = users.map(u => u.id);
|
|
144
|
+
const orders = await db.query(
|
|
145
|
+
'SELECT * FROM orders WHERE user_id = ANY($1)',
|
|
146
|
+
[userIds]
|
|
147
|
+
);
|
|
148
|
+
// Group orders by user_id in application code
|
|
149
|
+
// Total: 2 queries regardless of user count
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Full Table Scans - Extended
|
|
153
|
+
|
|
154
|
+
```sql
|
|
155
|
+
-- PROBLEM: Functions prevent index use
|
|
156
|
+
SELECT * FROM users WHERE LOWER(email) = 'john@example.com';
|
|
157
|
+
-- Sequential scan: O(n)
|
|
158
|
+
|
|
159
|
+
SELECT * FROM orders WHERE YEAR(created_at) = 2024;
|
|
160
|
+
-- Sequential scan: index on created_at cannot be used
|
|
161
|
+
|
|
162
|
+
SELECT * FROM products WHERE name LIKE '%widget%';
|
|
163
|
+
-- Sequential scan: leading wildcard prevents index use
|
|
164
|
+
|
|
165
|
+
-- SOLUTIONS:
|
|
166
|
+
|
|
167
|
+
-- 1. Functional index
|
|
168
|
+
CREATE INDEX idx_users_email_lower ON users(LOWER(email));
|
|
169
|
+
SELECT * FROM users WHERE LOWER(email) = 'john@example.com';
|
|
170
|
+
-- Now uses index
|
|
171
|
+
|
|
172
|
+
-- 2. Range query instead of function
|
|
173
|
+
SELECT * FROM orders
|
|
174
|
+
WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01';
|
|
175
|
+
-- Uses index on created_at
|
|
176
|
+
|
|
177
|
+
-- 3. Full-text search for LIKE patterns
|
|
178
|
+
CREATE INDEX idx_products_name_gin ON products USING gin(to_tsvector('english', name));
|
|
179
|
+
SELECT * FROM products WHERE to_tsvector('english', name) @@ to_tsquery('widget');
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Inefficient JOINs - Extended
|
|
183
|
+
|
|
184
|
+
```sql
|
|
185
|
+
-- PROBLEM: Joining large tables without filters
|
|
186
|
+
SELECT * FROM orders o
|
|
187
|
+
JOIN order_items oi ON oi.order_id = o.id
|
|
188
|
+
JOIN products p ON p.id = oi.product_id;
|
|
189
|
+
-- Returns millions of rows, processes entire tables
|
|
190
|
+
|
|
191
|
+
-- SOLUTION: Filter early, select specific columns
|
|
192
|
+
SELECT
|
|
193
|
+
o.id as order_id,
|
|
194
|
+
o.created_at,
|
|
195
|
+
oi.quantity,
|
|
196
|
+
p.name as product_name,
|
|
197
|
+
p.price
|
|
198
|
+
FROM orders o
|
|
199
|
+
JOIN order_items oi ON oi.order_id = o.id
|
|
200
|
+
JOIN products p ON p.id = oi.product_id
|
|
201
|
+
WHERE o.customer_id = 123
|
|
202
|
+
AND o.created_at > NOW() - INTERVAL '30 days';
|
|
203
|
+
-- Filters applied before join expands data
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Migration Violations
|
|
209
|
+
|
|
210
|
+
### Breaking Changes Without Migration Path
|
|
211
|
+
|
|
212
|
+
```sql
|
|
213
|
+
-- PROBLEM: Destructive change
|
|
214
|
+
ALTER TABLE users DROP COLUMN legacy_field;
|
|
215
|
+
-- Data is lost immediately!
|
|
216
|
+
|
|
217
|
+
-- SOLUTION: Phased approach
|
|
218
|
+
-- Phase 1: Stop writes (deploy code that doesn't write to column)
|
|
219
|
+
-- Phase 2: Add deprecation notice
|
|
220
|
+
ALTER TABLE users ALTER COLUMN legacy_field SET DEFAULT NULL;
|
|
221
|
+
-- Phase 3: Wait for deployment verification
|
|
222
|
+
-- Phase 4: Drop column after confirming no reads/writes
|
|
223
|
+
ALTER TABLE users DROP COLUMN legacy_field;
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Data Loss Risk
|
|
227
|
+
|
|
228
|
+
```sql
|
|
229
|
+
-- PROBLEM: Type change loses data
|
|
230
|
+
ALTER TABLE products ALTER COLUMN price TYPE INT;
|
|
231
|
+
-- Decimal values truncated: 19.99 becomes 19
|
|
232
|
+
|
|
233
|
+
-- SOLUTION: Validate first
|
|
234
|
+
SELECT id, price FROM products WHERE price != FLOOR(price);
|
|
235
|
+
-- If results exist: handle decimal values first
|
|
236
|
+
|
|
237
|
+
-- Safe alternative: create new column
|
|
238
|
+
ALTER TABLE products ADD COLUMN price_cents INT;
|
|
239
|
+
UPDATE products SET price_cents = price * 100;
|
|
240
|
+
-- Verify, then drop old column
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Missing Rollback Strategy
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// PROBLEM: No way to undo
|
|
247
|
+
export async function up(db) {
|
|
248
|
+
await db.query('DROP TABLE old_users');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export async function down(db) {
|
|
252
|
+
// Can't recreate dropped table with its data!
|
|
253
|
+
throw new Error('Irreversible migration');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// SOLUTION: Always plan rollback
|
|
257
|
+
export async function up(db) {
|
|
258
|
+
await db.query('ALTER TABLE old_users RENAME TO old_users_backup');
|
|
259
|
+
await db.query('CREATE TABLE users_v2 AS SELECT * FROM old_users_backup');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export async function down(db) {
|
|
263
|
+
await db.query('DROP TABLE IF EXISTS users_v2');
|
|
264
|
+
await db.query('ALTER TABLE old_users_backup RENAME TO old_users');
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Performance Impact
|
|
269
|
+
|
|
270
|
+
```sql
|
|
271
|
+
-- PROBLEM: Locks table for extended period
|
|
272
|
+
ALTER TABLE large_table ADD COLUMN new_field VARCHAR(100) NOT NULL DEFAULT 'value';
|
|
273
|
+
-- Rewrites entire table, holds exclusive lock
|
|
274
|
+
|
|
275
|
+
-- SOLUTION: Non-blocking approach (3 steps)
|
|
276
|
+
-- Step 1: Add nullable column (instant, no rewrite)
|
|
277
|
+
ALTER TABLE large_table ADD COLUMN new_field VARCHAR(100);
|
|
278
|
+
|
|
279
|
+
-- Step 2: Backfill in batches (no lock)
|
|
280
|
+
UPDATE large_table SET new_field = 'value' WHERE id BETWEEN 1 AND 10000;
|
|
281
|
+
UPDATE large_table SET new_field = 'value' WHERE id BETWEEN 10001 AND 20000;
|
|
282
|
+
-- ... continue in batches with small transactions
|
|
283
|
+
|
|
284
|
+
-- Step 3: Add constraint after backfill complete
|
|
285
|
+
ALTER TABLE large_table ALTER COLUMN new_field SET NOT NULL;
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Security Violations
|
|
291
|
+
|
|
292
|
+
### SQL Injection - Extended
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
// VULNERABLE: String interpolation
|
|
296
|
+
const query = `SELECT * FROM users WHERE email = '${email}'`;
|
|
297
|
+
// If email = "'; DROP TABLE users; --" -> disaster
|
|
298
|
+
|
|
299
|
+
// VULNERABLE: String concatenation
|
|
300
|
+
const query = 'SELECT * FROM users WHERE email = "' + email + '"';
|
|
301
|
+
// Same vulnerability
|
|
302
|
+
|
|
303
|
+
// SECURE: Parameterized queries
|
|
304
|
+
const query = 'SELECT * FROM users WHERE email = $1';
|
|
305
|
+
await db.query(query, [email]);
|
|
306
|
+
|
|
307
|
+
// SECURE: ORM with proper escaping
|
|
308
|
+
await User.findOne({ where: { email } });
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Excessive Privileges
|
|
312
|
+
|
|
313
|
+
```sql
|
|
314
|
+
-- PROBLEM: App has too many privileges
|
|
315
|
+
GRANT ALL PRIVILEGES ON DATABASE myapp TO app_user;
|
|
316
|
+
-- App can DROP tables, modify schema, etc.
|
|
317
|
+
|
|
318
|
+
-- SOLUTION: Minimum required privileges (principle of least privilege)
|
|
319
|
+
-- Read-only operations
|
|
320
|
+
GRANT SELECT ON users, products, orders TO readonly_user;
|
|
321
|
+
|
|
322
|
+
-- Application user (typical CRUD)
|
|
323
|
+
GRANT SELECT, INSERT, UPDATE ON users TO app_user;
|
|
324
|
+
GRANT SELECT ON products TO app_user;
|
|
325
|
+
GRANT SELECT, INSERT ON orders TO app_user;
|
|
326
|
+
-- No DELETE unless business requirement
|
|
327
|
+
-- No schema modification privileges
|
|
328
|
+
|
|
329
|
+
-- Migrations user (separate, restricted use)
|
|
330
|
+
GRANT ALL ON SCHEMA public TO migrations_user;
|
|
331
|
+
-- Only used during deployments, not by running application
|
|
332
|
+
```
|