didi-lot2-backend/backend/production/API_TESTING_GUIDE.md
2026-07-10 03:39:53 -07:00

17 KiB

DIDI Platform - Ghid Testare API

Acest document descrie toate API-urile platformei DIDI, cum se testeaza, ce constrangeri au, si cum se pot simula mai multi utilizatori.


Arhitectura pe scurt

Client (browser/curl/script)
    |
    v
Kong API Gateway (port 443, HTTPS)
    |
    +-- agent-v3 (port 24803, analiza continut)
    +-- didiFramework (port 3005, CRUD parametri + utilizatori)
    +-- admin-dashboard (port 3000, SPA React)

In staging, agent-v3 este accesibil si direct pe localhost:24803 (bind 127.0.0.1). Framework-ul nu expune port extern -- accesibil doar prin Docker network sau admin dashboard.


Autentificare

JWT (Keycloak)

Platforma foloseste Keycloak pentru autentificare OAuth2/OIDC.

Obtinere token:

POST http://localhost:28000/realms/didi-clients/protocol/openid-connect/token
Content-Type: application/x-www-form-urlencoded

grant_type=password&client_id=didi-web-app&username=EMAIL&password=PAROLA

Utilizatori pre-existenti:

Email Parola Tier Credite
admin@didi.local admin123 admin nelimitat
demo@didi.local Demo123! free 100
free@didi.local password123 free 100
paid@didi.local password123 paid 100
enterprise@didi.local password123 enterprise nelimitat

Exemplu complet cu curl:

# Pas 1: Obtine token
TOKEN=$(curl -s -X POST \
  "http://localhost:28000/realms/didi-clients/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password&client_id=didi-web-app&username=admin@didi.local&password=admin123" \
  | jq -r '.access_token')

echo $TOKEN

# Pas 2: Foloseste token-ul
curl -H "Authorization: Bearer $TOKEN" https://localhost:443/api/...

Token-ul expira in 10 minute. Refresh la fiecare 30s cu refresh_token.

API Key (extensie browser)

Extensia Chrome foloseste un API key in loc de JWT:

POST /api/v3/pipeline/extension/analyze
Header: X-API-Key: didi_ext_...

Cheile se creeaza prin: POST /api/v3/pipeline/extension/keys (necesita JWT admin).

Endpoint-uri fara autentificare

In staging, agent-v3 NU valideaza JWT-ul pe requesturi directe (localhost:24803). Kong valideaza JWT-ul in productie, dar in staging plugin-ul JWT nu este activat.

Asta inseamna:

  • Accesand direct localhost:24803 -- NU ai nevoie de JWT (dar user_id/email sunt extrase din header daca exista)
  • Accesand prin Kong (port 443) in staging -- NU ai nevoie de JWT (JWT plugin dezactivat in declarative mode)
  • Accesand prin Kong in productie -- AI NEVOIE de JWT

Pentru testare multi-user, trimite manual headerele:

curl -X POST http://localhost:24803/api/v3/pipeline/analyze \
  -H "Content-Type: application/json" \
  -H "X-User-Id: test-user-1" \
  -H "X-User-Email: test1@test.com" \
  -d '{"text": "textul de analizat"}'

Endpoint-uri Agent V3 (port 24803)

Prefix: /api/v3

Health (fara auth, fara body)

GET /api/v3/health

Raspuns: {"service": "agent-v3", "version": "3.0.0", "status": "ok"}

Analiza text sincron (endpoint principal)

POST /api/v3/pipeline/analyze
Content-Type: application/json

{
  "text": "Textul de analizat. Minim 20 caractere, maxim 50000.",
  "user_id": "optional",
  "user_email": "optional"
}

Raspuns: AnalysisSession complet (techniques + ai_tampered + claims + domain + verdict). Durata: 15-120 secunde in functie de lungimea textului.

Analiza text asincrona (recomandata pentru stress test)

POST /api/v3/pipeline/analyze-async
Content-Type: application/json

{
  "text": "Textul de analizat",
  "plan_type": 1
}

Raspuns 202:

{
  "success": true,
  "async": true,
  "data": {
    "session_id": "uuid",
    "poll_url": "/api/v3/pipeline/uuid/queue-status",
    "result_url": "/api/v3/pipeline/uuid/result"
  }
}

Polling progres:

GET /api/v3/pipeline/{session_id}/queue-status

Raspuns rezultat final (cand status=completed):

GET /api/v3/pipeline/{session_id}/result

Analiza URL

POST /api/v3/pipeline/analyze-url
Content-Type: application/json

