Memoize per-Geography style objects with useMemo so React.memo can
skip re-renders when only the tooltip position changes. Stabilize
mouse event handlers with useCallback using data-* attributes instead
of per-Geography closures. This eliminates the state-update race
condition that caused hover fill colors to flash back to defaults.
HistoryPage no longer requires Apply/Clear; filter state auto-syncs with query. Added guard to avoid redundant state updates. Updated task list in Docs/Tasks.md to mark completion.
Add source=archive option for dashboard endpoints and history service; update Docs/Tasks.md; include archive branch for list_bans, bans_by_country, ban_trend, bans_by_jail; tests for archive paths.
Extract jail, filter, and action configuration management into separate
domain-focused service modules:
- jail_config_service.py: Jail activation, deactivation, validation, rollback
- filter_config_service.py: Filter discovery, CRUD, assignment to jails
- action_config_service.py: Action discovery, CRUD, assignment to jails
Benefits:
- Reduces monolithic 3100-line module into three focused modules
- Improves readability and maintainability per domain
- Clearer separation of concerns following single responsibility principle
- Easier to test domain-specific functionality in isolation
- Reduces coupling - each service only depends on its needed utilities
Changes:
- Create three new service modules under backend/app/services/
- Update backend/app/routers/config.py to import from new modules
- Update exception and function imports to source from appropriate service
- Update Architecture.md to reflect new service organization
- All existing tests continue to pass with new module structure
Relates to Task 4 of refactoring backlog in Docs/Tasks.md
Task 2: rename 'Failures:' label to 'Failed Attempts:' and update tooltip
to 'Total failed authentication attempts currently tracked by fail2ban
across all active jails' — more accurate than 'Currently failing IPs'.
Task 3: move <ServerHealthSection /> to the top of ServerTab so users
see connectivity status before scrolling through all settings fields.