Files
rar-autopass/docs/ROADMAP.md
Claude Agent b48501d8e4 feat(web): light/dark mode cu comutator persistat + anti-FOUC (PRD 5.3)
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>
2026-06-22 19:39:12 +00:00

36 KiB
Raw Blame History

AutoPass — Roadmap & Proces de Dezvoltare

Sursa unica de progres + procesul de lucru. O sesiune noua are nevoie doar de promptul: "Citeste docs/ROADMAP.md si continua roadmap-ul [optional: livrabila X.Y]." Sesiunea isi detecteaza singura faza (§5.7), planifica SAU executa, verifica si inchide — cu doua porti umane: aprobarea PRD-ului si confirmarea commit-ului.

Contractul RAR (sursa de adevar de contract) = docs/api-rar-contract.md. Acolo unde un plan difera de contract, contractul are dreptate.

Status fara emoji (preferinta proiect): TODO neinceput · WIP in lucru · DONE gata · BLOCAT blocat de o dependenta · AMANAT deferat/taiat cu motiv.


1. Context

Gateway central care declara prestatiile de service-auto la RAR AUTOPASS (Legea 142/2023, OM 210/2024), portat din clasa Visual FoxPro RarAutoPass (ROAAUTO). Stack: Python/FastAPI + SQLite (WAL) + httpx + Jinja2/HTMX. Un container (API) + un proces separat (worker).

Doua canale de intrare, ambele LIVE pe endpoint-ul de test RAR:

  • Treapta 1 — canal API (POST /v1/prezentari) pentru ROAAUTO / soft propriu.
  • Treapta 2 — import xlsx/csv + mapare coloane + UI web (HTMX) pentru service-uri non-ROA.

2. Arhitectura (rezumat)

  Canal API (ROAAUTO)  ─┐
  Upload web (xlsx/csv) ─┴─▶ Gateway FastAPI ─▶ validare → mapare op→cod → enqueue (PII criptat)
                                  │
                                  ▼
                             WORKER (proces separat): claim atomic → login RAR → postPrezentare → retry
                                  │
  Dashboard (Jinja2+HTMX) ◀───────┴── monitorizare live RAR + coada + editor mapari + audit CSV

Reguli de contract (detalii in docs/api-rar-contract.md): FINALIZATA e terminal la RAR (fara anulare/corectie prin API); idempotency = hash de continut server-side; JWT TTL = 30h.


3. Stadiu Implementare (dashboard)

Singurul loc din document care se modifica pe parcurs. Detaliile NU intra aici — stau in PRD-uri (docs/prd/prd-X.Y-*.md), linkate in coloana Detalii. La fiecare livrabila terminata: schimba statusul + data + linkul PRD si actualizeaza "Ultima actualizare".

