Spaces:
Paused
Backend Architecture - Domain-Driven Design
Last Updated: 2026-01-15
Status: Production Ready β
ποΈ Architecture Overview
The backend follows a clean domain-driven architecture with clear separation between infrastructure and business logic.
Layer Structure
Backend
βββ core/ # Shared kernel (models, database, config)
βββ app/
β βββ modules/ # Domain Services (Business Logic)
β β βββ auth/ # Authentication & authorization
β β βββ cases/ # Case management
β β βββ users/ # User management
β β βββ analytics/ # Analytics & reporting
β β βββ transactions/ # Transaction management
β β βββ evidence/ # Evidence handling
β βββ services/
β β βββ infrastructure/ # Infrastructure services
β β β βββ auth_service.py # JWT & auth (shim)
β β β βββ cache_service.py # Multi-layer caching
β β β βββ logging_service.py # Structured logging (shim)
β β β βββ rbac_service.py # Role-based access
β β β βββ storage/
β β β βββ database_service.py # DB infrastructure ONLY
β β βββ ai/ # AI & ML services
β βββ routers/ # API endpoints
βββ tests/ # Test suites
π― Core Principles
1. Domain-Driven Design
- Domain Services (
app/modules/*) contain ALL business logic - Infrastructure Services (
app/services/infrastructure/*) provide technical capabilities - Clear boundaries between domains
2. Single Responsibility
- Each service has ONE clear purpose
- No overlapping functionalities
- Business logic separated from infrastructure
3. Dependency Direction
Routers β Domain Services β Repositories β Database
β
Infrastructure Services (cache, logging, etc.)
π¦ Domain Services
Authentication (app/modules/auth/)
Purpose: User authentication, JWT tokens, MFA
Key Methods:
register_user()authenticate_user()verify_token()enable_mfa()
Router: app/modules/auth/router.py
Case Management (app/modules/cases/)
Purpose: Fraud case lifecycle management
Key Methods:
get_cases_paginated()- List cases with filterscreate_case()- Create new investigationupdate_case()- Modify case detailsget_case_stats()- Case statisticsadd_note()- Add case notesdelete_case()- Remove case
Router: app/modules/cases/router.py
Repository: CaseRepository (data access)
Service: CaseService (business logic)
User Management (app/modules/users/)
Purpose: User administration and preferences
Key Methods:
get_users_paginated()- List userscreate_user()- Register new userupdate_user()- Modify user dataupdate_preferences()- User settingsdelete_user()- Remove user
Router: app/modules/users/router.py
Analytics (app/modules/analytics/)
Purpose: Business intelligence and reporting
Key Methods:
get_case_analytics()- Case metrics over timeget_transaction_aggregates()- Transaction statsget_dashboard_data()- Dashboard metricsgenerate_risk_heatmaps()- Risk visualization
Router: app/modules/analytics/router.py
Transactions (app/modules/transactions/) β NEW
Purpose: Financial transaction management
Key Methods:
get_transactions_by_case()- List transactionscreate_transaction()- Add new transactionupdate_transaction_status()- Change statusget_transaction_aggregates()- Calculate totals
Router: TBD (can be added if needed)
Evidence (app/modules/evidence/)
Purpose: Digital evidence handling
Key Methods:
get_evidence_paginated()- List evidenceprocess_file()- Process uploaded filesdelete_evidence()- Remove evidence
Router: app/modules/evidence/router.py
π§ Infrastructure Services
Database Service (infrastructure/storage/database_service.py)
Purpose: INFRASTRUCTURE ONLY β οΈ
What it DOES:
- β
Session management (
get_db()) - β Connection pooling
- β
Health checks (
health_check()) - β Performance monitoring
- β Query caching utilities
What it DOES NOT do:
- β Business logic (moved to domain services)
- β Case/user/transaction queries (use domain services)
- β Data aggregations (use AnalyticsService)
Migration: All business methods β Domain services
Cache Service (infrastructure/cache_service.py)
Purpose: Multi-layer caching (memory + Redis)
Features:
- L1: Fast in-memory cache
- L2: Larger in-memory cache
- L3: Redis distributed cache
- Automatic namespace management
- Cache statistics
Logging Service (infrastructure/logging_service.py)
Purpose: Structured logging with PII scrubbing
Features:
- JSON formatted logs
- Automatic PII detection & masking
- Email, SSN, credit card scrubbing
- Context enrichment
RBAC Service (infrastructure/rbac_service.py)
Purpose: Role-based access control
Features:
- Role hierarchy
- Permission checking
- FastAPI dependencies for auth
π Data Flow
Typical Request Flow
1. HTTP Request
β
2. Router (FastAPI endpoint)
β
3. Authentication (auth_service.get_current_user)
β
4. Authorization (rbac_service.require_role)
β
5. Domain Service (business logic)
β
6. Repository (data access)
β
7. Database (via db_service.get_db)
β
8. Response
Example: Get Cases
# router.py
@router.get("/cases")
async def list_cases(
db: Session = Depends(get_db),
current_user: User = Depends(auth_service.get_current_user),
):
# Use domain service
from app.modules.cases.service import case_service
result = case_service.get_cases_paginated(
db, page=1, per_page=20, filters={}
)
return result
π Design Patterns
Repository Pattern
Location: app/modules/*/repository.py
Purpose: Encapsulate data access logic
Responsibilities:
- SQL queries
- ORM operations
- Data mapping
Example:
class CaseRepository:
def get_paginated(self, page, per_page, filters):
query = self.db.query(Case)
# Apply filters, pagination
return query.all(), query.count()
Service Pattern
Location: app/modules/*/service.py
Purpose: Business logic orchestration
Responsibilities:
- Business rules
- Validation
- Transaction management
- Calling repositories
Example:
class CaseService:
def create_case(self, db, data, creator_id):
repo = CaseRepository(db)
case = repo.create(data)
db.commit()
return case
Dependency Injection
Framework: FastAPI's Depends()
Common Dependencies:
get_db()- Database sessionauth_service.get_current_user()- Current authenticated userrbac_service.require_admin()- Role requirements
π Migration Guide
From database_service to Domain Services
β OLD WAY (Don't use)
from app.services.infrastructure.storage.database_service import db_service
# WRONG - business logic in infrastructure
cases = db_service.get_cases_paginated(page=1, per_page=20)
β NEW WAY (Correct)
from app.modules.cases.service import case_service
from core.database import get_db
# CORRECT - business logic in domain service
db = next(get_db())
cases = case_service.get_cases_paginated(db, page=1, per_page=20, filters={})
Quick Reference
| Old (database_service) | New (Domain Service) |
|---|---|
db_service.get_cases() |
case_service.get_cases_paginated() |
db_service.get_case_stats() |
case_service.get_case_stats() |
db_service.get_users_paginated() |
user_service.get_paginated() |
db_service.get_case_analytics() |
analytics_service.get_case_analytics() |
db_service.get_transaction_aggregates() |
analytics_service.get_transaction_aggregates() |
db_service.get_transactions_by_case() |
transaction_service.get_transactions_by_case() |
β Benefits of This Architecture
1. Maintainability
- Clear separation of concerns
- Easy to find where logic lives
- Single responsibility per service
2. Testability
- Mock repositories easily
- Test business logic independently
- Infrastructure tests separate
3. Scalability
- Services can be extracted to microservices
- Clear boundaries for team ownership
- Easy to add new domains
4. Security
- Business logic protected by service layer
- Consistent authorization patterns
- PII scrubbing at infrastructure level
5. Performance
- Caching at the right layer
- Query optimization in repositories
- Infrastructure monitoring separate from business
π Code Metrics
Before Consolidation
database_service.py: 1,086 lines (mixed business + infrastructure)- Overlapping cache services: 2 implementations
- Overlapping logging: 2 implementations
- Unused services: 6 files (~2,500 lines)
After Consolidation
database_service.py: ~270 lines (pure infrastructure)- Cache service: 1 unified implementation
- Logging service: 1 unified implementation + PII scrubbing
- Domain services: Clear separation across 6 modules
Impact
- 75% reduction in database_service.py
- ~3,000 lines removed (dead code)
- Zero overlapping functions
- Clean architecture achieved
π― Next Steps
For New Features
- Identify the domain (cases, users, transactions, etc.)
- Add methods to the appropriate domain service
- Create repository methods if needed
- Add router endpoints
- Write tests
For Existing Code
- Check if using
database_servicefor business logic - Migrate to appropriate domain service
- Update imports
- Test thoroughly
For Infrastructure
- Use
database_serviceONLY for:- Session management
- Health checks
- Performance monitoring
- Everything else β domain services
π Related Documentation
Architecture Status: β
Production Ready
Last Audit: 2026-01-15
Compliance: Clean Architecture, DDD, SOLID Principles