fix(notruf): ehrlicher Status, wenn niemand verständigt werden kann

Bisher meldete ein Notruf ohne nutzbaren Kanal trotzdem Erfolg
(status="alerted", grüner Haken), obwohl tatsächlich niemand
benachrichtigt wurde — gefährlich für Senioren.

- emergency.py: drei klare Endzustände alerted / no_recipients /
  delivery_failed; notify_readiness() prüft, ob ein Kanal wirklich
  senden würde (SMTP+Empfaenger bzw. Webhook). Mehrsprachige Hinweise
  fuer die Fehlfaelle (nennen Selbsthilfe 112). Antwort traegt jetzt
  notified + notify_ready; Warn-Log, wenn nichts zugestellt wurde.
- /api/emergency/status liefert notify_ready fuer die Vorab-Warnung.
- Frontend: gelbe Vorab-Warnung im SOS-Dialog, wenn kein Empfaenger
  eingerichtet ist; bei no_recipients/delivery_failed kein gruenes
  Erfolgssignal mehr, sondern roter Fehlerzustand (app.js v54).
- Tests an die neue Semantik angepasst.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-27 16:50:03 +02:00
commit 37b4c175d2
6 changed files with 126 additions and 18 deletions

View file

@ -18,7 +18,11 @@ from app.dependencies import (
from app.core.memory_extractor import maybe_schedule_extraction
from app.quota import enforce_quota, record_usage, QuotaExceededError
from app.runtime_config import runtime_settings
from app.safety.emergency import record_manual_emergency, emergency_cooldown_status
from app.safety.emergency import (
record_manual_emergency,
emergency_cooldown_status,
notify_readiness,
)
from app.schemas import ChatRequest, EmergencyRequest
router = APIRouter()
@ -161,5 +165,8 @@ async def trigger_emergency(payload: EmergencyRequest, user: User = Depends(requ
@router.get("/emergency/status")
async def emergency_status(user: User = Depends(require_user)):
"""Aktueller Notruf-Sperr-Status des Nutzers (für die grüne Button-Anzeige,
auch nach einem Seiten-Neuladen)."""
return emergency_cooldown_status(user, get_store(), runtime_settings)
auch nach einem Seiten-Neuladen) plus notify_ready für die Vorab-Warnung,
falls (noch) kein Benachrichtigungskanal eingerichtet ist."""
st = emergency_cooldown_status(user, get_store(), runtime_settings)
st["notify_ready"] = notify_readiness(user, runtime_settings)
return st