feat: Phase 4 — viewer enrichi, non-cumul CCAM, fusion multi-PDFs + rebuild FAISS (21 141 vecteurs)

- Viewer : badges compteurs (DAS, actes, alertes, CMA), raisonnement LLM pliable, regroupement CCAM, navigation patient, alertes NON-CUMUL en rouge
- Non-cumul CCAM : 3 règles heuristiques (même base, même regroupement/jour, paires incompatibles)
- Fusion multi-PDFs : merge_dossiers() avec priorité Trackare, spécificité CIM-10, déduplication, champ source_files
- Index FAISS reconstruit : 21 141 vecteurs (CCAM dict 8 257 + CIM-10 alpha 306)
- 192 tests unitaires passent

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
dom
2026-02-11 12:43:34 +01:00
parent 7e69f994b0
commit 9d07894c6f
12 changed files with 1013 additions and 26 deletions

View File

@@ -31,12 +31,30 @@
{% set ns.count = ns.count + 1 %}
{% endif %}
{% endfor %}
<h3 style="display:flex;align-items:baseline;gap:0.75rem;">
{% set stats = group_stats.get(group_name, {}) %}
<h3 style="display:flex;align-items:baseline;gap:0.75rem;flex-wrap:wrap;">
{{ group_name }}
<span style="font-size:0.75rem;font-weight:400;color:#64748b;">
{{ items|length }} fichier(s){% if ns.count %} — total : {{ ns.total|round(1) }}s{% endif %}
</span>
{% if stats %}
<span class="badge-count badge-das">{{ stats.das_count }} DAS</span>
<span class="badge-count badge-actes">{{ stats.actes_count }} actes</span>
{% if stats.alertes_count %}<span class="badge-count badge-alertes">{{ stats.alertes_count }} alertes</span>{% endif %}
{% if stats.cma_count %}<span class="badge-count badge-cma">{{ stats.cma_count }} CMA</span>{% endif %}
{% endif %}
</h3>
{% if items|length > 1 %}
{% for item in items if 'fusionne' in item.name %}
{% if loop.first %}
<div style="margin-bottom:0.75rem;">
<a href="/dossier/{{ item.path_rel }}" class="badge-count badge-fusion" style="text-decoration:none;font-size:0.8rem;padding:4px 12px;">
Vue patient fusionnée
</a>
</div>
{% endif %}
{% endfor %}
{% endif %}
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:1rem;">
{% for item in items %}
<a href="/dossier/{{ item.path_rel }}" style="text-decoration:none;color:inherit;">
@@ -44,9 +62,15 @@
<div style="font-weight:600;font-size:0.9rem;margin-bottom:0.4rem;color:#0f172a;">
{{ item.name }}
</div>
{% if item.dossier.document_type %}
<span class="badge" style="background:#e0e7ff;color:#3730a3;">{{ item.dossier.document_type }}</span>
{% endif %}
<div style="display:flex;flex-wrap:wrap;gap:0.3rem;margin-bottom:0.4rem;">
{% if item.dossier.document_type %}
<span class="badge" style="background:#e0e7ff;color:#3730a3;">{{ item.dossier.document_type }}</span>
{% endif %}
{% if item.dossier.source_files %}<span class="badge badge-fusion">fusionné</span>{% endif %}
{% if item.dossier.diagnostics_associes %}<span class="badge-count badge-das">{{ item.dossier.diagnostics_associes|length }} DAS</span>{% endif %}
{% if item.dossier.actes_ccam %}<span class="badge-count badge-actes">{{ item.dossier.actes_ccam|length }} actes</span>{% endif %}
{% if item.dossier.alertes_codage %}<span class="badge-count badge-alertes">{{ item.dossier.alertes_codage|length }} alertes</span>{% endif %}
</div>
{% if item.dossier.diagnostic_principal %}
<div style="margin-top:0.5rem;font-size:0.8rem;color:#334155;">
<strong>DP :</strong> {{ item.dossier.diagnostic_principal.texte[:80] }}{% if item.dossier.diagnostic_principal.texte|length > 80 %}…{% endif %}