feat: Stage 1 — backend and frontend scaffolding
Backend (tasks 1.1, 1.5–1.8): - pyproject.toml with FastAPI, Pydantic v2, aiosqlite, APScheduler 3.x, structlog, bcrypt; ruff + mypy strict configured - Pydantic Settings (BANGUI_ prefix env vars, fail-fast validation) - SQLite schema: settings, sessions, blocklist_sources, import_log; WAL mode + foreign keys; idempotent init_db() - FastAPI app factory with lifespan (DB, aiohttp session, scheduler), CORS, unhandled-exception handler, GET /api/health - Fail2BanClient: async Unix-socket wrapper using run_in_executor, custom error types, async context manager - Utility modules: ip_utils, time_utils, constants - 47 tests; ruff 0 errors; mypy --strict 0 errors Frontend (tasks 1.2–1.4): - Vite + React 18 + TypeScript strict; Fluent UI v9; ESLint + Prettier - Custom brand theme (#0F6CBD, WCAG AA contrast) with light/dark variants - Typed fetch API client (ApiError, get/post/put/del) + endpoints constants - tsc --noEmit 0 errors
This commit is contained in:
78
backend/app/utils/constants.py
Normal file
78
backend/app/utils/constants.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""Application-wide constants.
|
||||
|
||||
All magic numbers, default paths, and limit values live here.
|
||||
Import from this module rather than hard-coding values in business logic.
|
||||
"""
|
||||
|
||||
from typing import Final
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# fail2ban integration
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DEFAULT_FAIL2BAN_SOCKET: Final[str] = "/var/run/fail2ban/fail2ban.sock"
|
||||
"""Default path to the fail2ban Unix domain socket."""
|
||||
|
||||
FAIL2BAN_SOCKET_TIMEOUT_SECONDS: Final[float] = 5.0
|
||||
"""Maximum seconds to wait for a response from the fail2ban socket."""
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Database
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DEFAULT_DATABASE_PATH: Final[str] = "bangui.db"
|
||||
"""Default filename for the BanGUI application SQLite database."""
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Authentication
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DEFAULT_SESSION_DURATION_MINUTES: Final[int] = 60
|
||||
"""Default session lifetime in minutes."""
|
||||
|
||||
SESSION_TOKEN_BYTES: Final[int] = 64
|
||||
"""Number of random bytes used when generating a session token."""
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Time-range presets (used by dashboard and history endpoints)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
TIME_RANGE_24H: Final[str] = "24h"
|
||||
TIME_RANGE_7D: Final[str] = "7d"
|
||||
TIME_RANGE_30D: Final[str] = "30d"
|
||||
TIME_RANGE_365D: Final[str] = "365d"
|
||||
|
||||
VALID_TIME_RANGES: Final[frozenset[str]] = frozenset(
|
||||
{TIME_RANGE_24H, TIME_RANGE_7D, TIME_RANGE_30D, TIME_RANGE_365D}
|
||||
)
|
||||
|
||||
TIME_RANGE_HOURS: Final[dict[str, int]] = {
|
||||
TIME_RANGE_24H: 24,
|
||||
TIME_RANGE_7D: 7 * 24,
|
||||
TIME_RANGE_30D: 30 * 24,
|
||||
TIME_RANGE_365D: 365 * 24,
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Pagination
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
DEFAULT_PAGE_SIZE: Final[int] = 50
|
||||
MAX_PAGE_SIZE: Final[int] = 500
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Blocklist import
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
BLOCKLIST_IMPORT_DEFAULT_HOUR: Final[int] = 3
|
||||
"""Default hour (UTC) for the nightly blocklist import job."""
|
||||
|
||||
BLOCKLIST_PREVIEW_MAX_LINES: Final[int] = 100
|
||||
"""Maximum number of IP lines returned by the blocklist preview endpoint."""
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Health check
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
HEALTH_CHECK_INTERVAL_SECONDS: Final[int] = 30
|
||||
"""How often the background health-check task polls fail2ban."""
|
||||
Reference in New Issue
Block a user