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:
@@ -17,7 +17,7 @@ from fastapi import APIRouter, Path
|
||||
|
||||
from app.dependencies import (
|
||||
AuthDep,
|
||||
DbDep,
|
||||
BanServiceContextDep,
|
||||
Fail2BanSocketDep,
|
||||
HttpSessionDep,
|
||||
)
|
||||
@@ -83,7 +83,7 @@ async def lookup_ip(
|
||||
)
|
||||
async def geo_stats(
|
||||
_auth: AuthDep,
|
||||
db: DbDep,
|
||||
ban_ctx: BanServiceContextDep,
|
||||
) -> GeoCacheStatsResponse:
|
||||
"""Return diagnostic counters for the geo cache subsystem.
|
||||
|
||||
@@ -91,12 +91,12 @@ async def geo_stats(
|
||||
|
||||
Args:
|
||||
_auth: Validated session — enforces authentication.
|
||||
db: BanGUI application database connection.
|
||||
ban_ctx: Ban service context containing db and repository.
|
||||
|
||||
Returns:
|
||||
:class:`~app.models.geo.GeoCacheStatsResponse` with current counters.
|
||||
"""
|
||||
stats: dict[str, int] = await geo_service.cache_stats(db)
|
||||
stats: dict[str, int] = await geo_service.cache_stats(ban_ctx.db)
|
||||
return GeoCacheStatsResponse(**stats)
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ async def geo_stats(
|
||||
)
|
||||
async def re_resolve_geo(
|
||||
_auth: AuthDep,
|
||||
db: DbDep,
|
||||
ban_ctx: BanServiceContextDep,
|
||||
http_session: HttpSessionDep,
|
||||
) -> GeoReResolveResponse:
|
||||
"""Retry geo resolution for every IP in ``geo_cache`` with a null country.
|
||||
@@ -117,10 +117,10 @@ async def re_resolve_geo(
|
||||
|
||||
Args:
|
||||
_auth: Validated session — enforces authentication.
|
||||
db: BanGUI application database (for reading/writing ``geo_cache``).
|
||||
ban_ctx: Ban service context containing db and repository.
|
||||
http_session: Shared HTTP session for geo lookups.
|
||||
|
||||
Returns:
|
||||
A :class:`~app.models.geo.GeoReResolveResponse` with retry counts.
|
||||
"""
|
||||
return await geo_service.re_resolve_all(db, http_session)
|
||||
return await geo_service.re_resolve_all(ban_ctx.db, http_session)
|
||||
|
||||
Reference in New Issue
Block a user