feat(5.20): US-001/002/003 schema medii per cont + disponibilitate + idempotenta env-aware
US-001: coloane accounts (rar_test/prod_enabled, rar_creds_test/prod_enc, rar_env_default) + submissions.rar_env; migrare cu backfill din ancora globala AUTOPASS_RAR_ENV (creds->slot, enabled doar pe mediul cu creds) + recompute idempotency_key env-aware (AUTO-FIX G + E4/3). US-002: app/rar_env.py — medii_disponibile + rar_env_efectiv (REQ-DISP/DEFAULT). US-003: build_key(account_id, canon, rar_env) — test vs prod = trimiteri distincte. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -70,17 +70,23 @@ def canonicalize_row(raw: dict[str, Any]) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
def build_key(account_id: int | None, canon: dict[str, Any]) -> str:
|
||||
"""SHA-256 partajat canal-API + canal-import.
|
||||
def build_key(account_id: int | None, canon: dict[str, Any], rar_env: str = "test") -> str:
|
||||
"""SHA-256 partajat canal-API + canal-import, env-aware (PRD 5.20 US-003).
|
||||
|
||||
Aplica account_or_default inainte de hash: None si 1 colapseaza la aceeasi
|
||||
cheie => acelasi rand logic din canale diferite nu se trimite de doua ori.
|
||||
|
||||
`rar_env` ('test'|'prod') intra in cheie: aceeasi prezentare la test si apoi la
|
||||
prod sunt DOUA trimiteri reale distincte (sisteme RAR separate), nu un duplicat.
|
||||
Default 'test' = back-compat cu apelantii care nu paseaza inca env-ul; toate
|
||||
rutele de ingestie paseaza env-ul rezolvat explicit.
|
||||
"""
|
||||
# Import local ca sa evitam import circular (mapping importa din idempotency via validator)
|
||||
from .mapping import account_or_default
|
||||
acct = account_or_default(account_id)
|
||||
canonic = {
|
||||
"account_id": acct,
|
||||
"rar_env": rar_env,
|
||||
"vin": canon.get("vin", ""),
|
||||
"nr_inmatriculare": canon.get("nr_inmatriculare", ""),
|
||||
"data_prestatie": canon.get("data_prestatie"),
|
||||
@@ -91,8 +97,8 @@ def build_key(account_id: int | None, canon: dict[str, Any]) -> str:
|
||||
return hashlib.sha256(blob.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def idempotency_key(account_id: int | None, prezentare: dict[str, Any]) -> str:
|
||||
"""SHA-256 peste (account_id + campurile semnificative ale prezentarii).
|
||||
def idempotency_key(account_id: int | None, prezentare: dict[str, Any], rar_env: str = "test") -> str:
|
||||
"""SHA-256 peste (account_id + rar_env + campurile semnificative ale prezentarii).
|
||||
|
||||
Wrapper backward-compat peste canonicalize_row + build_key.
|
||||
Exclude obs si b64Image (cosmetice, nu definesc unicitatea declaratiei).
|
||||
@@ -102,7 +108,7 @@ def idempotency_key(account_id: int | None, prezentare: dict[str, Any]) -> str:
|
||||
acoperite automat — dual-lookup sau recompute-keys la migrare productie.
|
||||
"""
|
||||
canon = canonicalize_row(prezentare)
|
||||
return build_key(account_id, canon)
|
||||
return build_key(account_id, canon, rar_env)
|
||||
|
||||
|
||||
def build_key_legacy(account_id: int | None, prezentare: dict[str, Any]) -> str:
|
||||
|
||||
Reference in New Issue
Block a user