{
  "url": "https://example.com/articol",
  "user_id": "optional"
}

Detecteaza automat tipul: YouTube (video), imagine, articol.

Analiza media (imagine/audio/video)

POST /api/v3/pipeline/analyze-media
Content-Type: application/json

{
  "media_url": "https://didi365.eu/api/v3/media/file/uploads/...",
  "media_type": "image|audio|video",
  "user_id": "optional"
}

Inainte de analiza media, uploadeaza fisierul:

POST /api/v3/media/upload
Content-Type: multipart/form-data
Field: file (max 50MB)

Componente individuale

Analiza doar o singura componenta (util pentru testare granulara):

POST /api/v3/techniques/analyze         {"text": "..."}
POST /api/v3/ai-tampered/analyze        {"text": "..."}
POST /api/v3/claims/analyze             {"text": "..."}
POST /api/v3/domain/analyze             {"url": "https://..."}
POST /api/v3/source-assessment/analyze  {"text": "...", "url": "optional"}

Istoric

GET /api/v3/pipeline/history?user_id=USER&page=1&limit=20
GET /api/v3/pipeline/history/{session_id}
DELETE /api/v3/pipeline/history/{session_id}?user_id=USER

GET /api/v3/pipeline/history/admin?page=1&limit=20&search=&risk_level=&status=&from_date=&to_date=

Configurare (read-only, util pentru debug)

GET /api/v3/techniques/definitions      -- ierarhie tehnici
GET /api/v3/techniques/config           -- config completa
GET /api/v3/techniques/models           -- modele LLM disponibile
GET /api/v3/ai-tampered/config
GET /api/v3/ai-tampered/categories
GET /api/v3/claims/config
GET /api/v3/claims/types
GET /api/v3/claims/statuses
GET /api/v3/pipeline/verdict-config     -- config verdict
GET /api/v3/pipeline/queue-health       -- health RabbitMQ

Endpoint-uri didiFramework (port 3005, doar Docker network)

Pentru acces extern, foloseste admin dashboard (nginx proxiaza la /framework/).

Health

GET /health
GET /health/all     -- verifica si PostgreSQL si MinIO

Sync Redis (IMPORTANT)

POST /api/sync-redis         -- sincronizeaza toti parametrii in Redis
GET  /api/sync-redis/status  -- cand s-a facut ultima sincronizare

CRUD parametri (toate au GET, POST, PUT, DELETE)

/api/dimensions, /api/subdimensions, /api/techniques, /api/indicators, /api/validation-rules, /api/verdicts/categories, /api/verdicts/risk, /api/verdicts/severity, /api/weights/components, /api/weights/scenarios, /api/weights/multipliers, /api/platforms, /api/sources, /api/claims/status, /api/claims/types, /api/claims/confidence, /api/claims/interpretation, /api/providers/configs, /api/providers/models, /api/providers/assignments, /api/providers/keys

Utilizatori

GET  /api/admin/users?page=1&limit=20&search=&planId=
PUT  /api/admin/users/:id
DELETE /api/admin/users/:id
GET  /api/admin/plans
PUT  /api/admin/plans/:id

Credite (apelat intern de agent-v3)

POST /api/auth/internal/check-credits   {"keycloak_id": "..."}
POST /api/auth/internal/deduct-credits  {"keycloak_id": "...", "media_type": "text"}

Constrangeri si limite

Dimensiune text

Parametru Valoare
Minim text 20 caractere
Maxim text 50,000 caractere
Encoding UTF-8 valid

Dimensiune fisiere (upload)

Tip Limita
Imagine 20 MB
Audio 100 MB
Video 500 MB
Text 10 MB
Document 50 MB
Upload API 50 MB (multer)

Durata media

Tip Limita
Video 180s (3 min)
Audio 420s (7 min)

Request payload (Kong)

Maxim 100 MB per request (request-size-limiting plugin).

Timeout-uri

Ruta Timeout
/api/v3/pipeline/* 660s (11 min)
/*/analyze-media 300s (5 min)
Toate celelalte 180s (3 min)
Kong -> agent-v3 660s connect, 660s read

Rate Limiting (Kong)

Nivel Per minut Per ora Per zi
Global 100 2000 10,000

Rate limiting-ul Kong este per consumer (global in staging, nu per user). In staging, toti clientii sunt un singur consumer anonim.

Keycloak defineste rate limits per grup dar NU sunt aplicate inca in Kong:

  • free-users: 10/min
  • paid-users: 60/min
  • enterprise-users: 600/min

