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

@@ -94,12 +94,10 @@ _POSTMAN_ITEMS = [
"body": {
"mode": "raw",
"options": {"raw": {"language": "json"}},
# rar_credentials e optional: cererea trimite doar cheia API + datele
# prezentarii; worker-ul foloseste creds-urile RAR salvate pe cont.
"raw": (
'{\n'
' "rar_credentials": {\n'
' "email": "user@exemplu.ro",\n'
' "password": "parola_rar"\n'
' },\n'
' "prezentari": [\n'
' {\n'
' "vin": "WVWZZZ1KZAW000123",\n'

View File

@@ -60,12 +60,15 @@ def create_prezentari(
implicit id=1 in dev fara cheie, 401 fara cheie valida in prod.
Nota: rar_credentials NU se persista (zero-storage) — worker-ul le va primi
pe alt canal (T2); in schelet enqueue-ul doar stocheaza prezentarea.
Cand rar_credentials lipseste, submission-ul intra fara creds efemere: worker-ul
cade pe creds-urile durabile ale contului (`accounts.rar_creds_enc`).
"""
acct = account_or_default(account_id)
# Creds RAR efemere: criptate si lipite de fiecare submission nou pana la
# primul login reusit pentru cont (worker le sterge atunci). Zero-storage at
# rest — niciodata in clar in DB/loguri (plan sect. 5).
creds_enc = encrypt_creds(req.rar_credentials.model_dump())
# rest — niciodata in clar in DB/loguri (plan sect. 5). Optional: cand lipsesc,
# creds_enc=NULL si worker-ul foloseste creds-urile durabile ale contului.
creds_enc = encrypt_creds(req.rar_credentials.model_dump()) if req.rar_credentials else None
conn = get_connection()
results: list[SubmissionResult] = []
try: