# Directory Structure > How backend code is organized in this project. --- ## Overview This project follows a **layered architecture** with clear separation of concerns: - **Schema → Repository → Service** layering pattern - Router layer for HTTP endpoints - Core infrastructure modules - Domain schemas for business models --- ## Directory Layout ``` backend/ ├── src/ │ ├── core/ # Infrastructure and cross-cutting concerns │ │ ├── agentscope/ # Agent runtime framework │ │ ├── auth/ # Authentication models and dependencies │ │ ├── config/ # Settings and configuration │ │ ├── db/ # Database base classes and session │ │ ├── http/ # HTTP utilities (errors, middleware) │ │ └── logging/ # Structured logging setup │ ├── models/ # SQLAlchemy ORM models │ ├── schemas/ # Business data models (Pydantic/dataclass) │ │ ├── agent/ # Agent-related schemas │ │ ├── domain/ # Domain objects │ │ └── ... │ ├── services/ # Shared infrastructure services │ │ ├── base/ # Base service interfaces │ │ ├── caches/ # Cache implementations │ │ └── llm_pricing/ # LLM pricing service │ └── v1/ # API v1 versioned modules │ ├── agent/ # Agent module │ ├── auth/ # Authentication module │ ├── memories/ # Memories module │ ├── points/ # Points module │ └── ... # Other modules ├── tests/ # Test suites ├── alembic/ # Database migrations │ └── versions/ # Migration files └── pyproject.toml # Project configuration ``` --- ## Module Organization Each module under `v1/` follows consistent structure: ``` v1// ├── __init__.py # Module exports ├── router.py # FastAPI router (HTTP endpoints) ├── schemas.py # Request/response schemas (Pydantic) ├── repository.py # Data access layer (CRUD + queries) ├── service.py # Business logic layer (authz + transactions) ├── dependencies.py # FastAPI dependencies (DI) └── utils.py # Module utilities (optional) ``` **Layering rules:** - **Router** → handles HTTP, calls service, returns response - **Service** → business logic, authz, transaction boundary, raises domain errors - **Repository** → CRUD + query composition only, no auth decisions **Example:** `v1/agent/` module: - `router.py` defines `/agent` endpoints - `service.py` enforces authz (`ensure_session_owner`) and coordinates repositories - `repository.py` handles database queries for agent sessions --- ## Naming Conventions ### Files - **snake_case**: Python files (e.g., `agent_service.py`) - **Module directories**: Singular or plural based on domain (e.g., `agent/`, `memories/`) ### Classes - **PascalCase**: Classes (`AgentService`, `AgentRepository`) - **Suffixes**: - `*Service` - Business logic layer - `*Repository` - Data access layer - `*Model` / `*Schema` - Data models (Pydantic) - `*Settings` - Configuration classes ### Functions/Variables - **snake_case**: Functions and variables (`get_by_id`, `soft_delete_by_id`) - **Private prefix**: `_` for internal methods (`_apply_soft_delete_filter`) ### Database Tables - **snake_case**: Table names (`agent_chat_session`, `llm_factory`) - **Timestamps**: `created_at`, `updated_at`, `deleted_at` (soft delete) - **Foreign keys**: `_id` (e.g., `factory_id`, `owner_id`) --- ## Examples ### Well-organized module: `v1/agent/` ``` v1/agent/ ├── router.py # HTTP endpoints, dependencies injection ├── service.py # Business logic, authz checks (ensure_session_owner) ├── repository.py # Database queries ├── schemas.py # Request/response DTOs ├── dependencies.py # Service instantiation (DI) ├── utils.py # Helper functions └── system_agents_config.py # Module config ``` ### Core infrastructure: `core/logging/` ``` core/logging/ ├── logger.py # get_logger() interface ├── config.py # Logging configuration ├── formatters.py # Structured log formatters ├── handlers.py # Log handlers ├── filters.py # Sensitive field filters └── middleware.py # Request logging middleware ``` ### ORM models: `models/` ```python # models/agent_chat_session.py class AgentChatSession(Base): __tablename__ = "agent_chat_session" id: Mapped[uuid.UUID] = ... owner_id: Mapped[uuid.UUID] = ... ``` ### Domain schemas: `schemas/domain/` ```python # schemas/domain/chat_message.py class AgentChatMessageMetadata(BaseModel): role: str content: str # ... business fields ```