Credite (agent-v3 -> framework)

Fiecare analiza costa credite. Agent-v3 verifica la framework inainte de analiza. Costul depinde de media_type (text < image < audio < video). Daca user-ul nu are credite, raspunsul este 403.

Utilizatorii pre-configurati au credite initiale limitate (100 pentru free/paid). admin@didi.local si enterprise@didi.local au credite nelimitate.

CORS

Origins permise: localhost:3000, localhost:3001, localhost:8100, * (wildcard). Metode: GET, POST, PUT, DELETE, OPTIONS, PATCH. Credentials: activat.


Cum sa testezi

Test simplu (un request)

# Health check
curl http://localhost:24803/api/v3/health

# Analiza text (sincron, poate dura 30-60s)
curl -X POST http://localhost:24803/api/v3/pipeline/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "Vaccinurile COVID au fost create de Bill Gates pentru a implanta cipuri 5G in populatie. Studiile arata ca milioane de oameni au fost afectati."}'

# Analiza asincrona (raspuns instant, polling pentru rezultat)
curl -X POST http://localhost:24803/api/v3/pipeline/analyze-async \
  -H "Content-Type: application/json" \
  -d '{"text": "Vaccinurile COVID au fost create de Bill Gates.", "plan_type": 1}'

Test cu JWT prin Kong

# Obtine token
TOKEN=$(curl -s -X POST \
  "http://localhost:28000/realms/didi-clients/protocol/openid-connect/token" \
  -d "grant_type=password&client_id=didi-web-app&username=admin@didi.local&password=admin123" \
  | jq -r '.access_token')

# Analiza prin Kong (productie path)
curl -k -X POST https://localhost:443/api/analyze \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "Text de test pentru analiza."}'

Test componenta individuala

# Doar techniques
curl -X POST http://localhost:24803/api/v3/techniques/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "Textul de analizat aici"}'

# Doar claims
curl -X POST http://localhost:24803/api/v3/claims/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "Romania are 20 milioane de locuitori si PIB-ul a crescut cu 15% anul trecut."}'

# Doar AI detection
curl -X POST http://localhost:24803/api/v3/ai-tampered/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "This text was definitely written by a human and not an AI."}'

Test upload media + analiza

# Upload imagine
UPLOAD=$(curl -s -X POST http://localhost:24803/api/v3/media/upload \
  -F "file=@/path/to/image.jpg" \
  -F "user_id=test-user")
echo $UPLOAD

# Extrage URL-ul
MEDIA_URL=$(echo $UPLOAD | jq -r '.data.public_url')

# Analiza imagine
curl -X POST http://localhost:24803/api/v3/pipeline/analyze-media \
  -H "Content-Type: application/json" \
  -d "{\"media_url\": \"$MEDIA_URL\", \"media_type\": \"image\"}"

Testare multi-user

Strategia

  1. Fiecare "user" simulat trimite request-uri cu un user_id diferit
  2. Agent-v3 accepta user_id si user_email in body-ul requestului
  3. In staging, JWT nu este validat -- deci poti simula useri fara token-uri reale
  4. Pentru teste realiste (cu credite, cu token), foloseste utilizatorii Keycloak

Ce trebuie stiut

  • Analiza sincrona blocheaza conexiunea 15-120 secunde
  • Analiza asincrona returneaza instant si workerii proceseaza in background
  • RabbitMQ are 24 cozi: 4 componente x 6 plan types
  • Workeri: 2 techniques, 2 ai-tampered, 3 claims, 2 domain, 2 media-preprocess, 2 aggregators
  • Fiecare worker proceseaza un singur mesaj la un moment dat (prefetch 3-10 in functie de componenta)
  • Claims este cel mai lent (cautare web per claim, 3 replici)
  • Domain este cel mai rapid (analiza locala, fara LLM)
  • Modelele LLM externe (OpenRouter, OpenAI, Groq) au propriile rate limits

Throughput estimat

Plan type Ce se intampla
1 (free) Prioritate minima in coada
6 (enterprise) Prioritate maxima in coada

Cu 2 workers techniques si prefetch 5, poti procesa ~10 analize text simultane. Claims este bottleneck: 3 workers x prefetch 3 = ~9 analize simultane. Video/audio sunt mult mai lente (transcriere + viziune): 1-5 minute per analiza.

Endpoint recomandat pentru stress test

Foloseste analiza asincrona:

POST /api/v3/pipeline/analyze-async
{"text": "...", "plan_type": 1}

