Backend Structure
The backend follows a clean layered architecture within the
backend/backend/ directory.
Directory Layout
backend/
├── pyproject.toml # Project metadata & dependencies
├── dockerfile # Multi-stage Docker build
├── backend/
│ ├── __init__.py
│ ├── dependencies.py # FastAPI dependency injection (auth, DB)
│ ├── permissions.py # Permission decorators & role checks
│ ├── api/
│ │ ├── main.py # FastAPI app factory & lifespan
│ │ ├── routers/ # HTTP route handlers
│ │ │ ├── project.py
│ │ │ ├── threads.py
│ │ │ ├── resources.py
│ │ │ ├── form_templates.py
│ │ │ ├── initial_diagnosis.py
│ │ │ └── users.py
│ │ └── schemas/ # Pydantic request/response models
│ ├── database/
│ │ ├── database.py # Engine & session factory
│ │ └── repositories/ # Generic CRUD repositories
│ ├── models/ # SQLAlchemy ORM models
│ │ ├── project.py
│ │ ├── user.py
│ │ ├── template_instance.py
│ │ ├── templates_phase1.py
│ │ ├── templates_phase2.py
│ │ ├── templates_phase3.py
│ │ └── templates_phase4.py
│ ├── service/ # Business logic
│ │ ├── project/
│ │ ├── template/
│ │ ├── user/
│ │ ├── chat/ # AI orchestrator & agents
│ │ ├── initial_diagnosis/
│ │ ├── form_templates/
│ │ ├── pdf/
│ │ └── project_maturity/
│ ├── utils/ # Shared utilities
│ └── tests/ # Test suite
└── migrations/ # Alembic database migrations
Layer Responsibilities
API Layer (api/)
Routers: Define HTTP endpoints, parse request parameters, return responses
Schemas: Pydantic models for request validation and response serialization
Main: Application factory, lifespan hooks, middleware setup
Service Layer (service/)
Contains all business logic
Orchestrates repository calls
Handles LLM integration, template generation, notifications
Each service is a class with async methods
Repository Layer (database/repositories/)
Generic base class with CRUD operations
One repository per model type
Async SQLAlchemy sessions
No business logic — pure data access
Models (models/)
SQLAlchemy ORM declarative models
Define table schemas, relationships, constraints
Organized by phase (templates_phase1.py, etc.)
Key Patterns
App Lifespan:
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup: DB init, orchestrator setup
await init_database()
await init_orchestrator()
yield
# Shutdown: cleanup
Dependency Injection:
@router.get("/projects")
async def list_projects(
user_id: str = Depends(get_current_user_id),
db: AsyncSession = Depends(get_db),
):
...
Repository Usage:
class ProjectService:
def __init__(self, db: AsyncSession):
self.repo = ProjectRepository(db)
async def create(self, data: ProjectCreate) -> Project:
project = Project(**data.dict())
return await self.repo.create(project)