Commit Graph

178 Commits

Author SHA1 Message Date
Claude Agent
cc8c712ed2 feat(landing): butonul hero 'Creeaza cont gratuit' duce la #pret + copy trial nou
Textul din sectiunea AUTH devine 'Ai Pro gratuit primele 30 de zile,
apoi pachetul ales'; testul de trial verifica noul copy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:20:47 +00:00
Claude Agent
251666feb6 feat(landing): pagini publice Termeni/GDPR/Documentatie API + fix link-uri moarte
Antet/footer/stil extrase in include-uri comune (_lp_*.html) folosite de
landing si de shell-ul paginilor statice (landing_static.html). Butoanele
'Vezi cum functioneaza' si 'Vezi documentatia API' devin link-uri reale;
footer-ul si consimtamantul de la inregistrare leaga paginile noi;
Contact indica spre romfast.ro/menu/contact.html.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 14:01:56 +00:00
Claude Agent
9b5006f26c exemple integrare 2026-07-09 13:42:55 +00:00
Claude Agent
e80a20c856 feat(landing): copy nou sectiunea Problem + slidere cu trepte discrete
- headline Problem: "Pierzi 6 zile pe an / introducand manual in Auto-Pass"
- hero: "Declara operatiile de service la RAR Auto-Pass, automat" (accent pe "automat")
- slidere calculator pe trepte fixe (50-500 trimiteri, 30-150 lei/h) cu repere vizibile
- denumirea oficiala "RAR Auto-Pass" peste tot in landing (ROA AUTOPASS ramane brand)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 13:34:15 +00:00
Claude Agent
dc6c1db439 docs(deploy): reguli Dokploy — env vars obligatorii inainte de push, chown volum la schimbare uid
Recapitulare incident 2026-07-09: deploy Error la 0s = interpolare env
(variabile ${VAR:?} nesetate in Dokploy), apoi 404 din volum SQLite
detinut de root fata de userul app uid 10001.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 11:17:14 +00:00
Claude Agent
ec5ca5ba84 feat(landing): fragment wizard import in loc de sectiunea 'calculator' + preturi pe 3 planuri
- sectiunea 'Cum functioneaza': mockup al wizard-ului real (stepper 4 pasi,
  incarcare, potrivire coloane, verificare cu stari si sugestie preselectata,
  bara de confirmare 'Trimite la RAR')
- carduri pret: chips canal de intrare (CSV/XLSX vs +API), banda de economie
  lunara, liste compacte 'Tot ce este la X +'
- cardul Premium eliminat din grila si din select-ul de plan (landing + /signup);
  tier-ul 'premium' ramane valid in backend, alocat doar de admin

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 09:38:38 +00:00
Claude Agent
3ba35abed2 feat(api): raspuns minim implicit + corelare cerere-raspuns + sugestie cod in raspuns; coloana # in lista trimiteri
- POST /v1/prezentari: camp optional 'raspuns' (minim implicit / complet);
  forma minima = 6 chei fixe (index, submission_id, vehicul, status, motiv,
  id_prezentare), formatul detaliat ramane la cerere
- corelare rezultat<->cerere: index 0-based + ecou vin/nr_inmatriculare
- sugestia principala de cod RAR pe nemapate (GOLD partajat > SILVER >
  embeddings > fuzzy peste prag), in motiv si in nemapate[].sugestie
  (si pe dry-run /valideaza); suggestion-only, nu se aplica automat
- lista Trimiteri: coloana # cu id-ul trimiterii (desktop + mobil)
- README: sectiune 'Mapari si sugestii de cod RAR'; contract actualizat

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 08:32:55 +00:00
Claude Agent
c2beede084 fix(web): detaliul trimiterii arata toate codurile RAR cand prima prestatie e exclusa
cod_rar se deriva acum din toate prestatiile (primul cod mapat), nu doar din
primul item; modalul afiseaza lista completa de coduri. Randurile importate
editate pastreaza operatia originala ca item 0 exclus fara cod, iar codurile
adaugate sunt itemii urmatori — modalul afisa fals "nemapat".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 19:42:25 +00:00
Claude Agent
56ebe1f7cb feat(editor): editor prestatii unificat in modal - un select, un rand de chips (PRD 5.23)
Inlocuieste cele 3 controale de asociere cod RAR cu un singur rand de chips
+ un singur select care adauga instant la change. Stare = un hidden chips_state
JSON versionat; post_form_chips redus la 2 actiuni (add/remove). Optgroup
Sugestii (fuzzy/k-NN) + optiune "Nu se declara la RAR" in select, cu tinta
implicita evidentiata si placeholder care o numeste. exclus persistat prin
payload_json (treapta noua de precedenta in resolve_prestatii, round-trip complet).

