Commit Graph

164 Commits

Author SHA1 Message Date
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
Claude Agent
3579a15363 feat(5.20): US-007 validare login RAR pe env-ul setului de credentiale
Login de validare loveste base_url_pentru_env(env) (NU ancora globala); endpoint
POST /cont/test-rar-creds + card in _integrare.html; mesaj distinct TESTARE vs
PRODUCTIE la 401 incrucisat (confirmat live).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:46:50 +00:00
Claude Agent
19d8aaa7aa feat(5.20): US-004/005/006/009 ingestie+API+worker+import pe mediu RAR
US-004: rezolva_rar_env (cerere>default cont>ancora globala) + MediuIndisponibil
+ cod RAR_MEDIU_INDISPONIBIL.
US-005: camp rar_env pe POST /v1/prezentari + /valideaza (Literal), echo in
SubmissionResult/ValidareResult/GET, build_key + INSERT env-aware.
US-006: AccountSessions re-cheiat (account_id, rar_env); RarClient base_url per
env; creds din slotul env; purge + recover_orphans scoped pe env (E1/1a, 1b/E6);
claim_one propaga rar_env (1c/E8); keepalive pe ancora globala (M2).
US-009: selector mediu la import (>=2 medii), eticheta la 1, banner la 0; commit
seteaza rar_env pe submissions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:30:11 +00:00
Claude Agent
d5ce0e2e2b feat(branding): redenumire ROMFAST AUTOPASS -> ROA AUTOPASS in UI
Titlu pagina, antet brand si /login afiseaza acum 'ROA AUTOPASS'.
Include redesignul sectiunii Problem+Calculator combinata din landing.
Teste de antet/nav aliniate la noul nume.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 19:42:31 +00:00
Claude Agent
deb6afff3e feat(5.20): US-001/002/003 schema medii per cont + disponibilitate + idempotenta env-aware
US-001: coloane accounts (rar_test/prod_enabled, rar_creds_test/prod_enc,
rar_env_default) + submissions.rar_env; migrare cu backfill din ancora globala
AUTOPASS_RAR_ENV (creds->slot, enabled doar pe mediul cu creds) + recompute
idempotency_key env-aware (AUTO-FIX G + E4/3).
US-002: app/rar_env.py — medii_disponibile + rar_env_efectiv (REQ-DISP/DEFAULT).
US-003: build_key(account_id, canon, rar_env) — test vs prod = trimiteri distincte.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:42:28 +00:00
Claude Agent
b4818349be docs(5.20): PRD medii RAR per cont (Testare/Productie) aprobat + roadmap
Doua medii RAR configurabile per cont, fiecare cu bifa de activare si set
propriu de credentiale. medii_disponibile=enabled AND creds deriva tot UX-ul.
13 stories / 6 valuri. Premisa verificata live: test/prod = sisteme separate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:27:50 +00:00
Claude Agent
ff9d0f41d1 feat(landing): titlu ROMFAST AUTOPASS, calculator pe trimiteri, grila preturi uniforma
- header cu titlu ROMFAST AUTOPASS + subtitlu Gateway RAR, nav la dreapta
- title/meta description aliniate pe mesajul "incarci fisierul, coduri o data"
- hero: subtext rescris + linie beneficiu "Gratuit pana la 60 de trimiteri/luna"
- scoase toate referintele la card bancar
- calculator: slider pe Trimiteri/luna (default 100), cifre uniforme grid 2x2,
  rotunjite fara zecimale
- preturi: carduri egale cu aceleasi componente (bifa/minus), Standard 49 lei +
  badge Popular + buton verde, Gratuit fara badge, "* fara TVA" la preturi
- sectiune separata beneficiu "30 de zile Pro gratuit"; FINAL CTA eliminat
- suport: Standard maxim 24h, Pro maxim 8h
- signup: pret Standard aliniat la 49 lei

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 18:56:49 +00:00
Claude Agent
7371c3703d chore(compose): parametrizeaza RAR_ENV si WORKER_SEND_ENABLED pentru staging
Permite override din Dokploy environment fara a schimba comportamentul prod
(default-uri pastrate: api RAR_ENV=prod, worker RAR_ENV=test, SEND_ENABLED=true).
Necesar pentru serviciul de staging autopass-test.roa.romfast.ro, care forteaza
RAR_ENV=test si WORKER_SEND_ENABLED=false ca sa NU trimita declaratii reale la RAR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:39:35 +00:00
Claude Agent
851f76ca16 feat(signup+admin): aliniere formular signup la landing + plan cerut, GDPR, control tier/trial in panou
Signup:
- /signup aliniat ca format la formularul din landing (campuri, etichete,
  placeholder-uri, select plan, checkbox GDPR, buton). Eticheta `name` = "Companie"
  (corecta: backendul salveaza nume de firma), uniform si in landing.
