Spaces:
Paused
Paused
Developer Migration Guide - From database_service to Domain Services
Effective Date: 2026-01-15
Breaking Changes: None (backward compatible)
Recommended Action: Update code to use domain services
π Quick Start
Before (β Old Way)
from app.services.infrastructure.storage.database_service import db_service
# Getting cases
cases = db_service.get_cases_paginated(page=1, per_page=20)
# Creating a case
case = db_service.create_case(case_data, creator_id="user123")
# Getting analytics
stats = db_service.get_case_analytics(date_from, date_to)
After (β New Way)
from app.modules.cases.service import case_service
from app.modules.analytics.service import analytics_service
from core.database import get_db
db = next(get_db())
# Getting cases
cases = case_service.get_cases_paginated(db, page=1, per_page=20, filters={})
# Creating a case
case = case_service.create_case(db, case_data, creator_id="user123")
# Getting analytics
stats = analytics_service.get_case_analytics(db, date_from, date_to)
π Complete Migration Map
Cases β case_service
| Old Method | New Method | Import |
|---|---|---|
db_service.get_cases() |
case_service.get_cases_paginated() |
from app.modules.cases.service import case_service |
db_service.get_cases_paginated() |
case_service.get_cases_paginated() |
Same |
db_service.get_case() |
case_service.get_case() |
Same |
db_service.create_case() |
case_service.create_case() |
Same |
db_service.update_case() |
case_service.update_case() |
Same |
db_service.delete_case() |
case_service.delete_case() |
Same |
db_service.get_case_stats() |
case_service.get_case_stats() |
Same |
db_service.add_case_note() |
case_service.add_note() |
Same |
db_service.get_case_notes() |
case_service.get_notes() |
Same |
Users β user_service
| Old Method | New Method | Import |
|---|---|---|
db_service.get_users_paginated() |
user_service.get_paginated() |
from app.modules.users.service import user_service |
db_service.get_user() |
user_service.get_user() |
Same |
db_service.update_user() |
user_service.update_user() |
Same |
db_service.delete_user() |
user_service.delete_user() |
Same |
Transactions β transaction_service β NEW
| Old Method | New Method | Import |
|---|---|---|
db_service.get_transactions_by_case() |
transaction_service.get_transactions_by_case() |
from app.modules.transactions.service import transaction_service |
db_service.create_transaction() |
transaction_service.create_transaction() |
Same |
db_service.update_transaction_status() |
transaction_service.update_transaction_status() |
Same |
Analytics β analytics_service
| Old Method | New Method | Import |
|---|---|---|
db_service.get_case_analytics() |
analytics_service.get_case_analytics() |
from app.modules.analytics.service import analytics_service |
db_service.get_transaction_aggregates() |
analytics_service.get_transaction_aggregates() |
Same |
Evidence β evidence_service
| Old Method | New Method | Import |
|---|---|---|
db_service.get_evidence_by_case() |
evidence_service.get_evidence_paginated() |
from app.modules.evidence.service import evidence_service |
db_service.create_evidence() |
evidence_service.process_file() |
Same |
π§ Infrastructure Methods (Still in database_service)
These methods remain in database_service - they are infrastructure, not business logic:
from app.services.infrastructure.storage.database_service import db_service
# β
These are CORRECT uses of db_service:
db = db_service.get_db() # Get database session
health = db_service.health_check() # Check DB health
stats = db_service.get_database_stats() # DB metrics
cache_stats = db_service.get_cache_stats() # Cache info
db_service.clear_all_cache() # Clear cache
π οΈ Step-by-Step Migration
1. Identify Usage
Search your codebase:
grep -r "db_service\." backend/app/ --include="*.py"
2. For Each File
Example file: app/modules/reports/service.py
Before
from app.services.infrastructure.storage.database_service import db_service
class ReportService:
def generate_case_report(self, case_id):
case = db_service.get_case(case_id) # β Business logic in infrastructure
transactions = db_service.get_transactions_by_case(case_id) # β
return self._format_report(case, transactions)
After
from app.modules.cases.service import case_service
from app.modules.transactions.service import transaction_service
from core.database import get_db
from fastapi import Depends
from sqlalchemy.orm import Session
class ReportService:
def generate_case_report(self, case_id: str, db: Session):
case = case_service.get_case(db, case_id) # β
Domain service
transactions = transaction_service.get_transactions_by_case(db, case_id) # β
return self._format_report(case, transactions)
3. Update FastAPI Routes
Before
@router.get("/cases/{case_id}")
async def get_case(case_id: str):
from app.services.infrastructure.storage.database_service import db_service
case = db_service.get_case(case_id) # β
return case
After
@router.get("/cases/{case_id}")
async def get_case(
case_id: str,
db: Session = Depends(get_db)
):
from app.modules.cases.service import case_service
case = case_service.get_case(db, case_id) # β
return case
β οΈ Common Pitfalls
1. Forgetting to Pass db Session
β Wrong:
case_service.get_case(case_id) # Missing db parameter!
β Correct:
case_service.get_case(db, case_id)
2. Using database_service for Business Logic
β Wrong:
# In a new feature
from app.services.infrastructure.storage.database_service import db_service
cases = db_service.get_cases() # Don't add new business logic here!
β Correct:
# Use domain service
from app.modules.cases.service import case_service
cases = case_service.get_cases_paginated(db, ...)
3. Not Importing Domain Services
β Wrong:
from app.services.infrastructure.storage.database_service import case_service # Doesn't exist!
β Correct:
from app.modules.cases.service import case_service # In modules/
π§ͺ Testing After Migration
1. Unit Tests
def test_get_case(db_session):
from app.modules.cases.service import case_service
# Create test data
case = case_service.create_case(db_session, {...})
# Test retrieval
retrieved = case_service.get_case(db_session, case.id)
assert retrieved.id == case.id
2. Integration Tests
def test_case_endpoint(test_client):
response = test_client.get("/api/v1/cases?page=1&per_page=20")
assert response.status_code == 200
assert "cases" in response.json()
π Rollout Strategy
Phase 1: Non-Breaking (Current)
- β All domain services created
- β database_service still works (infrastructure only)
- β Both old and new code work
Phase 2: Migration (This Week)
- Update routers to use domain services
- Update internal services
- Update tests
Phase 3: Cleanup (Next Week)
- Remove deprecated db_service methods (if any remain)
- Final testing
- Documentation update
π Need Help?
Decision Tree
Q: Should I use database_service?
- Is it for getting a database session? β β
Yes, use
db_service.get_db() - Is it for health checks/monitoring? β β
Yes, use
db_service.health_check() - Is it for business data (cases, users, etc.)? β β No, use domain service
Q: Which domain service should I use?
- Cases/investigations? β
case_service - Users/authentication? β
user_service - Transactions? β
transaction_service - Analytics/reports? β
analytics_service - Evidence/files? β
evidence_service
Reference Documentation
β Checklist
Before marking migration complete:
- All
db_servicecalls for business logic replaced - Only infrastructure methods use
db_service - All imports updated
- Tests passing
- No lint errors
- Documentation updated
Status: Active Migration
Contact: Backend Team
Last Updated: 2026-01-15