Siguranta: itemii exclusi sunt scosi din payload la momentul trimiterii
(worker split_prestatii_excluse inainte de build_rar_payload + filtru defensiv),
ca sa nu ajunga NICIODATA la RAR ca codPrestatie:null.

Suita: 1680 passed, 1 skipped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 15:45:34 +00:00
Claude Agent
0bc618763e feat(mapari): regula 'exclude de la declarare' per operatie + stare preview Nedeclarat
Operatiile care nu se declara la RAR (ex. ITP facturat in service) primesc o
regula exclus=1 in operations_mapping, setabila din panoul de mapare al
preview-ului de import si din tab-ul Mapari (optiunea 'Nu se declara la RAR').

- resolve_prestatii(excluded_ops): item nemapat cu op exclusa -> adnotat exclus,
  nu mai e needs_mapping; precedenta: cod explicit > exclus > mapare > reguli text
- split_prestatii_excluse: itemii exclusi nu intra niciodata in payload/cheie
- preview import: rand cu toate operatiile excluse -> stare 'excluded'
  (eticheta Nedeclarat), necomis; operatia dispare din panoul de mapat
- reresolve/corectie/API: submission cu toate operatiile excluse -> needs_data
  cu motiv explicit; ingestia API trateaza excluderea la clasificare
- migrare: coloana operations_mapping.exclus + rebuild import_rows pentru
  CHECK-ul resolved_status cu 'excluded' (o singura data, gardat pe sqlite_master)
- fix flake: clamp similaritate embeddings la [-1,1] (float32 dadea 1.0000001)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 17:49:47 +00:00
Claude Agent
c6e29aa65d fix(import): persista chips prestatii la salvarea din modalul de editare rand
Editorul de rand din preview afisa chips-urile operatie<->cod RAR dar salvarea
extragea doar EDIT_FIELDS — codurile alese se pierdeau si randul ramanea
needs_mapping. Starea chips se reconstruieste din form (conventia /form-chips),
se valideaza fata de nomenclator si se persista in override_json.

Caile de commit (API + web) aplica acum override-ul INAINTE de resolve_prestatii,
ca in preview — altfel prestatiile editate ajungeau nerezolvate in payload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 17:20:01 +00:00
Claude Agent
5a2c976d46 feat(web): UI compact Trimiteri + bara bulk contextuala + fix buton "+" editor (PRD 5.22)
Trimiteri desktop = tabel grid cu header, un rand per trimitere: status =
bulina cu tooltip, mediu = litera T/P, multi-cod = primul cod + badge +N,
sub-linie de eroare cu textul brut RAR doar pe error/needs_data. Mobil:
2 linii prin grid-areas, fara header. Actiunile bulk apar doar la selectie
(bara contextuala cu contor + texte explicite). Mapari: exemplu concret in
loc de descriere la Reguli automate.

Fix buton "+" chips (nu facea nimic, fara eroare): hx-disabled-elt="find
button" mostenit de la form-ul parinte crapa htmx inainte de request ->
hx-disabled-elt="this" explicit pe butoanele chips; separat, no-op-urile
silentioase din post_form_chips au acum mesaje (cod invalid/duplicat) si
confirmare cu chip evidentiat la succes.

Suita: 1622 passed. Verify E2E in browser (desktop 1280 + mobil 390).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 12:27:42 +00:00
Claude Agent
6674d0e3e1 fix(sugestii): inlocuirea de anvelope -> OE-8 + vot k-NN ponderat pe rang
Seed-ul Haiku eticheta sistematic "INLOCUIT ANVELOPE ..." cu OE-1 (223 vs 17
OE-8), desi RAR are cod dedicat OE-8 (inlocuire sezoniera anvelope), asa ca
votul k-NN propunea OE-1 pentru orice inlocuire de anvelope.

- tools/mapare-llm/fix_anvelope_oe8.py: re-etichetare deterministica (187
  randuri DB + seed JSON -> OE-8; regula exclude singular cu pozitie, D/R,
  janta, vulcanizare) + 13 intrari canonice curate manual pentru formularile
  sezoniere absente din corpus ("MONTAT CAUCIUCURI VARA" etc.); idempotent
- enrich_suggestions: ponderea votului = EMB_VOTE_DECAY^rang (0.7) in loc de
  similaritatea bruta — anizotropia modelului lasa zgomotul de coada (ex.
  INLOCUIT BECURII la 0.934 de INLOCUIRE ANVELOPE) sa invinga vecinii corecti
  de rang 1-2; LOO: precizie egala (93.1%), cod-gresit 4.67% -> 4.63%
