feat(api): rar_credentials optional pe POST /v1/prezentari

Cand `rar_credentials` lipseste din cerere, submission-ul intra fara creds
efemere, iar worker-ul cade pe creds-urile RAR durabile ale contului
(accounts.rar_creds_enc). Identificarea contului ramane pe cheia API.
Trimiterea explicita a creds-urilor suprascrie creds-urile contului pe acea
cerere (back-compat: fluxul vechi ROAAUTO merge identic).

- models.py: rar_credentials: RarCredentials | None = None
- router.py: cripteaza creds doar daca exista (altfel creds_enc=NULL)
- worker NEATINS: avea deja fallback _creds_for(...) or _creds_from_account(...)

Pagina /integrare aliniata: exemplele cod (7 limbaje) + export Postman nu mai
includ rar_credentials in payload; nota noua explica modelul (creds pe cont,
optional in payload). README rescris compact + reflecta optionalitatea.

Test nou: enqueue fara creds -> submission fara creds efemere -> fallback pe
contul cu creds salvate. Suita: 673 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-06-23 13:39:53 +00:00
parent 0517ae59fb
commit 5dc963a02c
8 changed files with 188 additions and 375 deletions

View File

@@ -109,6 +109,41 @@ def test_ingestie_stocheaza_creds_criptate(env):
assert decrypt_creds(row["rar_creds_enc"]) == {"email": "x@y.ro", "password": "SECRETPW"}
def test_ingestie_fara_creds_foloseste_contul(env):
"""POST /v1/prezentari fara rar_credentials -> submission fara creds efemere;
worker-ul cade pe creds-urile durabile ale contului (accounts.rar_creds_enc)."""
import app.worker.__main__ as w
from app.db import get_connection
from app.main import app
with TestClient(app) as c:
# Contul (id=1 in dev) isi salveaza creds RAR durabile o data.
r0 = c.post("/v1/conturi/rar-creds", json={"email": "web@y.ro", "password": "WEBPW"})
assert r0.status_code == 200
# Trimitere FARA rar_credentials (doar payload). Identificarea contului
# ramane pe API key / sesiune; creds RAR nu mai sunt necesare in cerere.
body = {"prezentari": [{
"vin": "WVWZZZ1KZAW000123", "nr_inmatriculare": "B999TST",
"data_prestatie": "2026-06-15", "odometru_final": "123456",
"prestatii": [{"cod_prestatie": "OE-1"}],
}]}
r = c.post("/v1/prezentari", json=body)
assert r.status_code == 200, r.text
sid = r.json()["results"][0]["submission_id"]
conn = get_connection()
try:
row = conn.execute("SELECT rar_creds_enc FROM submissions WHERE id=?", (sid,)).fetchone()
# Submission-ul nu poarta creds efemere...
assert row["rar_creds_enc"] is None
# ...iar lantul de rezolvare al worker-ului ia creds din cont.
creds = w._creds_for({"creds_enc": None}, w.get_settings()) or w._creds_from_account(conn, 1)
assert creds == {"email": "web@y.ro", "password": "WEBPW"}
finally:
conn.close()
# --------------------------------------------------------------------------- #
# Worker: sesiuni per-cont #
# --------------------------------------------------------------------------- #