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,272 @@
|
|
|
1
|
+
# Testing: Best Practices
|
|
2
|
+
|
|
3
|
+
Testing is your safety net for confident refactoring and deployment. This guide covers how to write tests that catch real bugs while staying maintainable.
|
|
4
|
+
|
|
5
|
+
## Test Behavior, Not Implementation
|
|
6
|
+
|
|
7
|
+
Tests should verify what the component does, not how it does it. Implementation details change; behavior should remain stable.
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// BAD: Tests implementation (useState, specific function calls)
|
|
11
|
+
function Counter() {
|
|
12
|
+
const [count, setCount] = useState(0);
|
|
13
|
+
return (
|
|
14
|
+
<div>
|
|
15
|
+
<div>{count}</div>
|
|
16
|
+
<button onClick={() => setCount(count + 1)}>Increment</button>
|
|
17
|
+
</div>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
test('Counter uses useState', () => {
|
|
22
|
+
// Can't test useState directly - this is implementation detail
|
|
23
|
+
// This test breaks if we refactor to use a state manager
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// GOOD: Test behavior (what user sees and can do)
|
|
27
|
+
test('Counter increments when button clicked', () => {
|
|
28
|
+
render(<Counter />);
|
|
29
|
+
|
|
30
|
+
expect(screen.getByText('0')).toBeInTheDocument();
|
|
31
|
+
|
|
32
|
+
fireEvent.click(screen.getByRole('button', { name: /increment/i }));
|
|
33
|
+
|
|
34
|
+
expect(screen.getByText('1')).toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Arrange-Act-Assert Pattern
|
|
39
|
+
|
|
40
|
+
Structure every test with three clear phases: setup, action, assertion.
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
test('Form submits user data', () => {
|
|
44
|
+
// Arrange: Set up test conditions
|
|
45
|
+
const handleSubmit = jest.fn();
|
|
46
|
+
render(<UserForm onSubmit={handleSubmit} />);
|
|
47
|
+
|
|
48
|
+
// Act: User action
|
|
49
|
+
fireEvent.change(screen.getByLabelText(/name/i), {
|
|
50
|
+
target: { value: 'Alice' }
|
|
51
|
+
});
|
|
52
|
+
fireEvent.change(screen.getByLabelText(/email/i), {
|
|
53
|
+
target: { value: 'alice@example.com' }
|
|
54
|
+
});
|
|
55
|
+
fireEvent.click(screen.getByRole('button', { name: /submit/i }));
|
|
56
|
+
|
|
57
|
+
// Assert: Expected outcome
|
|
58
|
+
expect(handleSubmit).toHaveBeenCalledWith({
|
|
59
|
+
name: 'Alice',
|
|
60
|
+
email: 'alice@example.com'
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Test Isolated Units
|
|
66
|
+
|
|
67
|
+
Each test should focus on one component or function. Use mocking to isolate dependencies.
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
// GOOD: Test one component in isolation
|
|
71
|
+
function UserCard({ userId }) {
|
|
72
|
+
const [user, setUser] = useState(null);
|
|
73
|
+
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
fetchUser(userId).then(setUser);
|
|
76
|
+
}, [userId]);
|
|
77
|
+
|
|
78
|
+
return user ? <div>{user.name}</div> : <div>Loading...</div>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Mock the external dependency
|
|
82
|
+
jest.mock('./api', () => ({
|
|
83
|
+
fetchUser: jest.fn()
|
|
84
|
+
}));
|
|
85
|
+
|
|
86
|
+
test('UserCard displays user after loading', async () => {
|
|
87
|
+
fetchUser.mockResolvedValue({ name: 'Bob' });
|
|
88
|
+
|
|
89
|
+
render(<UserCard userId={1} />);
|
|
90
|
+
|
|
91
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
92
|
+
|
|
93
|
+
await waitFor(() => {
|
|
94
|
+
expect(screen.getByText('Bob')).toBeInTheDocument();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Mock Strategically
|
|
100
|
+
|
|
101
|
+
Mock external dependencies (APIs, libraries) but test real component logic.
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
// BAD: Over-mocking
|
|
105
|
+
test('Button works', () => {
|
|
106
|
+
const mockClick = jest.fn();
|
|
107
|
+
// Mocking everything makes test useless
|
|
108
|
+
const Button = jest.fn(() => <button />);
|
|
109
|
+
|
|
110
|
+
render(<Button onClick={mockClick} />);
|
|
111
|
+
// Not testing the real component anymore!
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// GOOD: Mock external, test real logic
|
|
115
|
+
function SubmitButton({ onSubmit }) {
|
|
116
|
+
const [loading, setLoading] = useState(false);
|
|
117
|
+
const [error, setError] = useState(null);
|
|
118
|
+
|
|
119
|
+
const handleClick = async () => {
|
|
120
|
+
setLoading(true);
|
|
121
|
+
try {
|
|
122
|
+
await onSubmit();
|
|
123
|
+
setError(null);
|
|
124
|
+
} catch (err) {
|
|
125
|
+
setError(err.message);
|
|
126
|
+
} finally {
|
|
127
|
+
setLoading(false);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return (
|
|
132
|
+
<>
|
|
133
|
+
<button onClick={handleClick} disabled={loading}>
|
|
134
|
+
{loading ? 'Submitting...' : 'Submit'}
|
|
135
|
+
</button>
|
|
136
|
+
{error && <div role="alert">{error}</div>}
|
|
137
|
+
</>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
test('SubmitButton shows loading and error states', async () => {
|
|
142
|
+
const mockSubmit = jest.fn().mockRejectedValue(
|
|
143
|
+
new Error('Network error')
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
render(<SubmitButton onSubmit={mockSubmit} />);
|
|
147
|
+
|
|
148
|
+
// Click button
|
|
149
|
+
fireEvent.click(screen.getByRole('button'));
|
|
150
|
+
|
|
151
|
+
// Should show loading
|
|
152
|
+
expect(screen.getByRole('button')).toHaveTextContent('Submitting...');
|
|
153
|
+
expect(screen.getByRole('button')).toBeDisabled();
|
|
154
|
+
|
|
155
|
+
// Should show error after submission fails
|
|
156
|
+
await waitFor(() => {
|
|
157
|
+
expect(screen.getByRole('alert')).toHaveTextContent('Network error');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Test Coverage Guidelines
|
|
163
|
+
|
|
164
|
+
- Aim for 80%+ coverage on business logic
|
|
165
|
+
- Coverage numbers matter less than meaningful tests
|
|
166
|
+
- 100% coverage with bad tests is worse than 70% coverage with good tests
|
|
167
|
+
|
|
168
|
+
```javascript
|
|
169
|
+
// Test happy path, error path, and edge cases
|
|
170
|
+
function parseUserInput(input) {
|
|
171
|
+
if (!input) throw new Error('Input required');
|
|
172
|
+
if (typeof input !== 'string') throw new Error('Must be string');
|
|
173
|
+
|
|
174
|
+
const trimmed = input.trim();
|
|
175
|
+
if (trimmed.length === 0) throw new Error('Cannot be empty');
|
|
176
|
+
|
|
177
|
+
return trimmed.toLowerCase();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
test('parseUserInput: happy path', () => {
|
|
181
|
+
expect(parseUserInput(' Hello ')).toBe('hello');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('parseUserInput: null input', () => {
|
|
185
|
+
expect(() => parseUserInput(null)).toThrow('Input required');
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
test('parseUserInput: non-string input', () => {
|
|
189
|
+
expect(() => parseUserInput(123)).toThrow('Must be string');
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test('parseUserInput: whitespace-only input', () => {
|
|
193
|
+
expect(() => parseUserInput(' ')).toThrow('Cannot be empty');
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Async Testing
|
|
198
|
+
|
|
199
|
+
Handle promises and timers carefully. Use async/await and waitFor.
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
test('Async operation completes', async () => {
|
|
203
|
+
render(<DataLoader />);
|
|
204
|
+
|
|
205
|
+
// Wait for async operation
|
|
206
|
+
const result = await screen.findByText('Data loaded');
|
|
207
|
+
|
|
208
|
+
expect(result).toBeInTheDocument();
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test('Handles delayed state updates', async () => {
|
|
212
|
+
jest.useFakeTimers();
|
|
213
|
+
|
|
214
|
+
render(<Debounced />);
|
|
215
|
+
|
|
216
|
+
fireEvent.change(screen.getByRole('textbox'), {
|
|
217
|
+
target: { value: 'search' }
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Debounced function hasn't run yet
|
|
221
|
+
expect(mockFn).not.toHaveBeenCalled();
|
|
222
|
+
|
|
223
|
+
// Fast-forward time
|
|
224
|
+
jest.advanceTimersByTime(500);
|
|
225
|
+
|
|
226
|
+
// Now it should have run
|
|
227
|
+
expect(mockFn).toHaveBeenCalled();
|
|
228
|
+
|
|
229
|
+
jest.useRealTimers();
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Test Naming
|
|
234
|
+
|
|
235
|
+
Write descriptive test names that explain what is being tested and expected outcome.
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
// BAD: Unclear
|
|
239
|
+
test('works', () => { ... });
|
|
240
|
+
test('error', () => { ... });
|
|
241
|
+
test('loading', () => { ... });
|
|
242
|
+
|
|
243
|
+
// GOOD: Describes behavior
|
|
244
|
+
test('UserForm displays validation error when email is invalid', () => { ... });
|
|
245
|
+
test('API call retries after network timeout', () => { ... });
|
|
246
|
+
test('Modal closes when escape key is pressed', () => { ... });
|
|
247
|
+
|
|
248
|
+
// Pattern: "should [expected behavior] when [condition]"
|
|
249
|
+
test('should disable submit button when form is invalid', () => { ... });
|
|
250
|
+
test('should show error message when API fails', () => { ... });
|
|
251
|
+
test('should redirect to home when not authenticated', () => { ... });
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Testing Best Practices Checklist
|
|
255
|
+
|
|
256
|
+
- [ ] Tests verify behavior, not implementation
|
|
257
|
+
- [ ] Each test follows Arrange-Act-Assert structure
|
|
258
|
+
- [ ] Tests are independent and can run in any order
|
|
259
|
+
- [ ] External dependencies are mocked appropriately
|
|
260
|
+
- [ ] Happy path, error path, and edge cases covered
|
|
261
|
+
- [ ] Async operations tested with waitFor or findBy
|
|
262
|
+
- [ ] Test names clearly describe what is being tested
|
|
263
|
+
- [ ] No tests for implementation details (internal state, specific function calls)
|
|
264
|
+
- [ ] Tests run quickly (< 5 seconds per test)
|
|
265
|
+
- [ ] Coverage is meaningful, not just high percentage
|
|
266
|
+
|
|
267
|
+
## Related Guidance
|
|
268
|
+
|
|
269
|
+
- `/components` — designing testable components
|
|
270
|
+
- `/code-quality` — code organization for testability
|
|
271
|
+
- `/debugging` — debugging failing tests
|
|
272
|
+
- `/tools-setup` — testing tools and configuration
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Fullstack
|
|
2
|
+
|
|
3
|
+
Use this packet when a change crosses frontend, backend, API, persistence, and
|
|
4
|
+
deployment boundaries.
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
|
|
8
|
+
- UI-to-API workflows, forms, dashboards, and end-to-end product features.
|
|
9
|
+
- Contract changes that require coordinated frontend and backend updates.
|
|
10
|
+
- Feature flags, staged rollouts, and backward compatibility.
|
|
11
|
+
|
|
12
|
+
## Standards
|
|
13
|
+
|
|
14
|
+
- Define the user workflow and API contract together.
|
|
15
|
+
- Keep frontend and backend validation consistent without duplicating fragile logic.
|
|
16
|
+
- Roll out breaking changes in compatible phases.
|
|
17
|
+
- Verify the full path, not just isolated layers.
|
|
18
|
+
|
|
19
|
+
## Related Files
|
|
20
|
+
|
|
21
|
+
- `../frontend/`
|
|
22
|
+
- `../api/`
|
|
23
|
+
- `../backend/`
|
|
24
|
+
- `../database/`
|
|
25
|
+
- `../integration-tests/`
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Fullstack Checklists
|
|
2
|
+
|
|
3
|
+
## Design
|
|
4
|
+
|
|
5
|
+
- [ ] Define the user flow, API contract, data model, and rollout sequence.
|
|
6
|
+
- [ ] Identify compatibility requirements for old clients and old servers.
|
|
7
|
+
- [ ] Decide feature flag, migration, and fallback behavior.
|
|
8
|
+
|
|
9
|
+
## Implementation
|
|
10
|
+
|
|
11
|
+
- [ ] Update frontend states: loading, empty, error, success, and permission denied.
|
|
12
|
+
- [ ] Update backend validation, authorization, persistence, and observability.
|
|
13
|
+
- [ ] Keep contract fixtures or generated clients synchronized.
|
|
14
|
+
|
|
15
|
+
## Verification
|
|
16
|
+
|
|
17
|
+
- [ ] Add frontend behavior tests and backend contract tests.
|
|
18
|
+
- [ ] Run an end-to-end or integration check for the complete workflow.
|
|
19
|
+
- [ ] Verify rollout and rollback steps.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Fullstack Examples
|
|
2
|
+
|
|
3
|
+
## Coordinated Contract Change
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
Goal: Add "display_name" to user profile editing.
|
|
7
|
+
|
|
8
|
+
1. Add nullable database column.
|
|
9
|
+
2. Add API response field while accepting old clients.
|
|
10
|
+
3. Update frontend form and validation.
|
|
11
|
+
4. Add integration test for save-and-render flow.
|
|
12
|
+
5. Backfill display names.
|
|
13
|
+
6. Make field required only after clients are deployed.
|
|
14
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# GraphQL
|
|
2
|
+
|
|
3
|
+
Use this packet for GraphQL schemas, resolvers, mutations, subscriptions, and
|
|
4
|
+
client contracts.
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
|
|
8
|
+
- Schema design, field naming, input types, mutations, pagination, and errors.
|
|
9
|
+
- Resolver behavior, batching, data loading, authorization, and complexity limits.
|
|
10
|
+
- Schema evolution, deprecation, compatibility, and generated clients.
|
|
11
|
+
|
|
12
|
+
## Standards
|
|
13
|
+
|
|
14
|
+
- Treat the schema as a public contract.
|
|
15
|
+
- Keep resolvers thin and delegate business behavior to services.
|
|
16
|
+
- Add authorization checks at resolver or service boundaries.
|
|
17
|
+
- Prevent N+1 queries with batching or data loaders.
|
|
18
|
+
- Use deprecation before removal.
|
|
19
|
+
|
|
20
|
+
## Related Files
|
|
21
|
+
|
|
22
|
+
- `../api/` for contract principles.
|
|
23
|
+
- `../authorization/` for field and object access.
|
|
24
|
+
- `../performance/` for query cost and N+1 concerns.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# GraphQL Checklists
|
|
2
|
+
|
|
3
|
+
## Design
|
|
4
|
+
|
|
5
|
+
- [ ] Define schema changes, nullability, pagination, and deprecation impact.
|
|
6
|
+
- [ ] Identify resolver data sources and authorization rules.
|
|
7
|
+
- [ ] Define query complexity, depth, and rate limits.
|
|
8
|
+
|
|
9
|
+
## Implementation
|
|
10
|
+
|
|
11
|
+
- [ ] Keep resolver code small and call service-layer functions.
|
|
12
|
+
- [ ] Use data loaders or batching for repeated entity lookups.
|
|
13
|
+
- [ ] Return typed domain errors instead of leaking internal exceptions.
|
|
14
|
+
- [ ] Update generated client types or schema artifacts.
|
|
15
|
+
|
|
16
|
+
## Verification
|
|
17
|
+
|
|
18
|
+
- [ ] Add resolver tests for allowed, denied, missing, and invalid inputs.
|
|
19
|
+
- [ ] Test query complexity limits and N+1-sensitive paths.
|
|
20
|
+
- [ ] Verify schema compatibility for existing clients.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# GraphQL Examples
|
|
2
|
+
|
|
3
|
+
## Resolver Shape
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
const resolvers = {
|
|
7
|
+
Query: {
|
|
8
|
+
project: async (_parent, args, context) => {
|
|
9
|
+
const project = await context.projectService.getProject(args.id);
|
|
10
|
+
context.authz.requireProjectAccess(context.principal, project, 'read');
|
|
11
|
+
return project;
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Deprecation
|
|
18
|
+
|
|
19
|
+
```graphql
|
|
20
|
+
type User {
|
|
21
|
+
name: String @deprecated(reason: "Use displayName.")
|
|
22
|
+
displayName: String!
|
|
23
|
+
}
|
|
24
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Integration Tests
|
|
2
|
+
|
|
3
|
+
Use this packet when testing multiple components together: service plus database,
|
|
4
|
+
API plus worker, frontend plus API, or external dependency contracts.
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
|
|
8
|
+
- Contract tests, service integration tests, database-backed tests, and workflow tests.
|
|
9
|
+
- Test containers, fixtures, seeded data, mocks, fakes, and sandbox services.
|
|
10
|
+
- Boundary verification across modules, processes, or infrastructure.
|
|
11
|
+
|
|
12
|
+
## Standards
|
|
13
|
+
|
|
14
|
+
- Test behavior at real boundaries when unit tests cannot catch integration risk.
|
|
15
|
+
- Keep fixtures explicit and isolated.
|
|
16
|
+
- Prefer deterministic fakes over brittle live third-party calls.
|
|
17
|
+
- Clean up data and resources after tests.
|
|
18
|
+
- Keep integration tests slower than unit tests but still reliable.
|
|
19
|
+
|
|
20
|
+
## Related Files
|
|
21
|
+
|
|
22
|
+
- `../testing/`
|
|
23
|
+
- `../unit-tests/`
|
|
24
|
+
- `../api/`
|
|
25
|
+
- `../database/`
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Integration Test Checklists
|
|
2
|
+
|
|
3
|
+
## Design
|
|
4
|
+
|
|
5
|
+
- [ ] Identify the boundary that must be verified.
|
|
6
|
+
- [ ] Decide which dependencies are real, fake, mocked, or containerized.
|
|
7
|
+
- [ ] Define seed data, cleanup strategy, and isolation model.
|
|
8
|
+
|
|
9
|
+
## Implementation
|
|
10
|
+
|
|
11
|
+
- [ ] Use stable fixtures and explicit setup.
|
|
12
|
+
- [ ] Avoid depending on test order.
|
|
13
|
+
- [ ] Use realistic serialization, persistence, and auth behavior.
|
|
14
|
+
- [ ] Capture logs or diagnostics for failure triage.
|
|
15
|
+
|
|
16
|
+
## Verification
|
|
17
|
+
|
|
18
|
+
- [ ] Run the test alone and with the full suite.
|
|
19
|
+
- [ ] Confirm failures are deterministic and actionable.
|
|
20
|
+
- [ ] Confirm cleanup leaves no shared state behind.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Integration Test Examples
|
|
2
|
+
|
|
3
|
+
## API Plus Database
|
|
4
|
+
|
|
5
|
+
```python
|
|
6
|
+
async def test_create_user_persists_and_returns_contract(api_client, db):
|
|
7
|
+
response = await api_client.post(
|
|
8
|
+
"/v1/users",
|
|
9
|
+
json={"email": "ada@example.com", "display_name": "Ada"},
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
assert response.status_code == 201
|
|
13
|
+
body = response.json()
|
|
14
|
+
assert body["email"] == "ada@example.com"
|
|
15
|
+
|
|
16
|
+
row = await db.fetch_one("select email from users where id = :id", {"id": body["id"]})
|
|
17
|
+
assert row["email"] == "ada@example.com"
|
|
18
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Java
|
|
2
|
+
|
|
3
|
+
Use this packet for Java application code, libraries, services, tests, and build
|
|
4
|
+
configuration.
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
|
|
8
|
+
- Java language features, collections, concurrency, streams, exceptions, and generics.
|
|
9
|
+
- JVM service code, dependency injection, persistence, and API integration.
|
|
10
|
+
- Maven or Gradle builds, static analysis, and test suites.
|
|
11
|
+
|
|
12
|
+
## Standards
|
|
13
|
+
|
|
14
|
+
- Favor clear object boundaries and immutable value objects.
|
|
15
|
+
- Use checked and unchecked exceptions intentionally.
|
|
16
|
+
- Keep concurrency explicit and bounded.
|
|
17
|
+
- Use dependency injection for external collaborators.
|
|
18
|
+
- Add unit and integration tests for public behavior.
|
|
19
|
+
|
|
20
|
+
## Related Files
|
|
21
|
+
|
|
22
|
+
- `../springboot/` for Spring Boot-specific guidance.
|
|
23
|
+
- `../backend/` for service design.
|
|
24
|
+
- `../testing/` and `../unit-tests/` for verification.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Java Checklists
|
|
2
|
+
|
|
3
|
+
## Implementation
|
|
4
|
+
|
|
5
|
+
- [ ] Use project formatting, static analysis, and build conventions.
|
|
6
|
+
- [ ] Keep public APIs typed and documented when reused across modules.
|
|
7
|
+
- [ ] Prefer constructor injection for required dependencies.
|
|
8
|
+
- [ ] Handle nullability explicitly with validation, annotations, or Optional where appropriate.
|
|
9
|
+
- [ ] Avoid blocking calls in async or reactive flows unless isolated.
|
|
10
|
+
|
|
11
|
+
## Verification
|
|
12
|
+
|
|
13
|
+
- [ ] Add unit tests for business rules.
|
|
14
|
+
- [ ] Add integration tests for persistence, messaging, or HTTP clients when touched.
|
|
15
|
+
- [ ] Run the relevant Maven or Gradle test target.
|
|
16
|
+
- [ ] Check logs for noisy stack traces or swallowed exceptions.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Java Examples
|
|
2
|
+
|
|
3
|
+
## Service Shape
|
|
4
|
+
|
|
5
|
+
```java
|
|
6
|
+
public final class InvoiceService {
|
|
7
|
+
private final InvoiceRepository invoices;
|
|
8
|
+
private final PaymentGateway payments;
|
|
9
|
+
|
|
10
|
+
public InvoiceService(InvoiceRepository invoices, PaymentGateway payments) {
|
|
11
|
+
this.invoices = invoices;
|
|
12
|
+
this.payments = payments;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public Invoice capture(String invoiceId, Principal principal) {
|
|
16
|
+
Invoice invoice = invoices.getForUpdate(invoiceId);
|
|
17
|
+
invoice.requirePermission(principal, "capture");
|
|
18
|
+
payments.capture(invoice.paymentId(), invoice.id());
|
|
19
|
+
return invoices.save(invoice.markCaptured());
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# JavaScript
|
|
2
|
+
|
|
3
|
+
Use this packet for JavaScript application code across browser, server, scripts,
|
|
4
|
+
tests, and tooling.
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
|
|
8
|
+
- Language behavior, modules, async flows, error handling, and runtime APIs.
|
|
9
|
+
- Browser and Node.js code when TypeScript is not used.
|
|
10
|
+
- Build tooling, package scripts, linting, and test setup.
|
|
11
|
+
|
|
12
|
+
## Standards
|
|
13
|
+
|
|
14
|
+
- Prefer explicit data shapes and runtime validation for external inputs.
|
|
15
|
+
- Use `async` and `await` consistently for promise flows.
|
|
16
|
+
- Avoid global mutable state unless the lifecycle is clear.
|
|
17
|
+
- Keep side effects isolated and testable.
|
|
18
|
+
- Use linting and formatting to catch common mistakes.
|
|
19
|
+
|
|
20
|
+
## Related Files
|
|
21
|
+
|
|
22
|
+
- `../typescript/` for typed JavaScript guidance.
|
|
23
|
+
- `../node/` for Node.js runtime concerns.
|
|
24
|
+
- `../frontend/` for browser UI code.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# JavaScript Checklists
|
|
2
|
+
|
|
3
|
+
## Implementation
|
|
4
|
+
|
|
5
|
+
- [ ] Validate external data before use.
|
|
6
|
+
- [ ] Handle promise rejection and cancellation paths.
|
|
7
|
+
- [ ] Keep modules small and exports intentional.
|
|
8
|
+
- [ ] Avoid mutating inputs unless explicitly documented.
|
|
9
|
+
- [ ] Remove development-only console output before production.
|
|
10
|
+
|
|
11
|
+
## Verification
|
|
12
|
+
|
|
13
|
+
- [ ] Add tests for success, failure, and edge cases.
|
|
14
|
+
- [ ] Run lint, format, and test scripts.
|
|
15
|
+
- [ ] Check bundle or runtime impact when adding dependencies.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# JavaScript Examples
|
|
2
|
+
|
|
3
|
+
## Safe Async Function
|
|
4
|
+
|
|
5
|
+
```javascript
|
|
6
|
+
export async function loadUser(apiClient, userId) {
|
|
7
|
+
if (!userId) {
|
|
8
|
+
throw new Error('userId is required');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const response = await apiClient.get(`/users/${encodeURIComponent(userId)}`);
|
|
12
|
+
if (!response.ok) {
|
|
13
|
+
throw new Error(`Failed to load user: ${response.status}`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return response.json();
|
|
17
|
+
}
|
|
18
|
+
```
|