feat(T2): reconciliere anti-duplicat + retry/backoff + recuperare orfane
Inchide bucla de trimitere (plan.md sect. 4 worker, failure registry).
- app/reconcile.py: match_finalizata pe vin+dataPrestatie+odometruFinal (int),
alege id maxim la duplicate (RAR accepta duplicate, confirmat live)
- app/rar_client.get_finalizate: parseaza data.content (descoperit live ca
ruta = GET /prezentari/getAllPrezentariFinalizate; filtrele nu merg pe test)
- app/worker rescris:
- recuperare orfane (rand 'sending' peste lease = worker mort mid-POST)
- pe eroare tranzitorie/timeout: reconciliere INAINTE de re-send (anti-duplicat);
daca recordul exista la RAR -> sent fara re-POST
- retry/backoff exponential; peste worker_max_retries -> error + banner
- re-login la token expirat (JWT 30h)
- schema: coloana next_attempt_at (backoff) + migrare aditiva in init_db
- config: worker_sending_lease_s, worker_retry_base_s/max_s, worker_max_retries
- contract: documentata ruta+forma getAllPrezentariFinalizate (verificat live)
Verify: pytest 54 passed (15 noi T2) + validare live (reconciliere record 68514).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -202,8 +202,11 @@ Nimic din cod nu e scris încă (`app/`, `tools/` nu există). Ordine recomandat
|
||||
- [x] **T4 (P1) — payload builder** ✅ 2026-06-15. `app/payload.py`: `status:"FINALIZATA"`, `sistemReparat:"null"`, fără
|
||||
`tipPrestatie`, `odometruFinal`/`odometruInitial` string (initial gol → null), `prestatii:[{codPrestatie,idPrezentare:null}]`,
|
||||
obs/b64Image omise când lipsesc. Verify: 10 teste (`tests/test_payload.py`), inclusiv snapshot vs exemplul oficial din contract.
|
||||
- [ ] **T2 (P1) — `app/worker` reconciliere** VIN+dată+odometru înainte de re-send pe `sending` + lease/timeout orfane.
|
||||
Verify: test integration — răspuns pierdut simulat → fără duplicat la RAR.
|
||||
- [x] **T2 (P1) — `app/worker` reconciliere** ✅ 2026-06-15. `app/reconcile.py` match pe vin+dataPrestatie+odometruFinal(int,
|
||||
id maxim la duplicate) + worker: recuperare orfane (lease), reconciliere pe eroare tranzitorie/timeout înainte de re-send,
|
||||
retry/backoff exponential (peste `worker_max_retries` → error+banner), re-login la token expirat. Rută monitorizare descoperită
|
||||
live: `GET /prezentari/getAllPrezentariFinalizate` → `data.content` (filtrele nu merg pe test → fetch tot, match client-side).
|
||||
Verify: 15 teste (`tests/test_worker_reconcile.py`) + validare LIVE (reconciliere record 68514 din finalizate reale).
|
||||
- [ ] **T6 (P2) — worker proces/container propriu supravegheat;** `/healthz` pică → restart. Verify: worker omorât → restart automat.
|
||||
- [ ] **T7 (P2) — deploy:** SQLite pe volum persistent numit + backup (singura copie durabilă, re-push scos).
|
||||
Verify: recreare container → coada supraviețuiește.
|
||||
|
||||
Reference in New Issue
Block a user