ai-playbook 1.0.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/README.md +146 -0
- package/agents/README.md +168 -0
- package/agents/SKILL.md +633 -0
- package/agents/architect/AGENT.md +44 -0
- package/agents/architect/README.md +5 -0
- package/agents/coder/AGENT.md +43 -0
- package/agents/coder/README.md +5 -0
- package/agents/debugger/AGENT.md +42 -0
- package/agents/debugger/README.md +6 -0
- package/agents/devops/AGENT.md +43 -0
- package/agents/devops/README.md +5 -0
- package/agents/documentation/AGENT.md +45 -0
- package/agents/documentation/README.md +5 -0
- package/agents/examples.md +550 -0
- package/agents/performance/AGENT.md +45 -0
- package/agents/performance/README.md +6 -0
- package/agents/planner/AGENT.md +44 -0
- package/agents/planner/README.md +6 -0
- package/agents/product-owner/AGENT.md +46 -0
- package/agents/product-owner/README.md +6 -0
- package/agents/refactorer/AGENT.md +44 -0
- package/agents/refactorer/README.md +6 -0
- package/agents/release-manager/AGENT.md +45 -0
- package/agents/release-manager/README.md +6 -0
- package/agents/researcher/AGENT.md +44 -0
- package/agents/researcher/README.md +6 -0
- package/agents/reviewer/AGENT.md +43 -0
- package/agents/reviewer/README.md +6 -0
- package/agents/security/AGENT.md +46 -0
- package/agents/security/README.md +6 -0
- package/agents/support/AGENT.md +45 -0
- package/agents/support/README.md +6 -0
- package/agents/tester/AGENT.md +46 -0
- package/agents/tester/README.md +5 -0
- package/bin/cli.js +186 -0
- package/commands/README.md +266 -0
- package/commands/build.md +135 -0
- package/commands/clean.md +126 -0
- package/commands/deploy-prod.md +171 -0
- package/commands/deploy-staging.md +147 -0
- package/commands/deps.md +169 -0
- package/commands/dev.md +132 -0
- package/commands/format.md +142 -0
- package/commands/lint.md +125 -0
- package/commands/migrate.md +159 -0
- package/commands/release.md +183 -0
- package/commands/rollback.md +152 -0
- package/commands/seed.md +178 -0
- package/commands/setup.md +109 -0
- package/commands/test.md +134 -0
- package/commands/validate.md +147 -0
- package/context/README.md +7 -0
- package/context/aem.md +47 -0
- package/context/architecture.md +51 -0
- package/context/bullminder.md +57 -0
- package/context/coding-style.md +42 -0
- package/context/communication.md +53 -0
- package/context/company.md +46 -0
- package/context/engineering.md +63 -0
- package/context/project-template.md +71 -0
- package/context/trading.md +52 -0
- package/hooks/README.md +326 -0
- package/hooks/code-review/README.md +6 -0
- package/hooks/code-review/check-coverage.md +101 -0
- package/hooks/custom/README.md +6 -0
- package/hooks/custom/project-specific-hooks.md +273 -0
- package/hooks/deployment/README.md +6 -0
- package/hooks/deployment/health-check.md +102 -0
- package/hooks/deployment/pre-deploy-check.md +84 -0
- package/hooks/documentation/README.md +6 -0
- package/hooks/documentation/update-changelog.md +146 -0
- package/hooks/post-task/README.md +5 -0
- package/hooks/post-task/run-tests.md +61 -0
- package/hooks/pre-commit/README.md +6 -0
- package/hooks/pre-commit/format.md +63 -0
- package/hooks/pre-commit/lint.md +62 -0
- package/hooks/pre-commit/type-check.md +78 -0
- package/hooks/pre-task/README.md +6 -0
- package/hooks/pre-task/check-branch.md +48 -0
- package/hooks/pre-task/validate-environment.md +48 -0
- package/hooks/security-check/README.md +6 -0
- package/hooks/security-check/dependency-audit.md +85 -0
- package/hooks/security-check/secrets-scan.md +77 -0
- package/hooks/test-before-finish/README.md +6 -0
- package/hooks/test-before-finish/run-all-tests.md +128 -0
- package/index.js +69 -0
- package/knowledge/README.md +33 -0
- package/knowledge/ai-agents.md +74 -0
- package/knowledge/decision-making.md +73 -0
- package/knowledge/documentation.md +67 -0
- package/knowledge/engineering-principles.md +65 -0
- package/knowledge/product-discovery.md +68 -0
- package/knowledge/security-privacy.md +54 -0
- package/knowledge/testing-quality.md +63 -0
- package/package.json +63 -0
- package/patterns/README.md +7 -0
- package/prompts/README.md +208 -0
- package/prompts/architect/README.md +96 -0
- package/prompts/architect/design-system.md +140 -0
- package/prompts/debugger/README.md +96 -0
- package/prompts/debugger/diagnose-issue.md +141 -0
- package/prompts/developer/README.md +129 -0
- package/prompts/developer/fix-bug.md +136 -0
- package/prompts/developer/implement-feature.md +133 -0
- package/prompts/product-owner/README.md +116 -0
- package/prompts/product-owner/define-feature.md +145 -0
- package/prompts/reviewer/README.md +91 -0
- package/prompts/reviewer/code-review.md +129 -0
- package/prompts/support/README.md +154 -0
- package/prompts/support/resolve-issue.md +124 -0
- package/roles/README.md +6 -0
- package/roles/design-architect/README.md +98 -0
- package/roles/design-architect/accessibility/README.md +33 -0
- package/roles/design-architect/accessibility/checklists.md +29 -0
- package/roles/design-architect/accessibility/examples.md +35 -0
- package/roles/design-architect/checklists.md +76 -0
- package/roles/design-architect/component-library/README.md +35 -0
- package/roles/design-architect/component-library/checklists.md +29 -0
- package/roles/design-architect/component-library/examples.md +35 -0
- package/roles/design-architect/design-system/README.md +35 -0
- package/roles/design-architect/design-system/checklists.md +27 -0
- package/roles/design-architect/design-system/examples.md +41 -0
- package/roles/design-architect/examples/README.md +31 -0
- package/roles/design-architect/examples/checklists.md +26 -0
- package/roles/design-architect/examples/examples.md +46 -0
- package/roles/design-architect/examples.md +90 -0
- package/roles/design-architect/figma/README.md +33 -0
- package/roles/design-architect/figma/checklists.md +27 -0
- package/roles/design-architect/figma/examples.md +38 -0
- package/roles/design-architect/responsibilities.md +73 -0
- package/roles/design-architect/responsive/README.md +34 -0
- package/roles/design-architect/responsive/checklists.md +26 -0
- package/roles/design-architect/responsive/examples.md +39 -0
- package/roles/design-architect/role.md +129 -0
- package/roles/design-architect/skill-map.md +42 -0
- package/roles/design-architect/triggers.md +110 -0
- package/roles/design-architect/ui/README.md +36 -0
- package/roles/design-architect/ui/checklists.md +29 -0
- package/roles/design-architect/ui/examples.md +28 -0
- package/roles/design-architect/usability/README.md +34 -0
- package/roles/design-architect/usability/checklists.md +28 -0
- package/roles/design-architect/usability/examples.md +31 -0
- package/roles/design-architect/ux/README.md +36 -0
- package/roles/design-architect/ux/checklists.md +28 -0
- package/roles/design-architect/ux/examples.md +37 -0
- package/roles/design-architect/wireframes/README.md +34 -0
- package/roles/design-architect/wireframes/checklists.md +25 -0
- package/roles/design-architect/wireframes/examples.md +32 -0
- package/roles/design-architect/workflow.md +80 -0
- package/roles/devops/README.md +101 -0
- package/roles/devops/ansible/README.md +6 -0
- package/roles/devops/checklists.md +413 -0
- package/roles/devops/ci-cd/README.md +169 -0
- package/roles/devops/ci-cd/checklists.md +289 -0
- package/roles/devops/ci-cd/examples.md +429 -0
- package/roles/devops/cloud-platforms/README.md +109 -0
- package/roles/devops/cost-optimization/README.md +131 -0
- package/roles/devops/disaster-recovery/README.md +118 -0
- package/roles/devops/docker/README.md +6 -0
- package/roles/devops/examples/README.md +6 -0
- package/roles/devops/examples.md +775 -0
- package/roles/devops/github-actions/README.md +6 -0
- package/roles/devops/helm/README.md +6 -0
- package/roles/devops/infrastructure-as-code/README.md +160 -0
- package/roles/devops/infrastructure-as-code/checklists.md +124 -0
- package/roles/devops/jenkins/README.md +6 -0
- package/roles/devops/kubernetes/README.md +150 -0
- package/roles/devops/kubernetes/checklists.md +192 -0
- package/roles/devops/kubernetes/examples.md +189 -0
- package/roles/devops/monitoring/README.md +93 -0
- package/roles/devops/networking/README.md +83 -0
- package/roles/devops/performance/README.md +104 -0
- package/roles/devops/responsibilities.md +95 -0
- package/roles/devops/role.md +130 -0
- package/roles/devops/security/README.md +126 -0
- package/roles/devops/skill-map.md +162 -0
- package/roles/devops/terraform/README.md +6 -0
- package/roles/devops/triggers.md +241 -0
- package/roles/devops/workflow.md +197 -0
- package/roles/qa/README.md +16 -0
- package/roles/qa/api-testing/README.md +6 -0
- package/roles/qa/automation/README.md +6 -0
- package/roles/qa/checklists.md +24 -0
- package/roles/qa/examples/README.md +6 -0
- package/roles/qa/examples.md +27 -0
- package/roles/qa/performance/README.md +6 -0
- package/roles/qa/playwright/README.md +6 -0
- package/roles/qa/responsibilities.md +16 -0
- package/roles/qa/role.md +47 -0
- package/roles/qa/selenium/README.md +6 -0
- package/roles/qa/skill-map.md +14 -0
- package/roles/qa/triggers.md +10 -0
- package/roles/qa/workflow.md +9 -0
- package/roles/software-architect/README.md +16 -0
- package/roles/software-architect/agents/README.md +6 -0
- package/roles/software-architect/ai-architecture/README.md +6 -0
- package/roles/software-architect/aws/README.md +6 -0
- package/roles/software-architect/azure/README.md +6 -0
- package/roles/software-architect/caching/README.md +6 -0
- package/roles/software-architect/checklists.md +25 -0
- package/roles/software-architect/cloud/README.md +6 -0
- package/roles/software-architect/database-design/README.md +6 -0
- package/roles/software-architect/diagrams/README.md +6 -0
- package/roles/software-architect/distributed-systems/README.md +7 -0
- package/roles/software-architect/docker/README.md +6 -0
- package/roles/software-architect/event-driven/README.md +7 -0
- package/roles/software-architect/examples/README.md +6 -0
- package/roles/software-architect/examples.md +22 -0
- package/roles/software-architect/gcp/README.md +6 -0
- package/roles/software-architect/kubernetes/README.md +6 -0
- package/roles/software-architect/messaging/README.md +6 -0
- package/roles/software-architect/rag/README.md +7 -0
- package/roles/software-architect/responsibilities.md +17 -0
- package/roles/software-architect/role.md +46 -0
- package/roles/software-architect/scalability/README.md +6 -0
- package/roles/software-architect/security/README.md +6 -0
- package/roles/software-architect/skill-map.md +15 -0
- package/roles/software-architect/system-design/README.md +6 -0
- package/roles/software-architect/triggers.md +10 -0
- package/roles/software-architect/vector-db/README.md +6 -0
- package/roles/software-architect/workflow.md +9 -0
- package/roles/software-developer/README.md +116 -0
- package/roles/software-developer/api/README.md +365 -0
- package/roles/software-developer/api/checklist.md +131 -0
- package/roles/software-developer/api/examples.md +459 -0
- package/roles/software-developer/authentication/README.md +26 -0
- package/roles/software-developer/authentication/checklists.md +22 -0
- package/roles/software-developer/authentication/examples.md +32 -0
- package/roles/software-developer/authorization/README.md +26 -0
- package/roles/software-developer/authorization/checklists.md +21 -0
- package/roles/software-developer/authorization/examples.md +27 -0
- package/roles/software-developer/backend/README.md +26 -0
- package/roles/software-developer/backend/checklists.md +21 -0
- package/roles/software-developer/backend/examples.md +21 -0
- package/roles/software-developer/cache/README.md +25 -0
- package/roles/software-developer/cache/checklists.md +21 -0
- package/roles/software-developer/cache/examples.md +22 -0
- package/roles/software-developer/checklists.md +122 -0
- package/roles/software-developer/code-review/README.md +23 -0
- package/roles/software-developer/code-review/checklists.md +22 -0
- package/roles/software-developer/code-review/examples.md +20 -0
- package/roles/software-developer/database/README.md +27 -0
- package/roles/software-developer/database/checklists.md +21 -0
- package/roles/software-developer/database/examples.md +27 -0
- package/roles/software-developer/debugging/README.md +24 -0
- package/roles/software-developer/debugging/checklists.md +20 -0
- package/roles/software-developer/debugging/examples.md +28 -0
- package/roles/software-developer/examples/README.md +22 -0
- package/roles/software-developer/examples/checklists.md +8 -0
- package/roles/software-developer/examples/examples.md +25 -0
- package/roles/software-developer/examples.md +378 -0
- package/roles/software-developer/frontend/README.md +76 -0
- package/roles/software-developer/frontend/accessibility/README.md +136 -0
- package/roles/software-developer/frontend/accessibility/best-practices.md +368 -0
- package/roles/software-developer/frontend/code-quality/README.md +136 -0
- package/roles/software-developer/frontend/code-quality/best-practices.md +309 -0
- package/roles/software-developer/frontend/components/README.md +65 -0
- package/roles/software-developer/frontend/components/best-practices.md +273 -0
- package/roles/software-developer/frontend/debugging/README.md +149 -0
- package/roles/software-developer/frontend/debugging/best-practices.md +329 -0
- package/roles/software-developer/frontend/examples/README.md +19 -0
- package/roles/software-developer/frontend/examples/checklists.md +8 -0
- package/roles/software-developer/frontend/examples/examples.md +17 -0
- package/roles/software-developer/frontend/logging-observability/README.md +196 -0
- package/roles/software-developer/frontend/logging-observability/best-practices.md +430 -0
- package/roles/software-developer/frontend/performance/README.md +99 -0
- package/roles/software-developer/frontend/performance/best-practices.md +350 -0
- package/roles/software-developer/frontend/state-management/README.md +85 -0
- package/roles/software-developer/frontend/state-management/best-practices.md +344 -0
- package/roles/software-developer/frontend/testing/README.md +114 -0
- package/roles/software-developer/frontend/testing/best-practices.md +272 -0
- package/roles/software-developer/fullstack/README.md +25 -0
- package/roles/software-developer/fullstack/checklists.md +19 -0
- package/roles/software-developer/fullstack/examples.md +14 -0
- package/roles/software-developer/graphql/README.md +24 -0
- package/roles/software-developer/graphql/checklists.md +20 -0
- package/roles/software-developer/graphql/examples.md +24 -0
- package/roles/software-developer/integration-tests/README.md +25 -0
- package/roles/software-developer/integration-tests/checklists.md +20 -0
- package/roles/software-developer/integration-tests/examples.md +18 -0
- package/roles/software-developer/java/README.md +24 -0
- package/roles/software-developer/java/checklists.md +16 -0
- package/roles/software-developer/java/examples.md +22 -0
- package/roles/software-developer/javascript/README.md +24 -0
- package/roles/software-developer/javascript/checklists.md +15 -0
- package/roles/software-developer/javascript/examples.md +18 -0
- package/roles/software-developer/logging/README.md +105 -0
- package/roles/software-developer/logging/checklists.md +48 -0
- package/roles/software-developer/logging/examples.md +135 -0
- package/roles/software-developer/messaging/README.md +24 -0
- package/roles/software-developer/messaging/checklists.md +21 -0
- package/roles/software-developer/messaging/examples.md +26 -0
- package/roles/software-developer/microservices/README.md +25 -0
- package/roles/software-developer/microservices/checklists.md +21 -0
- package/roles/software-developer/microservices/examples.md +21 -0
- package/roles/software-developer/node/README.md +25 -0
- package/roles/software-developer/node/checklists.md +15 -0
- package/roles/software-developer/node/examples.md +15 -0
- package/roles/software-developer/nosql/README.md +24 -0
- package/roles/software-developer/nosql/checklists.md +21 -0
- package/roles/software-developer/nosql/examples.md +20 -0
- package/roles/software-developer/observability/README.md +25 -0
- package/roles/software-developer/observability/checklists.md +21 -0
- package/roles/software-developer/observability/examples.md +22 -0
- package/roles/software-developer/performance/README.md +26 -0
- package/roles/software-developer/performance/checklists.md +20 -0
- package/roles/software-developer/performance/examples.md +20 -0
- package/roles/software-developer/python/README.md +25 -0
- package/roles/software-developer/python/checklists.md +15 -0
- package/roles/software-developer/python/examples.md +17 -0
- package/roles/software-developer/react/README.md +24 -0
- package/roles/software-developer/react/checklists.md +15 -0
- package/roles/software-developer/react/examples.md +22 -0
- package/roles/software-developer/refactoring/README.md +23 -0
- package/roles/software-developer/refactoring/checklists.md +21 -0
- package/roles/software-developer/refactoring/examples.md +11 -0
- package/roles/software-developer/responsibilities.md +58 -0
- package/roles/software-developer/role.md +127 -0
- package/roles/software-developer/skill-map.md +88 -0
- package/roles/software-developer/springboot/README.md +25 -0
- package/roles/software-developer/springboot/checklists.md +15 -0
- package/roles/software-developer/springboot/examples.md +21 -0
- package/roles/software-developer/sql/README.md +24 -0
- package/roles/software-developer/sql/checklists.md +22 -0
- package/roles/software-developer/sql/examples.md +20 -0
- package/roles/software-developer/testing/README.md +25 -0
- package/roles/software-developer/testing/checklists.md +21 -0
- package/roles/software-developer/testing/examples.md +19 -0
- package/roles/software-developer/triggers.md +550 -0
- package/roles/software-developer/typescript/README.md +25 -0
- package/roles/software-developer/typescript/checklists.md +15 -0
- package/roles/software-developer/typescript/examples.md +18 -0
- package/roles/software-developer/unit-tests/README.md +24 -0
- package/roles/software-developer/unit-tests/checklists.md +19 -0
- package/roles/software-developer/unit-tests/examples.md +22 -0
- package/roles/software-developer/workflow.md +196 -0
- package/roles/sre/README.md +16 -0
- package/roles/sre/alerts/README.md +6 -0
- package/roles/sre/availability/README.md +6 -0
- package/roles/sre/chaos/README.md +6 -0
- package/roles/sre/checklists.md +24 -0
- package/roles/sre/examples/README.md +6 -0
- package/roles/sre/examples.md +19 -0
- package/roles/sre/observability/README.md +6 -0
- package/roles/sre/reliability/README.md +6 -0
- package/roles/sre/responsibilities.md +16 -0
- package/roles/sre/role.md +46 -0
- package/roles/sre/skill-map.md +14 -0
- package/roles/sre/slos/README.md +6 -0
- package/roles/sre/triggers.md +10 -0
- package/roles/sre/workflow.md +9 -0
- package/roles/support-engineer/README.md +16 -0
- package/roles/support-engineer/checklists.md +24 -0
- package/roles/support-engineer/datadog/README.md +6 -0
- package/roles/support-engineer/examples/README.md +6 -0
- package/roles/support-engineer/examples.md +17 -0
- package/roles/support-engineer/incident-response/README.md +6 -0
- package/roles/support-engineer/kubernetes/README.md +6 -0
- package/roles/support-engineer/linux/README.md +6 -0
- package/roles/support-engineer/logs/README.md +6 -0
- package/roles/support-engineer/monitoring/README.md +6 -0
- package/roles/support-engineer/networking/README.md +6 -0
- package/roles/support-engineer/newrelic/README.md +6 -0
- package/roles/support-engineer/postmortem/README.md +6 -0
- package/roles/support-engineer/production/README.md +6 -0
- package/roles/support-engineer/responsibilities.md +16 -0
- package/roles/support-engineer/role.md +47 -0
- package/roles/support-engineer/root-cause-analysis/README.md +6 -0
- package/roles/support-engineer/runbooks/README.md +6 -0
- package/roles/support-engineer/skill-map.md +14 -0
- package/roles/support-engineer/splunk/README.md +6 -0
- package/roles/support-engineer/triggers.md +10 -0
- package/roles/support-engineer/troubleshooting/README.md +6 -0
- package/roles/support-engineer/workflow.md +9 -0
- package/setup.sh +204 -0
- package/skills/.claude/README.md +7 -0
- package/skills/README.md +21 -0
- package/skills/ai-agents/README.md +207 -0
- package/skills/ai-agents/examples.md +335 -0
- package/skills/ai-agents/skill.md +392 -0
- package/skills/architecture/README.md +198 -0
- package/skills/architecture/examples.md +316 -0
- package/skills/architecture/skill.md +189 -0
- package/skills/design-architecture/README.md +107 -0
- package/skills/design-architecture/examples.md +84 -0
- package/skills/design-architecture/skill.md +192 -0
- package/skills/devops/README.md +177 -0
- package/skills/devops/examples.md +376 -0
- package/skills/devops/skill.md +210 -0
- package/skills/documentation/README.md +182 -0
- package/skills/documentation/examples.md +364 -0
- package/skills/documentation/skill.md +200 -0
- package/skills/performance/README.md +177 -0
- package/skills/performance/examples.md +376 -0
- package/skills/performance/skill.md +199 -0
- package/skills/qa/README.md +106 -0
- package/skills/qa/examples.md +84 -0
- package/skills/qa/skill.md +384 -0
- package/skills/security/README.md +108 -0
- package/skills/security/examples.md +85 -0
- package/skills/security/skill.md +223 -0
- package/skills/software-development/README.md +239 -0
- package/skills/software-development/assessment.md +0 -0
- package/skills/software-development/checklists.md +0 -0
- package/skills/software-development/examples.md +375 -0
- package/skills/software-development/prompts.md +0 -0
- package/skills/software-development/skill.md +390 -0
- package/skills/software-development/templates/README.md +7 -0
- package/skills/software-development/templates/api-development.md +0 -0
- package/skills/software-development/templates/bug-fix.md +0 -0
- package/skills/software-development/templates/code-review.md +0 -0
- package/skills/software-development/templates/feature-implementation.md +0 -0
- package/skills/software-development/templates/llm-integration.md +0 -0
- package/skills/software-development/templates/performance-review.md +0 -0
- package/skills/software-development/templates/security-review.md +0 -0
- package/skills/software-development/templates/test-generation.md +0 -0
- package/skills/software-development/tools.md +0 -0
- package/skills/software-development/workflows.md +0 -0
- package/skills/sre/README.md +107 -0
- package/skills/sre/examples.md +379 -0
- package/skills/sre/skill.md +256 -0
- package/skills/support-engineering/README.md +107 -0
- package/skills/support-engineering/examples.md +85 -0
- package/skills/support-engineering/skill.md +103 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# State Management: Best Practices
|
|
2
|
+
|
|
3
|
+
Effective state management is crucial for building scalable, maintainable frontend applications. This guide covers how to minimize state, place it correctly, and manage async operations.
|
|
4
|
+
|
|
5
|
+
## Minimize State
|
|
6
|
+
|
|
7
|
+
The less state you have, the fewer bugs you'll have. Before adding something as state, ask: "Does this need to change over time?"
|
|
8
|
+
|
|
9
|
+
**What should NOT be state:**
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
// BAD: Derived values as state
|
|
13
|
+
function User({ firstName, lastName }) {
|
|
14
|
+
const [fullName, setFullName] = useState('');
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setFullName(`${firstName} ${lastName}`);
|
|
18
|
+
}, [firstName, lastName]);
|
|
19
|
+
|
|
20
|
+
return <div>{fullName}</div>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// GOOD: Derive directly
|
|
24
|
+
function User({ firstName, lastName }) {
|
|
25
|
+
const fullName = `${firstName} ${lastName}`;
|
|
26
|
+
return <div>{fullName}</div>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// BAD: Stable values as state
|
|
30
|
+
function Form() {
|
|
31
|
+
const [submitUrl, setSubmitUrl] = useState('/api/users');
|
|
32
|
+
// submitUrl never changes!
|
|
33
|
+
|
|
34
|
+
return <form action={submitUrl}>{...}</form>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// GOOD: Use constant
|
|
38
|
+
const SUBMIT_URL = '/api/users';
|
|
39
|
+
|
|
40
|
+
function Form() {
|
|
41
|
+
return <form action={SUBMIT_URL}>{...}</form>;
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**What SHOULD be state:**
|
|
46
|
+
|
|
47
|
+
Values that:
|
|
48
|
+
- Change over time (user input, server data, UI state)
|
|
49
|
+
- Multiple parts of the component depend on
|
|
50
|
+
- Affect component behavior or rendering
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
// GOOD: Essential UI state
|
|
54
|
+
function SearchableList({ items }) {
|
|
55
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
56
|
+
const [sortBy, setSortBy] = useState('name');
|
|
57
|
+
|
|
58
|
+
const filtered = items.filter(item =>
|
|
59
|
+
item.name.includes(searchTerm)
|
|
60
|
+
);
|
|
61
|
+
const sorted = filtered.sort((a, b) =>
|
|
62
|
+
a[sortBy].localeCompare(b[sortBy])
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<>
|
|
67
|
+
<input
|
|
68
|
+
value={searchTerm}
|
|
69
|
+
onChange={(e) => setSearchTerm(e.target.value)}
|
|
70
|
+
placeholder="Search..."
|
|
71
|
+
/>
|
|
72
|
+
<select value={sortBy} onChange={(e) => setSortBy(e.target.value)}>
|
|
73
|
+
<option value="name">Name</option>
|
|
74
|
+
<option value="date">Date</option>
|
|
75
|
+
</select>
|
|
76
|
+
<ul>
|
|
77
|
+
{sorted.map(item => <li key={item.id}>{item.name}</li>)}
|
|
78
|
+
</ul>
|
|
79
|
+
</>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## State Placement
|
|
85
|
+
|
|
86
|
+
State belongs at the lowest level that needs it. Consider four categories:
|
|
87
|
+
|
|
88
|
+
**Local state:** Component manages its own UI state.
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
function Accordion({ items }) {
|
|
92
|
+
const [expanded, setExpanded] = useState(null);
|
|
93
|
+
|
|
94
|
+
return items.map(item => (
|
|
95
|
+
<div key={item.id}>
|
|
96
|
+
<button onClick={() => setExpanded(expanded === item.id ? null : item.id)}>
|
|
97
|
+
{item.title}
|
|
98
|
+
</button>
|
|
99
|
+
{expanded === item.id && <div>{item.content}</div>}
|
|
100
|
+
</div>
|
|
101
|
+
));
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Shared state:** Multiple components at the same level need data.
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
function Dashboard() {
|
|
109
|
+
const [selectedUser, setSelectedUser] = useState(null);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<>
|
|
113
|
+
<UserList onSelect={setSelectedUser} />
|
|
114
|
+
{selectedUser && <UserDetail user={selectedUser} />}
|
|
115
|
+
</>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Server state:** Data from API. Treat differently from UI state.
|
|
121
|
+
|
|
122
|
+
```javascript
|
|
123
|
+
function UserData({ userId }) {
|
|
124
|
+
const [data, setData] = useState(null);
|
|
125
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
126
|
+
const [error, setError] = useState(null);
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
fetchUser(userId)
|
|
130
|
+
.then(data => {
|
|
131
|
+
setData(data);
|
|
132
|
+
setIsLoading(false);
|
|
133
|
+
})
|
|
134
|
+
.catch(err => {
|
|
135
|
+
setError(err);
|
|
136
|
+
setIsLoading(false);
|
|
137
|
+
});
|
|
138
|
+
}, [userId]);
|
|
139
|
+
|
|
140
|
+
return <div>...</div>;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Derived state:** Computed from other state. Don't store it.
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
function ShoppingCart({ items }) {
|
|
148
|
+
const [quantities, setQuantities] = useState({});
|
|
149
|
+
|
|
150
|
+
// BAD: Store total as state
|
|
151
|
+
const [total, setTotal] = useState(0);
|
|
152
|
+
|
|
153
|
+
// GOOD: Calculate when needed
|
|
154
|
+
const total = items.reduce((sum, item) =>
|
|
155
|
+
sum + (item.price * (quantities[item.id] || 0)), 0
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
return <div>Total: ${total.toFixed(2)}</div>;
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Immutability
|
|
163
|
+
|
|
164
|
+
Never mutate state directly. Always create new objects and arrays.
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
// BAD: Mutation
|
|
168
|
+
function addTodo(text) {
|
|
169
|
+
todos.push({ id: Date.now(), text });
|
|
170
|
+
setTodos(todos);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// GOOD: Create new array
|
|
174
|
+
function addTodo(text) {
|
|
175
|
+
setTodos([...todos, { id: Date.now(), text }]);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// BAD: Mutating nested object
|
|
179
|
+
function updateUser(userId, changes) {
|
|
180
|
+
user.profile.name = changes.name;
|
|
181
|
+
setUser(user);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// GOOD: Create new object with spread
|
|
185
|
+
function updateUser(userId, changes) {
|
|
186
|
+
setUser({
|
|
187
|
+
...user,
|
|
188
|
+
profile: { ...user.profile, ...changes }
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// For complex updates, use a library like immer:
|
|
193
|
+
function updateNestedData(changes) {
|
|
194
|
+
setData(produce(data, draft => {
|
|
195
|
+
draft.deeply.nested.value = changes.value;
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Data Flow
|
|
201
|
+
|
|
202
|
+
Maintain unidirectional data flow: parent → child via props, child → parent via callbacks.
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
// GOOD: Unidirectional flow
|
|
206
|
+
function Parent() {
|
|
207
|
+
const [count, setCount] = useState(0);
|
|
208
|
+
|
|
209
|
+
return <Child count={count} onIncrement={() => setCount(count + 1)} />;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function Child({ count, onIncrement }) {
|
|
213
|
+
return (
|
|
214
|
+
<>
|
|
215
|
+
<div>Count: {count}</div>
|
|
216
|
+
<button onClick={onIncrement}>Increment</button>
|
|
217
|
+
</>
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// BAD: Bidirectional (child modifies parent's state directly)
|
|
222
|
+
// This breaks the dependency chain and makes debugging hard
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## State Management Patterns
|
|
226
|
+
|
|
227
|
+
**useReducer for complex state:**
|
|
228
|
+
|
|
229
|
+
```javascript
|
|
230
|
+
const initialState = { items: [], loading: false, error: null };
|
|
231
|
+
|
|
232
|
+
function reducer(state, action) {
|
|
233
|
+
switch (action.type) {
|
|
234
|
+
case 'FETCH_START':
|
|
235
|
+
return { ...state, loading: true };
|
|
236
|
+
case 'FETCH_SUCCESS':
|
|
237
|
+
return { items: action.payload, loading: false, error: null };
|
|
238
|
+
case 'FETCH_ERROR':
|
|
239
|
+
return { ...state, loading: false, error: action.payload };
|
|
240
|
+
default:
|
|
241
|
+
return state;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function Component() {
|
|
246
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
247
|
+
|
|
248
|
+
useEffect(() => {
|
|
249
|
+
dispatch({ type: 'FETCH_START' });
|
|
250
|
+
fetchItems()
|
|
251
|
+
.then(data => dispatch({ type: 'FETCH_SUCCESS', payload: data }))
|
|
252
|
+
.catch(err => dispatch({ type: 'FETCH_ERROR', payload: err }));
|
|
253
|
+
}, []);
|
|
254
|
+
|
|
255
|
+
return <div>...</div>;
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Context for shared state:**
|
|
260
|
+
|
|
261
|
+
```javascript
|
|
262
|
+
const ThemeContext = createContext();
|
|
263
|
+
|
|
264
|
+
function ThemeProvider({ children }) {
|
|
265
|
+
const [theme, setTheme] = useState('light');
|
|
266
|
+
|
|
267
|
+
const toggle = () => setTheme(theme === 'light' ? 'dark' : 'light');
|
|
268
|
+
|
|
269
|
+
return (
|
|
270
|
+
<ThemeContext.Provider value={{ theme, toggle }}>
|
|
271
|
+
{children}
|
|
272
|
+
</ThemeContext.Provider>
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function useTheme() {
|
|
277
|
+
const context = useContext(ThemeContext);
|
|
278
|
+
if (!context) throw new Error('useTheme must be used in ThemeProvider');
|
|
279
|
+
return context;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function Component() {
|
|
283
|
+
const { theme, toggle } = useTheme();
|
|
284
|
+
return <button onClick={toggle}>Theme: {theme}</button>;
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Async State
|
|
289
|
+
|
|
290
|
+
Handle async operations with three explicit states: loading, success, error.
|
|
291
|
+
|
|
292
|
+
```javascript
|
|
293
|
+
function useAsync(asyncFn, immediate = true) {
|
|
294
|
+
const [state, dispatch] = useReducer(
|
|
295
|
+
(state, action) => ({ ...state, ...action }),
|
|
296
|
+
{ status: 'idle', data: null, error: null }
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
const execute = useCallback(async () => {
|
|
300
|
+
dispatch({ status: 'pending' });
|
|
301
|
+
try {
|
|
302
|
+
const data = await asyncFn();
|
|
303
|
+
dispatch({ status: 'success', data });
|
|
304
|
+
} catch (error) {
|
|
305
|
+
dispatch({ status: 'error', error });
|
|
306
|
+
}
|
|
307
|
+
}, [asyncFn]);
|
|
308
|
+
|
|
309
|
+
useEffect(() => {
|
|
310
|
+
if (immediate) execute();
|
|
311
|
+
}, [execute, immediate]);
|
|
312
|
+
|
|
313
|
+
return { ...state, execute };
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Usage
|
|
317
|
+
function Component() {
|
|
318
|
+
const { status, data, error } = useAsync(() => fetchUser(123));
|
|
319
|
+
|
|
320
|
+
if (status === 'pending') return <div>Loading...</div>;
|
|
321
|
+
if (status === 'error') return <div>Error: {error.message}</div>;
|
|
322
|
+
if (status === 'success') return <div>{data.name}</div>;
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
## State Management Best Practices Checklist
|
|
327
|
+
|
|
328
|
+
- [ ] State is minimized (no derived values)
|
|
329
|
+
- [ ] Each state variable has clear ownership
|
|
330
|
+
- [ ] No prop drilling beyond 2-3 levels
|
|
331
|
+
- [ ] Async operations use loading/error/success pattern
|
|
332
|
+
- [ ] State mutations always create new objects
|
|
333
|
+
- [ ] Data flow is unidirectional (parent → child → parent)
|
|
334
|
+
- [ ] Complex state logic extracted to useReducer
|
|
335
|
+
- [ ] Shared state uses Context or state management library
|
|
336
|
+
- [ ] Server state separate from UI state
|
|
337
|
+
- [ ] useEffect dependencies are correct
|
|
338
|
+
|
|
339
|
+
## Related Guidance
|
|
340
|
+
|
|
341
|
+
- `/components` — component design for state placement
|
|
342
|
+
- `/code-quality` — naming conventions for state
|
|
343
|
+
- `/testing` — testing state changes
|
|
344
|
+
- `/logging-observability` — tracking state changes
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
Senior frontend developers test thoroughly: unit, integration, and e2e. Always test after changes.
|
|
4
|
+
|
|
5
|
+
## Testing Pyramid
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
E2E (few, full app flow)
|
|
9
|
+
/ \
|
|
10
|
+
Integration (component + API)
|
|
11
|
+
/ \
|
|
12
|
+
Unit (function, component in isolation)
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Test more at bottom, fewer at top.
|
|
16
|
+
|
|
17
|
+
## Unit Tests
|
|
18
|
+
|
|
19
|
+
### What to Test
|
|
20
|
+
- Pure functions (utilities, formatters, validators)
|
|
21
|
+
- Component rendering with different props
|
|
22
|
+
- State updates and side effects
|
|
23
|
+
- Event handlers and callbacks
|
|
24
|
+
- Logic branches (happy path + edge cases)
|
|
25
|
+
|
|
26
|
+
### What NOT to Test
|
|
27
|
+
- Framework internals (React's rendering)
|
|
28
|
+
- Third-party library behavior
|
|
29
|
+
- Implementation details (prefer testing behavior)
|
|
30
|
+
|
|
31
|
+
### Test Structure
|
|
32
|
+
```
|
|
33
|
+
describe('MyComponent', () => {
|
|
34
|
+
it('renders with required props', () => { ... })
|
|
35
|
+
it('calls onClick when clicked', () => { ... })
|
|
36
|
+
it('handles error state', () => { ... })
|
|
37
|
+
})
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Tools
|
|
41
|
+
- Jest (testing framework)
|
|
42
|
+
- React Testing Library (component testing)
|
|
43
|
+
- Vitest (modern Jest alternative)
|
|
44
|
+
|
|
45
|
+
## Integration Tests
|
|
46
|
+
|
|
47
|
+
### What to Test
|
|
48
|
+
- Components working together
|
|
49
|
+
- Component + state management
|
|
50
|
+
- Component + API (mock API)
|
|
51
|
+
- User workflows (form submission, navigation)
|
|
52
|
+
|
|
53
|
+
### Approach
|
|
54
|
+
- Mount multiple components
|
|
55
|
+
- Mock API responses
|
|
56
|
+
- Simulate user interactions
|
|
57
|
+
- Assert final state/DOM
|
|
58
|
+
|
|
59
|
+
### Tools
|
|
60
|
+
- React Testing Library (recommended)
|
|
61
|
+
- Cypress (browser-based)
|
|
62
|
+
- Playwright (full browser testing)
|
|
63
|
+
|
|
64
|
+
## E2E Tests
|
|
65
|
+
|
|
66
|
+
### What to Test
|
|
67
|
+
- Full user journeys
|
|
68
|
+
- Real backend (or staging)
|
|
69
|
+
- Navigation, data persistence
|
|
70
|
+
- Error handling in real conditions
|
|
71
|
+
|
|
72
|
+
### Characteristics
|
|
73
|
+
- Slow, expensive
|
|
74
|
+
- Real-world conditions
|
|
75
|
+
- Test critical paths only
|
|
76
|
+
- Run less frequently
|
|
77
|
+
|
|
78
|
+
### Tools
|
|
79
|
+
- Cypress
|
|
80
|
+
- Playwright
|
|
81
|
+
- Selenium (older)
|
|
82
|
+
|
|
83
|
+
## Test Coverage Guidelines
|
|
84
|
+
|
|
85
|
+
- **Aim for 80%+ line coverage**
|
|
86
|
+
- Don't chase 100% (diminishing returns)
|
|
87
|
+
- Focus on behavior, not coverage numbers
|
|
88
|
+
- Mission-critical paths: 100% coverage
|
|
89
|
+
- Utilities and helpers: 80%+ coverage
|
|
90
|
+
|
|
91
|
+
## Testing Anti-Patterns
|
|
92
|
+
|
|
93
|
+
- Testing implementation details
|
|
94
|
+
- Over-mocking (mocking too much loses integration value)
|
|
95
|
+
- Flaky tests (timing-dependent)
|
|
96
|
+
- Tests that depend on test order
|
|
97
|
+
- Not testing error cases
|
|
98
|
+
- Insufficient assertions (test passes but doesn't verify)
|
|
99
|
+
|
|
100
|
+
## Testing Checklist
|
|
101
|
+
|
|
102
|
+
After every change:
|
|
103
|
+
- [ ] Unit tests pass
|
|
104
|
+
- [ ] Integration tests pass
|
|
105
|
+
- [ ] Coverage maintained/improved
|
|
106
|
+
- [ ] No test regressions
|
|
107
|
+
- [ ] Edge cases covered
|
|
108
|
+
- [ ] Error paths tested
|
|
109
|
+
|
|
110
|
+
## Related Guidance
|
|
111
|
+
|
|
112
|
+
- `/code-quality` — test formatting and style
|
|
113
|
+
- `/debugging` — debug failing tests
|
|
114
|
+
- `/logging-observability` — logging in tests
|