US-007: rute web proprii /cont/roteste-cheie + /cont/rar-creds scoped pe sesiune (C13), sectiune "Contul meu" cu cheie afisata o data. US-010: rol admin (users.is_admin) + require_admin->403 + CLI set-admin + bootstrap primul cont=admin (count_admins in BEGIN IMMEDIATE, anti-race). US-011: panou /admin (activare/dezactivare conturi, CSRF + PRG), link admin + logout pe dashboard. US-012: app/email.py notify_signup best-effort degradat fara SMTP + config smtp_*. Fix: migrare defensiva users.is_admin/email_verified in _migrate. VERIFY x2 context curat (PASS) + /code-review high. 393 teste pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
18 KiB
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-18 — 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_admin→AdminRequired→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.pyparole scrypt cu eticheta de parametri onorata la verify;SessionMiddlewaresame_site=strict +app/web/session.pyguardrequire_login→LoginRequired; CSRF per-sesiune enforce in prod inclusiv pe login/signup + rate-limit signup & login in-proces; signupactive=0tranzactie atomica + cheie-o-data + logSIGNUP; login/logout; dashboard & import multi-tenant scoped pe sesiune cu regula NULL→cont 1 — toate rutele web care ating date sensibile subrequire_login+ scope; gate workerclaim_oneLEFT 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-reviewhigh 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 |
Etapa 4 — Viitor (Treapta 3)
| # | Livrabila | Status | Data | Detalii |
|---|---|---|---|---|
| 4.1 | Mapare AI / conector MCP (sugestie peste fuzzy) | TODO | ||
| 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
- 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.
- 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.
- Story atomic = unitate de paralelizare SI de rollback: un story = un commit logic = un worker = un test-suite verde.
- 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).
- Single writer: doar sesiunea lead scrie in PRD, ROADMAP si git. Workerii scriu doar cod si teste.
- 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 decomplete (decid ce se paralelizeaza). (d) backend + UI pentru acelasi comportament = 2 stories.
5.5 Executie — agent team (lead orchestreaza, NU scrie cod)
TeamCreatecreeaza echipa + lista de task-uri partajata;Agentcuteam_name+name+model: sonnetspawneaza teammates adresabili. Lead-ul ii coordoneaza prinSendMessage(clarificari/re-directionare la cald, fara re-spawn) siTaskUpdate(atribuire/inchidere task).- Valuri (waves): lead-ul grupeaza stories pe graful de dependente. Val 1 = stories fara
Depinde desi 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; apoiTaskUpdate→completed. - 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.
- Suita:
python3 -m pytest -q— verde (citeaza output-ul).- Criteriile de acceptare ale fiecarui story din PRD.
- E2E pe canalul atins: UI web →
./start.sh test both --send, browser pehttp://localhost:8000/(Playwright MCP sau/browse), fluxul din PRD; canal API →POST /v1/prezentaripe RAR test.- Regresia de aur: fluxul existent nu are voie sa se strice —
POST /v1/prezentari(sau import → commit) → worker →FINALIZATAla RAR test, vizibil in dashboard (./start.sh test finalizate).- 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
/code-reviewpe diff-ul livrabilei. Probleme → fix acum (worker) sau story nou (inapoi in PRD).- Writeback: in §3 dashboard — status
DONE+ data + link PRD; actualizeaza "Ultima actualizare". PRD:**Stare**: inchis. - 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.