Files
eryao/.trellis/spec/backend/directory-structure.md
T

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.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: <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