Ultima actualizare: 2026-06-22 — 5.3 LIVRAT (Light/Dark mode: tema light ca bloc [data-theme="light"] peste variabilele :root — dark NESCHIMBAT la octet; comutator soare/luna in header pe toate paginile, default OS-aware cu fallback dark, persistenta 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. Zero backend — pur frontend. VERIFY 2 runde: r1 FAIL a prins literalii dark ramasi in 7 fragmente HTMX (text invizibil in light, test vacuu pe doar base.html) → fix US-003 + test care scaneaza fragmentele; r2 PASS E2E browser (banner light ~13:1 contrast, toggle instant+persista+anti-FOUC, dark identic). /code-review high: 1 finding reparat (light --ok green sub AA ca text → green-700, ~5.0:1). 584 teste. PRD: prd-5.3). | ISTORIC: 5.2 LIVRAT (Endpoint dry-run POST /v1/prezentari/valideaza: valideaza payload + mapare si intoarce verdictul real — status_estimat queued/needs_data/needs_mapping + erori [{field,message}] + coduri nemapate + prestatii rezolvate — FARA enqueue, FARA creds, zero scriere DB). 1 story TDD. Cheia de design: helper pur partajat classify_prezentare folosit de AMBELE rute, ca dry-run-ul sa nu poata diverge de trimiterea reala (invariant de corectitudine); create_prezentari refactorizat pe el cu comportament identic. Scope minim per decizie user: doar validare+mapare (fara idempotency/duplicat, idempotency.py neatins), hub /integrare amanat ca follow-up (descoperibilitate). VERIFY context curat PASS (577 teste; E2E API cu cele 3 verdicte + COUNT(*)=0 dupa dry-run + fara leak creds in raspuns; regresia de aur verde; live RAR FINALIZATA neprobat — lipsa creds key, endpoint read-only nu atinge worker/coada/schema). /code-review high: 0 findings (refactor faithful, mutable-default Pydantic-safe, import local necesar anti-circular). PRD: prd-5.2. | ISTORIC: 5.1 LIVRAT (Hub de integrare /integrare: exemple cod multi-limbaj + retetar VFP cu 2 dialecte + GET /v1/ping readiness + export Postman/OpenAPI + "Testeaza conexiunea"). 4 stories in 2 valuri (Val 1 = US-001/US-002/US-004 paralel pe fisiere disjuncte via Agent team; Val 2 = US-003 UI). Atentie operationala: US-003 a rulat intr-un worktree branched din ultimul commit (FARA modificarile necomise ale US-004 din working-tree) si la "copiere manuala" a SUPRASCRIS routes.py, stergand ruta POST /integrare/test-cheie (8 teste 404) — reparat prin re-aplicarea rutei de catre autorul US-004 pe routes.py curent. Lectie: stories care ating acelasi fisier in valuri diferite + worktree = clobber daca worktree-ul nu vede working-tree-ul; foloseste fisiere disjuncte SAU merge atent de catre lead. VERIFY context curat PASS (568 teste) + E2E browser Playwright (deep-link server-side, IA pe 2 niveluri, VFP cu 3 niveluri de tab comuta corect, copy, htmx test-cheie → fragment eroare, 0 erori consola) + enqueue live (POST /v1/prezentari → queued); live RAR FINALIZATA NEPROBAT in sesiune (lipsa AUTOPASS_CREDS_KEY/creds RAR test) — risc minim, backend trimitere NEATINS. /code-review high a prins 4 bug-uri reale (toate in suprafata noua, reparate + lock-uite cu teste): snippet C# JSON multi-linie nevalid (CS1010), snippet VFP json.dumps(indent=0) inca cu newline-uri → string literal rupt in ambele dialecte, snippet Node node:buffer nu exporta FormData → TypeError, script _integrare.html ne-scoped acumuland event-listeneri pe tab-bar-ul principal la fiecare swap htmx (scoped pe #integrare-section). Notat ca cleanup viitor (nereparat): _render_integrare dubleaza SQL are_creds/are_cheie, ping cu 2 conexiuni DB + account_for_key de 2 ori, _campuri_obligatorii necache-uit, panouri limbaj copy-paste (candidat macro Jinja2). Backend trimitere (worker/masina stari/idempotenta/mapping) si schema NEATINSE. PRD: prd-5.1. | ISTORIC: 3.6 INCHIS (editare celule in preview + Acasa unificata). CLOSE: /code-review high a prins 1 bug real (decriptare override_json neprotejata de try/except in ambele cai de preview — 500 pe tot batch-ul la rotatie cheie Fernet vs. raw_json care degrada gratios), reparat in import_router.preview_import + routes._web_compute_preview; duplicarea _override_of/canonicalize notata ca cleanup viitor. 523 teste pass. 7 stories in 3 valuri, executate de 2 echipe in paralel (TeamCreate) pe fisiere disjuncte (core: routes/import/templates; mapari: _mapari.html) + US-007 secvential. Livrate: tab "Trimiteri" eliminat→sectiune "Trimiterile tale" sub upload pe Acasa (US-003); upload bara slim accentuata cu hero la first-run (US-004); editare de celule in preview prin import_rows.override_json (Approach B, Fernet, patch canonic aplicat ULTIMUL in _resolve_row_for_preview+commit_import — completeaza inclusiv coloane ABSENTE din fisier), mutatie pura cu status rederivat (US-001); buton Editeaza pe rand cu swap pe <tr>+OOB contoare (nu pe sectiune), form propriu, mutual-exclusion, reuse grila _trimitere_detaliu.html (US-002); Mapari + formate de coloane ca tabele .tablewrap, H4 auto_send stocat (US-005/006); bifa "auto-send"→comutator etichetat pe COADA ("Pune automat in coada"/"Tine pentru verificare"), scoped pe operatie, name=auto_send pastrat (zero backend) (US-007). 523 teste pass. VERIFY: E2E browser pe / (Acasa unificata, upload slim, editare rand needs_data→ok cu swap pe rand + contoare OOB, Mapari tabelar + comutator) + LIVE pe RAR test — import fara coloana data → editarea completeaza data (override) → commit → worker login RAR test → postPrezentaresent cu idPrezentare=68696, confirmat independent in lista finalizate RAR. 3 bug-uri JS (htmx 1.9.12) prinse DOAR la E2E in browser (invizibile la TestClient) si reparate: useTemplateFragments=true (raspunsul <tr>+OOB era parsat in context de tabel → swapError + contoare pierdute), re-activare confirm-btn deferita pe tick (race editing=true tranzitoriu), n-hint ok-count actualizat de updateN. Backend trimitere (worker, masina stari, idempotenta-logica, mapping-rezolvare) NEATINS — singura atingere de schema: 1 coloana nullable override_json cu migrare defensiva. PRD: prd-3.6. | ISTORIC: 3.5 LIVRAT (dashboard compact). 11 stories in 4 valuri, TDD. US-001 bara status compacta pe 2 randuri cu bife accesibile (glife ✓/✗ + text, nu doar culoare) + format_data_rar (dd.mm.yyyy hh24:mi:ss, helper pur). US-002 Acasa = ecranul de import (upload dominant inline, tab Import scos, ?tab=import→Acasa fara 404). US-003 helper pur partajat app/payload_view.py (payload→campuri afisabile, defensiv, coercion Excel) refolosit si de GET /v1/prezentari (DRY). US-004 "Coada"→"Trimiteri": coloane RO + stare umana + detaliu complet la click in panou dedicat #trimitere-detaliu (nu inline — poll 10s), scoped 404 cross-account. US-005/006 CRUD mapari operatii + formate coloane salvate (scoped, re-rezolvare auto la edit cod). US-007 "Mapari" 3 sectiuni (de rezolvat / op salvate / formate coloane), "Cont" doar cheie+creds. US-008 motiv (mesaj validare) pe randuri needs_data in preview. US-009 filtre Trimiteri (stare SQL / vehicul+data Python) scoped + "sterge filtrele". US-010 corectie inline needs_data→queued cu payload+idempotency recalculate, sent read-only (403), coliziune idempotency prinsa pre-UPDATE. US-011 badge contoare pe tab-uri (Mapari/Trimiteri), scoped, aria-label. VERIFY context curat PASS (483 teste; E2E browser/RAR LIVE neprobat — recomandata probare manuala --send). /code-review high a prins 4 findings reale, toate reparate: corectie needs_mapping re-rezolva prestatiile (nu mai poate trimite cod nul la RAR), filtru fara LIMIT silentios, coliziune idempotency atomica (try/except IntegrityError), comparatie data doar ISO. Backend trimitere (worker, masina stari, idempotenta-logica, mapping-rezolvare, schema) NEATINS. PRD: prd-3.5. Urmeaza Etapa 4 (4.1 mapare AI/MCP).

