---
paths:
  - "cofee_backend/cpv3/**/*.py"
---

# Backend Module Rules

## Module Structure (strict — do not deviate)

Every module contains exactly these files — no more, no subdirectories:
```
modules/<module>/
├── __init__.py
├── models.py      # SQLAlchemy models
├── schemas.py     # Pydantic DTOs (*Create, *Update, *Read)
├── repository.py  # Database CRUD
├── service.py     # Business logic + Dramatiq actors
└── router.py      # FastAPI endpoints
```

When in doubt, put logic in `service.py`. Cross-cutting concerns go in `infrastructure/`, not in module subdirectories.

## Repository Pattern

- One repository per model, accepts `AsyncSession` in constructor.
- Filter soft-deleted records (`is_deleted`) by default.
- Methods should be atomic and focused.

## Schemas

- Inherit from `cpv3.common.schemas.Schema` (Pydantic with `from_attributes=True`).
- Suffix names: `*Create`, `*Update`, `*Read`.
- Use `Literal` types for enums with string values.

## Models

- Inherit from `Base` + `BaseModelMixin` (`cpv3.db.base`).
- Use explicit column types, add indexes for frequently queried fields.
- Soft deletes via `is_deleted` flag.

## Endpoints

- Use dependency injection for DB session (`get_db`), auth (`get_current_user`), and services.
- Return typed response models. Use appropriate HTTP status codes.

## Settings

- All config via `get_settings()` from `cpv3.infrastructure.settings.py` (cached with `@lru_cache`).
- Never hardcode configuration values.

## Style

- Python 3.11+, `from __future__ import annotations` for forward references.
- Line length: 100 characters (Ruff). Type hints on all function signatures.
- Async-first for I/O. Use `anyio.to_thread.run_sync` for CPU-bound work in async context.
- Store error messages as module-level constants with `ERROR_` prefix.
