Docs: mark Task 8/9 completed and update architecture docs
This commit is contained in:
@@ -82,10 +82,12 @@ The backend follows a **layered architecture** with strict separation of concern
|
||||
backend/
|
||||
├── app/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # FastAPI app factory, lifespan, exception handlers
|
||||
│ ├── config.py # Pydantic settings (env vars, .env loading)
|
||||
│ ├── dependencies.py # FastAPI Depends() providers (DB, services, auth)
|
||||
│ ├── models/ # Pydantic schemas
|
||||
│ ├── `main.py` # FastAPI app factory, lifespan, exception handlers
|
||||
│ ├── `config.py` # Pydantic settings (env vars, .env loading)
|
||||
│ ├── `db.py` # Database connection and initialization
|
||||
│ ├── `exceptions.py` # Shared domain exception classes
|
||||
│ ├── `dependencies.py` # FastAPI Depends() providers (DB, services, auth)
|
||||
│ ├── `models/` # Pydantic schemas
|
||||
│ │ ├── auth.py # Login request/response, session models
|
||||
│ │ ├── ban.py # Ban request/response/domain models
|
||||
│ │ ├── jail.py # Jail request/response/domain models
|
||||
@@ -111,6 +113,12 @@ backend/
|
||||
│ │ ├── jail_service.py # Jail listing, start/stop/reload, status aggregation
|
||||
│ │ ├── ban_service.py # Ban/unban execution, currently-banned queries
|
||||
│ │ ├── config_service.py # Read/write fail2ban config, regex validation
|
||||
│ │ ├── config_file_service.py # Shared config parsing and file-level operations
|
||||
│ │ ├── raw_config_io_service.py # Raw config file I/O wrapper
|
||||
│ │ ├── jail_config_service.py # jail config activation/deactivation logic
|
||||
│ │ ├── filter_config_service.py # filter config lifecycle management
|
||||
│ │ ├── action_config_service.py # action config lifecycle management
|
||||
│ │ ├── log_service.py # Log preview and regex test operations
|
||||
│ │ ├── history_service.py # Historical ban queries, per-IP timeline
|
||||
│ │ ├── blocklist_service.py # Download, validate, apply blocklists
|
||||
│ │ ├── geo_service.py # IP-to-country resolution, ASN/RIR lookup
|
||||
@@ -119,17 +127,18 @@ backend/
|
||||
│ ├── repositories/ # Data access layer (raw queries only)
|
||||
│ │ ├── settings_repo.py # App configuration CRUD in SQLite
|
||||
│ │ ├── session_repo.py # Session storage and lookup
|
||||
│ │ ├── blocklist_repo.py # Blocklist sources and import log persistence
|
||||
│ │ └── import_log_repo.py # Import run history records
|
||||
│ │ ├── blocklist_repo.py # Blocklist sources and import log persistence│ │ ├── fail2ban_db_repo.py # fail2ban SQLite ban history read operations
|
||||
│ │ ├── geo_cache_repo.py # IP geolocation cache persistence│ │ └── import_log_repo.py # Import run history records
|
||||
│ ├── tasks/ # APScheduler background jobs
|
||||
│ │ ├── blocklist_import.py# Scheduled blocklist download and application
|
||||
│ │ ├── geo_cache_flush.py # Periodic geo cache persistence (dirty-set flush to SQLite)
|
||||
│ │ └── health_check.py # Periodic fail2ban connectivity probe
|
||||
│ │ ├── geo_cache_flush.py # Periodic geo cache persistence (dirty-set flush to SQLite)│ │ ├── geo_re_resolve.py # Periodic re-resolution of stale geo cache records│ │ └── health_check.py # Periodic fail2ban connectivity probe
|
||||
│ └── utils/ # Helpers, constants, shared types
|
||||
│ ├── fail2ban_client.py # Async wrapper around the fail2ban socket protocol
|
||||
│ ├── ip_utils.py # IP/CIDR validation and normalisation
|
||||
│ ├── time_utils.py # Timezone-aware datetime helpers
|
||||
│ └── constants.py # Shared constants (default paths, limits, etc.)
|
||||
│ ├── time_utils.py # Timezone-aware datetime helpers│ ├── jail_config.py # Jail config parser/serializer helper
|
||||
│ ├── conffile_parser.py # Fail2ban config file parser/serializer
|
||||
│ ├── config_parser.py # Structured config object parser
|
||||
│ ├── config_writer.py # Atomic config file write operations│ └── constants.py # Shared constants (default paths, limits, etc.)
|
||||
├── tests/
|
||||
│ ├── conftest.py # Shared fixtures (test app, client, mock DB)
|
||||
│ ├── test_routers/ # One test file per router
|
||||
@@ -158,8 +167,9 @@ The HTTP interface layer. Each router maps URL paths to handler functions. Route
|
||||
| `blocklist.py` | `/api/blocklists` | CRUD blocklist sources, trigger import, view import logs |
|
||||
| `geo.py` | `/api/geo` | IP geolocation lookup, ASN and RIR data |
|
||||
| `server.py` | `/api/server` | Log level, log target, DB path, purge age, flush logs |
|
||||
| `health.py` | `/api/health` | fail2ban connectivity health check and status |
|
||||
|
||||
#### Services (`app/services/`)
|
||||
#### Services (`app/services`)
|
||||
|
||||
The business logic layer. Services orchestrate operations, enforce rules, and coordinate between repositories, the fail2ban client, and external APIs. Each service covers a single domain.
|
||||
|
||||
@@ -175,7 +185,8 @@ The business logic layer. Services orchestrate operations, enforce rules, and co
|
||||
| `filter_config_service.py` | Discovers available filters by scanning filter.d/; reads, creates, updates, and deletes filter definitions; assigns filters to jails |
|
||||
| `action_config_service.py` | Discovers available actions by scanning action.d/; reads, creates, updates, and deletes action definitions; assigns actions to jails |
|
||||
| `config_file_service.py` | Shared utilities for configuration parsing and manipulation: parses config files, validates names/IPs, manages atomic file writes, probes fail2ban socket |
|
||||
| `conffile_parser.py` | Parses fail2ban `.conf` files into structured Python types (jail config, filter config, action config); also serialises back to text |
|
||||
| `raw_config_io_service.py` | Low-level file I/O for raw fail2ban config files |
|
||||
| `log_service.py` | Log preview and regex test operations (extracted from config_service) |
|
||||
| `history_service.py` | Queries the fail2ban database for historical ban records, builds per-IP timelines, computes ban counts and repeat-offender flags |
|
||||
| `blocklist_service.py` | Downloads blocklists via aiohttp, validates IPs/CIDRs, applies bans through fail2ban or iptables, logs import results |
|
||||
| `geo_service.py` | Resolves IP addresses to country, ASN, and RIR using external APIs or a local database, caches results |
|
||||
@@ -191,15 +202,26 @@ The data access layer. Repositories execute raw SQL queries against the applicat
|
||||
| `settings_repo.py` | CRUD operations for application settings (master password hash, DB path, fail2ban socket path, preferences) |
|
||||
| `session_repo.py` | Store, retrieve, and delete session records for authentication |
|
||||
| `blocklist_repo.py` | Persist blocklist source definitions (name, URL, enabled/disabled) |
|
||||
| `fail2ban_db_repo.py` | Read historical ban records from the fail2ban SQLite database |
|
||||
| `geo_cache_repo.py` | Persist and query IP geo resolution cache |
|
||||
| `import_log_repo.py` | Record import run results (timestamp, source, IPs imported, errors) for the import log view |
|
||||
|
||||
#### Models (`app/models/`)
|
||||
|
||||
Pydantic schemas that define data shapes and validation. Models are split into three categories per domain:
|
||||
Pydantic schemas that define data shapes and validation. Models are split into three categories per domain.
|
||||
|
||||
- **Request models** — validate incoming API data (e.g., `BanRequest`, `LoginRequest`)
|
||||
- **Response models** — shape outgoing API data (e.g., `JailResponse`, `BanListResponse`)
|
||||
- **Domain models** — internal representations used between services and repositories (e.g., `Ban`, `Jail`)
|
||||
| Model file | Purpose |
|
||||
|---|---|
|
||||
| `auth.py` | Login/request and session models |
|
||||
| `ban.py` | Ban creation and lookup models |
|
||||
| `blocklist.py` | Blocklist source and import log models |
|
||||
| `config.py` | Fail2ban config view/edit models |
|
||||
| `file_config.py` | Raw config file read/write models |
|
||||
| `geo.py` | Geo and ASN lookup models |
|
||||
| `history.py` | Historical ban query and timeline models |
|
||||
| `jail.py` | Jail listing and status models |
|
||||
| `server.py` | Server status and settings models |
|
||||
| `setup.py` | First-run setup wizard models |
|
||||
|
||||
#### Tasks (`app/tasks/`)
|
||||
|
||||
@@ -209,6 +231,7 @@ APScheduler background jobs that run on a schedule without user interaction.
|
||||
|---|---|
|
||||
| `blocklist_import.py` | Downloads all enabled blocklist sources, validates entries, applies bans, records results in the import log |
|
||||
| `geo_cache_flush.py` | Periodically flushes newly resolved IPs from the in-memory dirty set to the `geo_cache` SQLite table (default: every 60 seconds). GET requests populate only the in-memory cache; this task persists them without blocking any request. |
|
||||
| `geo_re_resolve.py` | Periodically re-resolves stale entries in `geo_cache` to keep geolocation data fresh |
|
||||
| `health_check.py` | Periodically pings the fail2ban socket and updates the cached server status so the frontend always has fresh data |
|
||||
|
||||
#### Utils (`app/utils/`)
|
||||
@@ -219,7 +242,16 @@ Pure helper modules with no framework dependencies.
|
||||
|---|---|
|
||||
| `fail2ban_client.py` | Async client that communicates with fail2ban via its Unix domain socket — sends commands and parses responses using the fail2ban protocol. Modelled after [`./fail2ban-master/fail2ban/client/csocket.py`](../fail2ban-master/fail2ban/client/csocket.py) and [`./fail2ban-master/fail2ban/client/fail2banclient.py`](../fail2ban-master/fail2ban/client/fail2banclient.py). |
|
||||
| `ip_utils.py` | Validates IPv4/IPv6 addresses and CIDR ranges using the `ipaddress` stdlib module, normalises formats |
|
||||
| `jail_utils.py` | Jail helper functions for configuration and status inference |
|
||||
| `jail_config.py` | Jail config parser and serializer for fail2ban config manipulation |
|
||||
| `time_utils.py` | Timezone-aware datetime construction, formatting helpers, time-range calculations |
|
||||
| `log_utils.py` | Structured log formatting and enrichment helpers |
|
||||
| `conffile_parser.py` | Parses Fail2ban `.conf` files into structured objects and serialises back to text |
|
||||
| `config_parser.py` | Builds structured config objects from file content tokens |
|
||||
| `config_writer.py` | Atomic config file writes, backups, and safe replace semantics |
|
||||
| `config_file_utils.py` | Common file-level config utility helpers |
|
||||
| `fail2ban_db_utils.py` | Fail2ban DB path discovery and ban-history parsing helpers |
|
||||
| `setup_utils.py` | Setup wizard helper utilities |
|
||||
| `constants.py` | Shared constants: default socket path, default database path, time-range presets, limits |
|
||||
|
||||
#### Configuration (`app/config.py`)
|
||||
|
||||
@@ -150,7 +150,7 @@ Reference: `Docs/Refactoring.md` for full analysis of each issue.
|
||||
|
||||
---
|
||||
|
||||
### Task 7 — Remove remaining service-to-service coupling
|
||||
### Task 7 — Remove remaining service-to-service coupling (✅ completed)
|
||||
|
||||
**Priority**: Medium
|
||||
**Refactoring ref**: Refactoring.md §1
|
||||
@@ -172,7 +172,7 @@ Reference: `Docs/Refactoring.md` for full analysis of each issue.
|
||||
|
||||
---
|
||||
|
||||
### Task 8 — Update Architecture documentation
|
||||
### Task 8 — Update Architecture documentation (✅ completed)
|
||||
|
||||
**Priority**: Medium
|
||||
**Refactoring ref**: Refactoring.md §4
|
||||
@@ -194,7 +194,7 @@ Reference: `Docs/Refactoring.md` for full analysis of each issue.
|
||||
|
||||
---
|
||||
|
||||
### Task 9 — Add React Error Boundary to the frontend
|
||||
### Task 9 — Add React Error Boundary to the frontend (✅ completed)
|
||||
|
||||
**Priority**: Medium
|
||||
**Refactoring ref**: Refactoring.md §6
|
||||
@@ -238,7 +238,7 @@ Reference: `Docs/Refactoring.md` for full analysis of each issue.
|
||||
|
||||
---
|
||||
|
||||
### Task 11 — Create generic `useConfigItem<T>` hook (frontend)
|
||||
### Task 11 — Create generic `useConfigItem<T>` hook (frontend) (✅ completed)
|
||||
|
||||
**Priority**: Low
|
||||
**Refactoring ref**: Refactoring.md §8
|
||||
|
||||
Reference in New Issue
Block a user