2026-06-18 — 3.4 LIVRAT (interfata web ergonomica: tab-uri + wizard + microcopy). US-001 modul pur app/web/labels.py (stari tehnice→text uman + clasa CSS; test parametrizat din CHECK-ul schema.sql iese rosu la stare nemapata). US-002 bara status /_fragments/status + _status.html (etichete umane, defalcare blocate pe motiv, poll 15s, scoped pe cont). US-003 shell 6 tab-uri (Acasa·Import·Coada·Mapari·Cont·Nomenclator) cu deep-link ?tab=, panou activ randat server-side, fragmente inactive lazy pe click, ARIA real (tablist/tab/tabpanel + aria-selected + navigare cu sageti). US-004 stepper import 4 pasi (PUR vizual, hx-target="#import-section" + csrf pastrate). US-005 Acasa onboarding checklist auto-bifat (are_creds/are_trimiteri) + colaps cand totul gata + empty states prietenoase Coada/Mapari. VERIFY lead-driven (TestClient ACs + 434 pytest pass; E2E browser/RAR LIVE neprobat in sesiune — recomandata probare manuala --send). Fix izolare teste (reset ratelimit._hits in fixturi, 429 la rulare subset). /code-review high: regasit avertisment "cont in asteptare de activare" (regresie din scoaterea /_fragments/banner) re-introdus in bara status + culori hardcodate→variabile paleta. 434 teste pass. Backend trimitere neatins. PRD: prd-3.4. Urmeaza Etapa 4 (4.1 mapare AI/MCP).

3.3b LIVRAT (self-service cheie/creds + admin web + email). US-007 rute web proprii pentru rotire cheie + setare creds RAR scoped pe sesiune (C13, nu endpointul API). US-010 rol admin (users.is_admin) + require_adminAdminRequired→403 + CLI tools/account.py set-admin + bootstrap automat (primul cont care se inregistreaza = admin, citit in BEGIN IMMEDIATE anti-race). US-011 panou /admin (conturi in asteptare/active, activare/dezactivare cu CSRF + PRG, contul dev id=1 protejat) + link "Panou admin" pe dashboard doar pentru admini + buton logout. US-012 app/email.py notify_signup best-effort DEGRADAT fara SMTP (no-op + log, prinde orice exceptie, nu blocheaza signup) + config smtp_*. Fix migrare defensiva users.is_admin/email_verified in _migrate (gap prins de VERIFY r1, ca C1 pe accounts.active). 2 runde VERIFY context curat (r2 PASS, sweep securitate toate rutele noi sub require_login/require_admin + CSRF, scoped sesiune). /code-review high: TOCTOU bootstrap mutat in tranzactie + _render_admin extras (anti-duplicare + N+1). 393 teste pass. Urmeaza Etapa 4 (4.1 mapare AI/MCP). Deferat din 3.1 (P3): rename/set-cui, --if-not-exists. SMTP real = follow-up pe US-012.

