Files
rar-autopass/docs/runbook-rollback-5.19.md
Claude Agent 3b5cf7a7d9 feat(5.19): auto-send toggle per cont + tinere manuala randuri (held)
Comutator accounts.auto_send_enabled per cont: Auto OFF (default) tine randurile
la ingestie (submissions.held=1), worker-ul (claim_one AND held=0) le sare pana la
eliberare umana (per rand/bulk/auto-release OFF->ON). Snapshot held prin chokepoint
unic held_for_account pe toate caile de ingestie (API, import, reresolve, reactivare).

- schema/migrare: coloana held + index partial idx_submissions_held; auto_send_enabled
- API: echo onest held+motiv (US-010), ruta /prezentari/{id}/trimite-acum
- web: toggle header, modal confirmare tipata, buton Trimite per rand + Trimite toate,
  banner coada tinuta imbatranita (L.142), contor "In asteptare (manual)"
- worker: expire_held (US-008, inchide gaura retentie PII), metrics held gauges
- ops: tools/carantina_held + runbook rollback (R4)

Nota review (/code-review high): re-snapshot held lipseste pe caile repune/corectie
(requeue_submission, post_corectie, bulk-fix) — de aliniat separat cu create_prezentari.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 08:34:40 +00:00

2.3 KiB

Runbook — Rollback sigur al feature-ului "Auto send / coada tinuta" (PRD 5.19)

Procedura operationala pentru cazul in care trebuie sa dai revert pe cod care atinge claim_one / logica held din PRD 5.19.

De ce e periculos revertul (Riscul R4)

Feature-ul 5.19 tine randuri manual: un rand queued AND held=1 NU pleaca la RAR pentru ca claim_one (worker) filtreaza cu AND held=0.

Daca dai revert pe codul worker-ului DUPA ce baza contine deja randuri cu held=1, worker-ul revenit pierde filtrul AND held=0 -> ar prelua si trimite la RAR TOATE randurile tinute. RAR FINALIZATA e IREVERSIBILA (fara anulare prin API) — declari real, definitiv, randuri care fusesera puse deoparte intentionat.

Procedura (copy-paste, in ordine)

1. INAINTE de orice revert — carantineaza randurile tinute

Pe masina gateway, cu acelasi mediu ca aplicatia (acelasi AUTOPASS_DB_PATH):

# Verifica intai cate randuri sunt tinute (nu scrie nimic):
python3 -m tools.carantina_held --dry-run

# Apoi carantineaza efectiv:
python3 -m tools.carantina_held

Optional, opreste worker-ul in timp ce faci operatia, ca sa nu concureze:

./start.sh stop

2. Ce face carantina

tools/carantina_held.py ruleaza, atomic:

UPDATE submissions
   SET status='error', rar_error='ROLLBACK_QUARANTINE', updated_at=datetime('now')
 WHERE held=1 AND status='queued';

Adica scoate randurile tinute din coada (queued -> error) cu mesajul ROLLBACK_QUARANTINE. Un worker fara filtrul held nu mai poate prelua un rand error -> randurile NU pleaca la RAR pe timpul revertului. sending / sent NU se ating (FINALIZATA e terminal la RAR). Tool-ul afiseaza cate randuri a carantinat.

3. DUPA revert (sau dupa ce revii pe codul 5.19) — reactiveaza randurile

Randurile carantinate sunt acum error / ROLLBACK_QUARANTINE. Ele NU sunt trimise si NU se re-incearca automat. Cand vrei sa le declari la RAR, repune-le manual din dashboard (butonul de repunere pe rand -> revine queued) si trimite-le controlat (per rand sau "Trimite toate"), dupa ce te-ai asigurat ca filtrul held este din nou in cod (revenire pe 5.19) sau ca trimiterea lor e intentionata.

Nu exista un "un-quarantine" automat: reactivarea e deliberat manuala, ca sa nu repui accidental in coada exact randurile pe care le protejai.