feat: Notruf mit Kontaktdaten + Geoposition anreichern (Backend, Phase 1+3)

Notruf-Meldungen tragen jetzt das Notfall-Profil der auslösenden Person und —
falls vom Gerät mitgeschickt — die Geoposition. Kanal-Rollen:
- E-Mail: Voll-Dossier (Name, Adresse, Telefone, Geburtsdatum, med. Hinweise,
  Koordinaten + Karten-Link + Genauigkeit + Zeit; sonst "nicht verfügbar")
- SMS: kompakt, Name + Adresse + Karten-Link
- Anruf (TTS): Name + Wohnadresse gesprochen, KEINE URL/Koordinaten, Verweis
  auf SMS/E-Mail

- schemas: GeoFix + EmergencyRequest.geo; AdminUserPrefsUpdate um Profilfelder
  erweitert (full_name, Adresse, Telefone, birth_date, medical_notes,
  emergency_contacts/_phones, location_consent) — in user.prefs (keine Migration)
- api/chat: geo an record_manual_emergency durchgereicht
- api/admin: list_users gibt Profilfelder mit zurück (für die spätere Admin-UI)
- emergency.py: _profile/_geo_fields/_maps_link/_location_block/_email_body,
  kanal-spezifische _emergency_texts; record_manual_emergency(..., geo=...)
- Tests: 9 neue (Profil-Injektion, SMS/Call/E-Mail-Texte, Geo→Map-Link,
  ohne-Geo-Fallback, Payload). Suite 237 grün.

Frontend (Phase 2: Browser-Geolocation beim 🆘 + Admin-Profil-UI) steht noch aus.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-25 15:33:58 +02:00
commit 5ed4a386bb
5 changed files with 265 additions and 30 deletions

View file

@ -105,14 +105,35 @@ class MemoryOut(BaseModel):
class GeoFix(BaseModel):
"""Geoposition des auslösenden Geräts (One-Shot, vom Browser erfasst)."""
lat: float
lon: float
accuracy: float | None = None # geschätzte Genauigkeit in Metern
ts: str | None = None # ISO-Zeitstempel des Fixes
class EmergencyRequest(BaseModel):
"""Vom Nutzer ausgelöster Notruf (Knopf). language für den Hinweistext."""
language: str | None = None
geo: GeoFix | None = None
class AdminUserPrefsUpdate(BaseModel):
"""Admin setzt Nutzer-Einstellungen (z. B. erlaubte Sprachen, CSV: "de,en")."""
"""Admin setzt Nutzer-Einstellungen: erlaubte Sprachen + Notfall-Profil."""
allowed_languages: str | None = None
# Notfall-Profil (in user.prefs gespeichert, fließt in die Notruf-Meldungen ein)
full_name: str | None = None
street: str | None = None
postal_code: str | None = None
city: str | None = None
phone_landline: str | None = None
phone_mobile: str | None = None
birth_date: str | None = None
medical_notes: str | None = None
emergency_contacts: str | None = None # Kontakt-E-Mail(s), CSV
emergency_phones: str | None = None # Kontakt-Telefon(e), CSV
location_consent: bool | None = None # Standort im Notfall mitsenden?
class UserAdminUpdate(BaseModel):