feat: dictionnaire CCAM complet (8 257 codes) + index FAISS enrichi + validation actes
Phase 2 (CCAM) : - Nouveau src/medical/ccam_dict.py : build depuis CCAM_V81.xls via xlrd, lookup 3 niveaux, validation codes - Intégration dans l'extracteur : fallback ccam_lookup + _validate_ccam() avec alertes - CLI : --build-ccam-dict, --rebuild-index Phase 3 (FAISS) : - Chunks CCAM depuis le dictionnaire JSON (priorité sur le PDF) - Chunks CIM-10 index alphabétique (terme → code) - Priorisation cim10_alpha dans la recherche RAG Viewer : endpoint reprocess + bloc scripts Tests : 8 tests CCAM + tests raisonnement RAG (161 passed) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ from typing import Optional
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from .cim10_dict import lookup as dict_lookup, normalize_text
|
||||
from .ccam_dict import lookup as ccam_lookup, validate_code as ccam_validate
|
||||
from ..config import (
|
||||
ActeCCAM,
|
||||
BiologieCle,
|
||||
@@ -113,6 +114,9 @@ def extract_medical_info(
|
||||
if use_rag:
|
||||
_enrich_with_rag(dossier)
|
||||
|
||||
# Post-processing : validation des codes CCAM contre le dictionnaire
|
||||
_validate_ccam(dossier)
|
||||
|
||||
# Post-processing : exclusions symptôme vs diagnostic précis
|
||||
_apply_exclusion_rules(dossier)
|
||||
|
||||
@@ -395,6 +399,13 @@ def _extract_actes(text: str, dossier: DossierMedical) -> None:
|
||||
date=date,
|
||||
))
|
||||
|
||||
# Fallback : tenter le lookup CCAM dict pour les actes sans code
|
||||
for acte in dossier.actes_ccam:
|
||||
if not acte.code_ccam_suggestion:
|
||||
code = ccam_lookup(acte.texte, domain_overrides=CCAM_MAP)
|
||||
if code:
|
||||
acte.code_ccam_suggestion = code
|
||||
|
||||
|
||||
def _extract_antecedents(text: str, dossier: DossierMedical) -> None:
|
||||
"""Extrait les antécédents."""
|
||||
@@ -625,6 +636,22 @@ def _is_negated_by_edsnlp(term: str, negated_terms: set[str]) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def _validate_ccam(dossier: DossierMedical) -> None:
|
||||
"""Valide les codes CCAM suggérés contre le dictionnaire officiel."""
|
||||
for acte in dossier.actes_ccam:
|
||||
if not acte.code_ccam_suggestion:
|
||||
acte.validite = "non_verifie"
|
||||
continue
|
||||
is_valid, desc = ccam_validate(acte.code_ccam_suggestion)
|
||||
if is_valid:
|
||||
acte.validite = "valide"
|
||||
else:
|
||||
acte.validite = "non_verifie"
|
||||
dossier.alertes_codage.append(
|
||||
f"CCAM {acte.code_ccam_suggestion} ({acte.texte}) : code absent du dictionnaire CCAM V81"
|
||||
)
|
||||
|
||||
|
||||
def _find_act_date(text: str, act_pattern: str) -> str | None:
|
||||
"""Trouve la date associée à un acte."""
|
||||
# Chercher "acte le DD/MM" ou "acte le DD/MM/YYYY"
|
||||
|
||||
Reference in New Issue
Block a user