- test_fix_anvelope_oe8: gardii pe regula + seed-ul din repo (regresie la
  regenerare); auditul k-NN al dezacordurilor nu a gasit alte erori
  sistematice (curatat=OE-2, reglat=OE-4, bujii/ulei=OE-3 raman apararabile)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:26:30 +00:00
Claude Agent
809823a8ae perf+calitate sugestii k-NN: matvec numpy, vot top-5 cu prag calibrat, indicatori import
- embeddings: corpus ca matrice numpy cu norme precalculate; suggest_nearest
  = un matvec (~0.6ms/query fata de ~500ms cosine pur-Python la 17k vectori)
- enrich_suggestions: vot ponderat cu similaritatea pe top-5 vecini (NUL =
  eticheta proprie); prag 0.5 -> 0.88, calibrat LOO pe corpusul SILVER
  (tools/mapare-llm/knn_calibrate.py): precizie 90.5% -> 93.1%, cod gresit
  preselectat 7.2% -> 4.7%; sub prag abtinere -> preselectie fuzzy
- UI: codul sugerat de sistem afisat explicit cu sursa si scorul, separat de
  lista fuzzy ("potrivire text"); indicator de progres reparat pe upload
  (display:inline anula .htmx-indicator) si adaugat pe pasii 2->3 si
  "Salveaza maparile"

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 10:10:58 +00:00
Claude Agent
65b6e4694d feat(web): deep-link-uri pe sub-taburile Setari + Primii pasi deasupra importului
Link-urile catre configurare (Acasa, Integrare, Upload) duc direct pe sub-tabul
relevant (?tab=cont&subtab=rar|api); pe Acasa, ghidajul "Primii pasi" apare
inaintea containerului de import.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 08:42:47 +00:00
Claude Agent
705ad030fe feat(embeddings): cache persistent de vectori in SQLite + warmup in fundal
Vectorii corpusului k-NN persista in tabela embedding_cache (PK model+text_hash,
blob float32 LE); la warmup se vectorizeaza doar textele lipsa din cache, deci
restartul cu corpus neschimbat nu mai plateste ~1-2 min de embed (embed=0).

- app/embedding_cache.py: serializare array('f'), load/save/purge chunk 500 cu
  BEGIN/COMMIT explicit (conexiuni autocommit), validare dimensiune la scriere
  si citire, orchestrare sync_corpus_vectors cu embed_fn injectat
- index_corpus(vectors=): vectori precalculati cu validare aliniere; mismatch
  -> fallback embed complet
- ensure_embeddings_corpus: warmup in thread la startup (block=True), calea de
  request ne-blocanta (acquire non-blocking pe lock; warmup in curs -> return
  imediat); purjare orfane + modele vechi doar dupa indexare reusita
- log warmup: cache=N embed=M in Xs
- 31 teste noi (cold/warm/incremental, model schimbat, concurenta, ranking
  exact, echivalenta float32); suita completa 1596 passed

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 21:57:49 +00:00
Claude Agent
a46e364594 feat(header): badge mediu RAR compact langa chip-ul RAR
Muta indicatorul de mediu (Testare/PRODUCTIE) din statusbar (randare
periodica, rand intreg) intr-un badge compact din header, langa chipul
RAR scurtat la "RAR". Click pe badge comuta mediul cand exista 2
disponibile; pe mobil (<=560px) eticheta scurta PROD/TEST ramane mereu
vizibila (semnal de risc L.142). Toggle-ul din header si schimbarea
mediului implicit din Setari actualizeaza badge-ul via OOB swap.

Co-Authored-By: Claude Agent <noreply@anthropic.com>
2026-07-06 21:15:12 +00:00
Claude Agent
d7adeaf382 feat(setari): pagina Setari compacta — 3 sub-taburi, plan clarificat, copy scurt
- Date firma mutat in sub-tabul Cont (date firma + plan + parola); 3 taburi in loc de 4
- Plan afisat o singura data (tier bold + consum) cu bara de progres; fara dublarea 'Plan curent'/'Plan:'
- Copy Credentiale RAR redus la un rand; confirmare Productie scurtata; parola setata are placeholder distinct
- Formulare compacte pe 2 coloane (setari-fgrid), titluri de sectiune uppercase mici, microcopy langa butoane
- activ_subtab implicit 'firma' -> 'cont'; 'firma' vechi mapat defensiv la 'cont'

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:53:05 +00:00
Claude Agent
e2627c1aa4 test(web): actualizeaza 4 teste pentru meniul grupat + pagina Setari
- badge: cauta elementul randat (class="tab-badge"), nu substringul brut —
  CSS-ul nou din base.html contine mereu selectorul .tab-badge
