Refactor history sync into history_service and update docs/tests

This commit is contained in:
2026-04-14 15:09:58 +02:00
parent 86fa271c40
commit 58bb769a35
7 changed files with 147 additions and 90 deletions

View File

@@ -187,7 +187,7 @@ The business logic layer. Services orchestrate operations, enforce rules, and co
| `config_file_service.py` | Shared utilities for configuration parsing and manipulation: parses config files, validates names/IPs, manages atomic file writes, probes fail2ban socket |
| `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 |
| `history_service.py` | Queries the fail2ban database for historical ban records, builds per-IP timelines, computes ban counts and repeat-offender flags, and syncs new records into BanGUI's archive table |
| `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 |
| `server_service.py` | Reads and writes fail2ban server-level settings (log level, log target, syslog socket, DB location, purge age) |
@@ -233,6 +233,7 @@ APScheduler background jobs that run on a schedule without user interaction.
| `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 |
| `history_sync.py` | Periodically copies new records from the fail2ban SQLite database into BanGUI's `history_archive` table; delegates the sync algorithm to `history_service.py` |
#### Utils (`app/utils/`)

View File

@@ -145,7 +145,7 @@ Framework types in the service layer violate the Dependency Inversion principle,
---
### TASK-05 — Extract business logic out of `tasks/history_sync.py` into a service 🟠
### TASK-05 — Extract business logic out of `tasks/history_sync.py` into a service
**Where:**
`backend/app/tasks/history_sync.py` — lines 1516 import repositories directly; the entire `_run_sync_with_settings()` function contains paging logic, backfill window calculation, and `archive_ban_event` calls that constitute business logic.
@@ -371,7 +371,7 @@ Module-level asyncio primitives are a known footgun in Python async codebases. F
---
### TASK-12 — Remove duplicate import in `server_service.py` 🟡
### TASK-12 — Remove duplicate import in `server_service.py`
**Where:**
`backend/app/services/server_service.py` — lines 1718: