# 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: ```bash # 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: ```bash 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: ```json { "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) ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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: ```bash # 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 ```