3.3a LIVRAT (self-onboarding web core: app/users.py parole scrypt cu eticheta de parametri onorata la verify; SessionMiddleware same_site=strict + app/web/session.py guard require_loginLoginRequired; CSRF per-sesiune enforce in prod inclusiv pe login/signup + rate-limit signup & login in-proces; signup active=0 tranzactie atomica + cheie-o-data + log SIGNUP; login/logout; dashboard & import multi-tenant scoped pe sesiune cu regula NULL→cont 1 — toate rutele web care ating date sensibile sub require_login + scope; gate worker claim_one LEFT JOIN ... COALESCE(active,1)=1. 2 runde VERIFY context curat — runda 1 a prins un leak cross-account pe /_fragments/mapari, reparat; runda 2 PASS. /code-review high a prins 3 findings, reparate. 361 teste pass). Urmeaza 3.3b (self-service cheie/creds + admin web + email). Deferat din 3.1 (P3): rename/set-cui, --if-not-exists.

Etapa 1 — Canal API ROAAUTO (Treapta 1)

# Livrabila Status Data Detalii
1.1 Gateway complet: validare + mapare + coada + worker + reconciliere + dashboard DONE 2026-06-15 E2E LIVE prin gateway: POST /v1/prezentari → worker → FINALIZATA la RAR test (idPrezentare=68516). Cod app/, 279 teste.

Etapa 2 — Import xlsx/csv + UI web (Treapta 2)

# Livrabila Status Data Detalii
2.1 Parser xlsx/csv 2-treceri + staging criptat (POST /v1/import) DONE 2026-06 app/import_parse.py; encoding RO, delimiter sniff, coercion, robustete sheet/merged/footer
2.2 Creds RAR durabile per-cont + worker re-login fallback DONE 2026-06 accounts.rar_creds_enc, gate purjare worker
2.3 batch_id scope reresolve_account (inchide R1 bulk-send) DONE 2026-06 app/mapping.py
2.4 Mapare coloane + semnatura + detectie drift + fuzzy DONE 2026-06 app/api/v1/import_router.py
2.5 Preview 6 stari + canonicalize partajat + gate HARD + atestare DONE 2026-06 duplicate_in_file, already_sent, needs_review, import_attestations, TOCTOU ON CONFLICT
2.6 UI web upload HTMX (drop → mapare → preview → confirma) DONE 2026-06 app/web/templates/_upload.html, _mapcoloane.html, _preview_import.html
2.7 Export randuri esuate CSV + job purjare purge_after + E2E DONE 2026-06 export_failed_rows, tests/test_import_e2e.py

Etapa 3 — Multi-cont / self-onboarding (URMATORUL FOCUS)

