"""Service Patients (médical) : dossier clinique chiffré côté central + profils on-device pilotés par RPC (profile_dump/upsert base64-JSON, vc19). Séparation stricte : la **fiche clinique** (identité/contact/clinique) est PII santé → elle reste chiffrée sur le PC, jamais poussée sur la tablette. Seul l'**opérationnel** (langue, voix, prompt) vit sur le profil on-device et se pousse via `profile_upsert`. """ from __future__ import annotations from typing import Any from kazeia_central.core.adb import Adb from kazeia_central.core.provider import ProviderClient from kazeia_central.core.store import Store def list_patients(adb: Adb, store: Store, serial: str) -> list[dict[str, Any]]: """Profils on-device de la tablette croisés avec le dossier clinique central.""" profs = ProviderClient(adb, serial).profiles() fiches = store.fiches(serial) if store.is_unlocked else {} out = [] for p in profs: f = fiches.get(p.id, {}) civil = (f.get("fiche") or {}).get("civil") or {} out.append({ "profile_id": p.id, "display_name": p.display_name, "voice_id": p.voice_id, "has_pin": p.has_pin, "is_default": p.is_default, "turn_count": p.turn_count, "has_fiche": bool(f.get("fiche")), "language": f.get("language"), "full_name": civil.get("full_name"), }) return out def get_patient(adb: Adb, store: Store, serial: str, profile_id: str) -> dict[str, Any]: """Détail : profil on-device riche (prompt/langue via profile_dump) + fiche clinique.""" prof = ProviderClient(adb, serial).profile_dump(profile_id) rec = store.fiche(serial, profile_id) or {} return {"profile": prof, "fiche": rec.get("fiche") or {}, "language": rec.get("language") or prof.get("language")} def save_fiche(store: Store, serial: str, profile_id: str, fiche: dict, language: str | None, *, now: int, actor: str | None = None) -> dict[str, Any]: """Enregistre la fiche clinique chiffrée côté central (ne touche PAS la tablette).""" store.save_fiche(serial, profile_id, fiche, language, now=now) store.audit("patient_fiche_saved", actor=actor, target=f"{serial}/{profile_id}", now=now) return {"ok": True, "profile_id": profile_id} def set_language(adb: Adb, store: Store, serial: str, profile_id: str, language: str, *, now: int, actor: str | None = None) -> dict[str, Any]: """Pousse la langue sur le profil on-device (profile_dump → +language → profile_upsert ; PIN absent = inchangé) et la reflète dans le dossier central.""" c = ProviderClient(adb, serial) prof = c.profile_dump(profile_id) prof["language"] = language c.profile_upsert(prof) store.set_fiche_language(serial, profile_id, language, now=now) store.audit("patient_language_set", actor=actor, target=f"{serial}/{profile_id}", detail={"language": language}, now=now) return {"profile_id": profile_id, "language": language, "pushed": True}