Project Conventions
Golden Rules
Enforced by pre-commit hooks (block commits)
- •No file > 500 lines → Split into smaller modules
- •No
print()/console.log()→ Uselogger.info("msg", extra={...}) - •No TODO without issue →
# TODO(#123): description - •No secrets in code → Use environment variables
- •No function > 50 lines → Extract helpers, each does one thing
- •No magic numbers → Extract to named constant
- •No cross-layer imports → Respect architecture boundaries (requires
.import-boundaries.json)
Not yet mechanically enforced (follow as guidelines)
- •No
Anywithout comment → Add type annotation or explain why
Naming
- •Python:
snake_casefor functions/variables,PascalCasefor classes - •TypeScript:
camelCasefor functions/variables,PascalCasefor classes/interfaces - •Files:
kebab-casefor non-class files,PascalCasefor class files - •Tests:
test_<module>_<behavior>.pyor<module>.test.ts
Structure
- •Business logic in
src/services/ - •API handlers in
src/routes/orsrc/api/ - •Data models in
src/models/ - •Shared utilities in
src/utils/(only if used by 3+ modules) - •Tests mirror
src/structure undertests/
Error Handling
- •Use typed exceptions, not generic
Exception - •Log errors with context:
logger.error("msg", extra={"user_id": uid, "action": "login"}) - •Return appropriate HTTP status codes (don't swallow errors)
- •Fail fast on invalid input at system boundaries
Testing
- •Test writer is separate from implementer
- •Tests see interfaces, not implementation
- •One assertion per test (or one logical behavior)
- •No test depends on execution order
- •Mock external services, not internal modules