389b878dbd
Bug: zweimal CRITICAL-Alert für dieselbe Brute-Force-Erkennung kam an. Ursache: detectThresholds() hat als Cutoff für den "existing"-Check floor(now, hour) genutzt. Bei Stundenwechsel resettete der Bucket und der nächste Cron-Lauf fand nichts mehr "in der aktuellen Stunde" → erzeugte zweites SUSPICIOUS-Event → zweite Mail. Fix: gleitendes 60min-Fenster (now - 60min). Pro IP gibt es jetzt zuverlässig max. 1 CRITICAL-Alert pro Stunde, unabhängig von der absoluten Uhrzeit. Live-verifiziert in DB: zwei Alerts kamen um 07:41 und 08:00 – genau das Pattern, das der Stunden-Reset erzeugt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>