feat(errors): erori pe 3 niveluri (problema+cauza+fix) pe API si UI (PRD 5.4)
Catalog central pur app/errors.py ca sursa unica cod->{problema,fix},
consumat de API+UI+worker. Aditiv (field/message pastrate la octet) +
rar_error stocat superset. Scope: fluxul de declarare; login/signup/CSRF
neatinse. labels.parse_erori degradeaza gratios; UI progresiv AA light+dark.
631 teste.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -175,6 +175,127 @@ Aplicate deja pe ambele medii (test + producție):
|
||||
→ Acestea devin reguli Pydantic exacte în `app/api`. Validează la gateway înainte de enqueue
|
||||
(stare `needs_data`) ca să nu primești 4xx de la RAR.
|
||||
|
||||
## Envelope de eroare imbogatit (PRD 5.4)
|
||||
|
||||
### Forma unui obiect de eroare
|
||||
|
||||
Incepand cu PRD 5.4, fiecare obiect de eroare returnat de gateway contine **6 chei**:
|
||||
|
||||
| Cheie | Tip | Rol | Back-compat |
|
||||
|---|---|---|---|
|
||||
| `field` | string \| null | Campul care a generat eroarea (null daca eroarea e globala) | DA — existent anterior |
|
||||
| `message` | string | Mesajul scurt (identic cu `cauza` cand e disponibila, altfel `problema`) | DA — existent anterior |
|
||||
| `cod` | string | Identificator stabil de tip eroare (ex. `VIN_FORMAT`). Camp nou. | NU — adaugat 5.4 |
|
||||
| `problema` | string | Ce s-a intamplat — descriere scurta, inteligibila pentru utilizator | NU — adaugat 5.4 |
|
||||
| `cauza` | string | De ce a aparut eroarea — concret; pentru erorile RAR 400, mesajul exact de la RAR (passthrough) | NU — adaugat 5.4 |
|
||||
| `fix` | string | Ce trebuie facut pentru remediere | NU — adaugat 5.4 |
|
||||
|
||||
**Exemplu JSON concret** (eroare VIN invalid, returnat de `POST /v1/prezentari/valideaza`):
|
||||
|
||||
```json
|
||||
{
|
||||
"field": "vin",
|
||||
"message": "VIN trebuie sa aiba exact 17 caractere majuscule, fara spatii/caractere speciale si fara O, I, Q.",
|
||||
"cod": "VIN_FORMAT",
|
||||
"problema": "VIN invalid",
|
||||
"cauza": "VIN trebuie sa aiba exact 17 caractere majuscule, fara spatii/caractere speciale si fara O, I, Q.",
|
||||
"fix": "Verifica VIN-ul pe talon (pozitia E) sau pe caroserie: exact 17 caractere majuscule, fara spatii si fara literele O, I, Q."
|
||||
}
|
||||
```
|
||||
|
||||
### Nota de back-compat
|
||||
|
||||
Cheile `field` si `message` sunt **pastrate neschimbate** pe toate raspunsurile. Cheile `cod`, `problema`, `cauza`, `fix` sunt **aditive** (camp nou in plus). Clientii care citesc doar `field`/`message` (sau `error`/`message` la import) continua sa functioneze fara modificare.
|
||||
|
||||
### Unde apare envelope-ul imbogatit
|
||||
|
||||
**1. `POST /v1/prezentari/valideaza` (dry-run)**
|
||||
|
||||
Campul `erori` (array) si campul `nemapate` (array) din raspuns contin obiecte cu toate cele 6 chei.
|
||||
|
||||
**2. `submissions.rar_error` (stocat in DB, vizibil prin `GET /v1/prezentari/{id}` si in dashboard)**
|
||||
|
||||
Campul `rar_error` e superset al formei de mai sus si variaza cu starea submission-ului:
|
||||
|
||||
- `needs_data` — array de obiecte `{field, message, cod, problema, cauza, fix}`:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"field": "dataPrestatie",
|
||||
"message": "Data prestatiei nu poate fi anterioara datei de 01.12.2024.",
|
||||
"cod": "RAR_VALIDARE",
|
||||
"problema": "RAR a respins prezentarea",
|
||||
"cauza": "Data prestatiei nu poate fi anterioara datei de 01.12.2024.",
|
||||
"fix": "Corecteaza campul semnalat de RAR (vezi cauza) si reincearca; detaliile exacte sunt in mesajul tehnic RAR."
|
||||
}
|
||||
]
|
||||
```
|
||||
- `needs_mapping` (cod nemapat): obiect cu cheile `unmapped` (array), `cod`, `problema`, `cauza`, `fix`:
|
||||
```json
|
||||
{
|
||||
"unmapped": ["SCHIMB_ULEI_COMPLET"],
|
||||
"cod": "COD_NEMAPAT",
|
||||
"problema": "Lipseste codul RAR al operatiei",
|
||||
"cauza": "Operatia SCHIMB_ULEI_COMPLET nu are un cod RAR mapat.",
|
||||
"fix": "Alege codul RAR pentru aceasta operatie in tab-ul Mapari (ai sugestii automate)."
|
||||
}
|
||||
```
|
||||
- `needs_mapping` cu `auto_send` oprit: obiect cu `auto_send`, `cod: "AUTO_SEND_OPRIT"`, `problema`, `cauza`, `fix`.
|
||||
- Eroare RAR 400: array imbogatit cu `cod: "RAR_VALIDARE"` pe fiecare element.
|
||||
- Eroare RAR 401 (creds invalide): obiect cu `cod: "RAR_CREDS_INVALIDE"`, `problema`, `cauza`, `fix`.
|
||||
|
||||
**3. Erori de import (`POST /v1/import`, preview, commit)**
|
||||
|
||||
Campul `detail` din raspunsurile de eroare este superset: contine cheile vechi `error`/`message` plus `cod`, `problema`, `cauza`, `fix`.
|
||||
|
||||
**Exceptii din scope 5.4**: erorile de login/signup si CSRF raman mesaje plate (fara envelope imbogatit).
|
||||
|
||||
### Tabel cod → problema / fix (toate codurile din `app/errors.CATALOG`)
|
||||
|
||||
#### Validare date prestatie
|
||||
|
||||
| Cod | Problema | Fix |
|
||||
|---|---|---|
|
||||
| `VIN_FORMAT` | VIN invalid | Verifica VIN-ul pe talon (pozitia E) sau pe caroserie: exact 17 caractere majuscule, fara spatii si fara literele O, I, Q. |
|
||||
| `NR_INMATRICULARE_FORMAT` | Numar de inmatriculare invalid | Foloseste doar litere si cifre majuscule, maxim 10 caractere, fara spatii sau cratima (ex. B123ABC). |
|
||||
| `DATA_FORMAT` | Data prestatiei in format gresit | Scrie data ca AAAA-LL-ZZ (ex. 2026-06-22). |
|
||||
| `DATA_PREA_VECHE` | Data prestatiei prea veche | RAR accepta prestatii doar incepand cu 01.12.2024; verifica data prestatiei. |
|
||||
| `DATA_VIITOR` | Data prestatiei in viitor | Data prestatiei nu poate fi dupa ziua de azi; corecteaza data. |
|
||||
| `ODOMETRU_FINAL_FORMAT` | Odometru final invalid | Scrie kilometrajul final ca numar intreg, fara zecimale sau text (ex. 145000). |
|
||||
| `ODOMETRU_INITIAL_LIPSA` | Lipseste odometrul initial | Prestatiile R-ODO / I-ODO cer kilometrajul initial; completeaza-l. |
|
||||
| `ODOMETRU_INITIAL_FORMAT` | Odometru initial invalid | Scrie kilometrajul initial ca numar intreg, fara zecimale sau text. |
|
||||
| `ODOMETRU_INITIAL_ORDINE` | Odometru initial mai mare decat finalul | Kilometrajul initial trebuie sa fie mai mic sau egal cu cel final; verifica cele doua valori. |
|
||||
| `PRESTATII_GOALE` | Nicio prestatie | Adauga cel putin o prestatie cu cod RAR valid. |
|
||||
| `B64_INVALID` | Imaginea nu este base64 valid | Trimite imaginea codata base64 corect, sau omite campul daca nu ai imagine. |
|
||||
|
||||
#### Mapare operatie
|
||||
|
||||
| Cod | Problema | Fix |
|
||||
|---|---|---|
|
||||
| `COD_NEMAPAT` | Lipseste codul RAR al operatiei | Alege codul RAR pentru aceasta operatie in tab-ul Mapari (ai sugestii automate). |
|
||||
| `AUTO_SEND_OPRIT` | Necesita confirmare manuala | Codul e mapat cu trimitere automata oprita; verifica randul si pune-l manual in coada. |
|
||||
|
||||
#### Erori RAR (raspuns live de la RAR)
|
||||
|
||||
| Cod | Problema | Fix |
|
||||
|---|---|---|
|
||||
| `RAR_VALIDARE` | RAR a respins prezentarea | Corecteaza campul semnalat de RAR (vezi cauza) si reincearca; detaliile exacte sunt in mesajul tehnic RAR. |
|
||||
| `RAR_CREDS_INVALIDE` | Credentiale RAR invalide | Verifica email-ul si parola contului RAR in tab-ul Cont; trimiterea nu se reincearca automat la credentiale gresite. |
|
||||
|
||||
#### Import fisier
|
||||
|
||||
| Cod | Problema | Fix |
|
||||
|---|---|---|
|
||||
| `IMPORT_FISIER_PREA_MARE` | Fisier prea mare | Imparte fisierul in bucati de maxim 5000 de randuri si incarca-le pe rand. |
|
||||
| `IMPORT_ANTET_NECLAR` | Antet de coloane neclar | Asigura-te ca primul rand contine numele coloanelor (ex. VIN, Numar, Data). |
|
||||
| `IMPORT_ENCODING` | Codare de caractere nesuportata | Salveaza fisierul ca CSV UTF-8 (sau xlsx) si reincarca. |
|
||||
| `IMPORT_FISIER_NERECUNOSCUT` | Fisier nerecunoscut | Incarca un fisier .xlsx sau .csv valid. |
|
||||
| `IMPORT_MULTIPLE_SHEETS` | Mai multe foi in fisier | Pastreaza datele intr-o singura foaie sau alege foaia de import. |
|
||||
| `IMPORT_FARA_MAPARE_COLOANE` | Coloanele nu sunt mapate | Mapeaza intai coloanele fisierului la campurile cerute, apoi continua. |
|
||||
| `IMPORT_CONFIRMARE_GRESITA` | Numar confirmat gresit | Numarul confirmat difera de randurile gata de trimis; verifica preview-ul si reconfirma. |
|
||||
| `IMPORT_OVERRIDE_ILIZIBIL` | Editarea anterioara nu se poate citi | Editarea salvata este ilizibila (probabil cheia s-a schimbat); reediteaza randul. |
|
||||
| `COLOANE_FORMAT_JSON` | Format de coloane (JSON) invalid | Verifica sintaxa JSON a maparii de coloane (ghilimele duble, acolade inchise corect). |
|
||||
|
||||
## Nomenclator prestații (18 coduri, verificat live 2026-06-15)
|
||||
|
||||
| cod | nume |
|
||||
|
||||
Reference in New Issue
Block a user