Commit Graph

9 Commits

Author SHA1 Message Date
alf 06f08bd82f feat(medical): feature Patients — dossier clinique chiffré + langue poussée (RPC)
Première feature médicale (features/medical/patients/), valide le patron features/medical
ET le round-trip d'écriture RPC live.
- store : table patient_fiche (identité/contact/clinique CHIFFRÉES, PC-only) + language ;
  save_fiche/fiche/fiches/set_fiche_language.
- service : list_patients (profils on-device × fiche centrale), get_patient (profile_dump
  riche + fiche), save_fiche (central, ne touche pas la tablette), set_language
  (profile_dump → +language → profile_upsert → miroir central).
- router /api/patients/{serial}[/{profile_id}][/fiche|/language] ; enregistré dans _FEATURES.
- UI : section Patients (liste + détail, fiche clinique éditable par rubriques, sélecteur
  de langue + push sur la tablette).
- tests +4 (fiche chiffrée, merge, get, push langue). 46/46.
- validé LIVE vc19 : profile_upsert (langue es + prompt riche ':' intact) round-trip + delete.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 18:12:01 +02:00
alf bf02f6ca5d refactor+ui: distinction nette Technique / Médical
Séparation des deux domaines produit, code ET interface.
- code : features/technical/ (voices, fleet) vs features/medical/ (prêt pour patients,
  conversations, rag, questionnaires). Imports cross-domaine en absolu (robustes aux
  déplacements). 42/42.
- UI : nav en 2 blocs distincts — 🔧 Technique (Flotte, Voix, Mises à jour, Config &
  moteur, Audit) et ⚕️ Médical/clinique (Patients & profils, Conversations, RAG
  thérapeutique, Questionnaires — nouvelle section). Accents de couleur par domaine.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:54:43 +02:00
alf 8d4ab9a07f feat(ui): réécriture front « clinique-apaisé » — shell d'app (phase 2)
Refonte UX complète (page blanche assumée sur l'UI uniquement) :
- web/styles.css : design system clair (tokens couleurs/espacements, cartes, tables,
  badges, boutons, toasts, spinner, écran de déverrouillage).
- web/index.html : shell minimal (charge css + js).
- web/app.js : shell d'application — top-bar (contexte tablette + état coffre), nav
  latérale par sections (Flotte · Voix · Mises à jour · Audit + stubs Profils/
  Conversations/Config/RAG « à venir »), écran de déverrouillage propre, toasts +
  états de chargement, sélecteur de tablette global.
- Sections Flotte (vue parc + détail device), Voix (catalogue global + chargées/
  chargeables + déploiement + ré-enrôlement + autosync), Updates (OTA parc), Audit.
- Sans build (vanilla JS servi par StaticFiles), wrappable pywebview.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 17:02:55 +02:00
alf 2894771bf4 feat(voice): ré-enrôlement (régénère .ovsp + re-déploie) — pour appliquer le fix §7
deploy_voice réutilise le .ovsp stocké → une voix enrôlée avec l'ancien cap garde son
artefact pollué. reenroll_voice : ré-enrôle depuis le WAV archivé (enroll §7) + re-pousse
sur toutes les tablettes déployées. API POST /voices/catalog/{id}/reenroll, bouton UI
(si WAV archivé). tests +2. 42/42.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 23:45:52 +02:00
alf 6640cfd79e feat(voice): catalogue GLOBAL (flotte) + déploiement par tablette
Refonte : une voix n'est plus liée à sa tablette d'enregistrement. Catalogue central
clé voice_id, .ovsp stocké chiffré → déployable sur N tablettes sans ré-enrôler.
- store : voices PK voice_id (+ origin_serial, ovsp_enc) + table voice_deployments
  (many-to-many) + migration de l'ancien schéma (serial,voice_id)→global. Méthodes
  globales + add/remove_deployment, voices_on, deployments_of, store/voice_ovsp_bytes.
- orchestrator : catalog(), deploy_voice/undeploy_voice (scope-conscient), list_for_tablet
  (chargées + chargeables), ingest_voice/sync_admin au catalogue global. Suppr. legacy
  /voices-based (list_voices/prepare/enroll_deploy/sync_device).
- API : GET /voices/catalog, POST /voices/catalog/{vid}/lock|unlock, GET /voices/{serial}
  (chargées+chargeables), POST /voices/{serial}/deploy|undeploy.
- UI : carte Catalogue flotte (visible sans tablette) + par tablette chargées/chargeables
  avec charger/retirer.
- tests réécrits (40/40). Validé live : catalog [], /voices/{serial} chargées+chargeables.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 19:39:00 +02:00
alf 783bca1ba4 feat(voice): UI panneau voix + fix dérivation dossier omnivoice
- web : bouton "🎙 Voix" + vue par tablette : déclencheur auto (armer/désarmer +
  delete_source + statut), voix admin à enrôler (nom/scope/propriétaire/statut/
  consentement + bouton "Synchroniser"), voix déployées (statut/verrou/profils +
  verrouiller/déverrouiller).
- fix : list_voices et enroll_deploy dérivaient le dossier omnivoice depuis
  /voices.wav_path (VIDE post-migration → chemin relatif → 502/échec). Passent
  désormais par _patient_omnivoice_dir (env → wav_path legacy → sonde MODELS_DIR).
- 46/46 ; vérifié live : /voices/{serial} et /admin répondent 200, UI servie.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 11:35:38 +02:00
alf 4b38efca4f feat(fleet): fan-out parc — vue d'ensemble + OTA groupé, rapport par device
- fleet.py : fan_out() séquentiel isolant les échecs par tablette (§9), et
  device_overview() (résumé santé partiel, sous-requêtes isolées).
- API : GET /api/fleet/overview (enrichi des labels), POST /api/fleet/update-check,
  POST /api/fleet/update-install (audité).
- UI : bouton « Vue parc » → tableau d'ensemble (état, RAM, MAJ, RAG, profils,
  sessions, crashes) + vérification OTA sur tout le parc.
