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:
2026-02-28 21:15:01 +01:00
parent 460d877339
commit 7392c930d6
59 changed files with 7601 additions and 17 deletions

45
frontend/src/App.tsx Normal file
View File

@@ -0,0 +1,45 @@
/**
* Application root component.
*
* Wraps the entire application in:
* 1. `FluentProvider` — supplies the Fluent UI theme and design tokens.
* 2. `BrowserRouter` — enables client-side routing via React Router.
*
* Route definitions are delegated to `AppRoutes` (implemented in Stage 3).
* For now a placeholder component is rendered so the app can start and the
* theme can be verified.
*/
import { FluentProvider } from "@fluentui/react-components";
import { BrowserRouter } from "react-router-dom";
import { lightTheme } from "./theme/customTheme";
/**
* Temporary placeholder shown until full routing is wired up in Stage 3.
*/
function AppPlaceholder(): JSX.Element {
return (
<div style={{ padding: 32, fontFamily: "Segoe UI, sans-serif" }}>
<h1 style={{ fontSize: 28, fontWeight: 600 }}>BanGUI</h1>
<p style={{ fontSize: 14, color: "#605e5c" }}>
Frontend scaffolding complete. Full UI implemented in Stage 3.
</p>
</div>
);
}
/**
* Root application component.
* Mounts `FluentProvider` and `BrowserRouter` around all page content.
*/
function App(): JSX.Element {
return (
<FluentProvider theme={lightTheme}>
<BrowserRouter>
<AppPlaceholder />
</BrowserRouter>
</FluentProvider>
);
}
export default App;