Expense Manager Service Architecture
The expense manager service is built with FastAPI, following Clean Architecture principles.
Folder Structure (Backend)β
expense-manager-service/
βββ .coveragerc # Test coverage config
βββ .dockerignore # Docker ignore file
βββ .env # Environment variables (for local development)
βββ .env.sample # Sample env file for reference
βββ .gitignore # Git ignore file
βββ Dockerfile # Dockerfile for containerizing the app
βββ mypy.ini # Mypy config (static type checking)
βββ pyproject.toml # Project metadata and dependencies
βββ pytest.ini # Pytest configurations
βββ README.md # Project documentation
βββ ruff.toml # Ruff config (linting)
βββ tox.ini # Tox config (testing in isolated environments)
βββ uv.lock # UV lock file (dependency management)
βββ app/ # Main application code
β βββ __init__.py
β βββ main.py # FastAPI app entrypoint
β βββ entities/ # Domain layer
β β βββ errors/ # Domain-specific errors
β β βββ models/ # Domain models
β β βββ repositories/ # Repository interfaces
β βββ infrastructures/ # Infrastructure layer (external systems)
β β βββ inmemory_db/ # In-memory DB implementations (for testing/dev)
β β βββ sqlite_db/ # SQLite DB implementations (for production)
β β βββ models/ # SQLAlchemy models
β βββ routers/ # Presentation/API layer
β β βββ v1/ # API version 1
β β β βββ endpoints/ # FastAPI routers
β β β βββ mappers/ # Mappers between schemas and entities
β β β βββ schemas/ # Pydantic schemas
β β β βββ services.py # Dependency injection
β β β βββ __init__.py
β β βββ __init__.py
β βββ settings/ # Configuration layer
β β βββ base.py # Base settings
β β βββ config.py # Config loader
β β βββ dev.py # Development settings
β β βββ __init__.py
β βββ use_cases/ # Use Cases layer (Business logic)
β βββ errors/ # Use-case-specific errors
β βββ models/ # Use-case-specific models
βββ docs/ # Documentation
βββ tests/ # Test cases
β βββ conftest.py # Pytest configurations at root
β βββ integration/ # Integration tests
| | βββ conftest.py # Pytest configurations at integration test level
β β βββ routers/
β β βββ v1/
β βββ unit/ # Unit tests
β βββ conftest.py # Pytest configurations at unit test level
β βββ settings.py
β βββ use_cases/
Layered Architecture & File-Level Detailsβ
The backend follows Clean Architecture principles, with each layer mapped to specific folders and files:
Domain Layer (app/entities/)β
- Purpose: Core business logic, domain models, and error definitions.
- Key Files:
models/*: Define immutable business entities (e.g.,AccountName).models/base.py: Base entity with common fields (e.g.,id).errors/: Custom exceptions for domain errors (e.g.,AccountNotFoundError).repositories/: Abstract repository interfaces (e.g.,AccountRepositoryInterface).
Use Cases Layer (app/use_cases/)β
- Purpose: Application-specific business logic and orchestration.
- Key Files:
- Service classes encapsulating business use cases (e.g.,
AccountService). models/: Use-case-specific models if needed.errors/: Use-case-specific errors, distinct from domain errors.
- Service classes encapsulating business use cases (e.g.,
Infrastructure Layer (app/infrastructures/)β
- Purpose: External system integration, persistence, and adapters.
- Key Files:
inmemory_db/: In-memory repository implementations for testing/dev.sqlite_db/: SQLite repository implementations and DB config (e.g.,accounts.py,database.py).
Presentation/API Layer (app/routers/)β
- Purpose: API endpoints, request/response schemas, and routing.
- Key Files:
v1/endpoints/: FastAPI routers for each resource (e.g.,accounts.py).v1/mappers/: Convert between schemas and entities. DTO not needed here as Schemas serve that purpose.v1/schemas/: Pydantic schemas for API requests/responses.v1/services.py: Dependency injection for repositories/services.
Configuration Layer (app/settings/)β
- Purpose: Environment and application configuration.
- Key Files:
base.py,dev.py,config.py: Settings for different environments, loaded via Pydantic.
Entrypointβ
main.py: FastAPI app initialization, middleware, and startup logic.
Testsβ
tests/: Unit and integration tests for all layers.
Technology Stack & Rationaleβ
- Python 3.13+: Backend technology.
- FastAPI: High-performance, async web framework for building APIs.
- Pydantic: Data validation and settings management.
- SQLAlchemy (async): Async ORM for database access (SQLite).
- Uvicorn: ASGI server for running FastAPI apps.
- UV: Dependency management.
- Mypy: Static type checking.
- Pytest: Testing framework.
- Tox: Testing in isolated environments.
- Ruff: Linting and code quality.
- Clean Architecture: Promotes separation of concerns, testability, and maintainability.
- In-memory, SQLite & PostgreSQL Repositories: Support for both development/testing and production persistence.
Notes & Best Practicesβ
- Dependency Rule: Outer layers (API, Infrastructure) depend on inner layers (Use Cases, Entities), never the reverse.
- Extensibility: Add new features by extending the appropriate layer, maintaining separation of concerns.
- Configuration: Environment-specific settings are managed in
settings/and.envfiles. - Testing: All tests are in
tests/.
info
This structure ensures maintainability, testability, and clear separation of concerns as the service evolves.