5.0 KiB
5.0 KiB
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/<module>/
├── __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.pydefines/agentendpointsservice.pyenforces authz (ensure_session_owner) and coordinates repositoriesrepository.pyhandles 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:
<entity>_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/
# 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/
# schemas/domain/chat_message.py
class AgentChatMessageMetadata(BaseModel):
role: str
content: str
# ... business fields