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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user