System Architecture
This document outlines the standard system architecture for backend applications, including the application structure, client layers, and backend topology.
High-Level Architecture
┌─────────────────────────────────────────────────────────────┐
│ Client Layer │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Client App 1 │ │ Client App 2 │ │
│ │ (e.g., Mobile) │ │ (e.g., Admin) │ │
│ │ │ │ │ │
│ └──────────────────┘ └──────────────────┘ │
└────────────────────────┬─────────────────┬──────────────────┘
│ │
│ HTTPS + SSE │ HTTPS
│ │
┌────────────────────────┴─────────────────┴──────────────────┐
│ FastAPI Backend (Service) │
│ Uvicorn Workers │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Main App (main.py) │ │
│ │ - Authentication & Authorization │ │
│ │ - Management APIs │ │
│ │ - Business Logic & CRUD │ │
│ │ - Background Workers (lifespan) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Secondary App (mounted at /subpath) │ │
│ │ - Public/Streaming APIs │ │
│ │ - Specialized Logic │ │
│ │ │ │
│ └──────────────────────────────────────────────────────┘ │
│ └────────────────────────────┬────────────────────────────────┘
│ │
│ ┌────────────────┼────────────────┐
│ │ │ │
│┌───────────┴───────┐ ┌─────┴──────┐ ┌──────┴────────┐
││ PostgreSQL │ │ LLM │ │ External │
││ (Database) │ │ Provider │ │ Services │
││ + pgvector │ │ │ │ │
│└───────────────────┘ └────────────┘ └───────────────┘
Client Applications
The architecture supports multiple client types:
- Real-time Clients: Connecting via SSE/WebSockets for updates.
- Admin Dashboards: Single Page Applications (SPAs) managing configuration and data.
- Mobile/Web Apps: Consuming RESTful endpoints.
Application Layers
1. API Layer (main.py + route handlers)
Main Application:
- RESTful API endpoints for core business logic
- Admin/management endpoints
- OAuth2 authentication with JWT tokens
- Rate limiting and security middleware
- CORS configuration
- Exception handling
Secondary/Mounted Applications (Optional):
- Separate FastAPI instances mounted at subpaths (e.g.,
/chat,/public) - Isolated middleware or auth requirements
- Specialized streaming endpoints
2. Business Logic Layer
Module Organization: Each business entity follows a consistent structure:
database/{entity}/
├── models.py # SQLAlchemy database models
├── schemas.py # Pydantic validation schemas
├── crud.py # Database CRUD operations
└── apis.py # FastAPI route handlers
Key Responsibilities:
- Input validation (Pydantic)
- Business rules enforcement
- Data transformation
- Authorization checks
- Transaction management
3. Data Access Layer
SQLAlchemy ORM:
- Declarative models with type hints
- Async database operations via asyncpg
- Connection pooling
- Query optimization
- Relationship management
Database Connection:
# database/database.py
engine = create_async_engine(DATABASE_URL)
SessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
4. AI Engine Layer (If Applicable)
Core Components:
- Orchestrator: Central logic handling LLM interactions (e.g., Pydantic AI)
- Agents: Specialized agents for specific tasks (routing, extraction, generation)
- Tools: Functions exposed to agents (database search, calculations, API calls)
Agent Processing Flow:
- Orchestrator receives input and context
- Agent selects tools based on intent
- Tools execute (queries, logic)
- Agent synthesizes response
- System returns: response text + metadata/flags
Data Flow Diagrams
Standard Request Flow
User Request
│
├─> /api/v1/resource
│
├─> Authentication Check (JWT)
│
├─> Rate Limiting (IP or User based)
│
├─> Input Validation (Pydantic)
│
├─> Authorization Check (RBAC/Ownership)
│
├─> Business Logic (CRUD)
│
└─> Database Operation
Authentication Flow
User Request
│
├─> Extract JWT from Authorization header
│
├─> Validate Token
│ ├─> Check signature
│ ├─> Check expiration
│ └─> Extract user_id
│
├─> Load User
│
├─> Check Permissions
│ ├─> User role check
│ └─> Resource access check
│
└─> Proceed with Request / Return 401/403
Module Dependencies
main.py
├─> database/
│ ├─> users/
│ ├─> [entity_a]/
│ └─> [entity_b]/
│
├─> utils/
│ ├─> auth.py
│ ├─> security.py
│ ├─> rate_limiter.py
│ └─> [other utilities]
│
├─> notifications/
│ ├─> email_sender.py
│ └─> sms_sender.py
│
└─> tasks/
├─> workers/
└─> setup/
Scalability Considerations
Horizontal Scaling
- Stateless application design
- Database connection pooling
- External session storage (Redis/DB) if needed
- Load balancer ready
Database Optimization
- Indexed queries
- Connection pooling
- Query result caching
- Vector index optimization (if using embeddings)
Background Workers
- Run as asyncio tasks in same process (simplifies deployment)
- Started via FastAPI lifespan events
- Concurrency control (lock files) for multi-worker setups
- Scheduled tasks for maintenance/cleanup
Caching Strategy
- Application-level caching where appropriate
- Database query caching
- Configuration caching
Deployment Architecture
Containerization
- Docker-based deployment
- Single service or microservices depending on scale
- Uvicorn workers for concurrency
Database
- PostgreSQL primary instance
- Connection pooling (SQLAlchemy + Pgbouncer if needed)
- Vector extension enabled (if using AI features)
Environment Separation
- local: Developer machines
- development: Staging/Test environment
- production: Live environment
Each environment has:
- Separate database instances
- Environment-specific configuration (env vars)
- Isolated API keys and secrets
Monitoring and Observability
Logging
- Structured logging (JSON preferred in prod)
- Request/response logging (with sensitive data redaction)
- Error tracking and reporting
Health Checks
- Database connectivity
- External service availability
- Worker status
Metrics
- API response times
- Database query performance
- Error rates