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:
@@ -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'
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -80,9 +80,14 @@ class PrezentareIn(BaseModel):
|
||||
|
||||
|
||||
class PrezentareRequest(BaseModel):
|
||||
"""Body pentru POST /v1/prezentari — una sau mai multe prezentari + creds RAR."""
|
||||
"""Body pentru POST /v1/prezentari — una sau mai multe prezentari + creds RAR.
|
||||
|
||||
rar_credentials: RarCredentials
|
||||
`rar_credentials` e OPTIONAL: daca lipseste, worker-ul foloseste creds-urile RAR
|
||||
durabile salvate pe cont (`accounts.rar_creds_enc`, via POST /v1/conturi/rar-creds).
|
||||
Trimite-le explicit doar cand vrei sa suprascrii creds-urile contului pe acea cerere.
|
||||
"""
|
||||
|
||||
rar_credentials: RarCredentials | None = None
|
||||
prezentari: list[PrezentareIn] = Field(..., min_length=1)
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ def _payload_prezentari_dict(account_id: int) -> dict:
|
||||
|
||||
Campurile cu default (odometru_initial, obs, b64_image, sistem_reparat) sunt
|
||||
omise pentru concizie — nu sunt obligatorii.
|
||||
|
||||
`rar_credentials` NU e inclus: cererea trimite doar cheia API + datele prezentarii,
|
||||
iar worker-ul foloseste credentialele RAR salvate pe cont (tab-ul Cont). Trimiterea
|
||||
lor in payload e optionala (suprascrie creds-urile contului pe acea cerere).
|
||||
"""
|
||||
# Construim un dict cu toate campurile obligatorii
|
||||
campuri = _campuri_obligatorii()
|
||||
@@ -48,13 +52,7 @@ def _payload_prezentari_dict(account_id: int) -> dict:
|
||||
# Fallback generic pentru campuri neasteptate adaugate ulterior
|
||||
prezentare[camp] = f"<{camp}>"
|
||||
|
||||
return {
|
||||
"rar_credentials": {
|
||||
"email": "utilizator@service.ro",
|
||||
"password": "parola_rar",
|
||||
},
|
||||
"prezentari": [prezentare],
|
||||
}
|
||||
return {"prezentari": [prezentare]}
|
||||
|
||||
|
||||
def _payload_json_str(account_id: int, indent: int = 2) -> str:
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
<span class="muted" style="font-size:13px; margin-left:16px;">Endpoint:</span>
|
||||
<code style="font-size:12px; color:var(--accent);">{{ base_url }}</code>
|
||||
</div>
|
||||
<p class="muted" style="font-size:12px; margin:10px 0 0;">
|
||||
Cererile trimit doar cheia API + datele prezentarii. Credentialele RAR se configureaza
|
||||
o data in <a href="/?tab=cont">Cont</a> si sunt folosite automat la trimitere. Optional,
|
||||
poti include <code>rar_credentials</code> in payload ca sa le suprascrii pe acea cerere.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{# Tab-list PRIMAR: limbaje #}
|
||||
|
||||
Reference in New Issue
Block a user