- Cache persistant JSON thread-safe pour les résultats Ollama (invalidation par modèle) - Parallélisation des appels Ollama (ThreadPoolExecutor, 2 workers) - 6 nouvelles règles de filtrage DAS parasites (doublons, ponctuation, OCR, labo, fragments) - Client Ollama centralisé (mode JSON natif + retry) - Module GHM (estimation CMD/sévérité) - Module contrôle CPAM (parser + contre-argumentation RAG) - Export RUM (format RSS) - Viewer enrichi (détail dossier) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
190 lines
6.0 KiB
Python
190 lines
6.0 KiB
Python
"""Tests pour le module d'estimation GHM."""
|
|
|
|
import pytest
|
|
|
|
from src.config import ActeCCAM, Diagnostic, DossierMedical
|
|
from src.medical.ghm import estimate_ghm, find_cmd, _detect_type_ghm, _compute_severity
|
|
|
|
|
|
class TestFindCMD:
|
|
def test_k85_hepatobilaire(self):
|
|
cmd, libelle = find_cmd("K85.1")
|
|
assert cmd == "07"
|
|
assert "hépatobiliaire" in libelle.lower() or "pancréat" in libelle.lower()
|
|
|
|
def test_j18_respiratoire(self):
|
|
cmd, _ = find_cmd("J18")
|
|
assert cmd == "04"
|
|
|
|
def test_n17_renal(self):
|
|
cmd, _ = find_cmd("N17")
|
|
assert cmd == "11"
|
|
|
|
def test_n40_genital_masculin(self):
|
|
cmd, _ = find_cmd("N40")
|
|
assert cmd == "12"
|
|
|
|
def test_f10_toxicomanie(self):
|
|
cmd, _ = find_cmd("F10")
|
|
assert cmd == "20"
|
|
|
|
def test_z00_facteurs(self):
|
|
cmd, _ = find_cmd("Z00")
|
|
assert cmd == "23"
|
|
|
|
def test_k40_digestif(self):
|
|
cmd, _ = find_cmd("K40")
|
|
assert cmd == "06"
|
|
|
|
def test_b20_vih(self):
|
|
cmd, _ = find_cmd("B20")
|
|
assert cmd == "25"
|
|
|
|
def test_t25_brulures(self):
|
|
cmd, _ = find_cmd("T25")
|
|
assert cmd == "22"
|
|
|
|
def test_s72_traumatismes(self):
|
|
cmd, _ = find_cmd("S72")
|
|
assert cmd == "21"
|
|
|
|
def test_code_with_dot(self):
|
|
cmd, _ = find_cmd("K85.1")
|
|
assert cmd == "07"
|
|
|
|
def test_code_lowercase(self):
|
|
cmd, _ = find_cmd("k85.1")
|
|
assert cmd == "07"
|
|
|
|
def test_empty_code(self):
|
|
cmd, libelle = find_cmd("")
|
|
assert cmd is None
|
|
assert libelle is None
|
|
|
|
def test_none_code(self):
|
|
cmd, libelle = find_cmd(None)
|
|
assert cmd is None
|
|
assert libelle is None
|
|
|
|
def test_short_code(self):
|
|
cmd, libelle = find_cmd("K8")
|
|
assert cmd is None
|
|
|
|
|
|
class TestDetectTypeGHM:
|
|
def test_chirurgical(self):
|
|
actes = [ActeCCAM(texte="Cholécystectomie", code_ccam_suggestion="HMFC004")]
|
|
assert _detect_type_ghm(actes) == "C"
|
|
|
|
def test_interventionnel(self):
|
|
actes = [ActeCCAM(texte="Échographie", code_ccam_suggestion="ZCQM001")]
|
|
assert _detect_type_ghm(actes) == "K"
|
|
|
|
def test_medical_no_actes(self):
|
|
assert _detect_type_ghm([]) == "M"
|
|
|
|
def test_medical_no_code(self):
|
|
actes = [ActeCCAM(texte="Biopsie", code_ccam_suggestion=None)]
|
|
assert _detect_type_ghm(actes) == "M"
|
|
|
|
def test_chirurgical_overrides_interventionnel(self):
|
|
actes = [
|
|
ActeCCAM(texte="Écho", code_ccam_suggestion="ZCQM001"),
|
|
ActeCCAM(texte="Cholécystectomie", code_ccam_suggestion="HMFC004"),
|
|
]
|
|
assert _detect_type_ghm(actes) == "C"
|
|
|
|
|
|
class TestSeverityLevels:
|
|
def test_no_cma_level_1(self):
|
|
das = [Diagnostic(texte="HTA", cim10_suggestion="I10")]
|
|
niveau, cma, cms = _compute_severity(das)
|
|
assert niveau == 1
|
|
|
|
def test_two_cma_level_2(self):
|
|
das = [
|
|
Diagnostic(texte="FA", cim10_suggestion="I48.9", est_cma=True),
|
|
Diagnostic(texte="IRA", cim10_suggestion="N17.9", est_cma=True),
|
|
]
|
|
niveau, cma, cms = _compute_severity(das)
|
|
assert niveau == 2
|
|
assert cma == 2
|
|
|
|
def test_one_cms_level_3(self):
|
|
das = [
|
|
Diagnostic(texte="Sepsis sévère", cim10_suggestion="A41.9", est_cma=True, est_cms=True),
|
|
]
|
|
niveau, cma, cms = _compute_severity(das)
|
|
assert niveau == 3
|
|
assert cms == 1
|
|
|
|
def test_two_cms_level_4(self):
|
|
das = [
|
|
Diagnostic(texte="Sepsis", cim10_suggestion="A41.9", est_cma=True, est_cms=True),
|
|
Diagnostic(texte="IRA", cim10_suggestion="N17.9", est_cma=True, est_cms=True),
|
|
]
|
|
niveau, cma, cms = _compute_severity(das)
|
|
assert niveau == 4
|
|
assert cms == 2
|
|
|
|
def test_three_cma_level_3(self):
|
|
das = [
|
|
Diagnostic(texte="FA", cim10_suggestion="I48.9", est_cma=True),
|
|
Diagnostic(texte="IRA", cim10_suggestion="N17.9", est_cma=True),
|
|
Diagnostic(texte="Diabète", cim10_suggestion="E11.9", est_cma=True),
|
|
]
|
|
niveau, cma, cms = _compute_severity(das)
|
|
assert niveau == 3
|
|
assert cma == 3
|
|
|
|
|
|
class TestEstimateGHM:
|
|
def test_chirurgical_with_cma(self):
|
|
dossier = DossierMedical(
|
|
diagnostic_principal=Diagnostic(texte="Cholécystite", cim10_suggestion="K80.1"),
|
|
actes_ccam=[ActeCCAM(texte="Cholécystectomie", code_ccam_suggestion="HMFC004")],
|
|
diagnostics_associes=[
|
|
Diagnostic(texte="FA", cim10_suggestion="I48.9", est_cma=True),
|
|
Diagnostic(texte="IRA", cim10_suggestion="N17.9", est_cma=True),
|
|
],
|
|
)
|
|
ghm = estimate_ghm(dossier)
|
|
assert ghm.cmd == "07"
|
|
assert ghm.type_ghm == "C"
|
|
assert ghm.severite == 2
|
|
assert ghm.ghm_approx == "07C??2"
|
|
assert ghm.cma_count == 2
|
|
|
|
def test_medical_sans_actes(self):
|
|
dossier = DossierMedical(
|
|
diagnostic_principal=Diagnostic(texte="Pneumonie", cim10_suggestion="J18.9"),
|
|
)
|
|
ghm = estimate_ghm(dossier)
|
|
assert ghm.cmd == "04"
|
|
assert ghm.type_ghm == "M"
|
|
assert ghm.severite == 1
|
|
assert ghm.ghm_approx == "04M??1"
|
|
|
|
def test_dp_absent(self):
|
|
dossier = DossierMedical()
|
|
ghm = estimate_ghm(dossier)
|
|
assert ghm.cmd is None
|
|
assert ghm.ghm_approx is None
|
|
assert any("DP absent" in a for a in ghm.alertes)
|
|
|
|
def test_dp_sans_code(self):
|
|
dossier = DossierMedical(
|
|
diagnostic_principal=Diagnostic(texte="Douleur thoracique"),
|
|
)
|
|
ghm = estimate_ghm(dossier)
|
|
assert ghm.cmd is None
|
|
assert any("sans code" in a for a in ghm.alertes)
|
|
|
|
def test_dp_symptomatique(self):
|
|
dossier = DossierMedical(
|
|
diagnostic_principal=Diagnostic(texte="Douleur thoracique", cim10_suggestion="R07.4"),
|
|
)
|
|
ghm = estimate_ghm(dossier)
|
|
assert ghm.cmd == "23"
|
|
assert any("symptomatique" in a for a in ghm.alertes)
|