refactor(ban_service): extract _bans_by_country_load_data helper

Break up long function into focused helper. Load data logic separate from aggregation.
This commit is contained in:
2026-05-03 17:00:34 +02:00
parent 5058a50143
commit 2df029f7e8
8 changed files with 458 additions and 321 deletions

View File

@@ -97,6 +97,7 @@ Note on field naming:
from typing import Generic, Literal, TypeVar
from pydantic import BaseModel, ConfigDict, Field
from typing_extensions import TypedDict
T = TypeVar("T")
@@ -318,7 +319,7 @@ class ErrorResponse(BanGuiBaseModel):
code: str = Field(..., description="Machine-readable error code for client-side branching.")
detail: str = Field(..., description="Human-readable error description.")
metadata: dict[str, str | int | float | bool | None] = Field(
metadata: "ErrorMetadata" = Field(
default_factory=dict,
description="Optional structured context for the error.",
)
@@ -328,6 +329,53 @@ class ErrorResponse(BanGuiBaseModel):
)
# ErrorMetadata must be defined after ErrorResponse due to Pydantic forward-ref resolution
# but before use at type-check time. This ordering is intentional.
class ErrorMetadata(TypedDict, total=False):
"""Typed metadata fields for error responses.
Allows type-safe access to known metadata keys in exception handlers.
Keys are optional — exceptions return only relevant fields.
Fields:
jail_name: Name of the jail involved in the error.
filename: Config filename involved in the error.
filter_name: Name of the filter involved in the error.
action_name: Name of the action involved in the error.
source_id: ID of a blocklist source involved in the error.
ip: IP address involved in the error.
pattern: Regex pattern that caused an error.
error: Regex compilation error message.
pattern_length: Actual length of an oversized pattern.
max_length: Maximum allowed length for a pattern.
timeout_seconds: Timeout value for regex compilation.
retry_after_seconds: Seconds to wait before retrying (rate limit errors).
socket_path: fail2ban socket path for connection errors.
current_status: Current jail status for conflict errors.
actual_length: Actual pattern length (alias for pattern_length).
message: Generic error message string.
"""
jail_name: str
filename: str
filter_name: str
action_name: str
source_id: int
ip: str
pattern: str
error: str
pattern_length: int
max_length: int
timeout_seconds: int
retry_after_seconds: float
socket_path: str
current_status: str
actual_length: int
message: str
class ComponentHealth(BanGuiBaseModel):
"""Health status of a single application component.