"""Pydantic schemas for case list, detail, update, ICD, and coding endpoints.""" from datetime import date, datetime from typing import Optional from pydantic import BaseModel class CaseResponse(BaseModel): """Full representation of a case returned by list and detail endpoints.""" id: int fall_id: Optional[str] = None crm_ticket_id: Optional[str] = None jahr: int kw: int datum: date anrede: Optional[str] = None vorname: Optional[str] = None nachname: Optional[str] = None geburtsdatum: Optional[date] = None kvnr: Optional[str] = None versicherung: str icd: Optional[str] = None fallgruppe: str strasse: Optional[str] = None plz: Optional[str] = None ort: Optional[str] = None email: Optional[str] = None ansprechpartner: Optional[str] = None telefonnummer: Optional[str] = None mobiltelefon: Optional[str] = None unterlagen: bool unterlagen_verschickt: Optional[date] = None erhalten: Optional[bool] = None unterlagen_erhalten: Optional[date] = None unterlagen_an_gutachter: Optional[date] = None gutachten: bool gutachter: Optional[str] = None gutachten_erstellt: Optional[date] = None gutachten_versendet: Optional[date] = None schweigepflicht: bool ablehnung: bool abbruch: bool abbruch_datum: Optional[date] = None gutachten_typ: Optional[str] = None therapieaenderung: Optional[str] = None ta_diagnosekorrektur: bool ta_unterversorgung: bool ta_uebertherapie: bool kurzbeschreibung: Optional[str] = None fragestellung: Optional[str] = None kommentar: Optional[str] = None sonstiges: Optional[str] = None abgerechnet: bool abrechnung_datum: Optional[date] = None import_source: Optional[str] = None imported_at: datetime updated_at: datetime disclosure_granted: bool = False disclosure_expires_at: Optional[datetime] = None model_config = {"from_attributes": True} class CaseListResponse(BaseModel): """Paginated case list response.""" items: list[CaseResponse] total: int page: int per_page: int class CaseUpdate(BaseModel): """Partial update for case fields (admin only). All fields are optional; only provided fields are applied. """ anrede: Optional[str] = None vorname: Optional[str] = None nachname: Optional[str] = None geburtsdatum: Optional[date] = None kvnr: Optional[str] = None versicherung: Optional[str] = None strasse: Optional[str] = None plz: Optional[str] = None ort: Optional[str] = None email: Optional[str] = None ansprechpartner: Optional[str] = None telefonnummer: Optional[str] = None mobiltelefon: Optional[str] = None unterlagen: Optional[bool] = None unterlagen_verschickt: Optional[date] = None erhalten: Optional[bool] = None unterlagen_erhalten: Optional[date] = None unterlagen_an_gutachter: Optional[date] = None gutachten: Optional[bool] = None gutachter: Optional[str] = None gutachten_erstellt: Optional[date] = None gutachten_versendet: Optional[date] = None schweigepflicht: Optional[bool] = None ablehnung: Optional[bool] = None abbruch: Optional[bool] = None abbruch_datum: Optional[date] = None kurzbeschreibung: Optional[str] = None fragestellung: Optional[str] = None kommentar: Optional[str] = None sonstiges: Optional[str] = None abgerechnet: Optional[bool] = None abrechnung_datum: Optional[date] = None class ICDUpdate(BaseModel): """Payload for setting ICD codes on a case.""" icd: str class CodingUpdate(BaseModel): """Payload for setting coding/gutachten classification on a case.""" gutachten_typ: str # "Bestätigung" or "Alternative" therapieaenderung: str # "Ja" or "Nein" ta_diagnosekorrektur: bool = False ta_unterversorgung: bool = False ta_uebertherapie: bool = False SENSITIVE_FIELDS = ( "nachname", "vorname", "geburtsdatum", "anrede", "strasse", "plz", "ort", "email", "telefonnummer", "mobiltelefon", "ansprechpartner", ) def mask_case_for_mitarbeiter(case_dict: dict, disclosure_granted: bool = False) -> dict: """Remove sensitive personal data fields for dak_mitarbeiter users. If disclosure_granted is True, the fields remain visible. """ if not disclosure_granted: for field in SENSITIVE_FIELDS: case_dict[field] = None case_dict["disclosure_granted"] = disclosure_granted return case_dict