Architecture Overview
This section contains architecture diagrams and documentation for full-stack-fastapi-template.
Available Diagrams
System Context Diagram for Full-Stack FastAPI Template
This system context diagram provides a high-level overview of the full-stack application template. It illustrates how users and administrators interact with the system through a Traefik Proxy Architecture reverse proxy, which routes traffic to the Frontend Framework Architecture frontend and FastAPI Backend Architecture backend. The backend manages data persistence via a Database Connection Strings database and integrates with external services for email notifications and error tracking.
Key architectural features discovered:
- Traefik acts as the entry point, handling SSL termination via Let's Encrypt and routing requests based on hostnames (e.g.,
api.domainvsdashboard.domain). - The React Frontend is a single-page application served by Nginx, communicating with the backend via RESTful API calls.
- The FastAPI Backend implements the core business logic, using SQLModel for database interactions and JWT for authentication.
- External Integrations include an SMTP Email Service for transactional emails (password resets, etc.) and Sentry for real-time error monitoring.
- Adminer is provided as an internal tool for direct database management.
Key Architectural Findings:
- Traefik serves as the primary entry point, managing routing and automated SSL certificates via Let's Encrypt.
- The React frontend is served by Nginx and interacts with the FastAPI backend through a versioned API (/api/v1).
- PostgreSQL is the primary data store, with SQLModel providing the ORM layer in the backend.
- Transactional emails are handled via an external SMTP service, configured through environment variables.
- Sentry is integrated into the FastAPI application for production error tracking and performance monitoring.
- The system includes an Adminer container for database administration, accessible through the reverse proxy.
Component Architecture of Frontend and Backend
The component architecture of this monorepo follows a modern full-stack pattern with a decoupled frontend and backend.
The Frontend is built with React and uses TanStack Router for client-side navigation. Data fetching and state management are handled by TanStack Query, which interacts with an auto-generated API Client (SDK). This SDK is produced from the backend's OpenAPI specification, ensuring type safety across the network boundary.
The Backend is a FastAPI application. It organizes logic into API Routes which handle incoming HTTP requests. These routes utilize FastAPI's dependency injection system for authentication and database session management. The CRUD Layer contains reusable logic for database interactions, while SQLModel serves a dual purpose: defining the database schema (SQLAlchemy) and the API data transfer objects (Pydantic).
The system persists data in a PostgreSQL database and includes utility services for tasks like sending emails. The entire stack is containerized using Docker Compose for consistent development and deployment environments.
Key Architectural Findings:
- The project uses SQLModel to unify SQLAlchemy models and Pydantic schemas, reducing boilerplate.
- Frontend data fetching is powered by TanStack Query, which consumes an auto-generated TypeScript SDK.
- FastAPI dependencies (SessionDep, CurrentUser) are used to inject database sessions and authenticated users into routes.
- The frontend uses TanStack Router for type-safe routing and Shadcn UI for component styling.
- Alembic is used for database migrations, while the CRUD layer provides a clean abstraction for data operations.
User Authentication and Data Retrieval Flow
This sequence diagram illustrates the end-to-end flow for user authentication and protected data retrieval in the FastAPI/React application.
The Login Flow begins with the user providing credentials to the UI Framework & Theming, which uses a generated Global Client Configuration to send a request to the login_access_token endpoint. The API Communication Layer authenticates the user against the Database Schema and Table Definitions using crud.authenticate and generates a JWT token via security.create_access_token. This token is then stored in the browser's localStorage.
The Data Retrieval Flow demonstrates how subsequent requests (like fetching items) are authorized. The Global Client Configuration automatically attaches the stored JWT to the Authorization header. The Token Validation and Security (implemented as a FastAPI dependency get_current_user) intercepts the request, validates the token, and retrieves the user from the Database Schema and Table Definitions. Finally, the route handler (read_items) executes the business logic to fetch the requested data.
Key Architectural Findings:
- Authentication is implemented using OAuth2 password flow with JWT tokens.
- The frontend stores the access token in
localStorageand retrieves it for every request via theOpenAPI.TOKENconfiguration. - Backend authorization is handled by the
get_current_userdependency, which decodes the JWT and verifies the user exists in the database. - Database interactions use SQLModel for both authentication (user lookup) and data retrieval (item queries).
- Password security is managed using the
pwdliblibrary with Argon2/Bcrypt hashing.
Domain Entity Relationship Diagram
The data model for this full-stack application is built using Data Models, which integrates SQLAlchemy ORM with Pydantic validation. The core of the domain consists of two primary database entities: User and Item.
Key Entities
- User: Represents a registered user in the system. It includes authentication details (
email,hashed_password), authorization flags (is_active,is_superuser), and profile information (full_name). Users are uniquely identified by aUUID. - Item: Represents a resource owned by a user. Each item has a
title, an optionaldescription, and a timestamp. It is linked to aUservia a foreign key. - Token: A non-persistent model used for authentication responses, containing the JWT
access_token. - Message: A utility model used for generic API responses (e.g., success messages).
Relationships
- User to Item: A one-to-many relationship where one
Usercan own multipleItems. This is enforced by a foreign key constraint onitem.owner_idwith a cascade delete policy, meaning if a user is deleted, all their items are also removed. - Authentication: While not a direct database relationship, the
TokenPayload(decoded from the JWT) contains asubfield that corresponds to theUser.id, allowing the system to identify the current user for each request.
Key Architectural Findings:
- The codebase uses SQLModel to define both database tables and API schemas in a single class definition.
- Primary keys were migrated from Integers to UUIDs to improve security and scalability.
- The User entity includes both authentication (hashed_password) and authorization (is_superuser) fields.
- A one-to-many relationship exists between User and Item, with cascade delete enabled at the database level.
- Utility models like Token and Message are used for standardized API communication but are not persisted in the database.
Dockerized Deployment Architecture with Traefik Proxy
The deployment architecture for this template is centered around a containerized setup managed by Docker Compose, with Traefik serving as the primary entry point and reverse proxy.
Key Components:
- Traefik Proxy: Acts as the gateway for all incoming traffic. It handles SSL termination via Let's Encrypt and routes requests to the appropriate services based on subdomains (e.g.,
api.,dashboard.,adminer.). - Frontend: A React application built with Vite and served by an Nginx container. It communicates with the backend via the public API URL.
- Backend: A FastAPI application running with multiple workers. It handles the core business logic, authentication, and database interactions.
- PostgreSQL: The primary relational database for the system, persisted via a Docker volume.
- Adminer: A lightweight database management tool providing a web interface for the PostgreSQL database.
- Prestart: A one-off container that runs database migrations (using Alembic Environment) and initialization scripts before the backend service starts.
Infrastructure & Connectivity:
- Docker Networks: Services are connected via a
traefik-publicnetwork for external access and adefaultnetwork for internal communication. - External Services: The backend is configured to integrate with Sentry for error tracking and an SMTP server for sending emails (e.g., password resets).
- CI/CD: Deployment is automated via GitHub Actions using self-hosted runners on the target server, supporting both
stagingandproductionenvironments.
Key Architectural Findings:
- Traefik is used as the reverse proxy and SSL terminator, routing traffic to subdomains.
- The frontend is a static React app served by Nginx.
- The backend is a FastAPI service running with 4 workers.
- A 'prestart' service handles database migrations before the backend starts.
- PostgreSQL is the primary database, with Adminer provided for management.
- The setup supports multi-environment deployments (staging/production) on a single server.
User Account and Item Lifecycle States
This state diagram illustrates the lifecycle and states of User Accounts and Items within the system.
User Account States
The User Account Lifecycle States state is primarily governed by two boolean flags: is_active and is_superuser.
- Active: The default state for new users (via signup or admin creation). Active users can log in, manage their own items, and reset their passwords.
- Inactive: A state where the user account exists but is disabled. Inactive users are blocked from logging in or performing any actions, including password recovery.
- Superuser: A privileged state that allows the user to access administrative routes, manage other users, and view all items in the system.
Item Lifecycle
The Item Model lifecycle follows a standard CRUD pattern but is tightly coupled with the User who owns it.
- Created: The initial state when an item is added to the system.
- Updated: Items can be modified multiple times by their owner or a superuser.
- Deleted: Items can be removed explicitly or automatically via a cascade delete if the owner's account is removed.
Key Constraints
- Authentication Guard: The
is_activeflag is checked during every authenticated request. - Self-Deletion Protection: Superusers are prevented from deleting their own accounts to ensure at least one administrator remains.
- Cascade Deletion: Deleting a user automatically transitions all their associated items to the deleted state.
Key Architectural Findings:
- User accounts have three primary states based on
is_activeandis_superuserflags. - The
is_activeflag serves as a global guard; inactive users cannot authenticate or reset passwords. - Superusers have a distinct state allowing them to manage other users and all items.
- Items follow a simple lifecycle of Created -> Updated -> Deleted.
- Item deletion is linked to the User lifecycle via SQLAlchemy cascade deletes.
- Superusers are restricted from self-deletion to prevent system lockout.