- Changed REFACTOR step from optional to MANDATORY - Added explicit Claude Code instructions requiring refactor-scan after every GREEN - Split Quality Gates into "After Every GREEN" and "Before Every PR" - Added clear process: commit → refactor-scan → apply → commit separately Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7.7 KiB
Development Standards
Core Philosophy
TDD is non-negotiable. Every line of production code must be written in response to a failing test. No exceptions.
Model Strategy: Use opusplan - Opus for planning/architecture, Sonnet for code execution.
Quick Reference
Languages & Tools
| Language | Test Framework | Linter | Formatter |
|---|---|---|---|
| Python | pytest + pytest-asyncio | Ruff | Ruff |
| TypeScript | Vitest | ESLint | ESLint |
| Rust | cargo test | clippy | rustfmt |
| Terraform | terraform validate | tflint | terraform fmt |
Commands by Language
# Python
pytest # Run tests
pytest --cov=src --cov-report=term-missing # With coverage
ruff check . && ruff format . # Lint and format
# TypeScript
npm test # Vitest
npm run lint # ESLint
npm run typecheck # tsc --noEmit
# Rust
cargo test # Run tests
cargo clippy -- -D warnings # Lint (deny warnings)
cargo fmt --check # Check formatting
# Terraform
terraform validate # Validate
terraform fmt -check -recursive # Check formatting
terraform plan # Preview changes
TDD Workflow (RED-GREEN-REFACTOR)
1. RED: Write a Failing Test
- Write test first that fails for the right reason
- NO production code until test fails
2. GREEN: Make It Pass
- Write MINIMUM code to pass the test
- No "while you're there" additions
3. REFACTOR: Mandatory Quality Assessment
CRITICAL: This step is MANDATORY after every GREEN, not optional.
Process:
-
Commit immediately after tests pass (before any refactoring)
git add . && git commit -m "feat: implement X" -
Invoke refactor-scan agent - THIS IS NOT OPTIONAL
- Use
@refactor-scanto assess the code - This happens AUTOMATICALLY after every successful test pass
- The agent identifies refactoring opportunities
- Use
-
Apply refactoring if recommended
- Make improvements identified by the scan
- Ensure all tests still pass
- Commit refactoring separately:
git commit -m "refactor: improve X based on scan"
Claude Code Instructions (MANDATORY)
After every successful test pass (GREEN state), you MUST:
- Commit the working code immediately
- Proactively invoke the
@refactor-scanagent (or use Task tool withsubagent_type: refactor-scan) - NOT proceed to the next feature/test until refactor assessment is complete
- Apply recommended refactoring and commit separately
This is not optional. Treat refactor-scan invocation with the same priority as running tests.
Coverage Requirements
| Layer | Target | Notes |
|---|---|---|
| Domain/Business Logic | 90%+ | Critical path |
| API Routes | 80%+ | Validation paths |
| Infrastructure/DB | 70%+ | Integration points |
| UI Components | 80%+ | Behavior testing |
Exceptions (document in code):
- Generated code (migrations, types)
- Third-party thin wrappers
- Debug utilities
Type Safety
Python
- Pydantic v2 for validation at boundaries
- Type hints on all public functions
mypy --strictcompliance
TypeScript
- Strict mode always (
"strict": true) - No
anytypes - useunknownif truly unknown - Zod schemas at trust boundaries
typefor data,interfacefor behavior contracts only
Rust
- Leverage the type system fully
- Use
Result<T, E>for fallible operations - Prefer
thiserrorfor error types
Testing Principles
Test Behavior, Not Implementation
// BAD - tests implementation
it('should call validateAmount', () => {
const spy = jest.spyOn(validator, 'validateAmount');
processPayment(payment);
expect(spy).toHaveBeenCalled();
});
// GOOD - tests behavior
it('should reject negative amounts', () => {
const payment = getMockPayment({ amount: -100 });
const result = processPayment(payment);
expect(result.success).toBe(false);
});
Factory Functions (No let/beforeEach)
const getMockPayment = (overrides?: Partial<Payment>): Payment => ({
amount: 100,
currency: 'GBP',
...overrides,
});
Security (Zero Tolerance)
- NEVER hardcode secrets, passwords, API keys
- NEVER commit
.envfiles with real values - Use AWS Secrets Manager or environment variables
- Validate ALL user input at boundaries
- Parameterized queries only (no string concatenation)
Code Style
- Immutable by default - no mutations
- Pure functions where possible
- Early returns over nested conditionals
- Options objects for 3+ parameters
- No comments - code should be self-documenting
- DRY (Don't Repeat Knowledge) - eliminate duplicate business logic, but don't abstract merely similar code
DRY Clarification
DRY means don't duplicate knowledge, not code. Structural similarity is fine.
// NOT duplication - different business rules
const validatePaymentLimit = (amount: number) => amount <= 10000;
const validateTransferLimit = (amount: number) => amount <= 10000;
// These will evolve independently - keep separate
// IS duplication - same business rule in multiple places
// BAD: FREE_SHIPPING_THRESHOLD defined in 3 files
// GOOD: Single constant imported where needed
"Duplicate code is far cheaper than the wrong abstraction."
Monorepo Patterns
project/
├── apps/
│ ├── backend/ # Python FastAPI
│ └── frontend/ # React TypeScript
├── packages/
│ └── shared/ # Shared types/utils
├── infrastructure/
│ ├── terraform/ # IaC
│ └── ansible/ # Config management
└── tests/
├── backend/
└── frontend/
Git Workflow
- Conventional commits:
feat:,fix:,refactor:,test:,docs: - One logical change per commit
- Tests and implementation in same commit
- PR must pass all checks before merge
Chrome/Browser Testing
For quick verification during development:
- Use Claude's Chrome MCP tools for rapid testing
- Take screenshots to verify UI state
- Record GIFs for complex interactions
For CI/permanent tests:
- Write Playwright tests for E2E flows
- Use React Testing Library for component behavior
- Test accessibility with axe-core
When to Use Which Model
Opus (via plan mode or explicit switch):
- Architecture decisions
- Complex debugging
- Code review
- Multi-file refactoring plans
Sonnet (default execution):
- Writing code
- Running tests
- Simple fixes
- File operations
Skills (Auto-Loaded)
Skills are automatically loaded when relevant context is detected. Available skills:
Languages: Python, TypeScript, Rust, Go, Java, C#
Infrastructure: AWS, Azure, GCP, Terraform, Ansible, Docker/Kubernetes, Database/Migrations, CI/CD
Testing: TDD workflow, UI Testing, Browser Testing (Playwright + Chrome MCP)
Patterns: Monorepo, API Design, Observability (logging, metrics, tracing)
Agents (Invoke with @)
@tdd-guardian- TDD enforcement and guidance@code-reviewer- Comprehensive PR review@security-scanner- Vulnerability detection@refactor-scan- Refactoring assessment (TDD step 3)@dependency-audit- Package security/updates
Quality Gates
After Every GREEN (Before Next RED)
- Tests pass (GREEN achieved)
- Code committed (preserve working state)
- refactor-scan agent executed (MANDATORY)
- Refactoring applied (if recommended)
- Tests still pass (after refactoring)
- Separate refactor commit created (if changes made)
Before Every PR/Push
- All tests pass
- Coverage meets threshold (80%+)
- No linting errors
- Type checking passes
- No secrets in code
- TDD compliance verified