Avantaje:

  • Raspuns instant (202 Accepted)
  • Workerii proceseaza in paralel
  • Poti monitoriza progresul individual per sesiune
  • Nu blocheaza conexiunea HTTP

Polling status:

GET /api/v3/pipeline/{session_id}/queue-status

Bottleneck-uri de monitorizat

Resursa Cum verifici
RabbitMQ http://localhost:15672 (admin/rabbitmq123)
Redis memorie docker exec didi-cache redis-cli -a redis123 info memory
Workers activi docker ps --filter name=agent-v3-worker
PG conexiuni Prin PgAdmin http://localhost:5050
Cozi pline RabbitMQ UI -> Queues -> Ready messages

Limitari stress test

  1. API keys LLM (OpenRouter, OpenAI, Groq) au rate limits proprii -- daca trimiti 50 analize simultan, vei primi erori 429 de la providerii LLM
  2. Modelul local Qwen Vision (10.11.10.17:14011) proceseaza secvential -- nu scala orizontal
  3. M17 Whisper (10.11.10.17:54300) -- un singur endpoint, probabil limitat
  4. Redis 512MB -- la volum mare de sesiuni simultane, verifica memoria
  5. PostgreSQL cluster -- in general nu este bottleneck, dar verifica conexiunile active

Chei Redis pentru monitoring

# Sesiuni active
docker exec didi-cache redis-cli -a redis123 keys "didi:pipeline:*:status" | wc -l

# Lock-uri active (workeri in procesare)
docker exec didi-cache redis-cli -a redis123 keys "didi:queue:lock:*" | wc -l

# Framework config (trebuie sa existe mereu)
docker exec didi-cache redis-cli -a redis123 keys "didi:framework:*"

Structura raspuns AnalysisSession

Orice analiza completa returneaza acest format:

session_id          -- UUID unic
status              -- running | completed | failed
input_type          -- text | url | image | audio | video
risk_score          -- 0-100 (scor final)
risk_category       -- RELIABLE | MOSTLY_RELIABLE | MIXED | UNRELIABLE | DISINFORMATION | INCONCLUSIVE
risk_level          -- VERY_LOW | LOW | MODERATE | HIGH | VERY_HIGH | CRITICAL
confidence          -- 0-100
total_duration_ms   -- milisecunde

techniques.manipulation_score    -- 0-100
ai_tampered.ai_probability      -- 0-100
claims.credibility_score         -- 0-100 (null daca nu sunt claims)
domain.trust_score               -- 0-100 (null daca nu exista URL)
verdict.risk_score               -- 0-100 (identic cu root risk_score)
verdict.explanation_ro            -- explicatie in romana
verdict.explanation_en            -- explicatie in engleza

Coduri eroare frecvente

Cod Cauza Solutie
400 Text prea scurt (<20 chars) sau invalid Mareste textul
400 media_type invalid sau lipsa Verifica parametrii
403 Credite insuficiente Foloseste admin@didi.local
408 Timeout (analiza prea lenta) Foloseste analyze-async
413 Payload prea mare (>100MB) Micoreaza fisierul
429 Rate limit Kong Asteapta 1 minut
500 Eroare interna (LLM, Redis, PG) Verifica logs: docker logs didi-agent-v3
502 Serviciu backend indisponibil Verifica ca agent-v3 ruleaza
504 Gateway timeout Analiza dureaza prea mult

Verificare rapida ca totul functioneaza

Aceste comenzi, in ordine, confirma ca platforma este operationala:

# 1. Health agent-v3
curl -s http://localhost:24803/api/v3/health | jq .

# 2. Config exista in Redis (trebuie sa fie non-null)
curl -s http://localhost:24803/api/v3/techniques/definitions | jq '.dimensions | length'

# 3. Analiza text rapida (30-60s)
curl -s -X POST http://localhost:24803/api/v3/techniques/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "Studiile demonstreaza ca pamantul este plat si NASA ne minte de decenii. Milioane de oameni au descoperit adevarul."}' | jq '{manipulation_score, techniques_count}'

# 4. Analiza completa (60-120s)
curl -s -X POST http://localhost:24803/api/v3/pipeline/analyze \
  -H "Content-Type: application/json" \
  -d '{"text": "Studiile demonstreaza ca pamantul este plat si NASA ne minte de decenii. Milioane de oameni au descoperit adevarul."}' | jq '{risk_score, risk_category, confidence}'

# 5. RabbitMQ functional (trebuie sa fie cozi)
curl -s -u admin:rabbitmq123 http://localhost:15672/api/queues | jq '.[].name' | head -10