refactor(backend): clean up jail service, add error handling service

- Extract jail status/processing to helper functions
- Add error_handling.py service for centralized error handling
- Update config.py with validation and defaults
- Update .env.example with all config options
- Remove obsolete Tasks.md, add Service-Development.md
- Minor fixes across routers and services

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-05-03 17:40:37 +02:00
parent 2df029f7e8
commit 2f9fc8076d
15 changed files with 332 additions and 154 deletions

View File

@@ -25,6 +25,7 @@ from app.dependencies import (
Fail2BanSocketDep,
HistoryServiceContextDep,
HttpSessionDep,
SettingsDep,
)
from app.exceptions import HistoryNotFoundError
from app.mappers import history_mappers
@@ -54,6 +55,7 @@ async def get_history(
socket_path: Fail2BanSocketDep,
http_session: HttpSessionDep,
fail2ban_metadata_service: Fail2BanMetadataServiceDep,
settings: SettingsDep,
range: TimeRange | None = Query(
default=None,
description="Optional time-range filter. Omit for all-time.",
@@ -78,8 +80,7 @@ async def get_history(
page_size: int = Query(
default=DEFAULT_PAGE_SIZE,
ge=1,
le=500,
description="Items per page (max 500).",
description="Items per page.",
),
) -> HistoryListResponse:
"""Return a paginated list of historical bans with optional filters.
@@ -114,6 +115,7 @@ async def get_history(
source=source,
page=page,
page_size=page_size,
max_page_size=settings.max_page_size,
http_session=http_session,
db=history_ctx.db,
fail2ban_metadata_service=fail2ban_metadata_service,
@@ -138,6 +140,7 @@ async def get_history_archive(
socket_path: Fail2BanSocketDep,
http_session: HttpSessionDep,
fail2ban_metadata_service: Fail2BanMetadataServiceDep,
settings: SettingsDep,
range: TimeRange | None = Query(
default=None,
description="Optional time-range filter. Omit for all-time.",
@@ -145,7 +148,7 @@ async def get_history_archive(
jail: str | None = Query(default=None, description="Restrict results to this jail name."),
ip: str | None = Query(default=None, description="Restrict results to IPs matching this prefix."),
page: int = Query(default=1, ge=1, description="1-based page number."),
page_size: int = Query(default=DEFAULT_PAGE_SIZE, ge=1, le=500, description="Items per page (max 500)."),
page_size: int = Query(default=DEFAULT_PAGE_SIZE, ge=1, description="Items per page."),
) -> HistoryListResponse:
domain_result = await history_service.list_history(
@@ -156,6 +159,7 @@ async def get_history_archive(
source="archive",
page=page,
page_size=page_size,
max_page_size=settings.max_page_size,
http_session=http_session,
db=history_ctx.db,
fail2ban_metadata_service=fail2ban_metadata_service,