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>
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>
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>
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>
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>