# 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 ```bash # 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 FIRST - Test must fail for the right reason - NO production code until test fails 2. **GREEN**: Write MINIMUM code to pass - Only what's needed for current test - No "while you're there" additions 3. **REFACTOR**: Assess improvements (if tests green) - Commit BEFORE refactoring - Only refactor if it adds value - All tests must still pass ## 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 --strict` compliance ### TypeScript - Strict mode always (`"strict": true`) - No `any` types - use `unknown` if truly unknown - Zod schemas at trust boundaries - `type` for data, `interface` for behavior contracts only ### Rust - Leverage the type system fully - Use `Result` for fallible operations - Prefer `thiserror` for error types ## Testing Principles ### Test Behavior, Not Implementation ```typescript // 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`) ```typescript const getMockPayment = (overrides?: Partial): Payment => ({ amount: 100, currency: 'GBP', ...overrides, }); ``` ## Security (Zero Tolerance) - **NEVER** hardcode secrets, passwords, API keys - **NEVER** commit `.env` files 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. ```typescript // 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: 1. Use Claude's Chrome MCP tools for rapid testing 2. Take screenshots to verify UI state 3. Record GIFs for complex interactions For CI/permanent tests: 1. Write Playwright tests for E2E flows 2. Use React Testing Library for component behavior 3. 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 (Before Every Commit) - [ ] All tests pass - [ ] Coverage meets threshold - [ ] No linting errors - [ ] Type checking passes - [ ] No secrets in code - [ ] TDD compliance verified