# Coding Standards

Universal code quality principles. Language-specific rules extend these.

## Immutability

- Prefer creating new objects over mutating existing ones
- Use `const` by default; `let` only when mutation is required
- Avoid side effects in functions where possible

## Function Size and Complexity

- Functions: 50 lines max (excluding docstring/comments)
- Max nesting depth: 4 levels (use early returns to flatten)
- Single responsibility: one function does one thing
- If a function needs a comment explaining what it does, it needs a better name

## File Size

- Typical: 200-400 lines
- Maximum: 800 lines
- If a file exceeds 800 lines, split by responsibility

## Organization

- Organize by feature/domain, not by file type
- Good: `features/payments/controller.ts`, `features/payments/service.ts`
- Bad: `controllers/paymentController.ts`, `services/paymentService.ts`
- Co-locate tests with implementation (`foo.ts` + `foo.test.ts`)

## No Hardcoded Values

- Magic numbers and strings go into named constants
- Configuration values come from config files or environment variables
- URLs, ports, timeouts, limits — all configurable

## Error Handling

- Handle errors at system boundaries (API calls, file I/O, DB queries)
- Use typed errors or error codes, not generic catch-all
- Never swallow errors silently
- Log errors with context (what was attempted, what failed, relevant IDs)

## Input Validation

- Validate all external input at system boundaries
- Parse, don't validate: transform untyped input into typed structures
- Fail fast with clear error messages

## DRY Without Over-Abstraction

- Three similar lines are better than one premature abstraction
- Extract when you see the pattern three times (Rule of Three)
- Abstractions should simplify, not just reduce line count