- meniu mapari: fereastra de context largita — iconita SVG sta intre href si text
- setari: eticheta sub-tabului e "Cheie API", nu "Cheia mea API"

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 13:50:33 +00:00
Claude Agent
44f261e269 refactor: comentarii strict functionale, fara referinte PRD/stories
Curatare globala a comentariilor si docstring-urilor (app, tools, teste,
scripturi): eliminate referintele la PRD-uri, US-xxx, task-uri istorice si
review-uri; pastrata doar informatia functionala, formulata scurt. Regula
adaugata in CLAUDE.md (sectiunea Stil). Fara modificari de cod sau comportament.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 13:48:38 +00:00
Claude Agent
86408887e5 feat(setari): meniu grupat + pagina Setari cu sub-taburi + schimbare parola
Meniu hamburger reorganizat pe grupuri cu etichete (LUCRU / CONT) cu iconite
SVG discrete; "Cont" redenumit "Setari" (URL ?tab=cont pastrat, zero rute moarte).

Pagina Setari restructurata in sub-taburi interne: Date firma / Credentiale RAR /
Cheie API / Cont (plan + schimbare parola), cu indicator de stare per tab. Sub-tabul
activ e pastrat server-side (activ_subtab) dupa fiecare swap HTMX; comutarea intre
taburi e client-side, delegata pe document (supravietuieste swap-urilor).

Credentiale RAR: mediile Testare/Productie ca doua carduri paralele.

Schimbare parola de acces din sub-tabul Cont (functie noua, lipsea):
- users.change_password (scrypt): verifica parola actuala constant-time, valideaza
  noua (10..128, diferita), rescrie hash+salt nou;
- ruta POST /cont/schimba-parola, scoped pe user_id din sesiune, CSRF enforce,
  parola niciodata re-pusa in raspuns, jurnal 'parola_schimbata'.

Referinte copy "Meniu cont > Cont" -> "Setari".

Teste: schimbare parola (succes / parola actuala gresita / confirmare nepotrivita /
lungime) + izolare rate-limit login in fixture-ul clientului.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 13:40:38 +00:00
Claude Agent
164f90d603 fix(securitate): inchide nit-urile din review-ul hardening (N1-N3)
- N1: test HSTS pe monkeypatch.setenv (fara env var scursa la assert picat)
- N2: backup_db.sh refuza AUTOPASS_BACKUP_KEEP < 1 (retentia ar fi sters
  backup-ul abia creat)
- N3: teste ASGI directe pentru Content-Length malformat/negativ in
  BodyCapMiddleware (comportamentul defensiv exista deja, acum e fixat in teste)

Suita completa: 1559 passed, 1 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:01:00 +00:00
Claude Agent
0a96bd6a8e docs: ROADMAP actualizat cu hardening 80/20 LIVRAT (2026-07-06)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:50:53 +00:00
Claude Agent
63b6cbc01d fix(securitate): hardening prod — headere, body-cap, non-root, backup
Findings security-review P1/P2 (2026-07-03):
- headere de securitate pe toate raspunsurile (nosniff, X-Frame-Options,
  Referrer-Policy, HSTS doar pe HTTPS) + teste
- body-cap global 10MB ca middleware ASGI pur (413 inainte de parserul
  multipart/JSON; verificarea per-endpoint ramane strat 2)
- imagine Docker non-root (uid 10001), port 8010 aliniat, loguri pe
  volumul /data
- fail-fast la boot cu rar_env=prod fara AUTOPASS_REQUIRE_API_KEY sau
  AUTOPASS_SESSION_SECRET
- compose: env-uri critice obligatorii (:?) ca api/worker sa nu diverga
  tacit; FORWARDED_ALLOW_IPS ca rate-limit-ul sa vada IP-ul real dupa
  Traefik
- signup fara PII in stdout: log_event in loc de print cu email (idem
  notify degradat)
- ratelimit: sterge cheile fara timestamp-uri valide (crestere monotona
  a memoriei pe IP-uri reale)
- backup criptat SQLite (backup online API, gpg AES256) + verificare
  restore + docs/backup.md

