- Remove per-IP db.commit() from _persist_entry() and _persist_neg_entry();
add a single commit after the full lookup_batch() chunk loop instead.
Reduces commits from ~5,200 to 1 per bans/by-country request.
- Remove db dependency from GET /api/dashboard/bans and
GET /api/dashboard/bans/by-country; pass app_db=None so no SQLite
writes occur during read-only requests.
- Add _dirty set to geo_service; _store() marks resolved IPs dirty.
New flush_dirty(db) batch-upserts all dirty entries in one transaction.
New geo_cache_flush APScheduler task flushes every 60 s so geo data
is persisted without blocking requests.