Enforce repository boundary: Remove DbDep from routers

This commit enforces the repository boundary by eliminating direct database connection
dependencies (DbDep) from all routers. Routers now depend on service context dependencies
that combine the database connection with the related repositories.

Changes:
- Add 5 service context dependencies in dependencies.py:
  * SessionServiceContext: db + session_repo
  * BlocklistServiceContext: db + blocklist_repo + import_log_repo + settings_repo
  * SettingsServiceContext: db + settings_repo
  * BanServiceContext: db + fail2ban_db_repo
  * HistoryServiceContext: db + fail2ban_db_repo + history_archive_repo

- Refactor all 9 routers (auth, bans, blocklist, config_misc, dashboard, geo,
  history, jails, setup) to use service contexts instead of DbDep.

- Update Backend-Development.md with clear examples of the new pattern and
  documentation of available service contexts.

Rationale:
- Enforces the repository boundary through the dependency system
- Makes database operations explicit and auditable
- Improves testability by allowing service contexts to be mocked
- Prevents accidental direct database access from routers

The deprecated DbDep remains available for backward compatibility with
services that have not yet been refactored, but routers can no longer import it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-28 07:35:23 +02:00
parent 813cf09bed
commit 507f153ab9
11 changed files with 318 additions and 105 deletions

View File

@@ -8,9 +8,9 @@ from fastapi import APIRouter, HTTPException, Query, Request, status
from app.dependencies import (
AuthDep,
DbDep,
Fail2BanSocketDep,
Fail2BanStartCommandDep,
SettingsServiceContextDep,
)
from app.models.config import (
Fail2BanLogResponse,
@@ -241,19 +241,20 @@ async def preview_log(
async def get_map_color_thresholds(
_request: Request,
_auth: AuthDep,
db: DbDep,
settings_ctx: SettingsServiceContextDep,
) -> MapColorThresholdsResponse:
"""Return the configured map color thresholds.
Args:
request: FastAPI request object.
_request: FastAPI request object.
_auth: Validated session.
settings_ctx: Settings service context containing db and repository.
Returns:
:class:`~app.models.config.MapColorThresholdsResponse` with
current thresholds.
"""
return await config_service.get_map_color_thresholds(db)
return await config_service.get_map_color_thresholds(settings_ctx.db)
@router.put(
"/map-color-thresholds",
@@ -263,14 +264,15 @@ async def get_map_color_thresholds(
async def update_map_color_thresholds(
_request: Request,
_auth: AuthDep,
db: DbDep,
settings_ctx: SettingsServiceContextDep,
body: MapColorThresholdsUpdate,
) -> MapColorThresholdsResponse:
"""Update the map color threshold configuration.
Args:
request: FastAPI request object.
_request: FastAPI request object.
_auth: Validated session.
settings_ctx: Settings service context containing db and repository.
body: New threshold values.
Returns:
@@ -281,8 +283,8 @@ async def update_map_color_thresholds(
HTTPException: 400 if validation fails (thresholds not
properly ordered).
"""
await config_service.update_map_color_thresholds(db, body)
return await config_service.get_map_color_thresholds(db)
await config_service.update_map_color_thresholds(settings_ctx.db, body)
return await config_service.get_map_color_thresholds(settings_ctx.db)
@router.get(