Backend Project Structure
Clean, modular FastAPI backend designed for rapid development and scalability.
Directory Structure
starter-app/
├── apps/
│ ├── backend/ # FastAPI backend application
│ │ ├── src/
│ │ │ ├── main.py # FastAPI app & router setup
│ │ │ ├── models/ # API models
│ │ │ │ └── api_models.py # Pydantic API schemas
│ │ │ ├── routers/ # API endpoints by feature
│ │ │ │ ├── chat.py # AI chat interface
│ │ │ │ ├── ocr.py # Document processing
│ │ │ │ └── embedding.py # Vector search
│ │ │ └── utils/ # Authentication & helpers
│ │ └── pyproject.toml # Backend dependencies
│ ├── worker/ # Abraxas worker application
│ │ ├── src/
│ │ │ └── main.py # Worker entry point
│ │ └── pyproject.toml # Worker dependencies
│ └── frontend/ # Next.js frontend application
│ └── ...
├── common/ # Shared code across apps
│ ├── src/common/
│ │ ├── models/ # Database models
│ │ │ └── db_models.py # SQLModel database tables
│ │ ├── services/ # Business logic & integrations
│ │ │ ├── database_service.py # DB sessions
│ │ │ ├── mistral_service.py # AI API calls
│ │ │ └── file_storage/ # File storage providers
│ │ └── workflow/ # Abraxas workflows & activities
│ ├── alembic/ # Database migrations
│ ├── docker/ # PostgreSQL & Azurite setup
│ └── pyproject.toml # Common dependencies
├── pyproject.toml # Root workspace config
└── tasks.py # Invoke task runner
Architecture Overview
Data Flow:
Request → Router → Service → Database
↓
Response ← Pydantic ← SQLModel
Key Components:
apps/backend/src/main.py- FastAPI app, middleware, and router registrationapps/backend/src/models/- API schemas for request/response validationapps/backend/src/routers/- API endpoints organized by feature domainapps/backend/src/utils/- Authentication, validation, and shared helperscommon/src/common/models/- Shared database models (SQLModel)common/src/common/services/- Business logic, external APIs, and data accesscommon/src/common/workflow/- Long-running processes with Abraxasapps/worker/src/main.py- Abraxas worker for async processing
📊 Data Models
Database models (common/src/common/models/db_models.py):
class Task(ModelWithIdAndTimestamps, table=True):
title: str
completed: bool = Field(default=False)
user_id: UUID = Field(foreign_key="user.id")
API models (apps/backend/src/models/api_models.py):
# Auto-generated from base models
CreateTaskDTO = create_create_model(TaskBase, "CreateTask")
TaskDTO = create_read_model(TaskBase, "Task")
class UserWithTasks(UserBase):
tasks: list[TaskDTO]
Monorepo Benefits:
- Database models shared between backend and worker
- Services reused across applications
- Single source of truth for business logic
🔄 Background Processing
Workflows handle complex, multi-step processes:
@workflow
class DataProcessingWorkflow:
@workflow.run
async def run(self, user_id: int) -> dict:
# Multi-step process with automatic retries
pass
Worker (apps/worker/src/main.py) processes workflows in the background.
🛠️ Development Setup
Start services with Invoke:
# From project root
uvx invoke backend # Start FastAPI backend
uvx invoke worker # Start Abraxas worker
uvx invoke frontend # Start Next.js frontend
Database migrations:
# From project root
uvx invoke update-db # Apply migrations
uvx invoke create-db-migration "Add feature" # Create new migration
Local database:
docker-compose -p starter-app -f common/docker/docker-compose.yml up postgres -d
🎯 Design Principles
- Separation of concerns - Routes, services, models have distinct roles
- Dependency injection - Clean, testable service dependencies
- Type safety - SQLModel + Pydantic throughout the stack
- Feature organization - Related code grouped together
This structure scales from simple APIs to complex applications while keeping the codebase organized and maintainable.