- 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>
14 KiB
Contract RAR AUTOPASS — sursa de adevăr (verificat live)
Acesta este documentul autoritativ pentru contractul API RAR AUTOPASS. Înlocuiește presupunerile din
docs/plans/*acolo unde diferă. Dacă un plan contrazice acest fișier, acest fișier are dreptate.Surse:
docs/api-rar-documentatie-oficiala.md— răspuns oficial de la programatorii RAR.- Verificare live pe endpoint-ul de test (
/public/login+getNomenclatorPrestatii), 2026-06-15.- Cod VFP testat (
rar_autopass.prg) — confirmat ca URL-uri corecte.
Endpoint-uri
| Mediu | Bază |
|---|---|
| TEST (integrare — doar aici se testează) | https://apps.rarom.ro/test-rar-autopass |
| PRODUCȚIE | https://apps.rarom.ro/rar-autopass |
| Swagger test | https://apps.rarom.ro/test-rar-autopass/swagger-ui/index.html |
⚠️ …/v3/api-docs, …/v2/api-docs, …/swagger-resources întorc 403 (nu se pot
descărca programatic). Swagger-ul nu permite autentificare directă — testarea reală
se face din cod / Postman cu credențialele de test.
Rute confirmate
| Operație | Metodă + cale | Stare |
|---|---|---|
| Login | POST /public/login |
✅ verificat live |
| Nomenclator prestații | GET /nomenclator/getNomenclatorPrestatii |
✅ verificat live (200) |
| Adăugare prezentare | POST /prezentari/postPrezentare |
din VFP testat + doc oficial |
Nota: doc-ul oficial citează operationId-ul Swagger
getPrestatiiNomUsingGET, dar 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:
idUser, idAgent, cui, nume, prenume, email, token, activationToken,
activ, dataActivarii, dataSfarsit, blocat, expirat, tokenExists, authorities
- Tokenul JWT se atașează la apelurile securizate:
Authorization: Bearer {token}. - JWT claims (decodate live):
{ jti: "mobileJWT", sub: <email>, authorities: ["ADMIN"], iat, exp }. - ⚠️ JWT TTL = 108000 secunde = 30 de ORE (
exp - iat). NU e un token scurt. Vezi „Corecții față de planuri" #1 — schimbă strategia de robustețe a worker-ului. idUservine din răspunsul de login (ex. live:6766);idAgentpoate finullla login, dar serverul atribuieidAgentpe prezentare (vezi exemplul de răspuns oficial:idAgent: 1587).
postPrezentare — payload (request)
Câmpurile marcate OPTIONAL pot lipsi; restul sunt obligatorii. tipPrestatie NU se trimite
(îl generează serverul).
{
"vin": "XXXXXXXXXXXXXXXXX",
"nrInmatriculare": "B999GEN",
"dataPrestatie": "2024-07-25",
"odometruFinal": "9999999",
"odometruInitial": null,
"prestatii": [
{ "codPrestatie": "OE-1", "idPrezentare": null },
{ "codPrestatie": "OE-2", "idPrezentare": null }
],
"sistemReparat": "null",
"status": "FINALIZATA",
"obs": "TEST",
"b64Image": "UklGR...."
}
| Câmp | Obligatoriu | Note |
|---|---|---|
vin |
DA | 17 caractere, MAJUSCULE, fără spații/caractere speciale, fără literele O, I, Q |
nrInmatriculare |
DA | max 10 caractere, litere + cifre, MAJUSCULE, fără spații/caractere speciale |
dataPrestatie |
DA | format YYYY-MM-DD; nu mai devreme de 2024-12-01, nu mai târziu de azi |
odometruFinal |
DA | indicația km la final (exemplul oficial îl trimite ca string "9999999") |
odometruInitial |
condiționat | null normal; OBLIGATORIU dacă prestatii conține R-ODO sau I-ODO (indicația dinainte de reparație/schimbare) |
prestatii |
DA | listă {codPrestatie, idPrezentare:null}; codurile din nomenclator |
status |
DA | întotdeauna "FINALIZATA" prin API |
sistemReparat |
DA (poate fi "null") |
exemplul oficial trimite string-ul "null"; valori reale nedocumentate (vezi Open Q) |
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) — VERIFICAT LIVE 2026-06-15
Răspuns real pe contul nostru de test (record creat data.id=68514):
{
"statusCode": 200,
"message": "Prezentare adaugata cu succes",
"data": {
"id": 68514,
"dataPrestatie": "2026-06-15",
"vin": "WVWZZZ1KZAW000123",
"odometruFinal": 123456,
"idAgent": 40,
"tipPrestatie": "GENERIC",
"odometruInitial": null,
"idUser": 6766,
"sistemReparat": "null",
"obs": "TEST GATEWAY",
"nrInmatriculare": "B999TST",
"listaPrestatii": null,
"status": "FINALIZATA",
"prestatii": [
{ "idPrezentare": 68514, "codPrestatie": "OE-1" },
{ "idPrezentare": 68514, "codPrestatie": "OE-2" }
],
"b64Image": null
}
}
data.id= ID-ul prezentării la RAR (de reținut caidPrezentareî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 întorsnull, răspunsul are40).odometruFinaltrimis ca string"123456"→ întors ca număr123456(server normalizează).sistemReparat:"null"acceptat;b64Imageomis →null;odometruInitial:nullOK.- Câmp extra nedocumentat în răspuns:
listaPrestatii: null(prezent lângăprestatii). tipPrestatie="GENERIC"— generat de server, nu input client.
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:
{
"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)
Aplicate deja pe ambele medii (test + producție):
- dataPrestatie:
>= 2024-12-01și<= azi. - VIN: exact 17 caractere, majuscule, fără spații/caractere speciale, fără O, I, Q.
- nrInmatriculare: max 10 caractere, litere + cifre, majuscule, fără spații/caractere speciale.
- b64Image: dacă e prezent, trebuie base64 valid.
- odometruInitial: obligatoriu dacă
prestatiiconțineR-ODOsauI-ODO.
→ 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.
Nomenclator prestații (18 coduri, verificat live 2026-06-15)
| cod | nume |
|---|---|
| OE-1 | REPARAȚIE |
| OE-2 | INTRETINERE |
| OE-3 | REVIZIE PERIODICA |
| OE-4 | REGLARE FUNCTIONALA |
| OE-5 | MODIFICARE CONSTRUCTIVA |
| OE-6 | RECONSTRUCTIE |
| OE-7 | ACTUALIZARE SOFTWARE |
| OE-8 | INLOCUIRE SEZONIERA A ANVELOPELOR |
| OE-D | AVARII GRAVE LA SISTEMUL DE DIRECTIE |
| OE-F | AVARII GRAVE LA SISTEMUL DE FRANARE |
| OE-C | AVARII GRAVE LA STRUCTURA DE REZISTENTA A CAROSERIEI |
| OE-S | AVARII GRAVE LA STRUCTURA DE REZISTENTA A SASIULUI |
| OE-R | AVARII GRAVE LA UN SISTEM DE RETINERE SI PROTECTIE IN CAZ DE ACCIDENT |
| OE-A | AVARII GRAVE LA UN SISTEM AVANSAT DE ASISTENTA A CONDUCATORULUI AUTO (ADAS) |
| OE-I | ISTORICUL INDICATIEI ODOMETRULUI (vehicule anterior inmatriculate in alte tari) |
| AITLV | INREGISTRARE ATELIER INSPECTIE TAHOGRAFE / LIMITATOARE DE VITEZA |
| R-ODO | REPARATIE ODOMETRU → declanșează odometruInitial obligatoriu |
| I-ODO | INLOCUIRE ODOMETRU → declanșează odometruInitial obligatoriu |
numePrestatieredat prescurtat pentru OE-D…OE-A (în API e textul lung complet). Nomenclatorul se ia live din API; nu hard-coda — folosește acest tabel doar ca referință.
Ciclu de viață prezentare (la RAR) — IMPORTANT
- API-ul are un singur scop: INSERT prezentări cu status
FINALIZATA. Toate celelalte operațiuni CRUD se fac din interfața web. - Prezentările
FINALIZATANU se pot anula prin API (nici din web). Doar celeSALVATAsunt anulabile/editabile, dar API nu produceSALVATA.- Încercarea de anulare a unei
FINALIZATAîntoarce:EROARE_STATUS_ANULARE("... Id not found.").
- Încercarea de anulare a unei
- Corecția datelor eronate (după FINALIZATA) = solicitare la suport.autopass@rarom.ro (pe test nu e cazul). Nu există flux API de corecție/anulare pentru records-urile noastre.
Monitorizare (citire prezentări)
- Pe mediul de test: la interogarea listei de prezentări finalizate NU primești și
prestatiiîn răspuns. - Pe producție: prestațiile sunt disponibile; lista poate fi filtrată după keyword / interval de date și exportată în Excel.
- Implicație dashboard: nu te baza pe
prestatiidin listă pe test; le ai însubmissionslocal.
Corecții față de docs/plans/* (citește înainte de a refolosi planurile)
- JWT „scurt" → de fapt 30 de ORE. Planurile (
plan-design-review§„Gestiunea credențialelor",plan-eng-review§worker) presupun JWT scurt și mută durabilitatea pe re-push din ROAAUTO („coada acoperă minutele, ROAAUTO acoperă orele"). Fals. Cu 30h, worker-ul singur poate relua peste orice pană RAR realistă în fereastra tokenului. Re-push-ul din ROAAUTO devine plasă de siguranță secundară, nu mecanismul principal. Re-evaluează: poate nu mai e nevoie de re-push în treapta 1, sau credențialele se pot reține în memorie pe durata penei. - b64Image (poza odometrului) NU mai e obligatorie. Planurile o tratau ca posibil gap de conformitate / posibil obligatorie. Rezolvat: opțională. → Open Question „sursa pozei în ROAAUTO" se închide (nu mai e blocantă). Dacă e atașată, doar trebuie base64 valid.
tipPrestatieNU e input client — îl generează serverul ("GENERIC"). Open Question #2 (valori acceptatetipPrestatie) se închide pentru request — nu-l trimite.sistemReparat: planul presupunea că e derivabil server-side din coduri și nu input liber. Parțial fals — apare în request (exemplul oficial trimite string-ul"null"). Rămâne open ce valori reale acceptă; sigur: poți trimite"null"când nu se aplică.- Anulare / corecție prin API: NU există pentru records-urile noastre (sunt
FINALIZATA). Scoate din scope endpoint-urile gatewayPATCH /v1/prezentari/{id}/anulareși/corectie(proxy pestemarkPrezentareAnulataById/patchPrezentare) — nu se aplicăFINALIZATA. Maparea stărilor + „Error & rescue map" dinplan-eng-reviewtrebuie ajustate. - Regula
needs_datae acum deterministă:odometruInitiallipsă doar cândprestatiiconțineR-ODOsauI-ODO. (Planul vorbea generic de „repair odometru".) - URL nomenclator confirmat =
/nomenclator/getNomenclatorPrestatii(nu varianta din operationId Swagger). Constatarea #5 dinplan-eng-review(URL-uri din VFP, nu din spec) — confirmată.
Open questions rămase (actualizat)
Sursa pozei odometrului— închis (poză opțională).sistemReparat— ce valori reale acceptă (în afară de"null"). De probat la postPrezentare test.- Un singur user RAR per agent economic sau mai mulți (
idUser/idAgent— afectează filtrarea monitorizării). JWT TTL— închis: 30h. Decizie nouă: simplifică worker-ul; reconsideră necesitatea re-push ROAAUTO.Comportamentul răspunsului de eroare— închis (formatdata:[{field,message}], mesaje capturate mai sus).- WAF cere
User-Agent— închis/confirmat (vezi secțiunea de sus).
Rămas de verificat live (postPrezentare real pe test) — ✅ FĂCUT 2026-06-15
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/odometruInitialomise OK;- header
User-Agentobligatoriu (altfel 403 WAF).
Rămas neprobat: ce alte valori sistemReparat (în afară de "null") acceptă (Open Q #2).