Overview
The Water Quality Backend API is built using the Vertical Slice Architecture pattern, which organizes code by feature rather than by technical layer. This approach improves modularity, maintainability, and allows teams to work on features independently.Vertical Slice Architecture
What is Vertical Slice Architecture?
Unlike traditional layered architecture (presentation → business logic → data access), Vertical Slice Architecture organizes code by feature or use case. Each feature contains all the layers it needs to function independently. Benefits:- Feature Cohesion: All code related to a feature is in one place
- Reduced Coupling: Features don’t share business logic across boundaries
- Easier Testing: Each feature can be tested in isolation
- Faster Development: Teams can work on different features without conflicts
- Clear Boundaries: Feature responsibilities are well-defined
Project Structure
The API is organized into feature modules underapp/features/:
Feature Module Organization
Each feature follows a consistent internal structure:Standard Structure
Layer Responsibilities
Domain Layer
Domain Layer
Contains the core business logic and models:
- Models: Pydantic models representing business entities
- DTOs: Request/response data transfer objects
- Errors: Custom exceptions specific to the feature
- Repository Interfaces: Abstract contracts for data access
Infrastructure Layer
Infrastructure Layer
Handles external dependencies and data persistence:
- Repository Implementations: Concrete implementations using Firebase, databases, etc.
- External Services: Integration with third-party APIs (weather, notifications)
- Data Mapping: Converts between domain models and persistence formats
Presentation Layer
Presentation Layer
Exposes the API and handles HTTP concerns:
- Routes: FastAPI endpoint definitions with request/response handling
- Dependencies: Dependency injection setup for FastAPI
- Validation: Request validation using Pydantic
- Error Handling: HTTP exception mapping
Services Layer
Services Layer
Orchestrates business logic across the domain:
- Use Case Implementation: Coordinates domain models and repositories
- Business Rules: Enforces complex business logic
- Transaction Management: Handles multi-step operations
Feature Modules
Auth Module
Location:app/features/auth/
Responsibilities:
- User registration and login
- JWT token generation and validation
- GitHub OAuth integration
- Password reset flow
- Firebase authentication integration
services/services.py: Authentication business logicpresentation/routes.py: Auth endpoints (/auth/login,/auth/register,/auth/github/*)
Workspaces Module
Location:app/features/workspaces/
Responsibilities:
- Multi-tenant workspace management
- Workspace creation and configuration
- User workspace associations
- Workspace-level permissions
Meters Module
Location:app/features/meters/
Responsibilities:
- Water meter device registration
- Meter readings and measurements
- Meter configuration and calibration
- Real-time data streaming
Alerts Module
Location:app/features/alerts/
Responsibilities:
- Alert rule configuration
- Threshold monitoring
- Alert notifications (OneSignal, Email)
- Alert history and acknowledgment
Users Module
Location:app/features/users/
Responsibilities:
- User profile management
- User preferences and settings
- Role and permission management
Analysis Module
Location:app/features/analysis/
Responsibilities:
- Water quality analysis
- Machine learning predictions
- Statistical analysis of readings
- Report generation (PDF)
- Integration with AI models (OpenRouter)
Monitoring Module
Location:app/features/monitoring/
Responsibilities:
- System health checks
- Prometheus metrics export
- Application performance monitoring
- Resource usage tracking
Request Flow
Here’s how a typical request flows through the architecture:Presentation Layer
- FastAPI route handler receives the request
- Request body is validated using Pydantic models
- Dependencies are injected (services, repositories, tokens)
Service Layer
- Route handler calls the appropriate service method
- Service orchestrates business logic
- Service uses repository interfaces to access data
Infrastructure Layer
- Repository implementation queries Firebase/database
- External APIs are called if needed (weather, AI)
- Data is mapped to domain models
Example Flow Diagram
Shared Infrastructure
Theapp/share/ directory contains cross-cutting concerns used by multiple features:
firebase/: Firebase Admin SDK initialization and configurationjwt/: JWT token creation and validation utilitiesoauth/: OAuth provider configurations (GitHub)socketio/: WebSocket server for real-time updatesemail/: Email sending utilities (Resend integration)users/: Shared user models and repository
Shared infrastructure should contain only generic utilities. Feature-specific logic should remain in the feature module.
Application Entry Point
The application is initialized inapp/__init__.py:
Best Practices
Keep Features Focused: Each feature should have a single, well-defined responsibility. If a feature grows too large, consider splitting it.
Guidelines
- Domain Purity: Keep domain layer free of framework dependencies
- Dependency Direction: Always point inward (Presentation → Services → Domain)
- Interface Abstraction: Use repository interfaces in services, not implementations
- Feature Independence: Each feature should be deployable independently (in theory)
- Shared Carefully: Only share truly generic utilities across features
Adding a New Feature
To add a new feature to the API:Technology Stack
- Framework: FastAPI (async Python web framework)
- Database: Firebase Realtime Database
- Authentication: Firebase Auth + JWT
- Real-time: Socket.IO for WebSocket connections
- AI/ML: scikit-learn, pandas, OpenRouter API
- Monitoring: Prometheus metrics
- Deployment: Docker, Uvicorn ASGI server
Next Steps
Authentication
Learn how to authenticate and authorize API requests
Deployment
Deploy the API using Docker and production configurations