Add jail distribution chart (Stage 5)
- backend: GET /api/dashboard/bans/by-jail endpoint - JailBanCount + BansByJailResponse Pydantic models in ban.py - bans_by_jail() service function with origin filter support - Route added to dashboard router - 17 new tests (7 service, 10 router); full suite 497 passed, 83% coverage - frontend: JailDistributionChart component - JailBanCount / BansByJailResponse types in types/ban.ts - dashboardBansByJail endpoint constant in api/endpoints.ts - fetchBansByJail() in api/dashboard.ts - useJailDistribution hook in hooks/useJailDistribution.ts - JailDistributionChart component (horizontal bar chart, Recharts) - DashboardPage: full-width Jail Distribution section below Top Countries
This commit is contained in:
@@ -280,3 +280,29 @@ class BanTrendResponse(BaseModel):
|
||||
...,
|
||||
description="Human-readable bucket size label (e.g. '1h', '6h', '1d', '7d').",
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# By-jail endpoint models
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class JailBanCount(BaseModel):
|
||||
"""A single jail entry in the bans-by-jail aggregation."""
|
||||
|
||||
model_config = ConfigDict(strict=True)
|
||||
|
||||
jail: str = Field(..., description="Jail name.")
|
||||
count: int = Field(..., ge=0, description="Number of bans recorded in this jail.")
|
||||
|
||||
|
||||
class BansByJailResponse(BaseModel):
|
||||
"""Response for the ``GET /api/dashboard/bans/by-jail`` endpoint."""
|
||||
|
||||
model_config = ConfigDict(strict=True)
|
||||
|
||||
jails: list[JailBanCount] = Field(
|
||||
default_factory=list,
|
||||
description="Jails ordered by ban count descending.",
|
||||
)
|
||||
total: int = Field(..., ge=0, description="Total ban count in the selected window.")
|
||||
|
||||
Reference in New Issue
Block a user