zenith-backend / MIGRATION_GUIDE.md
teoat's picture
Upload folder using huggingface_hub
4ae946d verified
# 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)
```python
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)
```python
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:
```python
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:
```bash
grep -r "db_service\." backend/app/ --include="*.py"
```
### 2. For Each File
**Example file:** `app/modules/reports/service.py`
#### Before
```python
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
```python
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
```python
@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
```python
@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:**
```python
case_service.get_case(case_id) # Missing db parameter!
```
βœ… **Correct:**
```python
case_service.get_case(db, case_id)
```
### 2. Using database_service for Business Logic
❌ **Wrong:**
```python
# 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:**
```python
# Use domain service
from app.modules.cases.service import case_service
cases = case_service.get_cases_paginated(db, ...)
```
### 3. Not Importing Domain Services
❌ **Wrong:**
```python
from app.services.infrastructure.storage.database_service import case_service # Doesn't exist!
```
βœ… **Correct:**
```python
from app.modules.cases.service import case_service # In modules/
```
---
## πŸ§ͺ Testing After Migration
### 1. Unit Tests
```python
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
```python
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
- [Architecture Overview](./ARCHITECTURE.md)
- [Domain Services Guide](./ARCHITECTURE.md#domain-services)
- [API Documentation](./docs/API.md)
---
## βœ… Checklist
Before marking migration complete:
- [ ] All `db_service` calls 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