feat: Complete repository protocol coverage

- Add missing protocol methods to Fail2BanDbRepository:
  - get_ban_event_counts: Aggregate ban events per IP (used in ban_service)

- Add missing protocol methods to GeoCacheRepository:
  - delete_stale_entries: Remove old geo cache entries (used in geo_cache_cleanup)

- Add missing protocol methods to HistoryArchiveRepository:
  - purge_archived_history: Remove archived entries older than age threshold

- Add comprehensive protocol compliance tests:
  - Created test_protocol_compliance.py with 8 test classes
  - Validates all 7 repository modules fully implement their protocols
  - Prevents silent protocol drift when methods change signatures
  - Tests verify no unexpected public methods in repository modules

- Update documentation:
  - Add Repository Protocol Coverage Checklist to Backend-Development.md
  - Document procedure for adding new repositories with protocol definitions
  - List current protocol coverage (all 7 repositories, 40 total methods)

- All repositories now have 100% protocol coverage:
  - SessionRepository: 4 methods
  - SettingsRepository: 4 methods
  - BlocklistRepository: 6 methods
  - ImportLogRepository: 4 methods
  - GeoCacheRepository: 13 methods
  - HistoryArchiveRepository: 5 methods
  - Fail2BanDbRepository: 8 methods

This ensures:
- Enhanced mockability for testing
- Static contract verification
- Prevention of protocol drift
- Better IDE support and type checking

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-28 07:58:57 +02:00
parent 52a4d04d92
commit a273b96563
3 changed files with 183 additions and 1 deletions

View File

@@ -1710,6 +1710,26 @@ async def get_session_repo() -> SessionRepository:
**How the validation works (CI check):**
- Before each deployment, run `mypy --strict` to ensure all dependency providers return values compatible with their Protocol types.
- The `cast()` calls in `dependencies.py` are a documented signal that structural compatibility is being verified externally, not via explicit class inheritance.
- Automated tests in `backend/tests/test_repositories/test_protocol_compliance.py` verify that each repository module implements all protocol methods, preventing silent protocol drift.
#### 13.7.1.1 Repository Protocol Coverage Checklist
All public repository functions must be defined in a corresponding Protocol. To add a new repository:
1. **Create the repository module** — `backend/app/repositories/my_repo.py` with async functions.
2. **Define the Protocol** — Add a `MyRepository(Protocol)` class in `backend/app/repositories/protocols.py` with methods matching every public function signature.
3. **Add imports** — If the Protocol uses custom return types, import them in `protocols.py`.
4. **Run compliance tests** — Execute `pytest backend/tests/test_repositories/test_protocol_compliance.py` to verify coverage.
5. **Verify type safety** — Run `mypy --strict backend/app/repositories/protocols.py` to ensure all types are correct.
**Current repository protocol coverage** (all 7 repositories fully covered):
- `SessionRepository` — 4 methods
- `SettingsRepository` — 4 methods
- `BlocklistRepository` — 6 methods
- `ImportLogRepository` — 4 methods
- `GeoCacheRepository` — 13 methods
- `HistoryArchiveRepository` — 5 methods
- `Fail2BanDbRepository` — 8 methods
#### 13.7.2 Session Token Hashing — One-Way Protection Against Database Exposure