- Consimtamant GDPR validat server-side (functional, nu doar client-side) + salvat
  cu marca temporala (accounts.consent_at).
- Plan ales la signup salvat in accounts.requested_plan (intentie, NU drept): tier
  ramane sursa de adevar pentru gate-ul API; coloana pregateste integrarea platilor.
- landing: valorile `plan` = coduri tier (free/standard/pro/premium), data-plan
  sincronizat pe butoanele de pret; checkbox consimtamant primeste name.

Schema/DB:
- accounts: coloane noi requested_plan + consent_at (cu migrare aditiva in db.py).

Panou admin:
- Coloane noi: Plan curent (plan EFECTIV acum + zile trial ramase) si Plan cerut.
- Buton "Aplica" (POST /admin/set-tier): aloca plan real si INCHEIE trial-ul
  (efect imediat; altfel trial-ul Pro universal de 30z masca alegerea).
- Control "Trial Pro N zile" (POST /admin/set-trial via accounts.set_trial):
  acorda/prelungeste trial fara a schimba tier-ul de baza.

Teste: signup (consent obligatoriu, requested_plan persistat, tier ramane free),
panou admin (set-tier incheie trial, free opreste Pro imediat, set-trial, validari
+ CSRF). Call-site-urile existente POST /signup actualizate cu consent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:02:37 +00:00
Claude Agent
a29896a790 docs(5.19): PRD bifa "Trimite automat la RAR" + coada tinuta/eliberare manuala
PRD prin /prd + /autoplan (CEO/Design/Eng/DX, voce unica - Codex la plafon).
Per-cont accounts.auto_send_enabled (default OFF time-boxed) + per-rand
submissions.held; snapshot la TOATE ~8 situri queued via held_for_account()
(Eng a prins bug reactivare router:237 ce ocolea Auto OFF); claim_one AND held=0.
Crescut 6->10 stories: US-007 banner/metrics coada imbatranita, US-008 retentie
held (GDPR/L.142), US-009 fixturi teste + audit, US-010 onestitate API (invariant
5.7). 26 taskuri. Eticheta redenumita; testare sigura (rar_env/valideaza) -> TODOS.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 15:46:23 +00:00
Claude Agent
3f513f6c12 fix(landing): elimina announce bar, actualizeaza badge hero, ancoreaza nav, simplifica login
- Scoate announce bar-ul de deasupra header-ului
- Badge hero reformulat: "Este gratuit pentru service-urile mici — pana la 60 de trimiteri RAR/luna" + link "Creeaza cont in 2 minute"
- Nav links "Cum functioneaza", "API", "Pret" devin <a href="#..."> cu id-uri pe sectiunile corespunzatoare
- Pagina /login: scoate <aside> cu logo/tagline/trust, layout trece la o singura coloana centrata

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 15:04:40 +00:00
Claude Agent
8f39dfbc1e feat(5.16): aliniere lista/preview la mockup + fix lock seed la boot
Implementeaza planul aprobat din docs/raport-comparatie-mockup-5.16.md (T-1..T-9):

- T-1/T-8: rand lista 4->2 linii (placuta primar + cod RAR · operatie · data + pill),
  fallback placuta, eticheta-problema 10px->--fs-xs (_submissions.html, base.html)
