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) | |
| ```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 | |