Implementeaza PRD 5.6 complet (14 stories, TDD). Doua axe:
Lifecycle trimiteri blocate (Val A):
- submissions_admin.py: sterge/repune scoped (404 cross-account inaintea lui 409 stare)
- reactivare dedup peste `error` cu CAS (WHERE id=? AND status='error'), creds noi in
submissions + accounts.rar_creds_enc; worker invalideaza sesiunea RAR la creds proaspete
(JWT 30h vechi nu mai trimite cu parola gresita); camp aditiv `reactivated:true`
- retentie randuri blocate 30z; purge_expired exclude queued/sending; purge_after curatat
la reactivare/requeue
- API DELETE /v1/prezentari/{id} + /repune (200+JSON); UI butoane + bulk + banner actionabil
Observabilitate:
- app/observ.py log_event: dublu canal app_events (DB) + RotatingFileHandler per-proces,
redactare creds/PII la scriere (redact_pii/vin_partial)
- request_id middleware + X-Request-ID pe toate raspunsurile
- handler global excepții -> 500 envelope 6-chei + request_id (traceback doar in jurnal)
- audit cerere API (api_prezentari/api_auth_esuat) + audit worker (rar_login/tranzitii)
- tab "Jurnal" filtrabil scoped (non-admin doar contul sau); retentie jurnal 90z
- rar_error expus in GET /v1/prezentari/{id} (recovery observabil)
pytest -q: 741 passed, 0 failed. Docs: PRD raport VERIFY, contract endpointuri noi, ROADMAP.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
80 lines
2.7 KiB
HTML
80 lines
2.7 KiB
HTML
{% if rows %}
|
|
{# US-011: form de stergere bulk. Selectia opereaza DOAR pe randuri blocate
|
|
(gestionabil); sent/sending/queued nu au checkbox (read-only). #}
|
|
<form id="bulk-trimiteri"
|
|
hx-post="/trimiteri/sterge-bulk"
|
|
hx-target="#submissions-wrap"
|
|
hx-swap="innerHTML"
|
|
hx-confirm="Stergi definitiv trimiterile selectate?"
|
|
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;">
|
|
<button type="submit" id="bulk-sterge-btn"
|
|
style="background:var(--card); color:var(--err); border-color:var(--err); font-size:13px; padding:4px 10px;">
|
|
Sterge selectate
|
|
</button>
|
|
</div>
|
|
<div class="tablewrap">
|
|
<table>
|
|
<thead><tr>
|
|
<th style="width:28px;"><span class="muted" title="Selecteaza randuri blocate">✓</span></th>
|
|
<th>#</th>
|
|
<th>Stare</th>
|
|
<th>Vehicul</th>
|
|
<th>Operatie</th>
|
|
<th>Data prestatie</th>
|
|
<th>Nr. prezentare RAR</th>
|
|
<th>Actualizat</th>
|
|
<th>Motiv</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
{% for r in rows %}
|
|
<tr id="trimitere-row-{{ r.id }}"
|
|
hx-get="/_fragments/trimitere/{{ r.id }}"
|
|
hx-target="#trimitere-detaliu"
|
|
hx-swap="innerHTML"
|
|
style="cursor:pointer;"
|
|
title="Click pentru detaliul complet">
|
|
<td 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="muted">{{ r.id }}</td>
|
|
<td><span class="pill {{ r.stare_css }}">{{ r.stare_text }}</span></td>
|
|
<td>
|
|
{{ r.prez.vehicul_nr }}
|
|
{% if r.prez.vin_scurt and r.prez.vin_scurt != '—' %}
|
|
<span class="muted" style="font-size:12px;">{{ r.prez.vin_scurt }}</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ r.prez.operatie }}</td>
|
|
<td>{{ r.prez.data_prestatie }}</td>
|
|
<td>{{ r.id_prezentare or '—' }}</td>
|
|
<td class="muted">{{ r.updated_at }}</td>
|
|
<td class="muted" style="white-space:normal; max-width:280px;">{{ r.motiv }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</form>
|
|
{% elif filtru_activ %}
|
|
<div class="empty">
|
|
Nimic pe filtrul curent.
|
|
<a href="#"
|
|
onclick="var f=document.getElementById('filtre-trimiteri'); if(f) f.reset(); return true;"
|
|
hx-get="/_fragments/submissions" hx-target="#submissions-wrap" hx-swap="innerHTML">
|
|
sterge filtrele
|
|
</a>
|
|
</div>
|
|
{% else %}
|
|
<div class="empty">
|
|
Nicio trimitere inca —
|
|
<a href="/?tab=acasa">incepe cu un import</a>
|
|
sau trimite o prezentare prin API.
|
|
</div>
|
|
{% endif %}
|