fix(5.19): re-snapshot held pe caile de re-punere in coada

Finding #1 (/code-review high): create_prezentari (reactivare) si reresolve_account
re-calculau `held` din comutatorul contului la tranzitia -> queued, dar caile de
re-punere din dashboard/admin lasau `held` pe valoarea VECHE:
  - submissions_admin.requeue_submission (API /repune + web)
  - web post_corectie_trimitere
  - web post_repune_trimitere (calea cod_prestatie)
  - web post_bulk_fix

Consecinta: un rand ingerat pe Auto ON (held=0) care esueaza, apoi contul trecut pe
Auto OFF, la re-punere pastra held=0 -> worker-ul (claim_one AND held=0) il auto-trimitea
la RAR (FINALIZATA ireversibil) desi contul e Auto OFF. Directia inversa: rand held=1
repus pe cont trecut Auto ON ramanea blocat.

Fix: held=held_for_account(conn, account_or_default(account_id)) pe toate cele 4 UPDATE-uri
-> queued (paritate cu caile deja corecte). Bulk-fix hoisteaza snapshot-ul o data inainte
de bucla. Worker requeue_with_backoff neatins (opereaza doar pe randuri deja claim-uite,
held=0 -> corect).

Test: tests/test_held_requeue_snapshot.py (ambele directii). 1535 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-07-06 10:12:57 +00:00
parent 3b5cf7a7d9
commit 458c3fd43c
4 changed files with 117 additions and 9 deletions

View File

@@ -20,6 +20,7 @@ from __future__ import annotations
import json
from .accounts import held_for_account
from .mapping import (
account_or_default,
account_scope_clause,
@@ -103,11 +104,15 @@ def requeue_submission(conn, account_id: int, sid: int) -> dict:
valid_codes = load_nomenclator_codes(conn) or None
cl = classify_prezentare(content, mapping, mapping_meta, valid_codes)
# PRD 5.19 US-002: re-snapshot `held` din comutatorul contului la re-punere in coada
# (paritate cu create_prezentari/reresolve_account). Fara asta un rand repus pastra
# `held` VECHI si s-ar auto-trimite desi contul e Auto OFF (sau ar ramane blocat cand e ON).
held_val = held_for_account(conn, account_or_default(account_id))
conn.execute(
"UPDATE submissions SET status=?, payload_json=?, rar_error=?, retry_count=0, "
"next_attempt_at=NULL, sending_since=NULL, purge_after=NULL, updated_at=datetime('now') "
"next_attempt_at=NULL, sending_since=NULL, purge_after=NULL, held=?, updated_at=datetime('now') "
"WHERE id=?",
(cl["status"], json.dumps(cl["content"], ensure_ascii=False), cl["rar_error"], sid),
(cl["status"], json.dumps(cl["content"], ensure_ascii=False), cl["rar_error"], held_val, sid),
)
log_event(
"submission_repus",