- T-2: pill slim restilat fill-tint + dot 7px + text colorat per stare (base.html)
- T-3: bug 4a coliziune pill/vehicul in preview — col-stare 104->140px (base.html)
- T-4: preview 8->5 coloane (scos #, KM, Note; motivul -> title pe pill)
- T-5: titlu sectiune "Trimiterile tale" -> sr-only (a11y) + badge/export discret
- T-6: linia plan N/60 in corp doar pe avertizare; consum normal in badge+burger
- T-7: guard chenar gol chips extra (_chips_prestatii.html)
- T-9: "Anuleaza"->"Renunta"; nume operatie emfatic bold

Fix boot: init_db reincarca seedul de ~17k operatii (5.18) pe FIECARE pornire, pe
API + worker concurent -> "database is locked" la al doilea proces. Guard "_if_empty"
pe mapping_suggestions (ca seed_nomenclator_if_empty) -> boot rapid, fara cursa.

Teste actualizate (slim 2-linii, fallback placuta, plan in burger). TODOS.md:
defer trackuit (eroare HTMX lista, retokenizare px, diacritice).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 14:44:10 +00:00
Claude Agent
e1243f603e fix(mapari-mobil): butoane Salveaza/Sterge vizibile + carduri compacte la 390px
Doua probleme raportate de user pe pagina Mapari pe mobil (screenshot 390px):

1. Butoanele Salveaza/Sterge taiate: regula `.tabel-card td button {width:100%}`
   (specificitate 0,1,2) batea `.act {width:44px}` (0,1,0), deci cele doua butoane
   .act deveneau full-width si al doilea (Sterge) iesea din card (celula are nowrap).
   Fix: bloc @media (max-width:767px) nou, ultimul in <style> (castiga pe cascada) —
   celula Actiuni devine flex-row, butoanele .act width:auto/flex:1 cu text vizibil.

2. Carduri prea inalte + label-uri inutile: .tabel-card randa etichetele data-eticheta
   ca pseudo-titluri + linia redundanta "acum: COD — nume" (duplica select-ul de sub).
   Fix: pe mobil se ascund pseudo-etichetele si linia .map-acum, padding strans.
   Cardul trece de la ~7 la ~3 elemente. Atributele data-eticheta raman in DOM (a11y+teste).

Include si raportul de comparatie UI 5.16 cu appendix-ul /autoplan (CEO/Design/Eng,
audit trail, plan aprobat) + addendum cu corectia la sectiunea 8 ("Mapari conform" era
gresit: nu testase randarea mobila a paginilor actionabile).

Verificare: 80 teste web verzi (test_web_responsive + mapari + submissions + tabs + modal);
confirmare vizuala la 390px (render TestClient -> screenshot Playwright).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 08:18:27 +00:00
Claude Agent
80d90f317d fix(5.18): corectie 8 etichete coduri rare (verificare Opus pe coada sparse)
Subagent Opus a verificat cele 139 operatii cu coduri rare (R-ODO, OE-I,
OE-5, AITLV, OE-R, OE-8, OE-7): 130 confirmate, 8 corectate (source=opus_review):
- PERNA AER STG SPATE / PUNTE MOTRICA (x3): OE-R -> OE-1 (burduf suspensie
  pneumatica, NU airbag de retinere)
- INLOCUIT CABLU/SENZOR KM (x2): OE-I -> R-ODO (reparatie odometru, nu istoric import)
- SCHIMBAT FOAIE ARC: OE-8 -> OE-1 (arc suspensie, nu anvelopa)
- RULMENT SPATE (PIESA): OE-7 -> NUL (doar nume piesa, fara actiune)
- INLOCUIT CALCULATOR P INJECTIE: OE-7 -> OE-1 (inlocuire hardware, fara programare)

NUL 2200 -> 2201. SERVICII VULCANIZARE (Opus->NUL, increderea 0.5) tinut
neschimbat: vulcanizarea e reparatie reala de pneu, nu non-operatie (de decis user).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 07:41:32 +00:00
Claude Agent
12021eb269 feat(5.18): VERIFY+CLOSE — US-007 badge sursa + fix findings code-review
VERIFY PASS pe corpus k-NN exemple etichetate (seed real 17181 Haiku, comis
in 756f777): suita 1392 passed, 1 deselected (live); smoke init_db seeder
(17181/NUL=2200/idempotent); toate codurile in nomenclator.

US-007 (cerere user la CLOSE) — badge sursa pe sugestia fuzzy din editor:
- _mapari.html: chip confirmat (GOLD) / similar (SILVER+k-NN) / non-operatie (NUL)
- base.html: .sugg-sursa--{confirmat,similar,nul} pe tokeni de tema (color-mix)
- routes.py: cheia `nul` adaugata in surse_sugestie default (finding cross-file)
- tests/test_web_badge_sursa.py: gold/silver/nul/fara-sursa (4 teste)
- E2E render live verificat in serverul real (/_fragments/mapari)

CLOSE /code-review high (main..HEAD, 3 finder x 8 unghiuri) — runtime curat,
invariant #13 intact; 3 findings low/cosmetic REPARATE + lock-uite:
- shared_store.seed_suggestions: cod whitespace -> NULL (era ''), + test lock
- genereaza_seed.py: with open(...) in loc de open().read() (FD leak tool offline)
- embeddings.py: docstring-uri aliniate la [{cod, is_nul, similaritate}]

ROADMAP: 5.18 LIVRAT. PRD: raport VERIFY/CLOSE scris.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 07:29:14 +00:00