docs(prd): 5.15 revizuit prin /plan-ceo-review (SELECTIVE EXPANSION)
Review CEO + spec-review independent (scor 7/10). Scope 8 -> 10 stories / 6 valuri. Decizii incorporate (D6-D10): - D6 strip sanatate mereu-vizibil deasupra contoarelor (zero-silent-failures) - D7 operatia ramane in op_service + copiata in obs (nu se muta) - D8 obs EXCLUS din idempotenta (idempotency.py:98) - AC US-005 corectat - D9 secventiere 5.15 inainte de 5.14 - D10 4 extinderi acceptate: US-009 salvare mapare din chip, US-010 bulk-fix, require dinamic odometruInitial + keyboard-first (US-007) Remedieri din spec-review independent: - #1 contradictie prestatii: itemii pastreaza op_service/denumire, idPrezentare in payload.py (rupea D7/US-009 in forma initiala) - #2 sent_today/month: status='sent' AND date(updated_at), fara migrare - #3 US-006 numeste liniile de rewrite din handler-e (nu "fara schimbare logica") - #5/#6 nota suprafata JS + click target "De corectat" TODOS += premisa mobil nevalidata, dedup teme grafit~dark, optiune PRD separat US-009/010. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
15
TODOS.md
15
TODOS.md
@@ -38,3 +38,18 @@ Elemente deferate din review-uri. Negrupte de un PRD curent; de promovat cand de
|
||||
- [ ] **Validare premisa "utilizare mobil reala"** — inainte de orice extindere responsive viitoare,
|
||||
confirma device-mix-ul (analytics/cerere user). Daca ~95% desktop, nu mai investi in cardificare
|
||||
mobil. (CEO F1, high — premisa nedovedita acum.)
|
||||
|
||||
## Din /plan-ceo-review PRD 5.15 (2026-06-28)
|
||||
|
||||
- [ ] **Validare premisa "utilizare mobil reala" (reluare F1 din 5.13)** — partea slim/compact a lui
|
||||
5.15 presupune utilizare reala pe mobil. Inainte de orice rafinare responsive viitoare, confirma
|
||||
device-mix-ul (analytics / cerere user). Daca ~95% desktop, nu mai investi in cardificare mobil.
|
||||
(CEO, high — premisa nedovedita.)
|
||||
|
||||
- [ ] **Deduparea/etichetarea temelor grafit~dark si hartie~light** — 5.15 adauga 4 teme peste cele 3
|
||||
existente (7 + Auto). grafit e ~ identic cu dark, hartie ~ identic cu light. Daca selectorul devine
|
||||
confuz sau matricea de test apasa, dedupica sau eticheteaza-le clar. (CEO, low — simplificare optionala.)
|
||||
|
||||
- [ ] **US-009/US-010 ca PRD separat daca propagarea design e urgenta** — salvarea mapare-din-chip si
|
||||
bulk-fix sunt adiacente FUNCTIONALE (acceptate via SELECTIVE EXPANSION), dincolo de obiectivul pur de
|
||||
propagare design. Daca vrei sa livrezi designul rapid, pot fi scoase intr-un PRD propriu. (CEO, low.)
|
||||
|
||||
@@ -32,6 +32,23 @@ Decizii de produs confirmate cu userul (poarta de aprobare a acestui PRD):
|
||||
coloana Observatii, **concatenam denumirea operatiei de service in `obs`**. `obs` ramane in
|
||||
`payload_json` (camp din contractul RAR), fara coloana noua.
|
||||
|
||||
Decizii din /plan-ceo-review (2026-06-28, mod SELECTIVE EXPANSION):
|
||||
- **D6** (sanatate mereu-vizibila): cardurile-contor inlocuiesc bara de status, DAR sanatatea
|
||||
(worker viu? RAR accesibil? ultima autentificare) ramane intr-un **strip mereu-vizibil, colorat,
|
||||
deasupra contoarelor** (verde "declaratiile curg" / rosu "blocat: worker oprit / RAR inaccesibil").
|
||||
Invariant: zero-silent-failures — semnalul critic NU se ingroapa sub volum. (Rafineaza D1.)
|
||||
- **D7** (operatie -> obs, fara regresie de mapare): la import, denumirea operatiei RAMANE in
|
||||
`op_service` (sursa pentru maparea op->cod) SI se COPIAZA in `obs`. `obs` e sink aditional, nu
|
||||
mutare; fluxul needs_mapping ramane neatins. (Rafineaza D5.)
|
||||
- **D8** (idempotenta obs): `obs` e EXCLUS din cheia de idempotenta (`idempotency.py:98`). Deci
|
||||
editarea `obs` NU schimba cheia si NU poate crea duplicate — corecteaza AC-ul gresit din US-005.
|
||||
`prestatii` ESTE in cheie (sortat dupa cod) — multi-select re-cheieaza randul (US-006).
|
||||
- **D9** (secventiere): 5.15 INAINTE de 5.14 (mapare LLM). Editorul manual defineste forma listei
|
||||
`prestatii` si UX-ul de confirmare; 5.14 umple codurile peste aceeasi forma.
|
||||
- **D10** (extinderi acceptate, SELECTIVE EXPANSION): toate 4 intra in scope — (a) salvare mapare
|
||||
din chip (US-009), (b) bulk-fix din lista (US-010), (c) require dinamic odometruInitial la chip
|
||||
R-ODO/I-ODO (US-007), (d) editare keyboard-first in form slim (US-007).
|
||||
|
||||
Fapte verificate care fundamenteaza scope-ul (nu presupuneri):
|
||||
- `vin` la RAR e **un singur camp** (17 car., MAJUSCULE, fara O/I/Q) — cerinta "fara 2 campuri
|
||||
VIN" e deja respectata azi (`_form_editare.html` are un singur `vin`); ramane sa NU regresam.
|
||||
@@ -112,16 +129,25 @@ chips **pentru ca** dashboard-ul si formularul sa le consume DRY, identic cu moc
|
||||
- **Fisiere**: `app/web/templates/_status.html`, `app/web/templates/_acasa.html`,
|
||||
`app/web/routes.py` (`_status_counts` extins cu `sent_today`/`sent_month`), `tests/test_web_status.py`,
|
||||
`tests/test_web_dashboard.py` (~5 fisiere)
|
||||
- **Test intai (RED)**: `tests/test_web_status.py` — `test_trei_contoare_card`, `test_trimise_all_time_luna_azi`, `test_sanatate_compacta_worker_rar`, `test_fara_bara_veche`
|
||||
- **Test intai (RED)**: `tests/test_web_status.py` — `test_strip_sanatate_mereu_vizibil`, `test_strip_rosu_worker_oprit`, `test_trei_contoare_card`, `test_trimise_all_time_luna_azi`, `test_fara_bara_veche`
|
||||
- **Acceptance criteria**:
|
||||
- [ ] Antetul Acasa = card "Trimiteri RAR AUTOPASS" cu 3 contoare slim: **In coada** (queued, accent),
|
||||
- [ ] **Strip de sanatate mereu-vizibil, DEASUPRA contoarelor** (D6): o linie compacta colorata —
|
||||
verde "declaratiile curg" cand worker viu + RAR ok; **rosu** + text explicit cand worker
|
||||
oprit SAU RAR inaccesibil ("Blocat: worker oprit" / "Blocat: RAR inaccesibil"), cu ultima
|
||||
autentificare RAR. Glife accesibile ✓/✗ (nu doar culoare). Invariant zero-silent-failures:
|
||||
semnalul "declaratiile NU pleaca" e imposibil de ratat, NU ingropat sub volum.
|
||||
- [ ] Sub strip: card "Trimiteri RAR AUTOPASS" cu 3 contoare slim: **In coada** (queued, accent),
|
||||
**Trimise** (sent, verde), **De corectat** (blocate = needs_data + needs_mapping + error, rosu).
|
||||
- [ ] Cardul **Trimise** afiseaza trei valori temporale (D4): all-time (cifra principala) + "luna asta"
|
||||
+ "azi" (sub-linie secundara). `_status_counts` extins cu `sent_today`/`sent_month` (filtru pe
|
||||
`updated_at`/data trimitere; scoped pe cont), restul contoarelor din numaratoarea existenta.
|
||||
- [ ] Indicatorii de sanatate worker/RAR + ultima autentificare RAR raman, intr-o forma compacta
|
||||
(pill/glif), nu bara cu 2 randuri ca azi; pastreaza glifele accesibile ✓/✗ (nu doar culoare).
|
||||
- [ ] Navigarea existenta (Trimiteri/Mapari + badge needs_mapping) se pastreaza.
|
||||
+ "azi" (sub-linie secundara). `_status_counts` extins cu `sent_today`/`sent_month`.
|
||||
**Sursa de timp**: NU exista coloana `sent_at`; folosim `status='sent' AND date(updated_at)=...`.
|
||||
Justificare (verificat): un rand `sent` nu mai primeste scrieri ulterioare pana la purge-delete
|
||||
la +90z (`purge_after` se seteaza in ACEEASI scriere care marcheaza `sent`), deci `updated_at`
|
||||
== momentul trimiterii pentru randurile `sent` -> fara migrare de coloana (respecta Non-Goal).
|
||||
Daca pe viitor apar scrieri post-`sent`, reevalueaza o coloana `sent_at` dedicata.
|
||||
- [ ] Navigarea existenta (Trimiteri/Mapari + badge needs_mapping) se pastreaza. Click pe contorul
|
||||
**De corectat** deep-link-eaza in lista filtrata pe blocate (`?status=` existent din 5.x),
|
||||
nu intr-o pagina noua.
|
||||
- [ ] Scoped pe cont; poll-ul existent (`/_fragments/status`) randeaza noul antet fara a pierde tab-ul.
|
||||
- [ ] Responsive: cele 3 contoare pe un rand pe desktop, stivuite/2-pe-rand pe mobil, fara overflow.
|
||||
- **Verificare E2E**: browser pe `/` — contoare corecte vs date din DB, sanatate worker mort/viu,
|
||||
@@ -161,11 +187,13 @@ sa corectez/completez ce s-a facut, separat de codurile RAR.
|
||||
- [ ] `obs` traieste in `payload_json` (camp `obs` din contractul RAR); fara coloana noua / migrare (D5).
|
||||
- [ ] `obs` adaugat in `EDIT_FIELDS`; `corecteaza` si `editeaza` (preview) accepta si persista `obs`.
|
||||
- [ ] `obs` optional (text liber, fara validare de continut, doar trim); apare in `payload_view`.
|
||||
- [ ] `obs` se include in payload-ul trimis la RAR (camp `obs`) — fara a schimba celelalte campuri;
|
||||
idempotenta se recalculeaza ca la orice editare (mecanism existent).
|
||||
- [ ] **La import**, daca fisierul NU are coloana Observatii, denumirea operatiei de service se
|
||||
CONCATENEAZA in `obs` (D5: `obs` = operatiile efectuate); daca are coloana Observatii, se
|
||||
pastreaza textul ei. Format de concatenare definit (ex. denumiri separate prin "; ").
|
||||
- [ ] `obs` se include in payload-ul trimis la RAR (camp `obs`). **`obs` e EXCLUS din cheia de
|
||||
idempotenta** (`idempotency.py:98`) — deci editarea DOAR a `obs` NU schimba cheia si NU poate
|
||||
crea duplicat (D8). NU recalcula/forta cheia pe baza `obs`. (Corecteaza formularea anterioara.)
|
||||
- [ ] **La import** (D7): denumirea operatiei RAMANE in `op_service` (sursa pentru maparea op->cod);
|
||||
daca fisierul NU are coloana Observatii, denumirea operatiei se **COPIAZA** (nu se muta) si in
|
||||
`obs`; daca are coloana Observatii, se pastreaza textul ei. Format de concatenare definit
|
||||
(denumiri separate prin "; "). Fluxul needs_mapping ramane neatins.
|
||||
- **Verificare E2E**: `POST /trimitere/{id}/corecteaza` cu `obs` -> persistat -> vizibil in detaliu;
|
||||
optional proba live RAR ca `obs` apare in FINALIZATA.
|
||||
|
||||
@@ -174,17 +202,29 @@ sa corectez/completez ce s-a facut, separat de codurile RAR.
|
||||
comanda poate avea mai multe prestatii, asa cum accepta RAR.
|
||||
|
||||
- **Depinde de**: —
|
||||
- **Fisiere**: `app/web/routes.py` (`/corecteaza`, `/repune`),
|
||||
`app/api/v1/import_router.py` (`/editeaza`), `app/mapping.py` (folosit cu lista — fara schimbare
|
||||
de logica), `app/validation.py` (fiecare cod in nomenclator), `tests/test_web_corectie*.py`,
|
||||
`tests/test_mapping*.py` (~6 fisiere)
|
||||
- **Fisiere**: `app/web/routes.py` (`/corecteaza`, `/repune` — **rescrie logica single-`prestatii[0]`**
|
||||
de azi: `cod_prestatie_curent` la `routes.py:977-982` + injectia la `1146-1164`/`1288-1324`
|
||||
presupun UN cod; multi-select cere pre-fill din lista intreaga + scriere pe toti itemii),
|
||||
`app/api/v1/import_router.py` (`/editeaza`, idem), `app/mapping.py` (NEATINS — deja accepta lista),
|
||||
`app/validation.py` (fiecare cod in nomenclator), `tests/test_web_corectie*.py`,
|
||||
`tests/test_mapping*.py` (~6 fisiere). Nota: `mapping.py` e neatins, dar call-site-urile din
|
||||
handler-e cer un rewrite real (nu "fara schimbare de logica").
|
||||
- **Test intai (RED)**: `tests/test_web_corectie_prestatii.py` — `test_mai_multe_coduri_acceptate`, `test_cod_invalid_respins`, `test_lista_goala_needs_mapping`, `test_idempotency_recalculat`, `test_odometru_initial_conditionat_R_ODO`
|
||||
- **Acceptance criteria**:
|
||||
- [ ] Handler-ele de editare accepta o LISTA de `cod_prestatie` (mai multe valori), inlocuind
|
||||
selectul unic; reconstruiesc `prestatii` ca `[{cod_prestatie, idPrezentare:null}, ...]`.
|
||||
- [ ] Handler-ele de editare accepta o LISTA de `cod_prestatie`, inlocuind selectul unic. **NU
|
||||
reconstrui lista cu itemi goi**: handler-ele de azi injecteaza codul DOAR in `prestatii[0]`
|
||||
(`routes.py:1146-1164`, `1288-1324`) — multi-select le rescrie ca: pastreaza itemii existenti
|
||||
cu `cod_op_service`/`denumire` (invariant D7) si seteaza/adauga `cod_prestatie` pe ei.
|
||||
`idPrezentare:null` se adauga in `payload.py` la construirea payload-ului, NU in itemul intern.
|
||||
- [ ] **Pereche operatie<->cod definita**: cand exista operatii (`cod_op_service`), fiecare cod-chip
|
||||
se ataseaza unei operatii (1 operatie -> 1 cod, ca azi, dar acum N operatii -> N coduri);
|
||||
cand NU exista operatie (cod direct, ex. corectie pura), chip-urile sunt coduri libere intr-o
|
||||
lista fara `op_service`. Aceasta pereche e ce consuma US-009 (salvare mapare op->cod).
|
||||
- [ ] Fiecare cod e validat fata de nomenclator (`valid_codes`); cod necunoscut -> respins cu
|
||||
mesaj (NU se trimite raw — invariant ORA-12899 din CLAUDE.md/contract).
|
||||
- [ ] Lista goala de coduri -> ramane `needs_mapping` (nu se trimite fara cod).
|
||||
- [ ] **Coduri duplicate** (acelasi cod adaugat de 2x) -> deduplicate inainte de persistare
|
||||
(cheia sorteaza deja dupa identitate, dar lista persistata nu trebuie sa contina duplicate).
|
||||
- [ ] Recalcul idempotenta dupa editare (mecanism existent), cu prinderea coliziunii ca azi.
|
||||
- [ ] Se pastreaza regula `odometruInitial` obligatoriu cand lista contine `R-ODO`/`I-ODO`
|
||||
(contract §payload) — validare existenta, doar verificata pe lista.
|
||||
@@ -208,9 +248,20 @@ e compact si imi arata clar codurile RAR si observatiile, ca in mockup.
|
||||
nomenclator) adauga un cod nou; lista se trimite ca `cod_prestatie` multiplu (US-006).
|
||||
- [ ] Acelasi `_form_editare.html` slujeste ambele modale (detaliu `/corecteaza` si preview
|
||||
`/editeaza`), fara duplicare; degradare fara JS rezonabila (chips ca lista, picker = select).
|
||||
- [ ] Stilizare fidela mockup-ului pe cele 4 teme; tinte 44px pe mobil; a11y (label-uri, aria).
|
||||
- [ ] **Require dinamic odometruInitial** (D10c): cand lista de chips contine `R-ODO` sau `I-ODO`,
|
||||
formularul DEZVALUIE si cere `odometru_initial` (contract §payload), previne 400 RAR si un
|
||||
drum `needs_data`. Cand niciun chip R-ODO/I-ODO -> campul ramane optional/ascuns.
|
||||
- [ ] **Editare keyboard-first** (D10d): in picker, Enter adauga chip-ul selectat; sageti
|
||||
navigheaza optiunile; Esc inchide modalul; focus-ul revine logic dupa adaugare/stergere.
|
||||
- [ ] Stilizare fidela mockup-ului pe toate temele; tinte 44px pe mobil; a11y (label-uri, aria,
|
||||
anunt de chip adaugat/sters pentru screen-reader).
|
||||
- [ ] **Suprafata JS reala** (nota de efort): chips add/remove client-side + picker navigabil cu
|
||||
tastatura + management focus + reveal conditional odometruInitial = JS ne-trivial intr-un app
|
||||
HTMX/minimal-JS. Fallback fara JS: picker = `<select>` simplu (server valideaza R-ODO->odo,
|
||||
deci no-JS da `needs_data` corect, nu date gresite) — multi-select se degradeaza la un cod/submit.
|
||||
- **Verificare E2E**: browser — editare trimitere needs_data: schimb VIN + scriu Observatii + adaug
|
||||
2 coduri RAR (chips) + sterg unul -> salvare -> persistat; identic in preview import.
|
||||
2 coduri RAR (chips, cu tastatura) + adaug R-ODO (apare odometruInitial) + sterg un chip -> salvare
|
||||
-> persistat; identic in preview import.
|
||||
|
||||
### US-008: Teste de regresie + E2E final pe cele 4 teme
|
||||
**Ca** dezvoltator **vreau** acoperire si o trecere E2E completa **pentru ca** redesign-ul atinge
|
||||
@@ -219,11 +270,50 @@ fisiere fierbinti (base.html) si nu vreau regresii pe teme/liste/formular.
|
||||
- **Depinde de**: US-003, US-004, US-007
|
||||
- **Fisiere**: `tests/test_web_responsive.py`, `tests/test_tema.py`, `tests/test_web_submissions.py`
|
||||
(~3 fisiere)
|
||||
- **Test intai (RED)**: completare scenarii lipsa (4 teme x componente noi; slim list desktop+mobil)
|
||||
- **Test intai (RED)**: completare scenarii lipsa (componente noi pe TOATE temele; slim list desktop+mobil)
|
||||
- **Acceptance criteria**:
|
||||
- [ ] `pytest -q -m "not live"` verde (fara regresii fata de baseline).
|
||||
- [ ] E2E Playwright pe 390/820/1280, pe light/dark/petrol + cele 4 noi (esantion: grafit + hartie): dashboard contoare,
|
||||
lista slim cu filtre/paginare/bulk, formular slim cu chips, fara overflow orizontal.
|
||||
- [ ] **Test de tema robust, nu esantion**: un test parametrizat verifica fiecare token critic
|
||||
(`--card2`, `--line2`, `--accent`, `--ok`, `--err`) e DEFINIT in TOATE cele 7+1 stari
|
||||
(light/dark/petrol/grafit/cobalt/cupru/hartie/Auto). Ancorare pe SENTINEL CSS (nu felii
|
||||
fixe `[idx:idx+N]`) — vezi regresia false-green din ROADMAP 5.13.
|
||||
- [ ] E2E Playwright pe 390/820/1280, pe un dark (grafit) + un light (hartie) + petrol (verificare
|
||||
ca temele vechi nu au regresat): strip sanatate, dashboard contoare, lista slim cu
|
||||
filtre/paginare/bulk, formular slim cu chips, fara overflow orizontal.
|
||||
|
||||
### US-009: Salvare mapare din chip (compounding cu fluxul de mapare)
|
||||
**Ca** operator **vreau** ca atunci cand adaug un cod RAR la o operatie sa-l pot salva ca regula
|
||||
**pentru ca** data viitoare operatia sa se auto-rezolve, fara sa re-mapez manual.
|
||||
|
||||
- **Depinde de**: US-006, US-007
|
||||
- **Fisiere**: `app/web/templates/_form_editare.html`, `app/web/routes.py` (reuse `save_mapping` +
|
||||
`reresolve_account` — fara logica noua), `tests/test_web_mapare_din_chip.py` (~3 fisiere)
|
||||
- **Test intai (RED)**: `tests/test_web_mapare_din_chip.py` — `test_salveaza_regula_din_chip`, `test_reresolve_deblocheaza_frate`, `test_optional_nu_forteaza`
|
||||
- **Acceptance criteria**:
|
||||
- [ ] Cand operatia (`op_service`) e cunoscuta si userul adauga un cod RAR prin chip, apare optiunea
|
||||
"salveaza ca regula op->cod"; la confirmare reuse EXACT `save_mapping` + `reresolve_account`
|
||||
(acelasi mecanism ca maparea inline din 5.7), scoped pe cont + CSRF.
|
||||
- [ ] Re-rezolvarea deblocheaza si alte submission-uri `needs_mapping` cu aceeasi operatie (pe `batch_id`).
|
||||
- [ ] Optional: daca userul nu vrea sa salveze, editarea ramane one-off (fara regula). Se compune
|
||||
cu 5.14 (auto-maparea umple, salvarea din chip ramane fallback-ul uman).
|
||||
- **Verificare E2E**: adaug cod la operatie nemapata + salveaza regula -> al doilea rand cu aceeasi
|
||||
operatie se rezolva automat.
|
||||
|
||||
### US-010: Bulk-fix din lista (selectie multipla -> actiune unica)
|
||||
**Ca** operator **vreau** sa corectez mai multe randuri blocate dintr-o data **pentru ca** la 2-20
|
||||
de corectat/zi nu vreau sa intru in fiecare individual.
|
||||
|
||||
- **Depinde de**: US-004, US-006
|
||||
- **Fisiere**: `app/web/templates/_submissions.html`, `app/web/routes.py` (reuse infra bulk
|
||||
existenta din `_submissions` + `submissions_admin`), `tests/test_web_bulk_fix.py` (~3 fisiere)
|
||||
- **Test intai (RED)**: `tests/test_web_bulk_fix.py` — `test_bulk_remapeaza_selectie`, `test_bulk_doar_blocate`, `test_bulk_scoped_cont`
|
||||
- **Acceptance criteria**:
|
||||
- [ ] Pe randurile blocate (checkbox existent pe `gestionabil`), o actiune bulk noua: aplica un cod
|
||||
RAR / o remapare la toata selectia intr-o singura cerere (reuse forma `#bulk-trimiteri`).
|
||||
- [ ] Scoped pe cont (404-before-409 ca la bulk-delete); doar randuri blocate eligibile.
|
||||
- [ ] Fiecare rand re-validat + idempotenta recalculata individual (un cod invalid pe un rand nu
|
||||
pica tot lotul — sumar "N reusite, M esuate" ca la salvarea mapcoloane D#12).
|
||||
- **Verificare E2E**: selectez 3 randuri needs_mapping + aplic un cod -> toate 3 -> `queued`.
|
||||
- **Verificare E2E**: rulare completa documentata in Raportul VERIFY.
|
||||
|
||||
## 4. Riscuri
|
||||
@@ -238,6 +328,16 @@ fisiere fierbinti (base.html) si nu vreau regresii pe teme/liste/formular.
|
||||
refolosim mecanismul existent de recalcul + prindere coliziune (3.5/5.10), zero logica noua.
|
||||
- **Densitate vizuala pe mobil**: randul slim cu 2 linii + pill poate aglomera. Mitigare: tinte
|
||||
44px + verificare 390px in US-004/008.
|
||||
- **Premisa mobil nevalidata** (din TODOS 5.13, CEO F1): valoarea slim/compact pe mobil presupune
|
||||
utilizare reala pe mobil. Daca device-mix-ul e ~95% desktop, partea responsive e efort irosit.
|
||||
Mitigare: nu blocheaza (designul e bun si pe desktop), dar confirma analytics inainte de a investi
|
||||
in rafinari mobil viitoare.
|
||||
- **7 teme = suprafata de test/intretinere** pe fisierul cel mai fierbinte: fiecare componenta noua
|
||||
trebuie corecta in 7+1 stari. Istoricul (5.13) arata ca testele de tema au dat false-green o data.
|
||||
Mitigare: US-008 cere test parametrizat ancorat pe SENTINEL (nu felii fixe); deduparea
|
||||
grafit~dark / hartie~light ramana optiune de simplificare (reziduala, non-blocanta).
|
||||
- **Secventiere cu 5.14** (D9): 5.15 defineste forma listei `prestatii`; daca 5.14 (mapare LLM)
|
||||
porneste in paralel, sincronizeaza forma listei. Mitigare: 5.15 INAINTE de 5.14.
|
||||
|
||||
## 5. Intrebari deschise
|
||||
|
||||
@@ -257,15 +357,66 @@ fisiere fierbinti (base.html) si nu vreau regresii pe teme/liste/formular.
|
||||
```
|
||||
Val 1: [US-001] base.html teme + tokeni (autor unic pe base.html)
|
||||
Val 2: [US-002] base.html componente (dupa US-001, autor unic pe base.html)
|
||||
Val 3: [US-003] [US-004] dashboard + lista (consuma US-002; fisiere disjuncte) ||
|
||||
[US-005] [US-006] backend obs + prestatii (fisiere backend; pot rula in paralel cu UI)
|
||||
Val 4: [US-007] formular slim (dupa US-002+US-005+US-006)
|
||||
Val 5: [US-008] regresie + E2E final
|
||||
Val 3: [US-003] [US-004] dashboard + strip sanatate + lista (consuma US-002; disjuncte) ||
|
||||
[US-005] [US-006] backend obs + prestatii (fisiere backend; in paralel cu UI)
|
||||
Val 4: [US-007] formular slim cu chips (dupa US-002+US-005+US-006)
|
||||
Val 5: [US-009] [US-010] salvare mapare din chip || bulk-fix (dupa US-006/007 resp. US-004)
|
||||
Val 6: [US-008] regresie + E2E final (dupa toate)
|
||||
```
|
||||
|
||||
> Secventiere fata de alte PRD-uri (D9): **5.15 INAINTE de 5.14** (mapare LLM) — 5.15 fixeaza forma
|
||||
> listei `prestatii` si UX-ul de confirmare; 5.14 umple codurile peste aceeasi forma.
|
||||
|
||||
---
|
||||
|
||||
## 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 pe RAR test). Lipseste pana la VERIFY.
|
||||
|
||||
---
|
||||
|
||||
## GSTACK REVIEW REPORT
|
||||
|
||||
Review: `/plan-ceo-review` — 2026-06-28. Mod: **SELECTIVE EXPANSION**. Model: claude (opus).
|
||||
Abordare aleasa de user: tot PRD-ul (8 stories) + 4 extinderi acceptate -> **10 stories**.
|
||||
|
||||
| Pasaj | Status | Constatari materiale |
|
||||
|-------|--------|----------------------|
|
||||
| Audit sistem | OK | base.html cel mai fierbinte fisier (31x/30z); 5.15 = a 5-a iteratie pe acelasi UI (smell recurent); 5.14 in flight pe acelasi seam |
|
||||
| S1 Arhitectura | OK | Fara componente noi; fara migrare; rollback = revert template. Concentrare de risc pe base.html, nu coupling |
|
||||
| S2 Eroare/Rescue | 2 GAP | (a) coduri duplicate in chips nedefinit -> US-006 dedupe; (b) cod necunoscut: invariant ORA-12899 pastrat |
|
||||
| S4 Edge cases | 1 GAP HIGH | R-ODO/I-ODO cere odometruInitial; formularul nu il forta -> US-007 require dinamic (D10c) |
|
||||
| S2/Idempotenta | 1 FIX | `obs` EXCLUS din cheie (`idempotency.py:98`) -> AC US-005 corectat (D8); `prestatii` in cheie -> re-cheiere OK |
|
||||
| S6 Test | 1 GAP | 7 teme x componente pe fisier fierbinte; "esantion" prea lax -> US-008 test parametrizat ancorat pe SENTINEL |
|
||||
| S8/S11 Trust | 1 HIGH | carduri-contor ascundeau sanatatea -> strip mereu-vizibil deasupra contoarelor (D6) |
|
||||
| S9 Deploy | OK | Fara migrare; doar sent_today/sent_month (scoped). Rollback ieftin |
|
||||
| S10 Trajectorie | 1 DECIZIE | secventiere 5.15 inainte de 5.14 (D9) |
|
||||
| S11 Design/UX | OK + 4 EXT | strip trust; extinderi: salvare mapare din chip, bulk-fix, require dinamic odo, keyboard-first |
|
||||
|
||||
**Decizii incorporate (D6-D10):** strip sanatate mereu-vizibil (D6); operatie ramane in op_service +
|
||||
copiata in obs (D7); obs exclus din idempotenta, AC corectat (D8); 5.15 inainte de 5.14 (D9); cele 4
|
||||
extinderi acceptate (D10) -> US-007 imbogatit + US-009 (salvare mapare din chip) + US-010 (bulk-fix).
|
||||
|
||||
**Risc rezidual notat (non-blocant):** premisa "utilizare mobil reala" nevalidata (TODOS 5.13 F1);
|
||||
7 teme = suprafata de test pe fisier fierbinte (deduparea grafit~dark/hartie~light ramana optiune).
|
||||
|
||||
**Spec-review loop (reviewer independent, context curat) — scor 7/10, verdict ISSUES -> remediat:**
|
||||
- #1 HIGH (contradictie): US-006 spunea "reconstruieste prestatii ca itemi goi `{cod_prestatie}`",
|
||||
ceea ce ar fi sters `cod_op_service`/`denumire` -> rupea D7 si US-009. **Remediat**: US-006 pastreaza
|
||||
itemii existenti, seteaza doar `cod_prestatie`; pereche operatie<->cod definita; `idPrezentare` se
|
||||
adauga in `payload.py`, nu in itemul intern.
|
||||
- #2 MEDIUM: `sent_today`/`sent_month` nu aveau sursa de timp (nu exista `sent_at`). **Remediat**:
|
||||
US-003 foloseste `status='sent' AND date(updated_at)` cu justificare (randul `sent` nu mai e scris
|
||||
pana la purge la +90z) -> fara migrare.
|
||||
- #3 MEDIUM: US-006 subestima rewrite-ul handler-elor (logica single-`prestatii[0]`). **Remediat**:
|
||||
Fisierele US-006 numesc liniile exacte de rescris.
|
||||
- #5/#6 LOW: suprafata JS reala (US-007) + tinta de click "De corectat" (US-003). **Remediat** (note adaugate).
|
||||
- #4 LOW (scope): US-009/US-010 sunt adiacente FUNCTIONALE (din SELECTIVE EXPANSION), dincolo de
|
||||
obiectivul pur de propagare design. **Acceptat constient** (alegerea userului); ramane optiunea de
|
||||
a le scoate intr-un PRD separat daca propagarea design e ce e urgent.
|
||||
|
||||
**VERDICT:** APROBAT cu modificari incorporate (+remedieri spec-review). Scope: 10 stories / 6 valuri.
|
||||
Fara CODEX/cross-model in aceasta rulare (review uni-model). Gata de executie dupa confirmarea userului.
|
||||
|
||||
NO UNRESOLVED DECISIONS
|
||||
|
||||
Reference in New Issue
Block a user