Verificat contractul RAR AUTOPASS pe endpoint-ul de test si compilat sursa de adevar `docs/api-rar-contract.md`. Corectii majore fata de planurile vechi: - JWT TTL = 30h (nu scurt); worker se re-logheaza, retry neplafonat - b64Image optional; tipPrestatie generat de server (nu se trimite) - anulare/corectie prin API inexistente pentru FINALIZATA - needs_data determinist pe R-ODO/I-ODO; reguli validare exacte (VIN/data/nrInm) Rulat plan-eng-review + plan-design-review, apoi consolidat ambele intr-un singur plan executabil `docs/plans/plan.md` (design ca anexa). Outside voice a prins lost-ack double-submit (P1) -> reconciliere inainte de re-send. Re-push din ROAAUTO scos din v1 (durabilitate = SQLite persistent + restart). - mutat fisierele spec oficiale RAR in docs/ - adaugat raspunsul oficial al programatorilor RAR (api-rar-documentatie-oficiala.md) - sterse plan-eng-review.md + plan-design-review.md (consolidate in plan.md) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
215 lines
11 KiB
Markdown
215 lines
11 KiB
Markdown
# 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.
|
|
|
|
## 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.
|
|
- `idUser` vine din răspunsul de login (ex. live: `6766`); `idAgent` poate fi `null` la login,
|
|
dar serverul atribuie `idAgent` pe 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).
|
|
|
|
```json
|
|
{
|
|
"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)
|
|
|
|
```json
|
|
{
|
|
"statusCode": 200,
|
|
"message": "Prezentare adaugata cu succes",
|
|
"data": {
|
|
"id": 59950,
|
|
"dataPrestatie": "2024-07-25",
|
|
"vin": "...",
|
|
"odometruFinal": 9999999,
|
|
"idAgent": 1587,
|
|
"tipPrestatie": "GENERIC",
|
|
"odometruInitial": null,
|
|
"idUser": 22,
|
|
"sistemReparat": "null",
|
|
"obs": "TEST",
|
|
"nrInmatriculare": "B999GEN",
|
|
"status": "FINALIZATA",
|
|
"prestatii": [ { "idPrezentare": 599950, "codPrestatie": "OE-1" }, ... ],
|
|
"b64Image": "..."
|
|
}
|
|
}
|
|
```
|
|
|
|
- `data.id` = ID-ul prezentării la RAR (de reținut ca `idPrezentare` în submission).
|
|
- `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.
|
|
|
|
## Reguli de validare (server-side RAR, de aplicat și în gateway)
|
|
|
|
Aplicate deja pe ambele medii (test + producție):
|
|
|
|
1. **dataPrestatie**: `>= 2024-12-01` și `<= azi`.
|
|
2. **VIN**: exact 17 caractere, majuscule, fără spații/caractere speciale, **fără O, I, Q**.
|
|
3. **nrInmatriculare**: max 10 caractere, litere + cifre, majuscule, fără spații/caractere speciale.
|
|
4. **b64Image**: dacă e prezent, trebuie base64 valid.
|
|
5. **odometruInitial**: obligatoriu dacă `prestatii` conține `R-ODO` sau `I-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 |
|
|
|
|
> `numePrestatie` redat 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 `FINALIZATA` NU se pot anula prin API** (nici din web). Doar cele `SALVATA`
|
|
sunt anulabile/editabile, dar API nu produce `SALVATA`.
|
|
- Încercarea de anulare a unei `FINALIZATA` întoarce: `EROARE_STATUS_ANULARE("... Id not found.")`.
|
|
- 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 `prestatii` din listă pe test; le ai în `submissions` local.
|
|
|
|
## Corecții față de `docs/plans/*` (citește înainte de a refolosi planurile)
|
|
|
|
1. **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.
|
|
2. **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.
|
|
3. **`tipPrestatie` NU e input client** — îl generează serverul (`"GENERIC"`). Open Question #2
|
|
(valori acceptate `tipPrestatie`) **se închide pentru request** — nu-l trimite.
|
|
4. **`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ă.
|
|
5. **Anulare / corecție prin API: NU există** pentru records-urile noastre (sunt `FINALIZATA`).
|
|
Scoate din scope endpoint-urile gateway `PATCH /v1/prezentari/{id}/anulare` și `/corectie`
|
|
(proxy peste `markPrezentareAnulataById` / `patchPrezentare`) — nu se aplică `FINALIZATA`.
|
|
Maparea stărilor + „Error & rescue map" din `plan-eng-review` trebuie ajustate.
|
|
6. **Regula `needs_data` e acum deterministă:** `odometruInitial` lipsă **doar** când `prestatii`
|
|
conține `R-ODO` sau `I-ODO`. (Planul vorbea generic de „repair odometru".)
|
|
7. **URL nomenclator confirmat** = `/nomenclator/getNomenclatorPrestatii` (nu varianta din
|
|
operationId Swagger). Constatarea #5 din `plan-eng-review` (URL-uri din VFP, nu din spec) — confirmată.
|
|
|
|
## Open questions rămase (actualizat)
|
|
|
|
1. ~~Sursa pozei odometrului~~ — **închis** (poză opțională).
|
|
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).
|
|
|
|
## Rămas de verificat live (postPrezentare real pe test)
|
|
|
|
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.)
|
|
</content>
|
|
</invoke>
|