# Livrabila Status Data Detalii
3.1 Creare cont nou (CLI dedicat) DONE 2026-06-17 CLI tools/account.py (create/list[--pending]/activate/deactivate, --with-key atomic) + accounts.active + index unic CUI + app/accounts.py. 20 teste noi. PRD: prd-3.1
3.2 Filtrare pe cont a GET-urilor de listare DONE 2026-06-17 scope cheie pe /v1/prezentari(/{id}), /v1/mapari(/pending), /v1/audit/export (NULL→cont 1); nomenclator global; 404 cross-account identic (B3) + allowlist campuri detaliu (B4) + helper account_scope_clause (B2) + index (B5). 14 teste noi, 313 pass. PRD: prd-3.2
3.3a Self-onboarding web (core) DONE 2026-06-17 users (scrypt) + sesiune (SessionMiddleware, same_site=strict) + CSRF (enforce prod, inclusiv login/signup) + rate-limit signup/login + signup/login/logout + dashboard & import scoped pe sesiune (NULL→1, anti-leak C6) + gate worker active=0 (COALESCE). 2 runde VERIFY (leak /_fragments/mapari prins+reparat) + code-review (csrf erori, scrypt_params, login rate-limit). 361 teste. PRD: prd-3.3
3.3b Self-service cheie/creds + admin web + email DONE 2026-06-18 US-007 (rute web proprii /cont/roteste-cheie+/cont/rar-creds scoped sesiune, C13), US-010 (rol admin is_admin + require_admin→403 + CLI set-admin + bootstrap primul cont=admin), US-011 (/admin activare/dezactivare cu CSRF+PRG, link doar pt admini + logout), US-012 (app/email.py notify best-effort degradat fara SMTP + log SIGNUP). Fix migrare defensiva users.is_admin/email_verified. 2 runde VERIFY context curat (r1 a prins migrarea lipsa, reparat; r2 PASS) + /code-review high (TOCTOU bootstrap admin mutat in tranzactie + extras _render_admin anti-duplicare/N+1). 393 teste. PRD: prd-3.3
3.4 Interfata web ergonomica (tab-uri + wizard + microcopy uman) DONE 2026-06-18 Dashboard reorganizat in 6 tab-uri (Acasa·Import·Coada·Mapari·Cont·Nomenclator) cu deep-link ?tab= + panou activ server-side + lazy pe rest; bara status cu etichete umane (app/web/labels.py) + defalcare blocate; import ca stepper 4 pasi (PUR vizual); Acasa onboarding auto-bifat + empty states. Backend trimitere neatins. 434 teste. PRD: prd-3.4
3.5 Dashboard compact: import pe prima pagina, status cu bife, Trimiteri lizibile, Mapari complete DONE 2026-06-19 11 stories (4 valuri), 3 review-uri de plan facute. Acasa=ecran de import (scoate tab Import); bara status compacta font normal + bife accesibile (auto-send/RAR) + data dd.mm.yyyy hh24:mi:ss; "Coada"→"Trimiteri" cu coloane RO + detalii comanda din payload_json (helper partajat payload_view.py) + detaliu la click in panou dedicat; filtrare Trimiteri (US-009); corectie inline needs_data cu re-enqueue + detectie coliziune idempotency (US-010); badge contoare pe tab-uri (US-011); "Mapari" 3 sectiuni (de rezolvat / op salvate cu re-rezolvare auto / formate coloane), "Cont"=doar cheie+creds; feedback needs_data la import. Backend trimitere neatins. PRD: prd-3.5
3.6 Editare celule in preview + Acasa unificata (Trimiteri inline, upload slim, Mapari tabelar, comutator coada) DONE 2026-06-22 7 stories (3 valuri), 2 echipe in paralel (TeamCreate) pe fisiere disjuncte + US-007 secvential. US-003/004 tab "Trimiteri" eliminat→sectiune "Trimiterile tale" sub upload pe Acasa; upload bara slim (hero la first-run); ?tab=coada+/_fragments/coada→Acasa; poll gated visibilityState. US-001 import_rows.override_json (Approach B, Fernet, _migrate defensiv) aplicat ULTIMUL in _resolve_row_for_preview+commit_import (mutatie pura; completeaza si coloane ABSENTE din fisier); ruta .../rand/{i}/editeaza scoped JOIN→404, guard committed→409, empty=clear. US-002 buton Editeaza pe rand, swap pe <tr>+OOB contoare (nu pe sectiune), form propriu (confirm dezactivat la editare), mutual-exclusion, reuse grila _trimitere_detaliu.html. US-005/006 Mapari/formate tabelar (.tablewrap, H4 auto_send stocat). US-007 bifa auto-send→comutator pe COADA ("Pune automat in coada"/"Tine pentru verificare"), scoped operatie, name=auto_send pastrat (zero backend). 523 teste pass. VERIFY E2E browser + LIVE RAR test: import fara coloana data→editare completeaza data (override)→commit→worker login RAR test→postPrezentare→sent idPrezentare=68696 (confirmat in finalizate RAR). 3 bug-uri JS prinse la E2E (invizibile la TestClient) reparate: htmx useTemplateFragments (raspuns <tr>+OOB parsat in context tabel→swapError), re-activare confirm-btn deferita pe tick, n-hint actualizat. /code-review high (2026-06-22): 1 bug real reparat — decriptarea override_json era in afara try/except-ului care protejeaza raw_json in ambele cai de preview (import_router.preview_import + routes._web_compute_preview); la rotatie cheie Fernet / token corupt raw_json degrada gratios la {} dar override_json arunca 500 pe tot batch-ul — acum protejat identic. Notat ca cleanup viitor (nereparat, disciplina backend-neatins): _override_of + blocul canonicalize-dupa-override duplicate in 3-4 locuri (preview/commit API vs web). Backend trimitere (worker/masina stari/idempotenta/mapare) NEATINS. PRD: prd-3.6

Etapa 5 — Ergonomie & Integrare (FOCUS CURENT)

Directie noua (2026-06-22, decizie utilizator): produsul e functional, dar greu de adoptat de service-urile care vin din Visual FoxPro / soft propriu. Prioritatea trece pe usurinta de integrare + ergonomie, peste Etapa 4 (vezi nota de mai jos). Propunere fundamentata cu lentila DX gstack (/devex-review) pe codul real: lipseste suprafata de onboarding API self-service, exemplele de cod, puntea VFP, dry-run-ul si tema light.

