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:
| 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
- Fiecare "user" simulat trimite request-uri cu un user_id diferit
- Agent-v3 accepta user_id si user_email in body-ul requestului
- In staging, JWT nu este validat -- deci poti simula useri fara token-uri reale
- 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
- API keys LLM (OpenRouter, OpenAI, Groq) au rate limits proprii -- daca trimiti 50 analize simultan, vei primi erori 429 de la providerii LLM
- Modelul local Qwen Vision (10.11.10.17:14011) proceseaza secvential -- nu scala orizontal
- M17 Whisper (10.11.10.17:54300) -- un singur endpoint, probabil limitat
- Redis 512MB -- la volum mare de sesiuni simultane, verifica memoria
- 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