diff --git a/backend/app/services/disclosure_service.py b/backend/app/services/disclosure_service.py index a6b3ad1..189ef9e 100644 --- a/backend/app/services/disclosure_service.py +++ b/backend/app/services/disclosure_service.py @@ -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}", - related_entity_type="disclosure_request", - related_entity_id=dr.id, - )) + 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 diff --git a/docs/todo.md b/docs/todo.md index a7af9f3..2362d28 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -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.