# Livrabila Status Data Detalii
5.1 Hub de integrare (pagina /integrare autentificata): exemple cod multi-limbaj (curl/Python/PHP/C#/Node) + retetar Visual FoxPro (POST via MSXML2.ServerXMLHTTP + upload CSV) + export OpenAPI/Postman + buton "Testeaza conexiunea" DONE 2026-06-22 4 stories (2 valuri, 2 echipe paralel + restore dupa clobber de merge). US-001 GET /v1/ping readiness (account_id/mediu/autentificat_cu_cheie/are_creds_rar/ts) + GET /v1/integrare/postman.json (v2.1.0, allowlist 3 rute). US-002 integrare_examples.py pur (7 limbaje × 2 canale, drift-test is_required()). US-003 tab "Integrare" IA pe 2 niveluri (limbaj→canal, VFP cu dialecte MSXML2/WinHttp), copy din <pre><code>, empty-state CTA, export .cardlink, doar tokens. US-004 POST /integrare/test-cheie (account_for_key direct, scoped sesiune, no-echo). VERIFY: 568 teste + E2E browser (Playwright: VFP 3 niveluri comuta, htmx test-cheie → fragment eroare, 0 erori consola) + enqueue live; live RAR neprobat (lipsa creds key). /code-review high: 4 bug-uri reale reparate (C#/VFP snippet JSON multi-linie nevalid, Node node:buffer fara FormData, script ne-scoped acumuland listeneri). Backend trimitere NEATINS. PRD: prd-5.1
5.2 Endpoint dry-run POST /v1/prezentari/valideaza — valideaza payload + mapare, intoarce erorile reale FARA enqueue DONE 2026-06-22 1 story (US-001), un worker TDD. Helper pur partajat classify_prezentare (mapping.py) folosit de AMBELE rute → garanteaza ca dry-run-ul da acelasi verdict ca trimiterea reala (invariant de corectitudine, nu doar DRY); create_prezentari refactorizat pe el (comportament identic, test_api.py verde). Ruta read-only: {results:[{index,valid,status_estimat,erori,nemapate,prestatii_rezolvate}]}, rar_credentials optional+ignorat, zero scriere DB, scope prin resolve_account_id. Doar validare+mapare (FARA idempotency/duplicat — decizie user; idempotency.py neatins) + hub /integrare amanat. VERIFY context curat PASS (577 teste; E2E API: queued/needs_data/needs_mapping + COUNT(*)=0 dupa dry-run, fara leak creds; regresia de aur POST /v1/prezentari→queued verde; live RAR neprobat — lipsa AUTOPASS_CREDS_KEY/creds test, endpoint read-only nu atinge worker/coada). /code-review high: 0 findings. PRD: prd-5.2
5.3 Light/Dark mode — toggle in header, persistat (localStorage); CSS deja pe variabile :root DONE 2026-06-22 3 stories (US-001 paleta light + US-003 fix suprafete fragmente; US-002 comutator+persistenta+anti-FOUC), un worker TDD secvential (toate ating templates). Tema light = bloc [data-theme="light"] care suprascrie variabilele :root (dark NESCHIMBAT la octet, default pastrat); fundalurile de stare hardcodate (#241a1a/#201c0f/#16241c) convertite la color-mix(... 12%, var(--card)) in base.html + 7 fragmente _*.html. Comutator soare/luna in header (aria-label, >=36px), pe toate paginile (login/signup/dashboard/admin). Default OS-aware (prefers-color-scheme, fallback dark); persistenta localStorage DOAR la click (init doar sincronizeaza iconita → OS-aware ramane viu pana la comutare explicita); script anti-FOUC in <head> inainte de <style> (data-theme sincron pre-paint). Zero backend. VERIFY 2 runde context curat: r1 FAIL (literali dark hardcodati in 7 fragmente HTMX → text invizibil in light; testul scana doar base.html, verde vacuu) → fix US-003 (color-mix in fragmente + test care scaneaza _*.html de pe disc); r2 PASS (E2E browser: banner light rgb(246,234,225)/text rgb(26,29,36) ~13:1, toggle instant+persista+anti-FOUC, dark neschimbat). /code-review high: 1 finding real reparat (light --ok green-600 ~3.3:1 ca text pe alb → green-700 #15803d ~5.0:1, trece AA). Backend trimitere NEATINS. PRD: prd-5.3
5.4 Erori pe 3 niveluri (problema + cauza + fix) pe API si UI TODO DX: fight uncertainty; reduce suportul

Etapa 4 — Deprioritizat (post Etapa 5, daca apare nevoia din uz real)

# Livrabila Status Data Detalii
4.1 Mapare AI / conector MCP (sugestie peste fuzzy) AMANAT deprioritizat 2026-06-22 in favoarea ergonomiei/integrarii (Etapa 5)
4.2 Editare/anulare prezentari trimise BLOCAT FINALIZATA terminal la RAR — fara flux API; corectia = suport RAR

Amanat / taiat (cu motiv)

Livrabila Status Motiv
Drop-fisier SFTP / email-to-import AMANAT Valideaza intai upload-ul manual (wedge-ul real), apoi re-evalueaza
Contor volum + prag freemium AMANAT Metrici de pret inainte sa existe useri; trivial de adaugat post-validare
Billing complet (Stripe etc.) AMANAT Dupa validarea pragului de volum

4. Open questions / riscuri acceptate

  • Un cont = un agent RAR sau mai multi — afecteaza maparea creds in UI + filtrarea monitorizarii. Relevant pentru Etapa 3.
  • Valori reale sistemReparat — azi se trimite "null"; ce alte valori accepta RAR ramane de probat.
  • R4 (acceptat constient): creds RAR durabile-at-rest (Treapta 2) → la scurgerea cheii Fernet toate parolele sunt decriptabile (vs. doar in-flight pe canalul API). Mitigare: rotatie cheie + redactare loguri.

5. Proces de implementare

5.1 Principii

  1. PLAN separat de EXECUTE/VERIFY, pe sesiuni distincte. Planificarea consuma mult context (model puternic) si produce PRD-ul ca artefact de predare. Executia reia intr-o sesiune noua bazat doar pe PRD — nu pe transcriptul planificarii. Starea persista in PRD, nu in conversatie.
  2. TDD ca contract: testul scris ÎNAINTE = forma executabila a criteriilor de acceptare. Un worker cu test rosu clar nu poate declara fals victoria — testul decide.
  3. Story atomic = unitate de paralelizare SI de rollback: un story = un commit logic = un worker = un test-suite verde.
  4. VERIFY in context curat: un subagent dedicat care primeste DOAR PRD-ul + instructiunile §5.6, NU transcriptul executiei (altfel mosteneste partinirea de confirmare a celui care a implementat).
  5. Single writer: doar sesiunea lead scrie in PRD, ROADMAP si git. Workerii scriu doar cod si teste.
  6. E2E pe canalul real: un flux se verifica prin canalul lui (upload web prin browser, API prin POST /v1/prezentari), nu doar prin apel intern. RAR test = endpoint real.

5.2 Cele 4 faze (separabile pe sesiuni)

  SESIUNE A (Opus/Fable)            SESIUNE B (lead + agent team Sonnet)
  ┌─────────────────────┐          ┌──────────────────────────────────────────────────┐
  │ FAZA 1: PLAN        │  PRD     │ FAZA 2: EXECUTE   FAZA 3: VERIFY   FAZA 4: CLOSE   │
  │ citeste ROADMAP+cod │  aprobat │ TeamCreate +      subagent context  /code-review   │
  │ scrie PRD (stories  │ ───────▶ │ workeri Sonnet    curat: pytest +   writeback dash │
  │ atomice + teste)    │ (in PRD) │ TDD per story     E2E RAR test      propune commit  │
  │ plan-reviews gstack │          │ lead bifeaza PRD  raport in PRD                     │
  │  ▼ POARTA UMANA     │          │                                     ▼ POARTA UMANA  │
  │  aprobare PRD       │          │                                     confirmare commit│
  └─────────────────────┘          └──────────────────────────────────────────────────┘

PLAN poate rula singur intr-o sesiune (scump, model puternic) si se opreste la poarta de aprobare. EXECUTE → VERIFY → CLOSE reiau intr-o sesiune noua din PRD-ul aprobat. Pot fi si inlantuite in aceeasi sesiune daca vrei — starea din PRD le face reluabile oricum.

5.3 PRD per livrabila

  • 1 PRD per livrabila din dashboard: docs/prd/prd-X.Y-<slug>.md (skill /prd).
  • Prima linie dupa titlu: **Stare**: draft (vezi §5.7 pentru tranzitii).
  • Contine obligatoriu: obiectiv, Non-Goals (anti scope-creep), stories atomice (§5.4), riscuri, intrebari deschise (rezolvate cu utilizatorul ÎNAINTE de executie), graful de valuri.
  • PRD-ul nu repeta strategia/contractul — le linkeaza (docs/api-rar-contract.md, acest ROADMAP).
  • Review-uri de plan (aplicate IN PRD inainte de cod): /plan-ceo-review (valoare/scope) + /plan-eng-review (fezabilitate/teste) — obligatorii; /plan-design-review — doar daca atinge UI.

5.4 Story atomic (template)

### US-003: <titlu scurt>
**Ca** <rol> **vreau** <capabilitate> **pentru ca** <motiv>.

- **Depinde de**: US-001
- **Fisiere**: `app/<modul>.py`, `app/web/templates/<x>.html` (~N fisiere)
- **Test intai (RED)**: `tests/test_<x>.py``test_<caz_1>`, `test_<caz_2>`
- **Acceptance criteria**:
  - [ ] <criteriu testabil 1>
  - [ ] <criteriu testabil 2>
- **Verificare E2E**: <browser HTMX / POST /v1/prezentari pe RAR test>

Testul de atomicitate: (a) poate un Sonnet sa-l termine intr-o singura sesiune, cu teste, fara sa intrebe nimic? daca nu → sparge-l. (b) lasa sistemul functional daca e ultimul story? (c) Fisiere

  • Depinde de complete (decid ce se paralelizeaza). (d) backend + UI pentru acelasi comportament = 2 stories.

5.5 Executie — agent team (lead orchestreaza, NU scrie cod)

  • TeamCreate creeaza echipa + lista de task-uri partajata; Agent cu team_name + name + model: sonnet spawneaza teammates adresabili. Lead-ul ii coordoneaza prin SendMessage (clarificari/re-directionare la cald, fara re-spawn) si TaskUpdate (atribuire/inchidere task).
  • Valuri (waves): lead-ul grupeaza stories pe graful de dependente. Val 1 = stories fara Depinde de si fara fisiere comune → teammates paraleli. Val 2 = deblocate de Val 1. Etc.
  • Reguli hard: max 2-3 teammates simultan (server dev + SQLite partajate); fisiere comune = nu paralel (sau isolation: worktree + merge de catre lead); teammates nu comit, nu scriu in PRD/ROADMAP, nu pornesc/opresc servere, nu rezolva ambiguitati singuri (escaladeaza la lead).
  • Raport teammate (prin SendMessage): test RED citat → implementare → test GREEN citat → fisiere atinse → abateri; apoi TaskUpdatecompleted.
  • Dupa fiecare val: lead-ul ruleaza regresia (python3 -m pytest -q) si bifeaza stories in PRD.
  • Livrabile mici pot rula fara TeamCreate (un singur worker sau lead direct) — dar PRD-ul, verificarea in context curat si writeback-ul raman obligatorii.

5.6 VERIFY (subagent cu context curat)

Lead-ul spawneaza un subagent dedicat care primeste DOAR PRD-ul + aceste instructiuni, NU transcriptul:

Esti verificator independent pentru livrabila {X.Y} (PRD: docs/prd/prd-{X.Y}-<slug>.md). Citeste PRD-ul; NU porni de la premisa ca implementarea e corecta.

  1. Suita: python3 -m pytest -q — verde (citeaza output-ul).
  2. Criteriile de acceptare ale fiecarui story din PRD.
  3. E2E pe canalul atins: UI web → ./start.sh test both --send, browser pe http://localhost:8000/ (Playwright MCP sau /browse), fluxul din PRD; canal API → POST /v1/prezentari pe RAR test.
  4. Regresia de aur: fluxul existent nu are voie sa se strice — POST /v1/prezentari (sau import → commit) → worker → FINALIZATA la RAR test, vizibil in dashboard (./start.sh test finalizate).
  5. Raport PASS/FAIL per criteriu cu dovezi. FAIL-urile NU le repari (/qa-only, nu /qa) — le documentezi.

Lead-ul scrie raportul in PRD ca ## Raport VERIFY. Toate PASS → CLOSE. Exista FAIL → inapoi la EXECUTE (stories de fix), apoi VERIFY din nou cu subagent NOU.

5.7 Bootstrap sesiune (detectie faza din starea PRD)

Starea persista in PRD (prima linie dupa titlu), actualizata de lead la fiecare tranzitie: **Stare**: draft → aprobat → in-executie → verify-pass → inchis. Asta face procesul reluabil din orice sesiune noua — starea e in fisiere, nu in conversatie.

Stare gasita Faza de pornire
nu exista docs/prd/prd-{X.Y}-*.md PLAN
PRD **Stare**: draft PLAN (reia stories/review-uri)
PRD **Stare**: aprobat / in-executie, stories nebifate EXECUTE
toate stories bifate, fara ## Raport VERIFY cu PASS VERIFY
## Raport VERIFY = PASS CLOSE
PRD **Stare**: inchis livrabila gata — alege urmatoarea din dashboard

La bootstrap: daca utilizatorul a numit {X.Y}, aceea e; altfel prima WIP din dashboard, apoi prima TODO in ordinea etapelor. Confirma alegerea cu utilizatorul — singura intrebare permisa la start.

5.8 CLOSE + porti umane

  1. /code-review pe diff-ul livrabilei. Probleme → fix acum (worker) sau story nou (inapoi in PRD).
  2. Writeback: in §3 dashboard — status DONE + data + link PRD; actualizeaza "Ultima actualizare". PRD: **Stare**: inchis.
  3. POARTA UMANA: propune commit-ul (mesaj conventional commits, fara emoji; vezi git rules) si ASTEAPTA confirmarea explicita — niciodata commit automat.

5.9 Anti-patterns (opreste-te daca observi)

Anti-pattern Corectia
Teammate "termina" fara output de test citat Raportul e invalid — cere dovezi prin SendMessage
Test scris DUPA implementare ca formalitate Nu e TDD — testul e contractul; refa bucla
Lead-ul scrie cod "ca e mai rapid" Pierde orchestrarea; spawn teammate chiar si pt un fix mic
Stories paralele care ating acelasi fisier Re-planifica valurile sau worktree + merge de catre lead
PRD modificat in executie fara re-review Schimbare de scope → inapoi la PLAN
Lead verifica singur, fara subagent VERIFY Partinire de confirmare — VERIFY cere context proaspat
Continua peste poarta umana Aprobarea PRD si confirmarea commit sunt ale utilizatorului — opreste-te

6. Skill-uri in proces

Faza Skill Rol
PLAN /prd genereaza PRD-ul (docs/prd/prd-X.Y-<slug>.md)
PLAN /plan-ceo-review, /plan-eng-review, /plan-design-review review de plan (primele 2 obligatorii; design doar UI)
EXECUTE /investigate bug neinteles raportat de worker — root cause, nu patch orb
VERIFY /browse, /qa-only browser headless / QA doar-raport (nu repara — pastreaza independenta)
CLOSE /code-review review pe diff-ul livrabilei
oricand /learn salveaza gotcha-uri in .claude/rules/ (nu in acest doc)

7. Intretinere

Acest document se actualizeaza la schimbari de proces (nu per livrabila) si la dashboard (la fiecare livrabila terminata — §3). Lectiile operationale (gotchas, pattern-uri descoperite in executie) merg in .claude/rules/ via /learn, nu aici.