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
25 lines
519 B
TypeScript
25 lines
519 B
TypeScript
/**
|
|
* Application entry point.
|
|
*
|
|
* Mounts the root `<App />` component into the `#root` DOM element
|
|
* supplied by `index.html`.
|
|
*/
|
|
|
|
import { StrictMode } from "react";
|
|
import { createRoot } from "react-dom/client";
|
|
import App from "./App";
|
|
|
|
const rootElement = document.getElementById("root");
|
|
|
|
if (rootElement === null) {
|
|
throw new Error(
|
|
"Root element #root not found. Ensure index.html contains <div id='root'></div>."
|
|
);
|
|
}
|
|
|
|
createRoot(rootElement).render(
|
|
<StrictMode>
|
|
<App />
|
|
</StrictMode>
|
|
);
|