docs: contract RAR actualizat cu T1 verificat live (postPrezentare)

- WAF cere User-Agent pe toate apelurile (altfel 403); fara UA -> blocat
- format eroare validare: data=[{field,message}], 3 mesaje exacte capturate
- raspuns success live: data.id=68514, idPrezentare==id, idAgent server-side
- sistemReparat="null" acceptat, b64Image/odometruInitial omise OK
- odometruFinal string -> intors numar; camp extra listaPrestatii
- Open Q #5 (mesaje eroare) + WAF inchise

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-15 11:56:16 +00:00
parent 5ea2c4cedb
commit ff03041cd6

View File

@@ -33,6 +33,17 @@ se face din cod / Postman cu credențialele de test.
> **calea reală e `/nomenclator/getNomenclatorPrestatii`** (cea din VFP). `/nomenclator/getPrestatiiNom`
> întoarce 403 — nu o folosi. operationId ≠ path.
## ⚠️ Header obligatoriu pe TOATE apelurile: `User-Agent`
WAF-ul RAR întoarce **`403 Forbidden` („Request forbidden by administrative rules")**
la orice request **fără header `User-Agent` de browser** — inclusiv `/public/login` și
chiar `swagger-ui`. curl/clienți fără UA = blocați la WAF înainte de a ajunge la aplicație.
MSXML2.XMLHTTP din VFP trimite un UA implicit, de aceea VFP-ul merge.
→ Gateway-ul (`app/rar_client.py`) **trebuie** să seteze `User-Agent` pe fiecare apel
(ex. `Mozilla/5.0`). Confirmat live 2026-06-15: fără UA → 403; cu UA + creds greșite → 401;
cu UA + creds corecte → 200.
## Autentificare
`POST /public/login` body `{"email": "...", "password": "..."}` → 200, JSON cu câmpuri:
@@ -85,34 +96,71 @@ Câmpurile marcate OPTIONAL pot lipsi; restul sunt obligatorii. `tipPrestatie` *
| `obs` | NU (OPTIONAL) | text liber |
| `b64Image` | NU (OPTIONAL) | poza odometrului; **nu mai e obligatorie**; dacă se atașează, trebuie format base64 valid |
### postPrezentare — răspuns (success)
### postPrezentare — răspuns (success) — VERIFICAT LIVE 2026-06-15
Răspuns real pe contul nostru de test (record creat `data.id=68514`):
```json
{
"statusCode": 200,
"message": "Prezentare adaugata cu succes",
"data": {
"id": 59950,
"dataPrestatie": "2024-07-25",
"vin": "...",
"odometruFinal": 9999999,
"idAgent": 1587,
"id": 68514,
"dataPrestatie": "2026-06-15",
"vin": "WVWZZZ1KZAW000123",
"odometruFinal": 123456,
"idAgent": 40,
"tipPrestatie": "GENERIC",
"odometruInitial": null,
"idUser": 22,
"idUser": 6766,
"sistemReparat": "null",
"obs": "TEST",
"nrInmatriculare": "B999GEN",
"obs": "TEST GATEWAY",
"nrInmatriculare": "B999TST",
"listaPrestatii": null,
"status": "FINALIZATA",
"prestatii": [ { "idPrezentare": 599950, "codPrestatie": "OE-1" }, ... ],
"b64Image": "..."
"prestatii": [
{ "idPrezentare": 68514, "codPrestatie": "OE-1" },
{ "idPrezentare": 68514, "codPrestatie": "OE-2" }
],
"b64Image": null
}
}
```
- `data.id` = ID-ul prezentării la RAR (de reținut ca `idPrezentare` în submission).
- **`prestatii[].idPrezentare == data.id`** (live: ambele 68514). Exemplul vechi sugera un
număr separat mai mare (599950 vs 59950) — **fals**, e același id.
- `idAgent` = **atribuit de server** (login a întors `null`, răspunsul are `40`).
- `odometruFinal` trimis ca string `"123456"`**întors ca număr** `123456` (server normalizează).
- `sistemReparat:"null"` acceptat; `b64Image` omis → `null`; `odometruInitial:null` OK.
- Câmp extra nedocumentat în răspuns: **`listaPrestatii: null`** (prezent lângă `prestatii`).
- `tipPrestatie` = `"GENERIC"`**generat de server**, nu input client.
- Validările eșuate sunt raportate **în răspunsul API** (mesaj de eroare) când nu sunt respectate constrângerile.
### postPrezentare — răspuns (eroare validare) — VERIFICAT LIVE 2026-06-15
HTTP **400**. `data` este un **ARRAY** de `{field, message}` (NU string), un element per eroare:
```json
{
"statusCode": 400,
"message": "Validare eșuată pentru cererea de prezentare.",
"data": [
{ "field": "vin", "message": "VIN trebuie să aibă exact 17 caractere, fara spatii sau caractere speciale, litere invalide : O, I, Q." },
{ "field": "vin", "message": "VIN conține caractere invalide, spatii, sau O, I, Q." }
]
}
```
Mesaje exacte capturate live (de mapat în UI/loguri gateway):
| Constrângere încălcată | field | message (exact) |
|---|---|---|
| VIN cu O/I/Q | `vin` | `VIN trebuie să aibă exact 17 caractere, fara spatii sau caractere speciale, litere invalide : O, I, Q.` + `VIN conține caractere invalide, spatii, sau O, I, Q.` |
| dataPrestatie < 2024-12-01 | `dataPrestatie` | `Data prestatiei nu poate fi anterioara datei de 01.12.2024.` |
| dataPrestatie în viitor | `dataPrestatie` | `Data prestatiei nu poate fi în viitor.` |
Gateway: parsează `data` ca listă de erori de câmp (nu citi `data.message`). Pe success `data`
e obiect; pe 400 `data` e array discriminează după `statusCode`/HTTP code.
## Reguli de validare (server-side RAR, de aplicat și în gateway)
@@ -201,14 +249,18 @@ Aplicate deja pe ambele medii (test + producție):
2. `sistemReparat` ce valori reale acceptă (în afară de `"null"`). De probat la postPrezentare test.
3. Un singur user RAR per agent economic sau mai mulți (`idUser`/`idAgent` afectează filtrarea monitorizării).
4. ~~JWT TTL~~ **închis: 30h.** Decizie nouă: simplifică worker-ul; reconsideră necesitatea re-push ROAAUTO.
5. Comportamentul exact al răspunsului de eroare la fiecare constrângere (de capturat la primul postPrezentare test).
5. ~~Comportamentul răspunsului de eroare~~ **închis** (format `data:[{field,message}]`, mesaje capturate mai sus).
6. WAF cere `User-Agent` **închis/confirmat** (vezi secțiunea de sus).
## Rămas de verificat live (postPrezentare real pe test)
## ~~Rămas de verificat live (postPrezentare real pe test)~~ — ✅ FĂCUT 2026-06-15
Login + nomenclator + JWT TTL = ✅ făcute. Mai rămâne **un singur POST real pe test** ca să confirmi:
- mesajele de eroare exacte pentru fiecare constrângere (VIN cu O/I/Q, dată în afara intervalului etc.);
- valoarea `data.id` întoarsă și forma exactă a răspunsului pe contul nostru;
- acceptarea `sistemReparat: "null"` și omiterea `b64Image`/`odometruInitial`.
(Creează un record pe mediul de test — nu pe producție.)
Login + nomenclator + JWT TTL + **postPrezentare** = toate verificate live.
Record de test creat: `data.id = 68514` (FINALIZATA, permanent pe test). Confirmat:
- mesajele de eroare exacte (VIN O/I/Q, dată prea veche, dată viitoare) vezi tabelul de erori;
- forma răspunsului success pe contul nostru + `data.id`;
- `sistemReparat:"null"` acceptat, `b64Image`/`odometruInitial` omise OK;
- header `User-Agent` obligatoriu (altfel 403 WAF).
Rămas neprobat: ce alte valori `sistemReparat` (în afară de `"null"`) acceptă (Open Q #2).
</content>
</invoke>