- tests : +6 (isolation des échecs, overview partiel, endpoint). 25/25.
- validé live : overview + update-check sur tablette réelle (parse_call_bundle OK).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 22:52:11 +02:00
alf 7f999a06f0 feat(store): branchement API — déverrouillage opérateur, labels patients, audit
- API : /api/lock-status, /api/unlock, /api/lock, PUT /api/devices/{serial}/label,
  /api/audit ; /api/devices enrichi du label patient quand le store est déverrouillé.
- db.py thread-safe (check_same_thread=False + RLock) pour le threadpool FastAPI ;
  ajout lock(), device_labels().
- UI : barre de déverrouillage opérateur, affichage 👤 label, édition ✎ du nom.
- Sécurité : labels chiffrés (jamais en clair en base ni dans l'audit), opérations
  journalisées, store re-verrouillable.
- tests : +5 intégration API↔store (dont non-fuite PII dans l'audit). 19/19.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 22:49:43 +02:00
alf 465ddd4e7a feat: store chiffré, dashboard web flotte, accès réseau + durcissements
- store/ : archive clinique chiffrée (sqlite3 + PyNaCl SecretBox/Argon2id),
  mapping serial→label patient, audit. Choix sqlite+PyNaCl plutôt que SQLCipher
  (wheels Linux-only) pour rester facilement installable Mac/Win.
- web/ + montage StaticFiles : dashboard flotte en lecture (état, profils,
  sessions, RAG, updates, crashes), HTML+JS vanilla sans build.
- __main__.py : `python -m kazeia_central`, host/port via env + auth HTTP Basic
  optionnelle (KAZEIA_USER/PASS) pour exposition réseau (0.0.0.0).
- adb : devices() robuste au bruit daemon, réveil/retry du provider (§3.5).
- models : champs non-clés optionnels (résilience flotte hétérogène).
- spec : RAG à plat (miroir ConfigStore.toJson), ajout rag_dump_json, note PIN.
- tests : 14/14 (parsing adb + store chiffré).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 22:41:55 +02:00