feat: cache Ollama + parallélisation ThreadPool + filtrage DAS renforcé + modules GHM/CPAM/export RUM
- 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>
This commit is contained in:
@@ -69,6 +69,125 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ---- Estimation GHM ---- #}
|
||||
{% if dossier.ghm_estimation %}
|
||||
{% set ghm = dossier.ghm_estimation %}
|
||||
<div class="card section" style="border-left:4px solid #8b5cf6;">
|
||||
<h3 style="color:#6d28d9;">Estimation GHM</h3>
|
||||
<div class="info-grid">
|
||||
{% if ghm.cmd %}
|
||||
<div class="info-item">
|
||||
<label>CMD</label>
|
||||
<span><strong>{{ ghm.cmd }}</strong>{% if ghm.cmd_libelle %} — {{ ghm.cmd_libelle }}{% endif %}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="info-item">
|
||||
<label>Type</label>
|
||||
{% if ghm.type_ghm == 'C' %}
|
||||
<span class="badge" style="background:#fee2e2;color:#dc2626;">C — Chirurgical</span>
|
||||
{% elif ghm.type_ghm == 'K' %}
|
||||
<span class="badge" style="background:#fef3c7;color:#92400e;">K — Interventionnel</span>
|
||||
{% elif ghm.type_ghm == 'M' %}
|
||||
<span class="badge" style="background:#dbeafe;color:#1d4ed8;">M — Médical</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>Sévérité</label>
|
||||
{% if ghm.severite <= 1 %}
|
||||
<span class="badge" style="background:#d1fae5;color:#065f46;">Niveau {{ ghm.severite }}</span>
|
||||
{% elif ghm.severite == 2 %}
|
||||
<span class="badge" style="background:#fef3c7;color:#92400e;">Niveau {{ ghm.severite }}</span>
|
||||
{% elif ghm.severite == 3 %}
|
||||
<span class="badge" style="background:#fed7aa;color:#9a3412;">Niveau {{ ghm.severite }}</span>
|
||||
{% else %}
|
||||
<span class="badge" style="background:#fee2e2;color:#dc2626;">Niveau {{ ghm.severite }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if ghm.ghm_approx %}
|
||||
<div class="info-item">
|
||||
<label>Code GHM approx.</label>
|
||||
<code style="font-size:1.1rem;font-weight:700;letter-spacing:0.05em;">{{ ghm.ghm_approx }}</code>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="info-item">
|
||||
<label>CMA / CMS</label>
|
||||
<span>{{ ghm.cma_count }} CMA, {{ ghm.cms_count }} CMS</span>
|
||||
</div>
|
||||
</div>
|
||||
{% if ghm.alertes %}
|
||||
<div style="margin-top:0.75rem;">
|
||||
{% for alerte in ghm.alertes %}
|
||||
<div style="font-size:0.8rem;color:#c2410c;margin-bottom:0.2rem;">{{ alerte }}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div style="margin-top:0.75rem;font-size:0.7rem;color:#94a3b8;font-style:italic;">
|
||||
Estimation heuristique — le GHM définitif nécessite le groupeur officiel ATIH
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ---- Contrôle CPAM ---- #}
|
||||
{% if dossier.controles_cpam %}
|
||||
<div class="card section" style="border-left:4px solid #f59e0b;">
|
||||
<h3 style="color:#b45309;">Contrôle CPAM ({{ dossier.controles_cpam|length }})</h3>
|
||||
{% for ctrl in dossier.controles_cpam %}
|
||||
<div style="margin-bottom:1.5rem;{% if not loop.last %}border-bottom:1px solid #e2e8f0;padding-bottom:1rem;{% endif %}">
|
||||
<div style="display:flex;align-items:center;gap:0.5rem;margin-bottom:0.5rem;">
|
||||
<strong>OGC {{ ctrl.numero_ogc }} — {{ ctrl.titre }}</strong>
|
||||
{% if 'retient' in ctrl.decision_ucr|lower %}
|
||||
<span class="badge" style="background:#d1fae5;color:#065f46;">{{ ctrl.decision_ucr }}</span>
|
||||
{% elif 'confirme' in ctrl.decision_ucr|lower %}
|
||||
<span class="badge" style="background:#fee2e2;color:#dc2626;">{{ ctrl.decision_ucr }}</span>
|
||||
{% else %}
|
||||
<span class="badge" style="background:#e0e7ff;color:#3730a3;">{{ ctrl.decision_ucr }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{# Argument CPAM #}
|
||||
{% if ctrl.arg_ucr %}
|
||||
<div style="border-left:3px solid #f59e0b;padding:0.5rem 0.75rem;background:#fffbeb;margin-bottom:0.75rem;font-size:0.85rem;color:#78350f;">
|
||||
<div style="font-size:0.7rem;color:#92400e;text-transform:uppercase;font-weight:600;margin-bottom:0.25rem;">Argument CPAM</div>
|
||||
{{ ctrl.arg_ucr }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Codes contestés #}
|
||||
{% if ctrl.dp_ucr or ctrl.da_ucr or ctrl.dr_ucr or ctrl.actes_ucr %}
|
||||
<div style="margin-bottom:0.75rem;">
|
||||
<div style="font-size:0.7rem;color:#64748b;text-transform:uppercase;font-weight:600;margin-bottom:0.25rem;">Codes contestés</div>
|
||||
<div style="display:flex;gap:0.5rem;flex-wrap:wrap;">
|
||||
{% if ctrl.dp_ucr %}<span class="badge" style="background:#fef3c7;color:#92400e;">DP: {{ ctrl.dp_ucr }}</span>{% endif %}
|
||||
{% if ctrl.da_ucr %}<span class="badge" style="background:#fef3c7;color:#92400e;">DA: {{ ctrl.da_ucr }}</span>{% endif %}
|
||||
{% if ctrl.dr_ucr %}<span class="badge" style="background:#fef3c7;color:#92400e;">DR: {{ ctrl.dr_ucr }}</span>{% endif %}
|
||||
{% if ctrl.actes_ucr %}<span class="badge" style="background:#fef3c7;color:#92400e;">Actes: {{ ctrl.actes_ucr }}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Contre-argumentation #}
|
||||
{% if ctrl.contre_argumentation %}
|
||||
<div style="border-left:3px solid #3b82f6;padding:0.5rem 0.75rem;background:#eff6ff;margin-bottom:0.75rem;font-size:0.85rem;color:#1e3a5f;">
|
||||
<div style="font-size:0.7rem;color:#1d4ed8;text-transform:uppercase;font-weight:600;margin-bottom:0.25rem;">Contre-argumentation</div>
|
||||
<pre style="white-space:pre-wrap;font-family:inherit;margin:0;">{{ ctrl.contre_argumentation }}</pre>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# Sources RAG #}
|
||||
{% if ctrl.sources_reponse %}
|
||||
<details>
|
||||
<summary style="font-size:0.8rem;color:#64748b;">Sources RAG ({{ ctrl.sources_reponse|length }})</summary>
|
||||
{% for src in ctrl.sources_reponse %}
|
||||
<pre style="font-size:0.75rem;">{{ src.document }}{% if src.code %} — {{ src.code }}{% endif %}{% if src.page %} [p.{{ src.page }}]{% endif %}
|
||||
{{ src.extrait or '' }}</pre>
|
||||
{% endfor %}
|
||||
</details>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{# ---- Alertes de codage ---- #}
|
||||
{% if dossier.alertes_codage %}
|
||||
<div class="card section" style="border-left:4px solid #f97316;background:#fff7ed;">
|
||||
|
||||
Reference in New Issue
Block a user