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>
- 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>
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>
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>
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>
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>
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>
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>
- 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>
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>
- 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>
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>
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>
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>
5.15 (propagare design + dashboard editare) si 5.14 (mapare LLM distilata)
inchise dupa /code-review high. 8 buguri reparate TDD:
- HIGH modal nu se deschidea pe randul slim (base.html: trimitere-slim)
- HIGH /repune trunchia prestatii (declaratie incompleta la RAR) -> iterare
peste existing, codes pozitional
- HIGH embeddings incarca model ~230MB degeaba pe corpus gol -> poarta has_corpus()
- HIGH picker chips gol pe re-render eroare -> conn/account_id pe toate ramurile
- MED obs re-derivat dupa stergere explicita -> _merge_override pastreaza obs=''
- MED mapare salvata fara denumire poluă GOLD -> _record_gold_validation guard
- MED typo nome_prestatie -> nume_prestatie in select /repune
- MED bucketare timp +3h gresita iarna -> SQLite localtime + TZ=Europe/Bucharest
Embeddings WIRE-uit functional (PRD #15, decizie user): ensure_embeddings_corpus
construieste corpus din nomenclator, gated pe AUTOPASS_EMBEDDINGS_ENABLED (default
off). Marime model corectata ~50MB->~230MB (estimare PRD gresita).
Cleanup: hoist load_* din bucla bulk-fix; import re la top.
Regresie: 1256 passed, 1 deselected (live), 0 failed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Re-importa design-ul actualizat din claude.ai/design:
- sectiune noua PRIVACY ("Datele clientilor tai nu devin marfa")
- SOLVE rescris ("Nu trebuie sa fii bun cu calculatorul", text condensat)
- subtitlu preturi: "Premium gratuit 30 de zile, apoi automat pe Gratuit"
- butoane preturi uniformizate la "Creeaza cont gratuit"
Fix aliniere: wrapperele de sectiune aveau max-width inconsistent
(980/1040/1120/none) -> continutul nu se alinia intre sectiuni (unele benzi
pareau mai late). Scoatem capacele structurale ca tot continutul sa umple
acelasi gutter; capacele tipografice (text centrat) raman.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dogfood pe import + Trimiteri (mobil/tableta <1024px), pur CSS + markup, backend
trimitere neatins:
- Card compact real pentru .tabel-trimiteri (preview + Trimiteri): vehicul=titlu,
stare=pill dreapta-sus, operatie+cod, meta data/km muted, nota mica. Inlocuieste
stiva generica eticheta+valoare (carduri de ~450px -> ~135px). Anuleaza regula
desktop tr.trimitere-row > td{padding:11px} in blocul compact.
- FIX editare preview: OOB swap pe <tr> esua tacit in htmx 1.9 (un <tr> brut se
pierde la parsarea unui fragment fara context de tabel) -> randul ramanea cu
starea veche dupa salvare. Inlocuit cu reload complet al preview-ului prin
HX-Trigger:reincarcaPreview + detalii randSalvat. /editeaza si /confirma-review
folosesc helper-ul _raspuns_rand_salvat.
- Feedback post-salvare: toast global "Randul N actualizat · <stare>" + scroll +
flash pe randul actualizat (base.html window.arataToast + listener randSalvat).
- Modal editare: Salveaza + Anuleaza pe acelasi rand (sistem .act): desktop text,
mobil doua iconite Lucide 44px alaturate (save/x). Macro icon('x') + .act-primary.
- Randuri deja-trimise/duplicate colapsate implicit in preview + toggle "Arata N".
- Select "Operatii de mapat" full-width pe mobil (nu mai iese din viewport).
- Bara de filtre Trimiteri adaptata mobil: pills pe banda cu scroll orizontal,
cautare vehicul proeminenta (nu 8 butoane full-width stivuite).
- Nota preview = culoarea camp-fix (accent) ca sa atraga atentia; hint-urile
camp-fix per-camp scoase (campul Note e self-explanatory).
- Confirmare trimitere: scos campul email (Declarant); text mai clar
("Confirma numarul din N gata de trimis"). Backend confirmed_by ramane optional.
Teste: contractul OOB (rupt in browser) inlocuit cu noul contract
(reincarcaPreview + randSalvat) in test_web_preview_edit / test_preview_edit_ui /
test_import_review. Suita: 992 passed (exclus live).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.12 (livrat): editare in modal a randurilor de preview, cont obligatoriu inainte de
import, formular editare extras (_form_editare, _editare_preview_modal), plus suita de
teste aferenta (preview edit/compact, mapare op, form editare, signup, admin panel).
Design + planificare:
- docs/design.md: sistem de design (tokeni, breakpoints, scara control, componente, a11y).
- docs/prd/prd-5.12-* si prd-5.13-* (5.13 cu raport /autoplan: CEO+Design+Eng, audit trail).
Curatare: sterse PNG-urile de test/mockup temporare din radacina.
Nota: implementarea CSS 5.13 (responsive compact + sistem butoane) NU e inca facuta —
planul revizuit cere refactorul testelor fragile din test_web_responsive.py INAINTE de CSS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Eliminat zgomotul de trasabilitate (US-xxx, PRD x.x, Rn, OV-x, Tn, decizii/naratiune
istorica) din 41 fisiere app/ + template-uri. Pastrate comentariile care documenteaza
invarianti si logica ne-evidenta (idempotenta/hash, reconciliere anti-duplicat, RAR 500
esec definitiv, creds per cont, WAF User-Agent, 422 fara echo de parola, scope NULL->1),
curatate doar de tokeni.
Verificare: pentru cele 27 module .py curatate, structura de cod (tokeni non-comentariu/
non-string) e IDENTICA fata de HEAD -> doar comentarii/docstring-uri schimbate. Singura
schimbare de cod e in tests/test_web_responsive.py (scos 3 assert pe markeri US-006/007/008,
inlocuite de asertiunile structurale alaturate). 0 tokeni US/PRD reziduali in app/.
Regresie: 896 passed, 1 deselected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Fix bug: campul hidden de filtru randa literal "None" (status_filtru None +
Jinja default('')) -> poll-ul trimitea status=None -> tabel gol. status or "".
- Pills de stare mutate din bara de status in bara de filtre (filtreazaStare scrie
campul hidden + re-trimite form-ul; filtrul persista la reincarcari). Re-randate
OOB cu contoare proaspete la fiecare reincarcare a tabelului.
- Polling redesign: tabelul nu se mai reincarca singur (fara every 15s). Poller usor
JSON (/_fragments/trimiteri-versiune) detecteaza schimbari -> nudge "Date noi —
Reincarca". Reincarcarea (nudge / actiune) pastreaza filtrul+pagina. Scroll/selectia
nu se mai pierd. Poll-guard eliminat (nu mai exista poll periodic de pauzat).
- Logo ROMFAST 32px -> 60px (ca pe romfast.ro), header min-height 92px, 44px pe mobil.
Regresie: 896 passed, 1 deselected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- US-012c: logo .brand-logo mutat in header-left (32px, aliniat stanga); env badge mutat sub titlu in header-center; titlul ramane centrat; responsiv pastrat.
- US-014b: title-ul butonului de tema = doar numele temei curente (Light/Dark/Petrol/Auto), fara enumerarea ciclului; aria-label informativ + aria-live pastrate (a11y).
Regresie 896 passed, 1 skipped, 0 failed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- base.html: listener htmx:beforeRequest scopat la #submissions-wrap care
anuleaza (preventDefault) DOAR poll-ul periodic (fara requestConfig.triggeringEvent)
cat timp modalul de detaliu e deschis SAU exista checkbox de bulk bifat.
- F5/R6: trimiteriChanged si submit-ul de filtru au triggeringEvent -> trec mereu,
deci pauza nu ramane lipita permanent daca randul bifat paraseste filtrul.
- Resume automat (anularea nu opreste timer-ul htmx) + resume explicit pe checkbox
change via delegare pe body -> trimiteriChanged from:body (pastreaza filtrul).
- Vechea pauza pe „rand expandat" (5.8) era deja inlocuita de modalul global (US-003).
- 3 teste noi in tests/test_web_modal.py; suita 843 passed, 1 deselected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- _trimitere_detaliu.html rescris pe ordinea verticala R10: header+motiv,
eroare blocanta, mapare inline, formular editabil/context read-only, actiuni,
<details> Detalii tehnice colapsat
- zero dublare: campurile editabile apar O SINGURA DATA (nr rand propriu, VIN
dedesubt, restul in grila); blocul read-only de grila contopit cu formularul
- R9: operatie+cod read-only deasupra campurilor cu prez.cod_rar (fallback
nemapat), fara eticheta separata Cod RAR
- R2 (fix F7): buton primar conditionat de stare - error->Re-pune(/repune),
needs_data/needs_mapping->Salveaza si retrimite(/corecteaza); duplicatul gol eliminat
- R11: un singur Sterge outline var(--err) pe rand separat, hx-confirm specific,
full-width pe mobil (.detaliu-actiuni-jos in @media 767px, base.html)
- R5: hx-disabled-elt pe toate formele; inchidere pe succes prin inchideModal
- R4: script modal-appropriate pastrat (curatat de US-003)
- 6 teste noi in test_web_corectie.py; rutele + _detaliu_ctx NESCHIMBATE
- suita 835 passed (-m 'not live'); prd.json/progress.txt US-004 passes
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Sub pill-ul de Stare apare eticheta umana scurta (`eticheta_problema` din US-001),
text mic `s-error`, doar cand e ne-goala — stare transmisa prin text, nu doar culoare.
- Coloana Operatie linia 2: codul RAR ca chip discret FARA prefixul "cod RAR:";
cand nemapat ramane "nemapat" muted (comportament 5.8 pastrat).
- R8: regula touch 44px (min-height + padding) pe `tr.trimitere-row` + afordanta hover/focus;
chevron inexistent in cod (randul declanseaza deja modalul din US-003, fara aria-expanded).
- Teste: 7 teste noi US-002 + actualizate test_operatie_contine_cod_rar / test_tabel_nu_are_coloana_motiv;
suita completa 826 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reguli text per cont (operation_text_rules), resolve_prestatii cu param aditiv
text_rules + precedenta stricta, threadat pe toate cele 6 callsite-uri + valid_codes
+ seam classify_prezentare. UI Mapari: sectiune reguli + preview pre-salvare + overlap
+ telemetrie text_rule_hit. UX tabel: cod_rar sub operatie, pill eticheta scurta, fara
scroll orizontal (scopat .tabel-trimiteri + carduri <768px), detaliu inline expandabil
(a11y + pauza poll). code-review: reparat regula auto_send=0 care trimitea automat la RAR
in loc sa tina randul pentru review. 814 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Raportat din client VFP: POST /v1/prezentari raspundea submission_id+status
fara motiv pe randuri blocate (erori se popula doar pe on_unmapped_error=True),
deci un needs_data/needs_mapping parea succes.
API (aditiv): SubmissionResult += nemapate + motiv. create_prezentari
populeaza erori (validare continut, 3 niveluri) / nemapate (coduri fara
mapare, COD_NEMAPAT) / motiv (rezumat uman) pe TOATE caile non-queued —
enqueue, respins (on_unmapped_error=True) si reactivare dedup peste error,
prin helperele _rezultat_enqueue / _rezultat_respins / _motiv_clasificare.
on_unmapped_error=True pastreaza erori=COD_NEMAPAT (compat clienti vechi).
Web: mapare inline in panoul de detaliu trimitere — ruta
POST /trimitere/{id}/mapeaza (reuse save_mapping + reresolve_account, scoped
sesiune + CSRF, re-rezolva pe batch_id-ul randului), helper
_nemapate_pentru_submission + context in _detaliu_ctx, sectiune in
_trimitere_detaliu.html (selector cod RAR cu sugestie fuzzy preselectata).
Apare doar pe operatii nemapate reale (nu pe auto_send=0).
/code-review high: reparat raspuns neonest la reactivare + dublu
load_nomenclator in _detaliu_ctx.
Teste: pytest -q 765 passed. Backend trimitere (worker/masina stari/
idempotenta) si schema NEATINSE. PRD: docs/prd/prd-5.7-*.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cand `rar_credentials` lipseste din cerere, submission-ul intra fara creds
efemere, iar worker-ul cade pe creds-urile RAR durabile ale contului
(accounts.rar_creds_enc). Identificarea contului ramane pe cheia API.
Trimiterea explicita a creds-urilor suprascrie creds-urile contului pe acea
cerere (back-compat: fluxul vechi ROAAUTO merge identic).
- models.py: rar_credentials: RarCredentials | None = None
- router.py: cripteaza creds doar daca exista (altfel creds_enc=NULL)
- worker NEATINS: avea deja fallback _creds_for(...) or _creds_from_account(...)
Pagina /integrare aliniata: exemplele cod (7 limbaje) + export Postman nu mai
includ rar_credentials in payload; nota noua explica modelul (creds pe cont,
optional in payload). README rescris compact + reflecta optionalitatea.
Test nou: enqueue fara creds -> submission fara creds efemere -> fallback pe
contul cu creds salvate. Suita: 673 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Maparile pot creste la sute de randuri. Enhancer reutilizabil (data-dt) in
base.html filtreaza si pagineaza DOM-ul deja randat, fara cereri server; re-init
la full load si dupa swap-urile HTMX. Aplicat pe cele 3 tabele (De rezolvat /
operatii salvate / formate coloane).
Randurile cu <select> expun haystack explicit prin data-dt-row (cod_op + cod_rar
+ denumire): altfel optiunile selectului ar pune tot nomenclatorul in textContent
si orice cautare ar potrivi orice rand.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- "Panou admin" -> "Conturi clienti" (titlu, antet, link meniu hamburger)
- Kebab actiuni mutat in component partajat (base.html) cu position:fixed
pozitionat din JS: .tablewrap{overflow-x:auto} inducea overflow-y:auto care
taia dropdown-ul pe ultimul rand (meniul admin nu se vedea). Sters CSS local.
- Mapari salvate: Salveaza/Sterge mutate in kebab (legate prin form=); coloana
"In coada" doar checkbox (macro autosend_toggle compact, semantica de prezenta
pastrata); select cod RAR limitat la 240px -> tabelul incape fara scroll.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Aduce toate suprafetele dashboard-ului la grila tabelului Trimiteri, muta
navigarea intr-un meniu de cont (hamburger) si da panoului admin actiuni
reale de ciclu de viata. 9 stories, 3 valuri. UI pur (reskin + reasezare)
cu O SINGURA exceptie backend: modelul de stare a contului.
- US-001 sectiunea "Ajutor" eliminata din Acasa (wayfinding redundant).
- US-002 Nomenclator la grila standard (_submissions.html ca referinta).
- US-003 macro autosend compact (Manual<->Auto). Semantica de PREZENTA
`auto_send` (bifat->true, absent->false) NEALTERATA — compatibil cu ambele
parsere (Form(bool) la /mapari, bool(form.get()) la import). Zero backend.
- US-004 accounts.status (pending/active/blocked/archived/deleted), migrare
defensiva idempotenta derivata din `active`, gate worker claim_one pe
status='active' (echivalenta active=1 <=> status='active' pastrata).
- US-005 tabel Mapari compact + panou Ajutor (<details>, proza o singura data),
coloana "In coada".
- US-006 meniu hamburger dropdown (Cont/Integrare/Nomenclator/Admin/logout) +
context is_authenticated/is_admin/csrf_token defensiv in base.html.
- US-007 tab-bar redus la Acasa+Mapari; rutele /_fragments/{cont,integrare,
nomenclator} + deep-link ?tab= raman valide.
- US-008 rute admin block/archive/delete + bulk pe lista account_id,
require_admin + CSRF + PRG, dev id=1 sarit in bulk.
- US-009 admin UI: selectie bife + master + bara bulk + kebab per-rand,
grupare pe stare (bloc nou blocate/arhivate), nota "cont dev implicit" scoasa.
Stergere = SOFT: tombstone (status='deleted'), dar PII purjata IMEDIAT
(rar_creds_enc + chei API revocate + CUI eliberat pentru re-inregistrare),
GDPR/L.142.
VERIFY: 671 teste pass (+40). E2E browser (Playwright) a prins 2 bug-uri
invizibile la TestClient: bara bulk cu display:flex inline invingea [hidden]
(mutat in CSS .bulk-bar[hidden]); conturi arhivate cadeau sub "in asteptare"
(grupare pe status). /code-review high a prins 2 bug-uri reale: soft delete
pastra creds RAR + CUI la nesfarsit fara purjare accounts (GDPR neonorat);
apostrof in numele firmei rupea confirm() inline din kebab — ambele reparate,
plus cleanup boilerplate rute (_lifecycle_route).
Backend trimitere (worker masina stari/idempotenta/mapping) neatins, cu
exceptia gate-ului de cont. Design: docs/design/5.5-uniformizare-ui.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tema light ca bloc [data-theme="light"] peste variabilele :root (dark
nemodificat la octet). Comutator soare/luna in header pe toate paginile,
default OS-aware (prefers-color-scheme, fallback dark), persistenta in
localStorage doar la comutare explicita, script anti-FOUC in <head>
pre-paint. Suprafetele de stare hardcodate convertite la color-mix in
base.html + 7 fragmente _*.html (light lizibil, contrast WCAG AA).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implementeaza PRD 3.6 (US-001..007), pe canalul de import + stratul web;
worker / masina stari / idempotenta / mapare raman neatinse.
- US-003/004: tab-ul "Trimiteri" eliminat; Trimiterile devin sectiune
permanenta sub upload pe Acasa ("Trimiterile tale"); upload comprimat la
bara slim (hero pastrat la first-run); ?tab=coada si /_fragments/coada
servesc Acasa (fara fragment orfan); poll gated pe visibilityState.
- US-001: coloana noua import_rows.override_json (nullable, Fernet, Approach B)
+ _migrate defensiv; ruta v1 + alias web .../rand/{i}/editeaza aplica patch
canonic ULTIMUL in _resolve_row_for_preview si commit_import (mutatie pura,
status rederivat, fara drift). Scoping JOIN -> 404, guard committed -> 409,
semantica empty=clear, decrypt fail -> no-op.
- US-002: buton "Editeaza" pe rand; swap pe <tr> + OOB contoare (nu pe sectiune);
form propriu (confirm dezactivat la editare); refoloseste grila responsiva +
error-map din _trimitere_detaliu.html; mutual-exclusion intre randuri.
- US-005/006: "De rezolvat", "Operatii salvate" si "Formate de coloane" ca
tabele (.tablewrap); H4: comutatorul reflecta auto_send STOCAT.
- US-007: bifa "auto-send" devine comutator etichetat pe COADA ("Pune automat
in coada" / "Tine pentru verificare"), scoped pe operatie; name="auto_send"
pastrat (semantica de prezenta -> bool corect cu ambele parsere, zero backend).
Fix-uri gasite la verificarea E2E in browser (htmx 1.9.12, JS — invizibile la
TestClient): useTemplateFragments=true (raspuns <tr>+OOB era parsat in context
de tabel -> swapError + contoare pierdute); re-activarea confirm-btn dupa salvare
deferita pe tick (evita editing=true tranzitoriu); n-hint actualizat de updateN.
Teste: 523 passed. E2E browser: Acasa unificata, upload slim, editare rand
(needs_data -> ok, swap pe rand, contoare OOB), Mapari tabelar + comutator.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Acasa = ecran de import (tab Import scos, ?tab=import->Acasa). Bara status
compacta pe 2 randuri cu bife accesibile (glife + text) + data formatata.
'Coada'->'Trimiteri': coloane RO, stare umana, detaliu la click in panou
dedicat. Mapari pe 3 sectiuni (de rezolvat / op salvate / formate coloane),
Cont doar cheie+creds. Filtrare Trimiteri, corectie inline needs_data cu
re-enqueue + detectie coliziune idempotency, badge contoare pe tab-uri.
Helper pur partajat payload_view.py (web + GET /v1/prezentari).
Backend trimitere (worker/idempotenta/mapping/schema) neatins. 483 teste.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reorganizeaza interfata web pe trei principii, fara a atinge backend-ul de
trimitere (worker, mapping, idempotency, masina de stari neatinse):
- US-001 app/web/labels.py: modul pur stari tehnice -> text uman + clasa CSS
- US-002 bara status /_fragments/status: microcopy uman, defalcare blocate, scoped cont
- US-003 shell 6 tab-uri (Acasa/Import/Coada/Mapari/Cont/Nomenclator): deep-link
?tab=, panou activ randat server-side, fragmente inactive lazy, ARIA real
- US-004 stepper import 4 pasi (pur vizual; hx-target + csrf pastrate)
- US-005 Acasa onboarding checklist auto-bifat + colaps + empty states prietenoase
Reparat in cursul VERIFY/CLOSE: izolare teste (reset ratelimit._hits in fixturi),
regresie avertisment "cont in asteptare de activare" (re-introdus in bara status),
culori hardcodate -> variabile paleta. 434 teste pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Inchide deadlock-ul din canalul de import web: operatiile nemapate dintr-un
batch in staging nu aveau unde sa fie mapate din UI. Editorul "Mapari de
rezolvat" citea doar din submissions comise, iar commit-ul arunca randurile
needs_mapping -> utilizatorul ramanea blocat fara a putea trimite.
- camp canonic nou `denumire_op`: coloana descriptiva (ex. "Reparatie Motor")
alimenteaza denumirea operatiei, deci sugestia fuzzy devine utila (inainte
denumire = codul opac). Aplicat in cele 3 locuri de resolve (preview, commit
web, commit API).
- panou inline "Operatii de mapat la cod RAR" in preview: fiecare operatie
nemapata cu sugestie preselectata + dropdown + auto-send + salveaza.
- ruta POST /_import/{id}/mapare-operatie: salveaza maparea (persistenta,
operations_mapping) si re-randeaza preview-ul; randurile trec din
needs_mapping in ok fara re-upload, maparea se retine pentru fisiere viitoare.
- fix bug pre-existent de semnatura coloane: semnatura se calcula din campurile
mapate (json_mapare.keys), nu din antetul complet -> ignorarea unei coloane
schimba semnatura si maparea retinuta nu mai era gasita la preview/re-upload.
Acum mereu din antetul complet (web + API), consecvent cu preview/commit.
Teste noi: tests/test_import_mapare_operatie.py (6). Suita: 400 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Canalul web trece de la 100% deschis (hardcodat cont 1) la autentificat si
multi-tenant. Un service nou se inregistreaza din browser, primeste o cheie API
(o singura data) si o sesiune; contul se creeaza "in asteptare" (active=0) si nu
trimite la RAR pana la activarea de catre admin (tools/account.py activate).
- users + app/users.py: parole scrypt (salt per-user, eticheta parametri onorata
la verify pentru migrare cost), email unic case-insensitive
- sesiune: SessionMiddleware (same_site=strict, https_only config) + app/web/session.py
(current_account/web_account/require_login->LoginRequired, set_session clear-inainte)
- CSRF (app/web/csrf.py) enforce in prod inclusiv pe login/signup + rate-limit
in-proces (app/web/ratelimit.py) pe signup si login
- signup/login/logout (app/web/auth_routes.py): signup tranzactie atomica,
cheie-o-data, log SIGNUP pentru descoperire admin
- dashboard + import scoped pe contul sesiunii (regula NULL->cont 1); toate rutele
web care ating date sensibile sub require_login; nomenclator ramane global
- banner "cont in asteptare" pentru conturi active=0
- gate worker: claim_one LEFT JOIN accounts COALESCE(active,1)=1 (account_id NULL=activ)
VERIFY context curat (2 runde): leak cross-account /_fragments/mapari prins+reparat.
/code-review high: csrf_token lipsa pe re-randari de eroare, scrypt_params ignorat,
login fara rate-limit -- toate reparate. 361 teste pass (de la 313).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implementare completa U5 din plan-treapta2.md (sectiunea 13):
- _upload.html: drop zone + buton accesibil (a11y: drag nu e la tastatura),
drag-and-drop JS, mesaj 'NU se trimite nimic pana confirmi',
selector foi pt multi-sheet xlsx, stari eroare/mesaj
- _mapcoloane.html: formular mapare coloane cu .maprow/.mapcol.grow,
sugestii fuzzy pre-selectate, etiichete <label> vizibile, sample values,
format data configurabil
- _preview_import.html: tabel 6 stari, pills rezumat, filtre pe stare,
.chk per-rand pe needs_review (D11), banner declarant .banner.warn
direct deasupra input-ului N (D12), bara confirmare sticky,
text 'dubla cu randul N' pe duplicate_in_file (D10 daltonism),
link export CSV randuri esuate
- base.html: .s-needs_review (warn), .s-already_sent/.s-duplicate_in_file
(muted), .drop-zone, .banner.warn, .sticky-bar, .htmx-indicator
- routes.py: rute /_import/upload/mapare-coloane/preview/reset/confirma;
helper _web_compute_preview refoloseste _resolve_row_for_preview,
_already_sent_lookup, _signature din import_router (fara a-l edita);
commit ON CONFLICT DO NOTHING (TOCTOU); log atestare
- tests/test_import_ui.py: 15 teste (dashboard, upload, mapare, preview,
confirmare N corect/gresit, reset, erori, multi-sheet, a11y D10/D11/D12)
279 teste total, 0 esecuri.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>