feat: add email notifications for disclosure request decisions

Replace direct Notification inserts with notification_service functions
that send both in-app and email notifications. Admins receive an email
when a DAK-Mitarbeiter submits a new disclosure request. The requesting
Mitarbeiter receives an email when their request is approved (with
expiration date) or rejected. SMTP was already configured.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
CCS Admin 2026-02-28 12:59:21 +00:00
parent 5da1e523d3
commit 3216dd6d53
2 changed files with 33 additions and 20 deletions

View file

@ -5,9 +5,10 @@ from typing import Optional
from sqlalchemy.orm import Session
from app.models.audit import DisclosureRequest, Notification
from app.models.audit import DisclosureRequest
from app.models.case import Case
from app.models.user import User
from app.services.notification_service import create_notification, notify_all_users_with_role
def _utcnow_naive() -> datetime:
@ -60,24 +61,26 @@ def create_disclosure_request(
db.add(dr)
db.flush()
# Notify all active admins
# Notify all active admins (in-app + email)
case = db.query(Case).filter(Case.id == case_id).first()
fall_id = case.fall_id if case else str(case_id)
requester = db.query(User).filter(User.id == user_id).first()
requester_name = requester.username if requester else str(user_id)
admins = db.query(User).filter(User.role == "admin", User.is_active == True).all() # noqa: E712
for admin in admins:
db.add(Notification(
recipient_id=admin.id,
notification_type="disclosure_request",
title=f"Freigabe-Anfrage für Fall {fall_id}",
message=f"{requester_name} bittet um Einsicht in Personendaten. Begründung: {reason}",
notify_all_users_with_role(
db,
"admin",
"disclosure_request",
title=f"Neue Freigabe-Anfrage für Fall {fall_id}",
message=(
f"{requester_name} hat eine Freigabe für Personendaten beantragt.\n"
f"Begründung: {reason}\n\n"
"Bitte prüfen Sie die Anfrage im DAK Portal."
),
related_entity_type="disclosure_request",
related_entity_id=dr.id,
))
)
db.commit()
db.refresh(dr)
return dr
@ -99,21 +102,31 @@ def review_disclosure_request(
if new_status == "approved":
dr.expires_at = _utcnow_naive() + timedelta(hours=24)
# Notify requester
# Notify requester (in-app + email)
case = db.query(Case).filter(Case.id == dr.case_id).first()
fall_id = case.fall_id if case else str(dr.case_id)
status_text = "genehmigt" if new_status == "approved" else "abgelehnt"
db.add(Notification(
if new_status == "approved":
expires_str = dr.expires_at.strftime("%d.%m.%Y %H:%M Uhr") if dr.expires_at else "24h"
message = (
f"Ihre Freigabe-Anfrage für Fall {fall_id} wurde genehmigt.\n"
f"Die Personendaten sind bis {expires_str} sichtbar."
)
else:
message = f"Ihre Freigabe-Anfrage für Fall {fall_id} wurde abgelehnt."
create_notification(
db,
recipient_id=dr.requester_id,
notification_type="disclosure_resolved",
title=f"Freigabe-Anfrage {status_text}",
message=f"Ihre Anfrage für Fall {fall_id} wurde {status_text}.",
title=f"Freigabe-Anfrage {status_text} — Fall {fall_id}",
message=message,
related_entity_type="disclosure_request",
related_entity_id=dr.id,
))
)
db.commit()
db.refresh(dr)
return dr

View file

@ -2,7 +2,7 @@
## Hohe Priorität
- [ ] **Gutachten-Statistik Seite** — Route `/gutachten-statistik` existiert als Platzhalter. Visualisierung von Gutachten-Typen (Bestätigung/Alternative), Therapieänderungen, Diagnosekorrektur/Unterversorgung/Übertherapie und Trends pro KW/Jahr.
- [x] **Gutachten-Statistik Seite** — ✅ Implementiert: 4 KPIs, Stacked-Bar (Typ pro KW), Donut (Typ-Verteilung), Grouped-Bar (Therapieänderungen pro KW), Horizontal-Bars (Gründe). Backend-Endpoint + Frontend komplett.
- [ ] **Fallliste als Excel exportieren** — Export-Button auf der Cases-Seite für gefilterte Falllisten als .xlsx Download. Nutzt aktive Filter (Jahr, Fallgruppe, ICD-Status).
- [ ] **E-Mail-Benachrichtigungen bei Freigabe-Entscheidung** — DAK-Mitarbeiter per E-Mail informieren, wenn ihre Freigabe-Anfrage genehmigt oder abgelehnt wurde. SMTP ist bereits konfiguriert.