Suita completa verde: 1557 passed, 1 skipped (live).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:46:49 +00:00
Claude Agent
fa52468a80 fix(ux): mesaje mediu RAR mai clare + referinta corecta 'Meniu cont › Cont'
Banner upload compact/directiv (fara 'mediu global' derutant), text Cont
onest (importul web fara mediu activ nu are creds -> esueaza), si aliniere
referinta navigare la 'Meniu cont › Cont' in erori/integrare (nu exista
'tab-ul Cont' in UI).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 12:45:16 +00:00
Claude Agent
39d2ba3dd0 docs: ROADMAP actualizat cu 5.19 LIVRAT + findings /code-review rezolvate (2026-07-06)
Intrare noua in "Ultima actualizare": 5.19 (auto-send toggle + coada tinuta held)
livrat + push (main la eade702), cu cele doua runde de corectii /code-review high:
finding #1 (re-snapshot held pe caile de repunere, corectitudine) + findings #2-#6
(UX/retentie). Nota PLAN 5.19 marcata LIVRAT. 1541 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 11:55:57 +00:00
Claude Agent
eade702a52 fix(5.19): corectii UX/retentie held (findings #2-#6 /code-review high)
#2 Filtrul "doar tinute" (held=1) devine persistent: hidden #f-held in
   #filtre-trimiteri sincronizat prin OOB din _submissions.html + paginare
   pastreaza held=1; chip "Doar tinute manual / Arata tot" ca off-switch.
   Param `held` schimbat la str (held= gol nu mai da 422 la coercion).
#3 Banner bulk "Trimite toate (N)" extras in _bulk_held_banner.html si
   re-randat prin OOB (#bulk-held-banner-wrap) la fiecare reincarcare a listei
   -> nu mai ramane stale dupa eliberari (count revine la 0).
#4 tools/carantina_held seteaza purge_after (blocked_retention_days) pe randurile
   carantinate -> PII nu mai sta la nesfarsit (purge_expired le poate sterge).
#5 Panoul de detaliu marcheaza randul tinut (eticheta amber) si ofera buton
   "Trimite acum la RAR" (paritate cu randul din lista).
#6 expire_held seteaza purge_after=now-1s -> randul expirat e purjabil in ACELASI
   ciclu (purge_expired foloseste comparatie stricta), nu la ciclul urmator.

Teste noi: stickiness held + banner OOB + detaliu buton (test_web_auto_send),
purge_after carantina, purge acelasi-ciclu (test_worker_held). 1541 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 11:19:00 +00:00
Claude Agent
789e3f54be merge: PRD 5.19 auto-send toggle + tinere manuala randuri (held) 2026-07-06 10:13:02 +00:00
Claude Agent
458c3fd43c 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>
2026-07-06 10:12:57 +00:00
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
Claude Agent
2ec3292382 docs: ROADMAP actualizat cu cele 3 PR-uri ergonomie livrate (2026-07-03)
Paritate editor mapare (PR1), mesaj onest mediu RAR (PR2/Issue A),
confirmare valori needs_review bulk+rapid (PR3/Issue B) + cleanup ruta
moarta /cont/rar-creds. Intrarea 5.20 demota la ISTORIC.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 18:26:33 +00:00
Claude Agent
0a86e63213 refactor(web): elimina ruta moarta /cont/rar-creds
Ruta web POST /cont/rar-creds era cod mort: niciun template nu mai posta
catre ea (formularul live e /cont/rar-medii, US-008/PRD 5.20 cu sectiuni
explicite Testare+Productie si validare login per-env). Scria mereu in
slotul env-ului instantei — exact bug-ul semnalat la Issue A.

Elimina functia cont_rar_creds si cele doua teste care o exercitau
(test_set_creds_rar_din_sesiune, test_creds_alt_cont_neafectat). Actualizeaza
comentariul stale US-008 sa refere ruta reala /cont/rar-medii. Ruta API
/v1/conturi/rar-creds e separata si ramane neatinsa.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 18:23:56 +00:00
Claude Agent
367739f5bf merge: confirmare valori needs_review bulk+rapid (PR3 / Issue B) 2026-07-03 13:26:57 +00:00
Claude Agent
5afd79634f merge: mesaj onest mediu RAR instanta (PR2 / Issue A) 2026-07-03 13:26:52 +00:00
Claude Agent
4a39083fb7 merge: paritate editor mapare import-preview (PR1) 2026-07-03 13:26:48 +00:00
Claude Agent
a881b824bf feat(import): confirmare valori needs_review in bloc + rapid din tabel (B1)
Randurile needs_review (flaguri de coercion: VIN citit ca numar, odometru
float, data ambigua) cereau confirmare umana DOAR prin modalul de editare,
un rand pe rand. Adauga doua cai care pastreaza omul in bucla (fara
auto-accept):

- Buton "Confirma toate valorile" (bulk): ruta noua
  POST /_import/{id}/confirma-toate-review marcheaza reviewed=1 pe TOATE
  randurile needs_review din batch cu un click. Scoped pe cont (404
  cross-account, 409 batch comis), o singura recompute + re-randare
  #import-section, dupa modelul web_mapare_operatii.
- Confirm rapid per-rand direct din tabel: buton in coloana Actiuni pe
  randurile needs_review, refoloseste ruta existenta /confirma-review
  (reviewed=1 pe un singur rand) cu hx-swap="none"; HX-Trigger
  reincarcaPreview reincarca sectiunea cu contoare/banner corecte.

Butonul bulk e randat in bannerul de discoverability (si in varianta OOB
din _preview_rand.html). Editarea unei valori reseteaza reviewed=0 ca
inainte (D#9, neschimbat).

Teste noi (tests/test_import_review.py): bulk marcheaza toate randurile,
guard committed 409, scoping 404 cross-account (fara efect pe randurile
altui cont), prezenta butonului rapid in tabel, confirm rapid per-rand
seteaza reviewed=1 fara a atinge alte randuri.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:25:48 +00:00
Claude Agent
aac9971f2b fix(web): mesaj onest despre mediul RAR al instantei (Issue A / A1)
Textul din bannerul de import (0 medii) si din antetul formularului de
credentiale nu spunea concret ce mediu foloseste instanta curenta. Vechiul
"Trimiterea va folosi configuratia globala" era jargon, iar "Pentru a activa
Testare sau Productie" nu clarifica relatia instanta<->mediu.

- Adauga globalul Jinja `mediu_instanta()` = eticheta umana a ancorei globale
  AUTOPASS_RAR_ENV (Testare/Productie), fallback sigur pe Testare.
- `_upload.html`: bannerul de 0 medii numeste concret mediul global al instantei
  pe care cad trimiterile pana la activarea unui mediu.
- `_cont.html`: nota onesta sub antetul "Credentiale RAR" — instanta ruleaza pe
  mediul global X, ambele medii se pot configura aici (fiecare validat separat),
  iar la 0 medii active trimiterile cad pe mediul global al instantei.

Fara selector nou si fara schimbari in logica de scriere a credentialelor
(A1, aliniat PRD 5.20: instanta = ancora de fallback pentru env).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:24:33 +00:00
Claude Agent
e11a5efa0f feat(web): paritate editor mapare import-preview cu pagina /mapari
Panoul inline "Operatii de mapat la cod RAR" din preview-ul de import folosea
doar sugestii fuzzy si nu arata sursa sugestiei. Acum are paritate 1:1 cu pagina
/mapari: aceeasi sugestie_principala (GOLD partajat > SILVER > embeddings k-NN)
si acelasi badge sursa (confirmat / similar / non-operatie).

- _collect_unmapped_ops primeste `conn`: ataseaza sugestie_principala +
  surse_sugestie via enrich_suggestions, cu ensure_embeddings_corpus o data
  inainte de bucla (replica pattern-ul din pending_unmapped). Init default pe
  fiecare entry (inclusiv conn=None) -> contract template identic.
  SUGGESTION-ONLY: nu atinge resolve_prestatii/load_mapping (#13).
- _web_compute_preview paseaza conn=conn la _collect_unmapped_ops.
- _preview_import.html: preselect din sugestie_principala > fuzzy>=60 + badge
  sursa (clase .sugg-sursa--{confirmat,similar,nul} deja existente in base.html).
- Test de paritate TARE: seed embeddings + GOLD/SILVER/NUL, batch import cu
  needs_mapping, verifica _web_compute_preview()["unmapped_ops"] ==
  pending_unmapped(conn, account) pe sugestie_principala + surse_sugestie, cate
  un caz per sursa (gold/silver/embedding/nul).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:23:28 +00:00
Claude Agent
ab27be1e46 chore: adauga reguli de routing gstack in CLAUDE.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 13:11:56 +00:00
Claude Agent
d3ebf4762d docs: clarifica bootstrap admin (primul signup, independent de cont id=1)
README + CLAUDE.md: primul user din baza devine admin automat (is_admin,
neconditionat de account_id), nu e hardcodat in .env. Contul id=1 e doar
fallback dev pentru trafic API neautentificat, fara legatura cu admin.
Adauga fix manual (tools.account set-admin) pentru cazul cand primul
signup s-a consumat deja gresit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-03 12:40:01 +00:00
Claude Agent
cd24e75325 fix(web): tema partajata landing<->aplicatie (cheie theme + 8 teme + icon unic)
- Landing foloseste aceeasi cheie localStorage 'theme' ca aplicatia (era 'lp-theme'),
  deci preferinta de tema se pastreaza intre landing si aplicatie.
- Landing capata cele 8 teme din aplicatie (adaugate light/dark/petrol; auto se
  rezolva la light/dark), aceeasi ordine de ciclare.
- Selector tema: acelasi icon FIX (SVG semicerc din landing) in ambele locuri;
  aplicatia nu mai schimba glifa per tema. Eticheta temei curente ramane.
- Init-ul selectorului din landing nu mai scrie in localStorage (nu mai suprascrie
  alegerea facuta in aplicatie la simpla vizitare).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 12:39:42 +00:00
Claude Agent
f02f422560 docs: ghid utilizator (medii test/prod, termeni simpli) + README pe per-env
docs/ghid-utilizator.md (nou): ghid pentru service-uri, fara termeni tehnici —
cum configurezi credentialele RAR pe Testare/Productie, cum stii unde trimiti
(statusbar + badge rosu=real), cum trimiti (fisier/soft), starile unei trimiteri,
intrebari frecvente.

README: link catre ghid; sectiunea creds RAR actualizata la sloturi per-mediu
(rar_target pe POST /v1/conturi/rar-creds, rar_env pe POST /v1/prezentari);
corectata nota iesita din uz despre GET-uri (sunt account-scoped, nomenclator
public intentionat); RAR_ENV clarificat ca ancora globala peste care au prioritate
mediile per-cont.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 12:33:33 +00:00
Claude Agent
96973f60f3 test: repara flake nocturn miez-noapte RO + 2 teste stale landing/login
test_web_status::test_granita_miez_noapte_local_ro: ancoreaza boundary pe RO-now
(00:30 RO local, mereu ziua UTC precedenta, DST-aware) in loc de today_utc. Bug
vechi: boundary pe today_utc pica in fereastra de dupa miezul noptii RO cand
date('now','localtime') e deja ziua urmatoare. Fereastra de esec de ~3h -> race
sub-secunda la exact miezul noptii.

test_web_responsive::test_login_branded_nu_schelet: loginul a fost simplificat la
o coloana (commit 'simplifica login'); nu mai cerem .login-aside. Guard pastrat pe
.login-shell + titlu ROA AUTOPASS + POST /login + CSRF. Comentariile stale '2 coloane'
din login.html aliniate la realitate (o coloana).

test_web_responsive::test_landing_limita_60: terminologia landing prestații->trimiteri
(rework ff9d0f4); asertie pe '60 de trimiteri' (limita Gratuit), scoase asertiile pe
formularile vechi 'prestații'/'prezentări'.

Suita: 1458 passed, 1 deselected (live), 0 failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 12:25:01 +00:00
Claude Agent
cccd032ae4 docs(5.20): ROADMAP 5.20 LIVRAT + VERIFY PASS + raport VERIFY in PRD
Stadiu Implementare: 5.20 -> LIVRAT (13/13 stories, comituri per story).
PRD sectiunea 8: raport VERIFY (comituri, DROP cu garda 6a-6d, suita
1455 passed, 3 esecuri ne-legate incl. flake nocturn miez-noapte RO).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 21:05:08 +00:00
Claude Agent
b1d825e66b feat(5.20): US-013 retragere accounts.rar_creds_enc -> per-env + DROP cu garda
Toate citirile pe coloana legacy accounts.rar_creds_enc mutate pe sloturile
per-env (rar_creds_test_enc/rar_creds_prod_enc): worker fallback+keepalive,
are_creds (web) si are_creds_rar (integrare, +are_creds_test/_prod), write-back
API la reactivare, purjare la stergere cont, _get_acasa_context/_fetch_cont_env_state.

Contract API (aditiv): POST /v1/conturi/rar-creds primeste rar_target optional
(test/prod), scrie in slotul corect + activeaza mediul; DELETE primeste ?env
(sterge un slot sau ambele). Documentat in docs/api-rar-contract.md.

DROP cu garda in db.py (schema.sql fara coloana pe DB fresh):
- 6a: eliminat ADD COLUMN rar_creds_enc (fara ping-pong re-ADD dupa DROP)
- 6b: try/except fail-safe (nu crapa boot-ul) + garda sqlite_version >= 3.35
- 6c: re-backfill old->new imediat inainte de assert (ancora globala)
- garda orfane: DROP anulat daca vreun creds legacy nu a aterizat in slot per-env
- backup criptat accounts_rar_creds_enc_backup inainte de DROP
- 6d: verificare prin PRAGMA table_info (NU grep — submissions are aceeasi coloana)
Garda one-way, idempotenta la boot repetat (verificat). submissions.rar_creds_enc
ramane neatinsa.

tests/test_retragere_creds_enc.py: niciun read pe coloana veche, conturi rar-creds
env-aware, are_creds per-env, DROP blocat de garda la lipsa copiere. 9 teste
existente actualizate pe sloturi per-env.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 21:03:08 +00:00
Claude Agent
3d3eb71a1e feat(5.20): US-012 audit evenimente medii + teste e2e
log_event best-effort (refoloseste conn apelantului, fara PII in context) la:
- rar_env_activat / rar_env_dezactivat: activare/dezactivare mediu in cont_rar_medii
- rar_env_default_schimbat: schimbare efectiva default in cont_rar_medii si in
  toggle-ul din statusbar (fragment_status_toggle_env)
- rar_env_blocat: tinta indisponibila — 422 pe canalul API (router.py) + WARNING
  pe caile de import web (fallback existent neschimbat, doar logging adaugat)

tests/test_e2e_rar_env.py: lant import->queued cu rar_env corect (ambele canale),
activare Productie logata, tinta indisponibila blocata + logata.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 20:26:28 +00:00
Claude Agent
0a1df31126 feat(5.20): US-010 badge mediu RAR in liste/preview/detaliu/jurnal + audit + ecou API
labels.py: ETICHETE_ENV + eticheta_env(env)->(text,css). Productie afisata
"PRODUCȚIE" (majuscule+diacritice) cu badge fill de atentie (--err), Testare
outline discret muted — semnalizare risc L.142 (declaratie reala ireversibila).
Clase .env-badge-prod / .env-badge-test in base.html; eticheta_env expus ca
global Jinja.

Badge de mediu per rand in _submissions, _coada implicit prin view, _preview_rand,
_trimitere_detaliu, _jurnal. Statusbar (_status.html) aliniat la aceeasi conventie
(Productie = atentie, nu verde) — inlocuieste culorile ad-hoc din US-011, toggle
neatins.

rar_env in exportul de audit (AUDIT_COLUMNS + _audit_rows) si ecou in
GET /v1/prezentari(/{id}). _submission_row_view/_detaliu_ctx/fragment_submissions
duc rar_env pana in template.

tests/test_badge_rar_env.py: badge in lista, audit contine rar_env, GET ecou rar_env.
test_statusbar_env: asertie aliniata la eticheta PRODUCȚIE.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 20:16:08 +00:00
Claude Agent
d1978e2545 feat(5.20): US-011 statusbar indicator mediu + toggle conditionat
Statusbar afiseaza mediul RAR default al contului logat (Testare galben /
Productie verde, distinct vizual). La >=2 medii disponibile apare butonul
Comuta (HTMX POST /_fragments/status/toggle-env, account-scoped, verify_csrf)
care alterneaza rar_env_default intre mediile disponibile fara reload; la 1
mediu doar eticheta statica; la 0 medii indicatorul nu apare.

_build_status_ctx capata env_default + medii_disponibile + csrf_token
(via rar_env_efectiv_cont / medii_disponibile_cont).

Retrage badge-env global din header (base.html) pentru utilizatorul logat
(F11) — mediul per-cont traieste acum in statusbar; badge-ul global ramane
doar pentru vizitatorul nelogat.

tests/test_statusbar_env.py: afiseaza env default, toggle doar la 2 medii,
toggle schimba default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 20:02:10 +00:00
Claude Agent
3eaf1ca6cd test: actualizeaza asertia coloane list_accounts (requested_plan, consent_at)
Testul verifica setul exact de chei returnat de list_accounts; ramasese in urma
dupa ce coloanele requested_plan si consent_at au fost adaugate (5.17/consent).
Fara legatura cu 5.20 — esec pre-existent semnalat in checkpoint.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:55:48 +00:00
Claude Agent
1648960b13 feat(5.20): US-008 configurare medii RAR per cont (Testare/Productie)
Ruta noua POST /cont/rar-medii: doua sectiuni independente Testare/Productie,
fiecare cu bifa activare + email/parola. La salvare, mediu activat cu creds noi
e validat prin login pe env-ul respectiv (US-007); OK -> criptare Fernet in
rar_creds_{env}_enc + enabled=1; esec -> eroare per-env, creds nesalvate.

Prima activare Productie cere checkbox de confirmare (constientizare L.142).
Mediul implicit (rar_env_default) setabil DOAR pe un mediu disponibil, validat
server-side post-update. Parolele niciodata reflectate in pagina.

_fetch_cont_env_state deriva starea per-env pentru _cont.html; refactor al
handlerelor de cont sa foloseasca env_ctx in loc de are_creds legacy.

tests/test_cont_medii.py: 4 teste (salvare+creds criptate per env, default doar
dintre disponibile, confirmare prod obligatorie, fara echo parola).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 19:53:50 +00:00