feat(5.15+5.14): CLOSE — fix-uri code-review + embeddings functional

5.15 (propagare design + dashboard editare) si 5.14 (mapare LLM distilata)
inchise dupa /code-review high. 8 buguri reparate TDD:

- HIGH modal nu se deschidea pe randul slim (base.html: trimitere-slim)
- HIGH /repune trunchia prestatii (declaratie incompleta la RAR) -> iterare
  peste existing, codes pozitional
- HIGH embeddings incarca model ~230MB degeaba pe corpus gol -> poarta has_corpus()
- HIGH picker chips gol pe re-render eroare -> conn/account_id pe toate ramurile
- MED obs re-derivat dupa stergere explicita -> _merge_override pastreaza obs=''
- MED mapare salvata fara denumire poluă GOLD -> _record_gold_validation guard
- MED typo nome_prestatie -> nume_prestatie in select /repune
- MED bucketare timp +3h gresita iarna -> SQLite localtime + TZ=Europe/Bucharest

Embeddings WIRE-uit functional (PRD #15, decizie user): ensure_embeddings_corpus
construieste corpus din nomenclator, gated pe AUTOPASS_EMBEDDINGS_ENABLED (default
off). Marime model corectata ~50MB->~230MB (estimare PRD gresita).

Cleanup: hoist load_* din bucla bulk-fix; import re la top.
Regresie: 1256 passed, 1 deselected (live), 0 failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-28 20:48:34 +00:00
parent 9e42e7ed6f
commit 3fc53534e2
53 changed files with 9684 additions and 384 deletions

View File

@@ -12,9 +12,22 @@
{# Versiunea datelor cu care s-a randat tabelul; pollerul "Date noi" o compara. #}
<span id="trimiteri-versiune" data-v="{{ versiune_trimiteri | default('') }}" hidden></span>
{% if bulk_message %}
{# Sumar actiune bulk (US-010 PRD 5.15): afisat dupa bulk-fix, disparut la urmatoarea reincarcare. #}
<div class="bulk-message" role="status" aria-live="polite"
style="font-size:13px; color:var(--ink); background:var(--card2);
border:1px solid var(--line); border-radius:6px;
padding:6px 10px; margin-bottom:8px;">
{{ bulk_message }}
</div>
{% endif %}
{% if rows %}
{# Form de stergere bulk. Selectia opereaza DOAR pe randuri blocate
(gestionabil); sent/sending/queued nu au checkbox (read-only). #}
{# Form bulk cu DOUA actiuni: (1) aplica cod RAR la selectate (bulk-fix, US-010),
(2) sterge selectate (sterge-bulk). Selectia opereaza DOAR pe randuri blocate
(gestionabil); sent/sending/queued nu au checkbox (read-only).
Butonul "Aplica cod" foloseste hx-post propriu (override form action).
hx-disinherit="hx-confirm" pe form => butonul aplica-cod NU mosteneste confirmare. #}
<form id="bulk-trimiteri"
hx-post="/trimiteri/sterge-bulk"
hx-target="#submissions-wrap"
@@ -23,30 +36,47 @@
hx-disinherit="hx-confirm"
style="margin:0;">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<div style="display:flex; justify-content:flex-end; margin-bottom:8px;">
<div style="display:flex; justify-content:flex-end; align-items:center;
gap:6px; margin-bottom:8px; flex-wrap:wrap;">
{# Bulk-fix: input cod + buton aplica (US-010 PRD 5.15) #}
<input type="text" name="cod_prestatie" id="bulk-fix-cod"
placeholder="Cod RAR (ex: OE-1)"
autocomplete="off" autocapitalize="characters"
style="width:120px; font-size:12px; padding:3px 7px;
border:1px solid var(--line); border-radius:5px;
background:var(--card2); color:var(--ink);"
aria-label="Cod RAR de aplicat la randurile selectate">
<button type="button"
hx-post="/trimiteri/bulk-fix"
hx-target="#submissions-wrap"
hx-swap="innerHTML"
style="background:var(--card); color:var(--accent); border-color:var(--accent);
font-size:13px; padding:4px 10px; border-radius:5px; cursor:pointer;"
aria-label="Aplica codul RAR la randurile blocate selectate">
Aplica cod
</button>
{# Separator vizual #}
<span style="color:var(--muted); font-size:11px; padding:0 2px;" aria-hidden="true">|</span>
{# Bulk-delete: pastreaza exact comportamentul existent #}
<button type="submit" id="bulk-sterge-btn"
style="background:var(--card); color:var(--err); border-color:var(--err); font-size:13px; padding:4px 10px;">
style="background:var(--card); color:var(--err); border-color:var(--err);
font-size:13px; padding:4px 10px; border-radius:5px; cursor:pointer;">
Sterge selectate
</button>
</div>
<div class="tablewrap tabel-trimiteri">
<table>
<thead><tr>
<th class="col-chk"><span class="muted" title="Selecteaza randuri blocate">&#10003;</span></th>
<th class="col-id">#</th>
<th class="col-stare">Stare</th>
<th class="col-vehicul">Vehicul</th>
<th class="col-operatie">Operatie</th>
<th class="col-data">Data prestatie</th>
<th class="col-rar">Nr. prezentare RAR</th>
<th class="col-actualizat">Actualizat</th>
</tr></thead>
<tbody>
{# Lista slim trimiteri (US-004, PRD 5.15).
Inlocuieste tabelul cu randuri compacte: VIN mono + operatie·ora + pill.
Nr. inmatriculare, data prestatie si nr. prezentare RAR raman accesibile
pe linia meta discreta (linia 3) si in modalul de detaliu. #}
<ul class="lista-trimiteri-slim" role="list"
aria-label="Lista trimiteri">
{% for r in rows %}
{# Randul declanseaza deschiderea MODALULUI global (#detaliu-modal-body).
{# Randul slim: stanga = VIN mono scurt (L1) + operatie·ora muted (L2) + meta (L3);
dreapta = pill de stare. Click deschide modalul global (#detaliu-modal-body).
Clickabil/focusabil (role=button); Enter/Space deschid modalul (JS in base.html). #}
<tr id="trimitere-row-{{ r.id }}"
class="trimitere-row"
<li id="trimitere-row-{{ r.id }}"
class="trimitere-slim"
data-detaliu-id="{{ r.id }}"
hx-get="/_fragments/trimitere/{{ r.id }}"
hx-target="#detaliu-modal-body"
@@ -55,47 +85,61 @@
aria-haspopup="dialog"
style="cursor:pointer;"
title="Click pentru detaliul complet">
<td class="col-chk" onclick="event.stopPropagation();">
{# Zona checkbox — nu declanseaza modalul (stopPropagation).
Vizibila DOAR pe randurile gestionabile (error/needs_data/needs_mapping).
Latimea fixa previne reflow la prezenta/absenta checkbox-ului. #}
<div style="flex:0 0 22px; display:flex; align-items:center;" onclick="event.stopPropagation();">
{% if r.gestionabil %}
<input type="checkbox" name="submission_id" value="{{ r.id }}"
aria-label="Selecteaza trimiterea #{{ r.id }} pentru stergere">
{% endif %}
</td>
<td class="col-id muted" data-eticheta="#">{{ r.id }}</td>
<td class="col-stare" data-eticheta="Stare">
<span class="pill {{ r.stare_css }}" title="{{ r.stare_text }}">{{ r.stare_scurt }}</span>
{# Eticheta umana scurta sub pill — text mic, `s-error` pe error/needs_*
(singurele stari pe care `eticheta_problema` e ne-goala).
Stare transmisa prin TEXT, nu doar culoare. Codul brut ramane in modal. #}
{% if r.eticheta_problema and r.eticheta_problema != r.stare_scurt and r.eticheta_problema != r.stare_text %}
<div class="eticheta-problema s-error">{{ r.eticheta_problema }}</div>
{% endif %}
</td>
<td class="col-vehicul" data-eticheta="Vehicul">
{{ r.prez.vehicul_nr }}
</div>
{# Bloc text principal — stanga, ocupa spatiul ramas #}
<div style="flex:1 1 auto; min-width:0;">
{# Linia 1: VIN mono scurt (slim-vin).
Guard: vin_scurt='—' inseamna VIN lipsa; fallback la vehicul_nr. #}
{% if r.prez.vin_scurt and r.prez.vin_scurt != '—' %}
{# VIN pe rand separat sub nr (element block, nu span inline) #}
<div class="muted" style="font-size:12px;">{{ r.prez.vin_scurt }}</div>
{% endif %}
</td>
<td class="col-operatie" data-eticheta="Operatie">
<div>{{ r.prez.operatie }}</div>
{# Doar codul RAR (ex. OE-2), FARA prefixul "cod RAR:" — chip muted discret;
cand nemapat afiseaza "nemapat" muted. #}
{% if r.prez.cod_rar and r.prez.cod_rar != '—' %}
<div class="cod-rar-sub"><span class="cod-rar-cod">{{ r.prez.cod_rar }}</span></div>
<div class="slim-vin">{{ r.prez.vin_scurt }}</div>
{% else %}
<div class="muted cod-rar-sub">nemapat</div>
<div class="slim-vin muted">{{ r.prez.vehicul_nr }}</div>
{% endif %}
</td>
<td class="col-data" data-eticheta="Data prestatie">{{ r.prez.data_prestatie }}</td>
<td class="col-rar" data-eticheta="Nr. prezentare RAR">{{ r.id_prezentare or '—' }}</td>
<td class="col-actualizat muted" data-eticheta="Actualizat">{{ r.updated_at }}</td>
</tr>
{# Linia 2: Operatie · ora/data (slim-meta muted) #}
<div class="slim-meta">{{ r.prez.operatie }} · {{ r.updated_at }}</div>
{# Cod RAR sau indicatorul 'nemapat': discret sub operatie.
Mentine compatibilitatea cu testele cod_rar: OE-2 vizibil, fara prefix 'cod RAR:'. #}
{% if r.prez.cod_rar and r.prez.cod_rar != '—' %}
<div class="slim-meta"><span class="cod-rar-cod">{{ r.prez.cod_rar }}</span></div>
{% else %}
<div class="slim-meta muted cod-rar-sub">nemapat</div>
{% endif %}
{# Linia meta discreta: nr inmatriculare · data prestatie · nr prezentare RAR.
Accesibila pe rand; informatia completa e in modalul de detaliu. #}
<div class="slim-meta" style="opacity:0.7;">
{{ r.prez.vehicul_nr -}}
{%- if r.prez.data_prestatie and r.prez.data_prestatie != '—' %} · {{ r.prez.data_prestatie }}{% endif -%}
{%- if r.id_prezentare %} · #{{ r.id_prezentare }}{% endif %}
</div>
{# Eticheta umana scurta sub pill — text mic, s-error pe error/needs_*.
Afisata DOAR pe randuri cu problema (eticheta_problema ne-goala).
Starea transmisa prin TEXT, nu doar culoare. #}
{% if r.eticheta_problema and r.eticheta_problema != r.stare_scurt and r.eticheta_problema != r.stare_text %}
<div class="eticheta-problema s-error" style="font-size:10px; margin-top:2px;">{{ r.eticheta_problema }}</div>
{% endif %}
</div>
{# Pill de stare — dreapta, flex:none #}
<span class="pill {{ r.stare_css }}" title="{{ r.stare_text }}"
style="flex:0 0 auto; white-space:nowrap;">{{ r.stare_scurt }}</span>
</li>
{% endfor %}
</tbody>
</table>
</div>
</ul>
</form>
{#