CLAUDE.md¶
This is an example CLAUDE.md file. Copy it to your project root and customize for your codebase. Keep it under 300 lines. Shorter is better.
Project Overview¶
{PROJECT_NAME} is a {brief description, e.g., SaaS platform for project management built with Flask and HTMX}.
Tech Stack¶
- Backend: Python 3.12 / Flask
- Frontend: HTMX + Jinja2 templates
- Database: PostgreSQL 16 with pgvector extension
- Cache: Redis 7
- Infrastructure: Railway (production), local Docker (development)
- CI/CD: GitHub Actions
Project Structure¶
src/
app/
api/ # API route handlers
models/ # SQLAlchemy models
services/ # Business logic layer
templates/ # Jinja2 templates
static/ # CSS, JS, images
config.py # Configuration (reads from env vars)
extensions.py # Flask extensions initialization
tests/
unit/ # Unit tests (mirror src/ structure)
integration/ # Integration tests (require database)
conftest.py # Shared fixtures
migrations/ # Alembic database migrations
scripts/ # Utility scripts
Commands¶
# Development
flask run --debug # Start dev server on port 5000
flask db upgrade # Run pending migrations
flask db migrate -m "description" # Generate new migration
# Testing
pytest tests/unit # Unit tests only (~10 seconds)
pytest tests/integration # Integration tests (~30 seconds, needs DB)
pytest --cov=src/app # Full suite with coverage report
# Linting and Formatting
ruff check src/ tests/ # Lint check
ruff format src/ tests/ # Auto-format
mypy src/ # Type checking
# Database
docker compose up -d db # Start local PostgreSQL
flask seed-db # Seed development data
Coding Conventions¶
Python¶
- Functions and variables:
snake_case - Classes:
PascalCase - Constants:
SCREAMING_SNAKE_CASE - All functions must have type hints for parameters and return values
- Use
Resultpattern for error handling in service layer (never raise exceptions for expected failures) - Maximum function length: 30 lines. Extract helper functions if longer.
API Endpoints¶
- All responses use the shape:
{"data": ..., "error": ..., "meta": ...} - Error responses include a machine-readable
codeand human-readablemessage - Authentication required on all endpoints except
/healthand/auth/* - Rate limiting: 100 requests/minute per user for standard endpoints
Database¶
- All queries go through the repository layer (
src/app/repositories/) - Never write raw SQL in route handlers or service functions
- Use parameterized queries only (never string interpolation)
- All tables must have
created_atandupdated_attimestamps
Templates¶
- HTMX partials go in
templates/partials/ - Full pages go in
templates/pages/ - Shared components go in
templates/components/ - Use
hx-boostfor navigation,hx-swapfor partial updates
Testing¶
- Every service function has at least one unit test
- Integration tests use a test database (not mocks) for database operations
- Test names follow:
test_{function_name}_{scenario}_{expected_outcome} - Fixtures in
conftest.py, not duplicated across test files
Architecture Decisions¶
- Three-layer architecture: Routes (thin) -> Services (business logic) -> Repositories (data access). Routes never call repositories directly.
- No ORM queries in services: Services call repository methods. This keeps the data access layer swappable and testable.
- HTMX over React: We chose HTMX for simplicity. No build step, no client-side state management. Server renders HTML. This is a deliberate trade-off: less interactivity, dramatically less complexity.
- PostgreSQL for everything: Including vector search (pgvector). We will not add a separate vector database until we exceed 5 million embeddings or 500 QPS on vector queries.
Common Pitfalls¶
- The
auth_requireddecorator must be the outermost decorator on any route that needs authentication. Putting it after@validate_inputskips auth checks. - Redis connections use a pool. Never create new connections per request. Use
extensions.redis_client. - Database migrations must be reversible. Always include
downgrade()logic. - HTMX partial responses must NOT include the base layout. Check
request.headers.get('HX-Request')to determine response type.
Environment Variables¶
Required in production:
- DATABASE_URL -- PostgreSQL connection string
- REDIS_URL -- Redis connection string
- SECRET_KEY -- Flask session secret (32+ random bytes)
- API_KEY -- External API authentication
Never hardcode these values. Always read from config.py.