docs(prd): PRD 3.4 interfata web ergonomica (tab-uri + wizard + microcopy)
Reorganizare dashboard pe trei principii, doar stratul de prezentare (Jinja2+HTMX, zero build), fara atingerea worker/mapare/idempotenta: - tab-uri sus (Acasa/Import/Coada/Mapari/Cont/Nomenclator), un panou activ, fragmente lazy, deep-link ?tab= randat server-side, a11y tablist/aria - import ca stepper 4 pasi (Incarca/Potriveste/Verifica/Confirma) - ghid de pornire auto-bifat + empty states (US-005) - microcopy uman intr-un singur loc (labels.py): 'Trimitere automata: activa' in loc de 'worker viu' Intrebari deschise rezolvate (6 tab-uri, ?tab=, pas 2 auto-bifat). Plan-reviews CEO/Eng/Design aplicate in PRD (a11y, empty states, guard HTMX/CSRF la granita US-003<->US-004, randare server-side). Stare: aprobat. Rand 3.4 TODO in ROADMAP. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -78,6 +78,7 @@ Reguli de contract (detalii in `docs/api-rar-contract.md`): `FINALIZATA` e termi
|
||||
| 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](prd/prd-3.2-filtrare-cont-get.md) |
|
||||
| 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](prd/prd-3.3-self-onboarding-web.md) |
|
||||
| 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](prd/prd-3.3-self-onboarding-web.md) |
|
||||
| 3.4 | Interfata web ergonomica (tab-uri + wizard + microcopy uman) | TODO | | Reorganizare dashboard: tab-uri sus (Acasa/Import/Mapari/Cont/Nomenclator), import ca stepper 4 pasi, ghid de pornire auto-bifat, etichete umane (`labels.py`) in loc de "worker viu". Doar stratul de prezentare (Jinja2+HTMX), fara backend de trimitere. PRD: [prd-3.4](prd/prd-3.4-ux-dashboard-web.md) |
|
||||
|
||||
### Etapa 4 — Viitor (Treapta 3)
|
||||
|
||||
|
||||
273
docs/prd/prd-3.4-ux-dashboard-web.md
Normal file
273
docs/prd/prd-3.4-ux-dashboard-web.md
Normal file
@@ -0,0 +1,273 @@
|
||||
# PRD 3.4 — Interfata web ergonomica (tab-uri + wizard + microcopy uman)
|
||||
|
||||
**Stare**: aprobat
|
||||
|
||||
> Proces complet: `docs/ROADMAP.md` §5. Contractul RAR (sursa de adevar): `docs/api-rar-contract.md`.
|
||||
> Starea trece: `draft → aprobat → in-executie → verify-pass → inchis` (actualizata de lead).
|
||||
> Aceasta e o livrabila de **UI/UX** — atinge interfata web (Jinja2 + HTMX, zero build), nu logica de
|
||||
> trimitere catre RAR. Nu modifica `worker/`, `mapping.py`, `idempotency.py`, masina de stari.
|
||||
|
||||
## 1. Obiectiv
|
||||
|
||||
Dashboard-ul curent (`app/web/templates/dashboard.html`) ingramadeste toate sectiunile intr-un
|
||||
singur scroll lung: import, status, mapari, cont, coada, nomenclator. Utilizatorul nou nu stie ce
|
||||
pas urmeaza, iar etichetele sunt scrise pentru dezvoltator ("Worker viu", "RAR ok"), nu pentru
|
||||
operatorul de service.
|
||||
|
||||
Livrabila reorganizeaza interfata pe **trei principii**, fara a schimba comportamentul backend:
|
||||
1. **Tab-uri sus** — un singur panou activ la un moment dat (Acasa, Import, Mapari, Cont, Nomenclator);
|
||||
restul incarcate lazy prin HTMX. Bara de status ramane mereu vizibila, indiferent de tab.
|
||||
2. **Flux tip wizard** — pasii sunt numerotati si auto-explicativi; utilizatorul nu ghiceste ce
|
||||
are de facut. Importul devine un stepper explicit (Incarca → Mapeaza → Verifica → Confirma), iar
|
||||
pagina "Acasa" arata un ghid de pornire care bifeaza singur ce e deja configurat.
|
||||
3. **Microcopy uman** — etichete scrise pentru oameni, nu pentru cod: "Trimitere automata catre RAR:
|
||||
activa" in loc de "Worker viu". Vezi tabelul din §3 (US-001).
|
||||
|
||||
Decizie de layout confirmata cu utilizatorul (AskUserQuestion): **tab-uri sus**, cu cerinta explicita
|
||||
de "pagini ca un wizard, intuitive" si "caption-uri utile, relevante, simple, pentru oameni".
|
||||
|
||||
## 2. Non-Goals (anti scope-creep)
|
||||
|
||||
- **Fara schimbari de backend de trimitere**: worker, mapare op→cod, idempotenta, reconciliere,
|
||||
masina de stari submissions raman neatinse. Doar stratul de prezentare web.
|
||||
- **Fara framework JS / build step**: ramane Jinja2 + HTMX + CSS in `base.html`. Fara React/Vue/Tailwind,
|
||||
fara bundler. Eventualul JS e vanilla inline, minim (deja exista pattern: clipboard in `_cont.html`).
|
||||
- **Fara endpoint-uri API noi `/v1/*`** si fara schimbari de schema SQL. Tab-urile folosesc fragmentele
|
||||
HTMX existente (`/_fragments/*`) plus, la nevoie, fragmente de prezentare noi sub `/_fragments/`.
|
||||
- **Fara rescriere a fluxului de import** (parsare, mapare coloane, preview, commit raman ca logica) —
|
||||
doar se imbraca intr-un stepper vizual.
|
||||
- **Fara redesign al paginilor `login.html` / `signup.html` / `admin.html`** dincolo de aplicarea
|
||||
acelorasi etichete/clase daca e trivial. Focusul e dashboard-ul autentificat.
|
||||
- **Fara i18n / multi-limba**: textele raman in romana, hardcodate (ca tot proiectul).
|
||||
- **Fara tema light / toggle de tema**: pastram paleta dark din `base.html`.
|
||||
|
||||
## 3. Stories atomice
|
||||
|
||||
> Fiecare story: cea mai mica unitate care lasa sistemul functional. Backend + UI pentru acelasi
|
||||
> comportament = 2 stories. Toate atingerile sunt in `app/web/` (templates + routes + un modul de
|
||||
> etichete). Verificare E2E = browser HTMX pe `http://localhost:8000/` (Playwright MCP sau `/browse`).
|
||||
> **Regula de aur**: fluxul import → commit → worker → FINALIZATA la RAR test NU are voie sa se strice.
|
||||
|
||||
### US-001: Microcopy uman pentru status si stari (modul de etichete + teste)
|
||||
**Ca** operator de service **vreau** etichete pe care le inteleg fara sa fiu programator
|
||||
**pentru ca** sa stiu dintr-o privire ce face sistemul si ce am eu de facut.
|
||||
|
||||
- **Depinde de**: —
|
||||
- **Fisiere**: `app/web/labels.py` (nou), `tests/test_web_labels.py` (nou) (~2 fisiere)
|
||||
- **Test intai (RED)**: `tests/test_web_labels.py` — `test_eticheta_worker_viu`, `test_eticheta_worker_mort`,
|
||||
`test_eticheta_stare_submission`, `test_toate_starile_au_eticheta` (nicio stare din `schema.sql` fara mapare).
|
||||
- **Continut**: un singur loc (`labels.py`) care traduce starile tehnice in text uman + clasa CSS de
|
||||
culoare. Tabelul de adevar (caption-uri propuse, de finalizat cu utilizatorul daca difera):
|
||||
|
||||
| Tehnic (azi) | Eticheta umana propusa | Sub-text / tooltip |
|
||||
|---|---|---|
|
||||
| Worker `viu` | **Trimitere automata: activa** | Sistemul verifica coada si trimite la RAR la fiecare cateva secunde. |
|
||||
| Worker `mort` | **Trimitere automata: oprita** | Nimic nu pleaca spre RAR pana reporneste. Anunta administratorul. |
|
||||
| RAR `ok` | **Legatura cu RAR: functionala** | Portalul AUTOPASS raspunde. |
|
||||
| RAR `indisponibil` | **Legatura cu RAR: indisponibila** | Portalul RAR nu raspunde acum; coada se reia automat cand revine. |
|
||||
| `Ultimul login RAR` | **Ultima autentificare la RAR** | — |
|
||||
| `In coada` / `queued` | **In asteptare sa fie trimise** | — |
|
||||
| `Trimise` / `sent` | **Declarate la RAR (finalizate)** | Confirmate cu numar de prezentare; nu se mai pot modifica. |
|
||||
| `Blocate` | **Necesita atentia ta** | Defalcare pe motiv (lipsa cod / date incomplete / eroare). |
|
||||
| `sending` | **Se trimite acum** | — |
|
||||
| `needs_mapping` | **Lipseste codul prestatiei** | Alege codul RAR in tab-ul Mapari. |
|
||||
| `needs_data` | **Date incomplete (respinse de RAR)** | Corecteaza randul si reimporta. |
|
||||
| `error` | **Eroare la trimitere** | Vezi detaliul randului; se reincearca automat sau necesita corectie. |
|
||||
|
||||
- **Acceptance criteria**:
|
||||
- [ ] `labels.py` expune o functie/dict care, pentru fiecare stare din `schema.sql`, da `(text, css_class)`.
|
||||
- [ ] Nicio stare de submission existenta nu ramane fara eticheta (test parametrizat care iese rosu daca se adauga o stare noua nemapata).
|
||||
- [ ] Functiile sunt pure (fara DB, fara request) — usor de testat unitar.
|
||||
- **Verificare E2E**: indirect, prin US-002/US-003 (etichetele apar in UI).
|
||||
|
||||
### US-002: Bara de status persistenta cu etichete umane (fragment)
|
||||
**Ca** operator **vreau** sa vad mereu, sus, starea sistemului in cuvinte clare
|
||||
**pentru ca** sa am incredere ca trimiterile chiar pleaca, fara sa stiu ce e un "worker".
|
||||
|
||||
- **Depinde de**: US-001
|
||||
- **Fisiere**: `app/web/templates/_status.html` (nou), `app/web/routes.py` (endpoint `/_fragments/status`),
|
||||
`tests/test_web_status_fragment.py` (nou) (~3 fisiere)
|
||||
- **Test intai (RED)**: `tests/test_web_status_fragment.py` — `test_status_fragment_text_uman`
|
||||
(contine "Trimitere automata", nu "worker viu"), `test_status_blocate_defalcare`,
|
||||
`test_status_se_reincarca_htmx` (are `hx-trigger` periodic).
|
||||
- **Continut**: extrage blocul de status din `dashboard.html` intr-un fragment dedicat care foloseste
|
||||
`labels.py`. Ramane sticky/vizibil sus indiferent de tab-ul activ. Defalca "Necesita atentia ta"
|
||||
pe motive. Pastreaza poll-ul HTMX (`every 15s`) deja existent pentru banner.
|
||||
- **Acceptance criteria**:
|
||||
- [ ] `/_fragments/status` randeaza bara cu etichetele din US-001 (scoped pe cont, ca restul UI).
|
||||
- [ ] Bara ramane vizibila sus cand se schimba tab-ul (nu e inghitita de panoul activ).
|
||||
- [ ] Cand exista submissions blocate, bara arata defalcarea pe motiv, nu doar un numar.
|
||||
- **Verificare E2E**: browser — incarca `/`, bara de status arata text uman; opreste workerul →
|
||||
"Trimitere automata: oprita".
|
||||
|
||||
### US-003: Navigare cu tab-uri (shell dashboard)
|
||||
**Ca** operator **vreau** sectiuni separate pe tab-uri, nu un scroll lung
|
||||
**pentru ca** sa gasesc rapid ce caut fara sa fiu coplesit.
|
||||
|
||||
- **Depinde de**: US-002
|
||||
- **Fisiere**: `app/web/templates/dashboard.html` (restructurare), `app/web/templates/_tabs.html` (nou,
|
||||
optional), `app/web/routes.py` (ruta `/` + suport deep-link tab), `tests/test_web_tabs.py` (nou) (~4 fisiere)
|
||||
- **Test intai (RED)**: `tests/test_web_tabs.py` — `test_dashboard_are_tabbar`,
|
||||
`test_tab_implicit_acasa`, `test_deeplink_tab_import` (`/?tab=import` randeaza panoul Import
|
||||
server-side la full load), `test_tab_activ_randat_server_side` (panoul activ e in HTML-ul initial,
|
||||
nu doar cerut prin HTMX dupa load), `test_fragmentele_inactive_lazy` (panourile inactive nu se cer
|
||||
la load), `test_tabbar_aria` (atribute `role=tablist`/`tab`/`tabpanel` + `aria-selected` prezente).
|
||||
- **Continut**: bara de tab-uri sub header: **Acasa · Import · Coada · Mapari · Cont · Nomenclator**
|
||||
(+ "Panou admin" / "Iesi" pastrate in coltul din dreapta sus). Panoul de submissions existent muta
|
||||
din scroll in tab-ul **Coada**. Un singur panou activ; tab-ul isi incarca fragmentul prin HTMX la
|
||||
activare (lazy), nu toate la load. **Randare server-side a panoului activ** la full load (din `?tab=`):
|
||||
fara palpaire la refresh si degradare gratioasa daca JS lipseste — utilizatorul vede macar panoul
|
||||
curent. Bara de status (US-002) sta deasupra tab-bar-ului, mereu vizibila. Tab activ marcat vizual.
|
||||
**Accesibilitate reala**: `role="tablist"` pe bara, `role="tab"` + `aria-selected` pe fiecare tab,
|
||||
`role="tabpanel"` pe panou, navigare cu sageti intre tab-uri (JS vanilla minim). Mobil: tab-bar se
|
||||
ruleaza orizontal / se sparge curat (fara meniu hamburger — pastram simplu).
|
||||
- **Acceptance criteria**:
|
||||
- [ ] Tab-bar cu cele 6 tab-uri (Acasa · Import · Coada · Mapari · Cont · Nomenclator); "Acasa" implicit la prima incarcare.
|
||||
- [ ] Un singur panou randat la un moment dat; celelalte fragmente NU se cer pana la activarea tab-ului.
|
||||
- [ ] Panoul activ (inclusiv din `?tab=`) e randat **server-side** la full load — fara palpaire la refresh, vizibil si fara JS.
|
||||
- [ ] Accesibilitate: `role=tablist/tab/tabpanel`, `aria-selected` pe tab-ul activ, navigare cu sageti (nu doar focus vizibil).
|
||||
- [ ] Refresh pe un tab non-implicit revine pe acelasi tab (deep-link prin query string `?tab=`).
|
||||
- [ ] Toate functiile existente raman accesibile dintr-un tab (nimic pierdut fata de pagina veche).
|
||||
- **Verificare E2E**: browser — click pe fiecare tab incarca panoul corect; refresh pe `?tab=import`
|
||||
ramane pe Import; navigare cu sageti intre tab-uri functioneaza (citior de ecran anunta tab-ul activ).
|
||||
|
||||
### US-004: Importul ca wizard cu pasi numerotati (stepper)
|
||||
**Ca** operator care incarca un fisier **vreau** sa vad clar in ce pas sunt si ce urmeaza
|
||||
**pentru ca** sa nu ma blochez intrebandu-ma "si acum ce fac?".
|
||||
|
||||
- **Depinde de**: US-003
|
||||
- **Fisiere**: `app/web/templates/_stepper.html` (nou, include partajat),
|
||||
`app/web/templates/_upload.html`, `_mapcoloane.html`, `_preview_import.html` (adauga antet stepper),
|
||||
`tests/test_web_import_stepper.py` (nou) (~5 fisiere)
|
||||
- **Test intai (RED)**: `tests/test_web_import_stepper.py` — `test_stepper_pas1_la_upload`,
|
||||
`test_stepper_pas2_la_mapare`, `test_stepper_pas3_la_preview`, `test_stepper_marcheaza_pasii_facuti`,
|
||||
`test_import_hx_target_in_tab` (fragmentele de import au `hx-target` care se rezolva in panoul de tab,
|
||||
nu pe vechiul container de pagina), `test_import_forms_pastreaza_csrf` (formularele mutate isi pastreaza
|
||||
`csrf_token` valid).
|
||||
- **Continut**: un antet de stepper reutilizabil cu 4 pasi vizibili in toate fragmentele de import:
|
||||
**1. Incarca fisier → 2. Potriveste coloanele → 3. Verifica → 4. Confirma trimiterea**. Pasul curent
|
||||
evidentiat, pasii facuti bifati, pasii viitori estompati. Fiecare ecran are un titlu-actiune si o
|
||||
fraza de ajutor ("Trage un fisier xlsx/csv aici" / "Spune-ne ce coloana e ce" / "Verifica inainte sa
|
||||
trimiti"). Stepper-ul e PUR vizual — nu schimba endpoint-urile sau ordinea logica existenta.
|
||||
**Granita cu US-003 (risc tehnic principal)**: cand fragmentele de import se randeaza in tab-ul Import,
|
||||
`hx-target`/`hx-swap` din upload→mapare→preview trebuie sa tinteasca un container din interiorul
|
||||
panoului de tab (nu vechiul container de la radacina paginii), iar `csrf_token` din formularele de
|
||||
import trebuie sa ramana corect. Verificat prin testele de mai sus + regula de aur.
|
||||
- **Acceptance criteria**:
|
||||
- [ ] Acelasi stepper apare in upload, mapare-coloane si preview, cu pasul corect evidentiat.
|
||||
- [ ] Pasii deja parcursi sunt marcati ca facuti; cei viitori sunt estompati.
|
||||
- [ ] Fiecare pas are un titlu-actiune + o fraza scurta de ajutor (microcopy din US-001 unde se aplica).
|
||||
- [ ] `hx-target` din fragmentele de import se rezolva in panoul de tab; `csrf_token` pastrat in formulare.
|
||||
- [ ] Fluxul de import functioneaza identic (upload → mapare → preview → confirma) — fara regresie.
|
||||
- **Verificare E2E**: browser — urca `test_data.csv`, parcurge cei 4 pasi; stepper-ul avanseaza corect;
|
||||
commit → randuri in coada → worker → FINALIZATA la RAR test (regula de aur).
|
||||
|
||||
### US-005: Pagina "Acasa" cu ghid de pornire (checklist auto-bifat)
|
||||
**Ca** utilizator nou **vreau** sa mi se spuna exact ce am de configurat ca sa pot trimite
|
||||
**pentru ca** sa ajung la prima declaratie reusita fara sa ghicesc pasii.
|
||||
|
||||
- **Depinde de**: US-003
|
||||
- **Fisiere**: `app/web/templates/_acasa.html` (nou), `app/web/routes.py` (context: are_creds, are_cheie_folosita,
|
||||
are_trimiteri), `tests/test_web_onboarding.py` (nou) (~3 fisiere)
|
||||
- **Test intai (RED)**: `tests/test_web_onboarding.py` — `test_checklist_pas_creds_neconfigurat`,
|
||||
`test_checklist_pas_creds_bifat_cand_exista`, `test_checklist_ascuns_cand_totul_gata`,
|
||||
`test_linkuri_ghid_duc_la_taburi`, `test_empty_state_coada_gol` (tab Coada fara submissions arata
|
||||
indemn catre Import, nu un tabel gol), `test_empty_state_mapari_gol`.
|
||||
- **Continut**: tab-ul "Acasa" (implicit) arata un card "Primii pasi" cu o lista bifabila:
|
||||
1. **Conecteaza-ti contul RAR** (email + parola portal AUTOPASS) — link la tab Cont.
|
||||
2. **(Optional) Ia-ti cheia API** daca trimiti din soft propriu — link la tab Cont.
|
||||
3. **Importa primul fisier** — link la tab Import.
|
||||
Fiecare pas se bifeaza automat cand e indeplinit (creds configurate → pas 1 bifat; exista cel putin
|
||||
o trimitere → pas 3 bifat). Cand toti pasii esentiali sunt gata, ghidul se colapseaza intr-o linie
|
||||
discreta ("Totul e configurat — vezi coada"), ca sa nu deranjeze utilizatorul experimentat. Sub ghid,
|
||||
pe acelasi tab, un rezumat scurt + scurtaturi (coada recenta / actiuni rapide).
|
||||
- **Acceptance criteria**:
|
||||
- [ ] Pasul "Conecteaza contul RAR" e nebifat fara creds, bifat cand `are_creds` e adevarat.
|
||||
- [ ] Pasul "Importa primul fisier" se bifeaza cand contul are cel putin un submission.
|
||||
- [ ] Cand toti pasii esentiali sunt gata, ghidul e colapsat/discret (nu ocupa tot ecranul).
|
||||
- [ ] Link-urile din ghid duc la tab-ul corect (Cont / Import).
|
||||
- [ ] **Empty states prietenoase**: tab Coada gol → "Nicio trimitere inca — incepe cu Import" (link la
|
||||
tab Import); tab Mapari gol → mesaj scurt + indemn, nu un tabel/lista goala fara context.
|
||||
- **Verificare E2E**: browser — cont nou (fara creds): ghid vizibil cu pasi nebifati + tab Coada arata
|
||||
empty state cu indemn la Import; dupa setarea credentialelor si un import, pasii se bifeaza si ghidul se restrange.
|
||||
|
||||
## 4. Riscuri
|
||||
|
||||
- **Regresie pe fluxul de import** (cel mai mare risc): stepper-ul (US-004) atinge cele 3 fragmente
|
||||
de import. Mitigare: stepper PUR vizual, endpoint-urile si ordinea logica raman; regula de aur in
|
||||
fiecare VERIFY (import → FINALIZATA la RAR test).
|
||||
- **Lazy-load gresit**: daca tab-urile cer toate fragmentele la load, dispare castigul de aglomerare
|
||||
si creste load-ul. Mitigare: test explicit `test_fragmentele_inactive_lazy` (US-003).
|
||||
- **Scope pe cont pierdut la mutarea in fragmente noi**: fragmentele existente sunt scoped pe sesiune
|
||||
(regula NULL→cont 1, anti-leak C6 din 3.3a). Orice fragment nou (status, acasa) trebuie sa pastreze
|
||||
acelasi scope. Mitigare: testele de fragment verifica izolarea pe cont; VERIFY reia sweep-ul anti-leak.
|
||||
- **CSRF / form-uri**: tab Cont muta form-urile de rotire cheie / creds RAR — trebuie pastrate
|
||||
`csrf_token` si `hx-target` corecte. Mitigare: reutilizam `_cont.html` ca atare in tab.
|
||||
- **Microcopy "definitiv"**: etichetele din §3 sunt propuneri; daca utilizatorul vrea alt ton, se
|
||||
ajusteaza in `labels.py` (un singur loc). Risc mic.
|
||||
|
||||
## 5. Intrebari deschise — REZOLVATE
|
||||
|
||||
> Rezolvate cu utilizatorul inainte de executie (poarta de aprobare PRD). Deciziile de mai jos sunt
|
||||
> obligatorii pentru EXECUTE.
|
||||
|
||||
1. **Tab-uri** — DECIS: **6 tab-uri**: **Acasa · Import · Coada · Mapari · Cont · Nomenclator**.
|
||||
Fata de propunerea initiala (5), "Coada submissions" devine tab propriu (e ecranul operational
|
||||
principal, nu se ascunde sub Acasa). Nomenclatorul ramane tab separat (referinta consultata rar,
|
||||
dar cautata explicit). Comasarea Nomenclator-sub-Mapari respinsa: sunt actiuni diferite (editezi
|
||||
mapari vs. doar consulti coduri).
|
||||
2. **Tab implicit** — DECIS: **Acasa** pentru toti, dar ghidul de pornire (US-005) se **restrange
|
||||
automat** cand contul e configurat (creds RAR setate + cel putin o trimitere), lasand un rezumat
|
||||
scurt + scurtatura la Coada. Utilizatorul experimentat vede de fapt un mini-rezumat, nu un wizard.
|
||||
3. **Etichete (§3 US-001)** — DECIS: se **adopta tabelul din US-001** ca atare. Ton: descriptiv-functional
|
||||
("Trimitere automata: activa"), nu colocvial ("Coada se trimite singura"). Toate textele intr-un
|
||||
singur loc (`labels.py`) — ajustabile ulterior fara atingerea template-urilor.
|
||||
4. **Persistenta tab activ** — DECIS: **query string** (`/?tab=import`). Supravietuieste refresh-ului,
|
||||
e testabil server-side (criteriul din US-003), si permite link-uri directe din ghid (US-005). Hash-ul
|
||||
respins: nu ajunge la server, deci netestabil in `test_deeplink_tab_import`.
|
||||
5. **Stepper import** — DECIS: **4 pasi ficsi** (Incarca · Potriveste coloanele · Verifica · Confirma).
|
||||
Cand semnatura de coloane e deja memorata, **pasul 2 apare bifat automat** si fluxul sare vizual la
|
||||
pasul 3, dar pasul 2 ramane afisat in stepper (estompat/bifat) pentru orientare — utilizatorul vede
|
||||
ca maparea a fost recunoscuta, nu ca a disparut un pas.
|
||||
|
||||
> Impact asupra stories: US-003 listeaza acum **6 tab-uri** (adaugat "Coada" ca tab propriu — panoul de
|
||||
> submissions existent muta din scroll in tab-ul Coada). Restul stories raman neschimbate.
|
||||
|
||||
## 6. Valuri de executie (graful de dependente)
|
||||
|
||||
```
|
||||
Val 1: [US-001] ← modul pur de etichete, fisiere distincte → poate porni singur
|
||||
Val 2: [US-002] ← bara de status, foloseste US-001
|
||||
Val 3: [US-003] ← shell-ul de tab-uri, are nevoie de bara de status (US-002)
|
||||
Val 4: [US-004] [US-005] ← ambele depind de shell-ul de tab-uri (US-003); fisiere distincte
|
||||
(US-004 = fragmentele de import; US-005 = _acasa.html) → paralel
|
||||
```
|
||||
|
||||
> US-004 si US-005 ating fisiere disjuncte (import vs acasa) — pot rula in paralel (max 2 teammates).
|
||||
> Atentie: US-003 si US-004 ating amandoua zona de import in `dashboard.html`/include-uri — NU paralel
|
||||
> cu US-003; de aceea US-004 e in valul urmator.
|
||||
|
||||
## 7. Plan-reviews aplicate (CEO / Eng / Design)
|
||||
|
||||
> Aplicate IN PRD inainte de cod (ROADMAP §5.3). Constatari pliate cu acordul utilizatorului.
|
||||
|
||||
- **CEO (valoare/scope)**: premisa validata — frecarea de activare pe Treapta 2 (service-uri non-ROAAUTO)
|
||||
e wedge-ul real; US-005 (ghid de pornire) are cel mai mare ROI. Scope sanatos (5 stories, doar strat
|
||||
de prezentare), fara expansiune. Nota de secventiere: daca timpul scade, US-001/002 + US-005 (microcopy
|
||||
+ activare) au prioritate peste estetica de tab-uri (US-003).
|
||||
- **Eng (fezabilitate/teste)**: cel mai mare risc tehnic = granita US-003↔US-004 (hx-target/CSRF din
|
||||
fragmentele de import mutate in tab) → AC + teste dedicate adaugate in US-004. Adaugat: randare
|
||||
server-side a panoului activ (degradare gratioasa fara JS) in US-003. Constrangere de testare:
|
||||
TestClient nu executa JS — testele unitare verifica atribute + stare initiala randata server-side;
|
||||
interactivitatea (swap, navigare cu sageti) cade pe E2E Playwright.
|
||||
- **Design (UI/UX)**: accesibilitate reala a tab-urilor (`role=tablist/tab/tabpanel` + `aria-selected`
|
||||
+ navigare cu sageti) in loc de "focus vizibil" — pliat in US-003. Empty states prietenoase (Coada/Mapari
|
||||
goale) — pliat in US-005. Tabelul de microcopy validat.
|
||||
|
||||
---
|
||||
|
||||
## Raport VERIFY
|
||||
|
||||
> Completat de subagentul verificator (context curat) in faza VERIFY — vezi ROADMAP §5.6.
|
||||
> PASS/FAIL per criteriu, cu dovezi (output pytest citat, E2E browser pe `http://localhost:8000/`,
|
||||
> plus regula de aur: import → worker → FINALIZATA la RAR test). Lipseste pana la VERIFY.
|
||||
Reference in New Issue
Block a user