"""Router integrare US-001 — endpoint-uri de integrare externe. Endpointuri: GET /v1/ping — readiness check per cont (autentificat sau dev fallback) GET /v1/integrare/postman.json — export colectie Postman v2.1.0 Ruta /v1/ping foloseste `resolve_account_id` (dependinta standard) pentru 401 pe cheie invalida / prod fara cheie. Flag-ul `autentificat_cu_cheie` e derivat separat citind header-ele brute si verificand cheia real-time (fara sa dubleze logica de 401 — aceea ramane in `resolve_account_id`). """ from __future__ import annotations from datetime import datetime, timezone from fastapi import APIRouter, Depends, Header from fastapi.responses import JSONResponse from ...auth import _extract_key, account_for_key, resolve_account_id from ...config import get_settings from ...db import get_connection from ...mapping import account_or_default router = APIRouter(prefix="/v1", tags=["integrare"]) @router.get("/ping") def ping( account_id: int = Depends(resolve_account_id), x_api_key: str | None = Header(default=None, alias="X-API-Key"), authorization: str | None = Header(default=None), ) -> JSONResponse: """Readiness check per cont. Intoarce: account_id — contul rezolvat din cheie (sau 1 in dev fara cheie) mediu — "test" / "prod" (settings.rar_env) autentificat_cu_cheie — True daca cererea a venit cu o cheie API reala valida are_creds_rar — True daca contul are rar_creds_enc stocat ts — timestamp ISO UTC al cererii """ settings = get_settings() # Detectam daca s-a folosit o cheie reala (nu fallback dev). # `resolve_account_id` a garantat deja ca nu e cheie invalida (ar fi dat 401). # Acum verificam doar daca exista o cheie extrasa si daca e valida pentru cont. cheie_bruta = _extract_key(x_api_key, authorization) autentificat_cu_cheie = False if cheie_bruta: conn = get_connection() try: acct = account_for_key(conn, cheie_bruta) finally: conn.close() autentificat_cu_cheie = acct is not None # Verificam daca contul are creds RAR stocate. aid = account_or_default(account_id) conn = get_connection() try: row = conn.execute( "SELECT rar_creds_enc FROM accounts WHERE id=?", (aid,) ).fetchone() finally: conn.close() are_creds_rar = bool(row and row["rar_creds_enc"]) return JSONResponse({ "account_id": aid, "mediu": settings.rar_env, "autentificat_cu_cheie": autentificat_cu_cheie, "are_creds_rar": are_creds_rar, "ts": datetime.now(timezone.utc).isoformat(), }) # Allowlist hardcodat (NU derivat din app.routes) — cele 3 rute de integrare expuse extern. _POSTMAN_ITEMS = [ { "name": "Trimite prezentari", "request": { "method": "POST", "header": [ {"key": "X-API-Key", "value": "{{api_key}}"}, {"key": "Content-Type", "value": "application/json"}, ], "url": { "raw": "{{base_url}}/v1/prezentari", "host": ["{{base_url}}"], "path": ["v1", "prezentari"], }, "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' ' "prezentari": [\n' ' {\n' ' "vin": "WVWZZZ1KZAW000123",\n' ' "nr_inmatriculare": "B999TST",\n' ' "data_prestatie": "2026-06-15",\n' ' "odometru_final": "123456",\n' ' "prestatii": [\n' ' {"cod_prestatie": "OE-1"}\n' ' ]\n' ' }\n' ' ]\n' '}' ), }, }, }, { "name": "Import fisier (xlsx/csv)", "request": { "method": "POST", "header": [ {"key": "X-API-Key", "value": "{{api_key}}"}, ], "url": { "raw": "{{base_url}}/v1/import", "host": ["{{base_url}}"], "path": ["v1", "import"], }, "body": { "mode": "formdata", "formdata": [ { "key": "file", "type": "file", "description": "Fisier xlsx sau csv cu prezentarile de importat", } ], }, }, }, { "name": "Ping (readiness check)", "request": { "method": "GET", "header": [ {"key": "X-API-Key", "value": "{{api_key}}"}, ], "url": { "raw": "{{base_url}}/v1/ping", "host": ["{{base_url}}"], "path": ["v1", "ping"], }, }, }, ] @router.get("/integrare/postman.json") def postman_export() -> JSONResponse: """Export colectie Postman v2.1.0 cu cele 3 rute de integrare. Allowlist hardcodat — NU deriva din app.routes pentru a nu expune rute interne (ex. /v1/conturi/rar-creds, rutele web etc.). """ colectie = { "info": { "name": "RAR AUTOPASS Gateway", "description": ( "Colectie de integrare pentru gateway-ul RAR AUTOPASS (Legea 142/2023, OM 210/2024). " "Seteaza variabilele `base_url` si `api_key` inainte de utilizare." ), "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", }, "variable": [ {"key": "base_url", "value": "http://localhost:8010", "type": "string"}, {"key": "api_key", "value": "", "type": "string"}, ], "item": _POSTMAN_ITEMS, } return JSONResponse(content=colectie, media_type="application/json")