didi-lot2-backend/backend/admin-dashboard/INDEX.md
2026-07-10 03:39:53 -07:00

46 KiB

admin-dashboard - Index

Dashboard administrativ pentru platforma DIDI. Aplicatie React SPA (Single Page Application) cu Material UI, montata la /admin. Ofera interfata grafica pentru managementul complet al platformei: monitorizare servicii, configurare framework analiza, management utilizatori, configurare modele LLM, vizualizare si executie pipeline-uri, si istoric analize.

Stack: React 19 + TypeScript + Material UI 7 + React Router 7 Container: didi-admin-local (nginx) -- porturi host 3081 -> 80 (HTTP) si 3001 -> 443 (HTTPS) Port intern: 80/443 (nginx) Basename: /admin (toate rutele prefixate cu /admin) Autentificare: Keycloak (client admin-dashboard, PKCE S256, realm didi-admins), Keycloak LOCAL didi-keycloak servit sub /auth prin nginx-ul dashboard-ului Build: node:20-alpine (build) -> nginx:alpine (serve) Network: didi-network (single unified network for all DIDI + AI platform stacks since 2026-05-04)

URL-uri de acces

URL Cum funcționează
https://<host-local>:3001/admin/ direct la containerul didi-admin-local (nginx HTTPS, port host 3001)
http://<host-local>:3081/admin/ direct la containerul didi-admin-local (nginx HTTP, port host 3081)
https://didi365.eu/admin/ public via Cloudflare tunnel + frontend nginx (când Cloudflare permite path)
https://didi365.eu/admin-backend/ public alias 301 → /admin/

<host-local> = mașina de deployment (host-ul local). Containerul didi-admin-local are propria nginx (porturi host 3081/3001); frontend didi-frontend adaugă proxy /admin/*. Detalii: frontend/INDEX.md secțiunea 21.


Ce face

  1. Monitorizare servicii -- health check pentru toate 14 serviciile backend (polling 30s)
  2. Configurare framework analiza -- CRUD complet pe 20+ tabele de parametri (dimensiuni, tehnici, indicatori, verdicte, ponderi, surse, claims)
  3. Management utilizatori -- lista, cautare, editare, stergere, sincronizare Keycloak, management planuri abonament
  4. Configurare modele LLM -- provideri, modele, assignments pe componente/etape, chei API, teste conectivitate
  5. Istoric analize -- vizualizare si stergere sesiuni analiza din agent-v3 (filtre: risk, status, date)
  6. Pipeline builder -- editor vizual DAG (ReactFlow) pentru pipeline-uri de analiza
  7. Executie si monitorizare -- lansare pipeline-uri, tracking progres real-time (WebSocket + polling)
  8. Catalog componente -- registry pentru functii, resurse AI, transformatoare, modele LLM
  9. Sincronizare Redis -- trigger manual sync parametri framework -> Redis (pentru agent-v3)

Rute (App.tsx)

Toate rutele sunt protejate cu ProtectedRoute (verifica autentificare Keycloak).

Path (relativ la /admin) Componenta Scop
/ ServicesDashboard Landing page: monitorizare health servicii
/dashboard ServicesDashboard Alias pentru /
/login LoginRedirect Trigger Keycloak login
/orchestrator OrchestratorDashboard Pipeline builder + catalog + executie + istoric
/orchestrator/runs/:runId RunDetailsPage Detalii run individual (timeline, I/O, raw)
/pipelines PipelinesPage NEW — CRUD + lifecycle pipeline-uri reale (input_type_profile) + dry-run/cancel (Modul 1); admin-only
/analysis UniversalAnalysisDashboard Executie analiza multi-modal (text/image/video/audio/URL)
/analysis/results/:runId UniversalResultsPage Rezultate live cu polling
/framework FrameworkDashboard CRUD complet parametri framework DIDI
/framework/progressive ProgressiveAnalysisTree Vizualizare arbore analiza progresiva
/users UserManagement Management utilizatori + planuri abonament
/history AnalysisHistory Istoric sesiuni analiza admin
/providers ProvidersManagement CRUD provideri LLM, modele, assignments, chei API
/techniques-v3 TechniquesV3Config Configurare modele pe etape techniques
/llm-components LLMComponentsConfig Configurare unificata LLM (Techniques + AI-Tampered + Claims + Verdict)
/text-analysis UniversalAnalysisDashboard Legacy (randeaza direct, nu redirect)
/image-analysis UniversalAnalysisDashboard Legacy (randeaza direct, nu redirect)
/video-analysis UniversalAnalysisDashboard Legacy (randeaza direct, nu redirect)
/audio-analysis UniversalAnalysisDashboard Legacy (randeaza direct, nu redirect)
/moderation ModerationQueue Lista pending HIL review queue cu filtre + paginatie
/moderation/:queueId ModerationDetail Detalii sesiune + Resolve dialog (action + corrections JSON + notes)
/moderation/stats ModerationStats Cards count (pending, in_review, resolved_24h) + by-priority + avg time
/unauthorized Unauthorized 403 page pentru useri fara rol staff

Structura fisiere

admin-dashboard/
  Dockerfile                    -- Multi-stage: node:20-alpine build -> nginx:alpine
  Dockerfile.dev                -- Dev build
  nginx.conf                    -- Nginx dev (port 80)
  nginx-ssl.conf                -- Nginx productie (HTTPS 443 + HTTP 80)
  package.json                  -- React 19, MUI 7, ReactFlow, Recharts, Keycloak JS
  .env                          -- REACT_APP_KEYCLOAK_URL, STAGING_MODE=false
  src/
    App.tsx                     -- Router principal (toate rutele) + AuthProvider + ThemeProvider
    index.tsx                   -- Entry point (randeaza App)
    services/
      api.ts                    -- Client API principal (axios, 100+ endpoint-uri)
      analysisService.ts        -- Serviciu analiza legacy (submit/status/results)
      keycloak.ts               -- Configurare Keycloak JS adapter
    contexts/
      AuthContext.tsx            -- Provider autentificare (token refresh 30s, logout pe 401)
      ThemeContext.tsx           -- Provider tema dark/light (persistat in localStorage)
    hooks/
      useAnalysisResults.ts     -- Rezultate analiza cu auto-refresh
      useRunsHistory.ts         -- Istoric run-uri paginat cu filtre
      usePipelineProgress.ts    -- WebSocket progres pipeline real-time
      useDeleteDialog.ts        -- Dialog confirmare stergere generic
      useExpandedItems.ts       -- Stare accordion expandat
      useTabState.ts            -- Stare tab per item
    pages/
      LandingPage.tsx           -- Pagina marketing (nefolosita in rute)
      FrameworkDashboard.tsx    -- CRUD framework (20+ tabele)
      OrchestratorDashboard.tsx -- Pipeline builder + catalog
      RunDetailsPage.tsx        -- Detalii run (3 tab-uri)
      UniversalAnalysisDashboard.tsx -- Executie analiza multi-modal
      UniversalResultsPage.tsx  -- Rezultate live polling
      AudioAnalysisDashboard.tsx -- Legacy
      ImageAnalysisDashboard.tsx -- Legacy
      TextAnalysisDashboard.tsx  -- Legacy
      VideoAnalysisDashboard.tsx -- Legacy
      CostDashboard/            -- Dashboard costuri LLM (orfan, nerutuit)
    components/
      auth/
        LoginRedirect.tsx       -- Redirect la Keycloak login
        ProtectedRoute.tsx      -- Guard autentificare pe rute (suporta requiredAnyRole?: string[] any-of)
        Unauthorized.tsx        -- NEW: 403 page cu lista roluri + "Go to Public App" + "Log out"
      dashboard/
        ServicesDashboard.tsx   -- Grid servicii cu health check
      services/
        ServiceCard.tsx         -- Card individual serviciu
      framework/
        CrudDataTable.tsx       -- Tabel CRUD generic (GET/POST/PUT/DELETE)
        TechniquesTreeView.tsx  -- Arbore tehnici
        ProgressiveAnalysisTree.tsx -- Arbore analiza progresiva
        AnalysisFlowVisualization/ -- Vizualizare ReactFlow DAG framework
      orchestrator/
        PipelineBuilder.tsx     -- Editor vizual DAG (ReactFlow)
        PipelineManager.tsx     -- Lista + CRUD pipeline-uri
        PipelineList.tsx        -- Lista pipeline-uri
        PipelineExecutor.tsx    -- Executor pipeline cu polling 500ms
        ComponentRegistry.tsx   -- Catalog componente (functii, resurse, transformatoare)
        benchmark/
          PipelineBenchmark.tsx -- Executie si monitorizare benchmark
          useBenchmarkRunner.ts -- Hook benchmark (execute + poll)
        runs-history/
          RunsHistoryPage.tsx   -- Istoric run-uri paginat
          RunsHistoryTable.tsx  -- Tabel run-uri
          RunDetailsDrawer.tsx  -- Drawer detalii run
          NodeWaterfallTimeline.tsx -- Timeline executie noduri
        nodes/, edges/, dialogs/, hooks/ -- Sub-componente pipeline builder
      Pipelines/                -- NEW (Modul 1)
        PipelinesPage.tsx       -- Tabel pipeline-uri reale (input_type_profile) + lifecycle (clone/activate/versions/restore/import/export)
        DryRunDialog.tsx        -- Run Console-lite: dry-run pe agent-v3 (flow + noduri + verdict profile, fara executie reala)
        pipelinesApi.ts         -- Client catre /framework/api/pipelines + /agent-v3/api/v3/pipeline/dry-run|cancel
      UserManagement/
        UserManagement.tsx      -- Tab utilizatori + planuri
        UserEditModal.tsx       -- Dialog editare utilizator
      AnalysisHistory/
        AnalysisHistory.tsx     -- Tabel istoric sesiuni analiza
        AnalysisDetailModal.tsx -- Modal detalii sesiune
      ProvidersManagement/
        ProvidersManagement.tsx -- CRUD 4 tabele: provideri, modele, assignments, chei
      TechniquesV3/
        TechniquesV3Config.tsx  -- Configurare modele techniques
      LLMComponentsConfig/
        index.tsx               -- Config unificata 3 componente + verdict + provideri
        VerdictConfig.tsx       -- Configurare verdict (ponderi, categorii, severitate)
      Moderation/               -- NEW
        api.ts                  -- fetch helpers + types + UI helpers (priorityColor, statusColor)
        ModerationQueue.tsx     -- paginated table + filters (status, priority), auto-refresh 30s pe pending tab
        ModerationDetail.tsx    -- back btn + action buttons (Claim/Approve/Resolve corrected/Reject) + side-by-side cards (Input + AI Verdict) + Resolve dialog cu JSON corrections editor
        ModerationStats.tsx     -- 3 stat cards + by-priority chips + avg time
      ModerationSettings/       -- NEW
        index.tsx               -- main panel cu 4 cards + auto-sync after save
        TriageCard.tsx          -- toggle, slider confidence_low, TextFields risk_grey + queue thresholds
        BrainClientCard.tsx     -- toggle, URL, timeouts, sliders confidence_min_silver + semantic_threshold, per-component checkboxes (techniques/ai_tampered/claims). Include alert "CLIENT settings only -- server config in AI platform"
        SensitiveTopicsCard.tsx -- chip list cu delete + add form (code regex validation)
        RolesCard.tsx           -- table cu toggles (can_resolve, can_escalate, can_force_gold_brain, is_active)
        api.ts                  -- fetch helpers pentru /api/moderation-config, /api/sensitive-topics, /api/moderation-roles + sync-redis trigger
      text-analysis/            -- Componente analiza text legacy
      image-analysis/           -- Componente analiza imagini legacy
      audio-analysis/           -- Componente analiza audio legacy
      video-analysis/           -- Componente analiza video legacy
    config/
      serviceGroups.ts          -- Definitie grupuri servicii sidebar
      providerConfigs.ts        -- Configurare provideri LLM
    theme/
      index.ts                  -- Tema MUI (light/dark, culori, tipografie)
    types/
      catalog.ts                -- Tipuri catalog componente
      keycloak.d.ts             -- Tipuri Keycloak

Servicii backend consumate

Aplicatia nu are backend propriu. Toate datele vin prin nginx reverse proxy de la 3 servicii + health checks directe.

1. didiFramework (proxiat la /framework)

Nginx: /framework/ -> http://didi-framework:3005

Folosit de: FrameworkDashboard, UserManagement, ProvidersManagement, LLMComponentsConfig, VerdictConfig

2. agent-v3 (proxiat la /agent-v3)

Nginx: /agent-v3/ -> http://didi-agent-v3:24803

Folosit de: AnalysisHistory, TechniquesV3Config, LLMComponentsConfig, ServicesDashboard (health)

3. Orchestrator API (proxiat la /api/v1 prin Kong)

Nginx: /api/ -> http://didi-kong:8000 (Kong LOCAL)

Folosit de: OrchestratorDashboard, UniversalAnalysisDashboard, ComponentRegistry, PipelineManager, RunsHistory, CostDashboard

4. Health checks directe

Nginx proxiaza catre containere individuale pentru verificare disponibilitate.


Endpoint-uri API consumate

Health checks (ServicesDashboard, polling 30s)

Metoda Endpoint Serviciu verificat
GET /framework/ didiFramework
GET /agent-v3/api/v3/health agent-v3
GET /api/status Kong
GET /auth/realms/didi-admins Keycloak (local didi-keycloak)
GET /health-check/redis-commander Redis Commander
GET /health-check/rabbitmq RabbitMQ Management
GET /health-check/minio MinIO
GET /health-check/pgadmin pgAdmin

Framework CRUD (FrameworkDashboard, baza /framework)

Fiecare endpoint suporta GET (lista), POST (creare), PUT /{id} (update), DELETE /{id} (stergere). Implementat prin componenta generica CrudDataTable.

Categorie Endpoint-uri
Analysis Core /api/dimensions, /api/subdimensions
Tehnici /api/techniques, /api/indicators, /api/validation-rules
Evaluare Sursa /api/platforms, /api/platform-modifiers, /api/source-credibility, /api/domain-age-scores, /api/domain-risk-levels, /api/domain-red-flags, /api/author-classifications, /api/author-credibility
Claims /api/claims/status, /api/claims/types, /api/claims/confidence, /api/claims/interpretation
Verdicte /api/verdicts/categories, /api/verdicts/risk, /api/verdicts/severity
Ponderi /api/weights/components, /api/weights/scenarios, /api/weights/multipliers
Provideri /api/providers/configs, /api/providers/models, /api/providers/assignments, /api/providers/keys

Extra:

Metoda Endpoint Scop
GET /api/overview/stats Statistici framework
GET /api/sync-redis/status Status ultima sincronizare
POST /api/sync-redis Trigger sincronizare Redis

Management utilizatori (UserManagement, baza /framework)

Metoda Endpoint Scop
GET /api/admin/users?page=&limit=&search=&planId= Lista utilizatori paginata cu filtre
GET /api/admin/plans Lista planuri abonament
DELETE /api/admin/users/:id Dezactivare utilizator
PUT /api/admin/users/:id/email-verified Toggle email verificat
POST /api/admin/users/sync Sincronizare utilizatori Keycloak -> PostgreSQL
PUT /api/admin/plans/:id Editare plan (nume, descriere, credite, pret)

Istoric analize admin (AnalysisHistory, baza /agent-v3/api/v3)

Metoda Endpoint Scop
GET /pipeline/history/admin?page=&limit=&search=&risk_level=&status=&from_date=&to_date= Lista sesiuni cu filtre
GET /pipeline/history/admin/:sessionId Detalii sesiune
DELETE /pipeline/history/admin/:sessionId Stergere sesiune

Configurare modele LLM (TechniquesV3Config + LLMComponentsConfig, baza /agent-v3/api/v3)

Metoda Endpoint Scop
GET /{component}/config Configurare componenta
GET /{component}/models Modele disponibile
GET /{component}/stage-assignments Assignments pe etape
PUT /{component}/stage-assignments Salvare assignments
POST /{component}/test-model Test conectivitate model
POST /{component}/analyze Test analiza (doar techniques)
GET /{component}/prompts Lista prompturi componenta
PUT /{component}/prompts/:id Update prompt

Unde {component} = techniques, ai-tampered, claims.

Moderation queue (ModerationQueue + Detail + Stats, baza /agent-v3/api/v3/moderation)

Metoda Endpoint Scop
GET /queue?status=&priority=&assigned_to=me&limit=20&offset=0 Lista paginata cu filtre
GET /queue/:queueId Detail (queue entry + full session JOIN)
POST /queue/:queueId/claim Atomic claim by current moderator
PUT /queue/:queueId/resolve body: {action, corrections?, notes?, user_id?}
POST /flag User report (browser extension)
GET /stats Counts + averages

Moderation Settings (ModerationSettings, baza /framework/api)

Metoda Endpoint Scop
GET /moderation-config Single-row config
PUT /moderation-config Update whitelisted fields
GET /sensitive-topics?active=all List topics
POST /sensitive-topics Create topic
PUT /sensitive-topics/:id Update label/is_active
DELETE /sensitive-topics/:id Soft delete
GET /moderation-roles List roles
PUT /moderation-roles/:code Update permission toggles

Provideri LLM (ProvidersManagement, baza /framework/api/providers)

Metoda Endpoint Scop
GET /all Toti providerii cu modele
POST /configs Creare provider
PUT /configs/:id Update provider
DELETE /configs/:id Stergere provider
POST /models Creare model
PUT /models/:id Update model
DELETE /models/:id Stergere model
POST /assignments Creare assignment
PUT /assignments/:id Update assignment
DELETE /assignments/:id Stergere assignment
POST /keys Creare cheie API
PUT /keys/:id Update cheie
DELETE /keys/:id Stergere cheie
POST /test/:providerId Test conexiune provider
GET /prompts?component={comp} Lista prompturi componenta
PUT /prompts/:id Update prompt

Orchestrator - Catalog componente (ComponentRegistry, baza /api/v1/catalog)

Metoda Endpoint Scop
GET /functions/ Lista feature extractors
GET /resources/ Lista resurse AI
GET /transformers/ Lista transformatoare
GET /models/ Lista modele LLM
GET /models/filters/options Optiuni filtre modele
POST /{type}/ Creare componenta
PUT /{type}/:id Update componenta
DELETE /{type}/:id Stergere componenta
PATCH /{type}/:id Toggle enabled/disabled

Orchestrator - Pipeline-uri (PipelineManager, baza /api/v1/pipelines)

Metoda Endpoint Scop
GET / Lista pipeline-uri
GET /:id Detalii pipeline
POST / Creare pipeline
PUT /:id Update pipeline
DELETE /:id Stergere pipeline
GET /:id/versions Lista versiuni
POST /:id/versions Creare versiune
GET /:id/preview Preview executie
POST /:id/execute Executie pipeline
POST /:id/versions/:ver/execute Executie versiune specifica

Orchestrator - Run-uri (RunsHistory + RunDetailsPage, baza /api/v1/runs)

Metoda Endpoint Scop
GET ?limit=&offset=&status=&date_from= Lista run-uri cu filtre
GET /:runId Detalii run
GET /:runId?include_live_status=true Detalii cu status live
GET /:runId/results?include_intermediate=true Rezultate complete
GET /status/:runId Status polling
GET /list?limit= Lista run-uri (analysisResults)
GET /history/enriched?skip=&limit=&pipeline_slug=&verdict= Istoric imbogatit cu filtre
DELETE /:runId Stergere run

Orchestrator - Template-uri si API-uri externe

Metoda Endpoint Scop
GET/POST/PUT/DELETE /api/v1/dynamic-templates/templates CRUD template-uri
GET /api/v1/dynamic-templates/templates/tasks/list Lista task-uri
GET /api/v1/dynamic-templates/templates/external-apis/list Lista API-uri externe
GET /api/v1/dynamic-templates/templates/feature-extractors/list Lista extractori
GET/POST/PUT/DELETE /api/v1/task-templates CRUD task template-uri
POST /api/v1/task-templates/:id/validate Validare template
POST /api/v1/task-templates/:id/test Test template
POST /api/v1/task-templates/:id/execute Executie template
GET /api/v1/external-apis/providers Lista provideri externi
GET/POST/PUT/DELETE /api/v1/external-apis/apis CRUD API-uri externe
POST /api/v1/sync/openapi/discover Descoperire OpenAPI
POST /api/v1/sync/openapi/import Import servicii descoperite
GET /api/v1/catalog/litellm-catalogue Catalog LiteLLM

Costuri LLM (CostDashboard -- pagina orfana, nerutata)

Metoda Endpoint Scop
GET /api/v1/costs/summary?start_date=&end_date=&period= Sumar costuri
GET /api/v1/costs/by-model?start_date=&end_date= Costuri per model
GET /api/v1/costs/by-job?start_date=&end_date= Costuri per job
GET /api/v1/costs/thresholds Praguri configurate
GET /api/v1/costs/alerts Alerte active
POST /api/v1/costs/thresholds Creare prag
DELETE /api/v1/costs/thresholds/:id Stergere prag
PUT /api/v1/costs/alerts/:id/acknowledge Confirmare alerta

WebSocket (progres real-time)

Endpoint Scop
wss://{host}/ws/runs/:runId/progress?include_outputs=true Progres executie pipeline

Mesaje WebSocket: connected, node_status (update per nod), run_complete, error. Reconnect cu exponential backoff: 1s -> 2s -> 4s -> ... -> 30s max.


Pagini -- ce face fiecare

ServicesDashboard (/, /dashboard)

Grid cu carduri pentru toate serviciile grupate pe layere (Data, Gateway/Auth, Orchestration, Monitoring). Fiecare card face health check la 30s si afiseaza status (verde/rosu). Sidebar cu navigare catre paginile admin (Providers, Users, History -- vizibile doar cu rol admin).

Logica: src/components/dashboard/ServicesDashboard.tsx + src/components/services/ServiceCard.tsx Configurare servicii: src/config/serviceGroups.ts (14 servicii in 4 grupuri)

FrameworkDashboard (/framework)

Management CRUD complet pentru parametrii framework-ului de analiza. 7 categorii cu sub-tab-uri, fiecare cu tabel editabil (CrudDataTable). Include vizualizare ReactFlow a fluxului de analiza si buton "Sync to Redis" pentru a trimite parametrii catre Redis (agent-v3 ii citeste de acolo).

Logica: src/pages/FrameworkDashboard.tsx (orchestrare tab-uri) Tabel generic: src/components/framework/CrudDataTable.tsx (GET/POST/PUT/DELETE pe orice endpoint) Vizualizare: src/components/framework/AnalysisFlowVisualization/

OrchestratorDashboard (/orchestrator)

Sidebar cu 2 sectiuni: Component Registry (Extractori, Componente AI, Transformatoare) si Pipelines (Lista, Creare, Executie, Istoric). Fiecare sectiune randeaza componenta corespunzatoare.

Logica: src/pages/OrchestratorDashboard.tsx (layout sidebar) Pipeline builder: src/components/orchestrator/PipelineBuilder.tsx (editor ReactFlow DAG) Pipeline manager: src/components/orchestrator/PipelineManager.tsx (lista + CRUD) Catalog: src/components/orchestrator/ComponentRegistry.tsx (tabele + dialoguri CRUD) Benchmark: src/components/orchestrator/benchmark/PipelineBenchmark.tsx (executie + monitorizare) Istoric: src/components/orchestrator/runs-history/RunsHistoryPage.tsx (tabel paginat + filtre)

RunDetailsPage (/orchestrator/runs/:runId)

Detalii complete pentru un run individual. 3 tab-uri: Timeline (waterfall executie noduri), Input/Output (date intrare/iesire), Raw Data (JSON complet). Auto-refresh la 3s cand run-ul e activ. Foloseste fetch() in loc de axios (workaround pentru extensie browser).

Logica: src/pages/RunDetailsPage.tsx Timeline: src/components/orchestrator/runs-history/NodeWaterfallTimeline.tsx

PipelinesPage (/pipelines) -- NEW (Modul 1)

Livrabil Modul 1 caiet ("Workflow Builder: CRUD/versionare pipeline; Run Console"). Opereaza pe definitiile reale de pipeline (input_type_profile din didiFramework), NU pe pipelineApi mort (/api/v1/pipelines, fara backend). Tabel cu profilurile + actiuni de lifecycle: dry-run, clone, activate/deactivate, versiuni (istoric + restore), import/export.

  • Dry-run (DryRunDialog.tsx): apeleaza POST /agent-v3/api/v3/pipeline/dry-run -> arata flow-ul, nodurile (component/queue/priority/stages/prompt keys), componentele skipped si verdict profile-ul rezolvat, fara a rula analiza reala. Cancel disponibil pe run-uri active.
  • Backing endpoints: /framework/api/pipelines/* (list/get/clone/activate/deactivate/PUT cu versionare/versions/restore/import) + /agent-v3/api/v3/pipeline/dry-run|:id/cancel.

Logica: src/components/Pipelines/PipelinesPage.tsx + DryRunDialog.tsx + pipelinesApi.ts Acces: admin-only (ProtectedRoute requiredRole="admin").

UniversalAnalysisDashboard (/analysis)

Executie analiza multi-modal: text, imagine, video, audio, URL. Sidebar cu 3 sectiuni: Analysis (formular + executor), Results (run-uri active, polling 10s), History (paginat cu filtre). Suporta upload fisiere in MinIO si tracking progres executie.

Logica: src/pages/UniversalAnalysisDashboard.tsx Polling executie: 2s (GET /api/v1/runs/:runId?include_live_status=true) Polling run-uri active: 10s (GET /api/v1/runs?limit=50)

UniversalResultsPage (/analysis/results/:runId)

Pagina rezultate live. Afiseaza progress bar, status per nod (accordion), rezultate finale JSON. Polling la 2s.

Logica: src/pages/UniversalResultsPage.tsx

UserManagement (/users)

2 tab-uri: Utilizatori (tabel paginat cu cautare, filtrare plan, editare, stergere, sync Keycloak, toggle email-verified) si Planuri Abonament (editare inline: nume, descriere, credite, pret).

Logica: src/components/UserManagement/UserManagement.tsx Dialog editare: src/components/UserManagement/UserEditModal.tsx

AnalysisHistory (/history)

Tabel paginat cu toate sesiunile de analiza din agent-v3. Filtre: cautare text, nivel risc (LOW/MODERATE/HIGH/VERY_HIGH/CRITICAL), status, interval date. Coloane: data, email, input preview, risk score, tehnici, AI %, claims, durata. View deschide AnalysisDetailModal cu toate detaliile sesiunii.

Cost display per analiza (USD) — in AnalysisDetailModal, sectiunea "LLM Usage" afiseaza:

  • Badge total cost langa titlul accordionului (ex: $0.0321)
  • Grid cu 5 celule: Calls / Prompt Tokens / Completion Tokens / Total Tokens / Est. Cost
  • Per Component: fiecare card contine cost chip individual (ex: Techniques: $0.0054)

Costul se calculeaza client-side dintr-o combinatie de:

  1. llm_usage.by_component[comp] — prompt_tokens, completion_tokens, models_used[] din agent-v3
  2. Fetch parallel la /framework/api/providers/models — care returneaza input_cost_per_1m + output_cost_per_1m per model
  3. Formula: cost = (prompt_tokens / 1M) * input_cost + (completion_tokens / 1M) * output_cost
  4. Cost-ul e charged pe primul model din models_used[] (aproximare: daca primary a picat si s-a dus pe fallback, cost-ul ar putea fi putin subestimat pe free chain, supra-estimat pe premium — dar in happy path e 100% corect)

Free tier afiseaza tot $0.00 (Qwen local nu are cost input/output). Premium arata cost real per analiza — tipic $0.02-0.05 pentru text simplu, pana la $0.10-0.15 pentru media cu claims multiple.

Logica: src/components/AnalysisHistory/AnalysisHistory.tsx Modal detalii: src/components/AnalysisHistory/AnalysisDetailModal.tsx (helpers: normalizeModelKey, computeTokenCost, formatUsd)

ProvidersManagement (/providers)

CRUD pe 4 tab-uri: Providers (configurare provideri LLM), Models (modele per provider), Assignments (assignment componenta -> model pe etapa), API Keys (chei de acces). Fiecare tab cu dialoguri add/edit/delete. Buton test conexiune.

Logica: src/components/ProvidersManagement/ProvidersManagement.tsx

TechniquesV3Config (/techniques-v3)

3 tab-uri: Stage Assignments (model primar + 3 fallback-uri per etapa screening/deep), Available Models (catalog cu info speed/quality/cost), Test Analysis (textarea + buton executie test). Comunicare cu agent-v3.

Logica: src/components/TechniquesV3/TechniquesV3Config.tsx

LLMComponentsConfig (/llm-components)

Pagina unificata pentru configurare LLM si scoring pe toate componentele. Top-level tab-uri: Techniques, AI Tampered, Claims, Source Assessment, Verdict, Moderation (NEW), Providers.

Moderation (NEW) — al 6-lea buton (alaturi de Techniques, AI Tampered, Claims, Source Assessment, Verdict). Randeaza <ModerationSettings /> cu 4 cards pentru HIL triage + brain client + sensitive topics + roles. Auto-syncs to Redis dupa fiecare save (snackbar feedback).

Toggle FREE | PREMIUM (Etapa 6) — peste Stage Assignments, un ToggleButtonGroup permite switch-ul intre chain-ul free si premium pentru componenta curenta:

  • Cand selectezi FREE, tabelul arata chain-ul primary+fallbacks din rows cu tier='free' (Qwen local primary + cloud fallbacks)
  • Cand selectezi PREMIUM, tabelul arata chain-ul din rows cu tier='premium' (Gemini 3 Flash / Claude Sonnet primary + Qwen local safety)
  • Badge-ul stage ([FREE] verde / [PREMIUM] galben) reflecta tier-ul curent selectat
  • Daca un stage NU are rows premium configurate, apare un Alert warning si fallback automat la chain-ul free
  • Editare: cand userul schimba un model in tabel, se aplica doar pe tier-ul curent selectat; salvarea itereaza ambele tiers si trimite PUT la /api/providers/assignments/:id

State-ul selectedTier e stored in componenta main LLMComponentsConfig; StageAssignmentsPanel primeste selectedTier ca prop si filtreaza stage.modelsByTier[selectedTier] la randare. Structura modelsByTier: Record<'free'|'premium', ModelConfig[]> e construita in fetchStageAssignments() prin grouping pe tier din response-ul GET /api/providers/assignments (care include acum campul tier).

Per componenta analiza (Techniques, AI Tampered, Claims, Source Assessment):

  • Stage Assignments: modele LLM pe fiecare etapa (primary + 3 fallback-uri) — cu toggle Free/Premium
  • Vision Models: cascade viziune (doar AI Tampered)
  • Available Models: catalog modele din PG
  • Parameters: scoring_config editabil — toti parametrii de calcul scor (din PG via didiFramework)
    • Techniques: count_scaler, severe_threshold, intensity bonus, dimension/count bonuses
    • AI Tampered: blend_weights, disclosure_impact, undisclosed_threshold, verdict thresholds
    • Claims: status_weights (VT/LT/UV/OP/LF/VF), all_unverified behavior/credibility
    • Source Assessment: axis_weights (publication/domain/author/platform), verdict_thresholds
  • Prompts: system prompt + user template editabile
  • Test Analysis: test cu text sample

Verdict (VerdictConfig) — 8 tab-uri:

  • Component Weights (ponderile globale, fallback daca profilurile nu exista)
  • Verdict Categories (RELIABLE..DISINFORMATION ranges, editabile)
  • Risk Levels (VERY_LOW..CRITICAL ranges, editabile)
  • Severity & Actions (LOW..CRITICAL + actiuni recomandate)
  • Overrides & Synergy (configurare override-uri globale)
  • Confidence (bonusuri/penalitati)
  • Topic Multipliers (elections, health, climate — editabile)
  • Input Profiles (NOU): ponderi per input type (text/image/audio/video/url), override-uri per profil, AI disclosure multipliers, reguli INCONCLUSIVE. Editabil cu save + sync to Redis.

Logica: src/components/LLMComponentsConfig/index.tsx Verdict: src/components/LLMComponentsConfig/VerdictConfig.tsx

ModerationQueue (/moderation)

Paginated table cu filtre (status: pending/in_review/resolved/all + priority CSV). Auto-refresh 30s pe pending tab. Click row -> detail. Top-right: link "View Stats".

Logica: src/components/Moderation/ModerationQueue.tsx Polling: 30s (auto-refresh pe pending tab)

ModerationDetail (/moderation/:queueId)

Side-by-side: Input (text/url + meta) | AI Verdict (risk_score, confidence, severity, components run/skipped). Card metadata queue cu enqueue_reason + meta JSONB. Action buttons:

  • Claim for Review (pe pending)
  • Approve as is / Resolve with Corrections / Reject (pe in_review)

Resolve dialog: action toggle + JSON corrections editor (validated client-side) + notes.

Logica: src/components/Moderation/ModerationDetail.tsx

ModerationStats (/moderation/stats)

3 stat cards (pending, in_review, resolved_24h) cu colored borders. Open by Priority chips. Avg time in queue. Auto-refresh 30s.

Logica: src/components/Moderation/ModerationStats.tsx


Autentificare (Keycloak)

Configurare

Fisier: src/services/keycloak.ts

Client ID: admin-dashboard (din REACT_APP_KEYCLOAK_CLIENT_ID, obligatoriu)
Realm: didi-admins (din REACT_APP_KEYCLOAK_REALM, obligatoriu)
PKCE: S256 (obligatoriu)
URL: din REACT_APP_KEYCLOAK_URL (requireEnv) — pointeaza spre /auth pe nginx-ul dashboard-ului, care proxiaza catre Keycloak LOCAL didi-keycloak

Flow

Fisier: src/contexts/AuthContext.tsx

  1. La pornire: keycloak.init({ onLoad: 'login-required' })
  2. Token stocat in localStorage.keycloak_token
  3. Refresh token la fiecare 30s (updateToken(70) -- refresh daca expira in < 70s)
  4. La 401 de la axios: event auth:unauthorized -> logout automat
  5. REACT_APP_STAGING_MODE=true sare peste toata autentificarea

Protectie rute

Fisier: src/components/auth/ProtectedRoute.tsx

  • Verifica isAuthenticated inainte de a randa componenta
  • Redirect la /login daca neautentificat
  • Suporta requiredRole (verificare rol Keycloak)
  • Suporta requiredAnyRole?: string[] (any-of) pentru rute partajate intre mai multe roluri staff

Fisier: src/components/auth/LoginRedirect.tsx -- apeleaza keycloak.login() imediat Fisier: src/components/auth/Unauthorized.tsx -- 403 page (lista roluri necesare + "Go to Public App" + "Log out")

Role gating (admin / moderator / senior_moderator)

Roluri definite pe Keycloak LOCAL didi-keycloak, realm didi-admins: moderator, senior_moderator (langa admin existent).

  • App.tsx: AdminLayout wrapped in ProtectedRoute requiredAnyRole=[admin, moderator, senior_moderator] (end-users tip viewer primesc 403 -> Unauthorized page)
  • Per-route guards:
    • /framework, /users, /providers, /llm-components -> admin-only
    • /history + /moderation/* -> admin OR moderator
  • AdminLayout sidebar: sectiunea Configuration admin-only; sectiunea Management split (Users=admin, History=staff, Moderation=moderator-aware)
  • Staging mode (REACT_APP_STAGING_MODE=true) face hasRole() sa returneze mereu true -> toate gates bypass pentru testare locala. In prod, Keycloak JWT roles enforcate strict.

Context expus

AuthContext expune: isAuthenticated, initialized, user (tokenParsed), token, login(), logout(), hasRole(role)


Configurare Nginx

Productie (nginx-ssl.conf)

HTTPS pe port 443 (TLS 1.2/1.3) + HTTP pe port 80.

Location Proxy catre Scop
/ SPA fallback /admin/index.html React app
/api/ http://didi-kong:8000 Orchestrator API prin Kong LOCAL
/auth/ http://keycloak:8080 Keycloak LOCAL (container didi-keycloak); NU strip — Keycloak servit sub /auth (KC_HTTP_RELATIVE_PATH)
/agent-v3/ http://didi-agent-v3:24803 agent-v3 direct (strip prefix)
/framework/ http://didi-framework:3005 didiFramework direct (strip prefix)
/health-check/redis-commander http://staging-dataLayer-redis-commander:8081 Health check Redis Commander
/health-check/rabbitmq http://staging-dataLayer-rabbitmq:15672 Health check RabbitMQ
/health-check/minio http://staging-dataLayer-minio:9000 Health check MinIO
/health-check/pgadmin http://staging-dataLayer-pgadmin:80 Health check pgAdmin
/health-check/postgres http://staging-dataLayer-postgres:5432 Health check PostgreSQL

Headere securitate: X-Frame-Options SAMEORIGIN, X-Content-Type-Options nosniff, X-XSS-Protection. Cache static: 1 an + immutable pentru .js, .css, .png, .svg, .ico.

Dev (nginx.conf)

Acelasi layout fara SSL, porturi 3000 si 80. Nu are proxy pentru /api/, /auth/, sau health checks (doar /agent-v3/ si /framework/).


Comunicare real-time

WebSocket (usePipelineProgress)

Fisier: src/hooks/usePipelineProgress.ts

Conectare la wss://{host}/ws/runs/:runId/progress?include_outputs=true pentru tracking progres pipeline.

Mesaje primite:

  • connected -- confirmare subscriptie
  • node_status -- update executie nod (key, status, label, type, timestamp, duration_ms)
  • run_complete -- pipeline terminat (status: success/error/stopped, total_duration_ms)
  • error -- mesaj eroare

Reconnect exponential backoff: 1s -> 2s -> 4s -> ... -> 30s max.

Polling HTTP

Componenta Interval Endpoint
ServicesDashboard 30s Health checks (8 endpoint-uri)
UniversalAnalysisDashboard 2s GET /api/v1/runs/:runId?include_live_status=true
UniversalAnalysisDashboard 10s GET /api/v1/runs?limit=50
PipelineExecutor 500ms GET /api/v1/runs/:runId?include_live_status=true
UniversalResultsPage 2s GET /api/v1/runs/status/:runId
RunDetailsPage 3s GET /api/v1/runs/:runId/results
RunsHistory 10s GET /api/v1/runs (optional, toggle)
useAnalysisResults 5s GET /api/v1/runs/:id?include_live_status=true

Hooks custom

Hook Fisier Scop
useAnalysisResults src/hooks/useAnalysisResults.ts Rezultate analiza cu auto-refresh 5s, filtrare pe tags
useRunsHistory src/hooks/useRunsHistory.ts Istoric run-uri paginat (fetch(), nu axios), filtre status/date/search
usePipelineProgress src/hooks/usePipelineProgress.ts WebSocket progres pipeline, reconnect backoff
useDeleteDialog src/hooks/useDeleteDialog.ts State generic dialog confirmare stergere
useExpandedItems src/hooks/useExpandedItems.ts State accordion expandat (Set)
useTabState src/hooks/useTabState.ts State tab per item (Record)
useBenchmarkRunner src/components/orchestrator/benchmark/useBenchmarkRunner.ts Executie benchmark pipeline + polling status
useAutoLayout src/components/orchestrator/hooks/useAutoLayout.ts Auto-layout noduri ReactFlow
useDagValidation src/components/orchestrator/hooks/useDagValidation.ts Validare DAG (detectie cicluri)
useEdgeSuggestions src/components/orchestrator/hooks/useEdgeSuggestions.ts Sugestii edge-uri data-flow
useProviderModels src/components/orchestrator/hooks/useProviderModels.ts Fetch modele si resurse catalog
useResourceEndpoints src/components/orchestrator/hooks/useResourceEndpoints.ts Fetch resurse catalog

Tema (light/dark)

Fisier: src/theme/index.ts Persistenta: localStorage['didi-admin-theme'] Toggle: src/components/ThemeToggle.tsx (buton in sidebar ServicesDashboard)

Culori

Rol Valoare Nume
Primary #0052CC Deep Trust Blue
Secondary #00BFA6 Honest Teal
Success #28A745 Truth Green
Error #E63946 Caution Red
Warning #FF8C42 Insight Orange
Background (light) #F5F7FA --
Background (dark) #121212 --
Text (light) #1F2933 Slate Charcoal

Tipografie

Font: Inter, Roboto, Helvetica, Arial

  • h1: 32px/700, h2: 24px/600, h3: 20px/500, body1: 16px/400, button: 14px/500/uppercase

Overrides MUI

  • Button: radius 8, padding 12px 24px
  • Card: radius 12, hover shadow
  • TextField: primary border on focus
  • Chip: rounded 16px

Dependente principale (package.json)

Pachet Versiune Scop
react ^19.1.1 UI framework
react-router-dom ^7.7.1 Routing
@mui/material ^7.3.1 Component library
axios ^1.11.0 HTTP client
keycloak-js ^26.2.0 Autentificare Keycloak
@react-keycloak/web ^3.4.0 React bindings Keycloak
reactflow ^11.11.4 Vizualizare DAG pipeline
recharts ^3.1.0 Grafice costuri
react-dnd ^16.0.1 Drag-and-drop
react-dropzone ^14.3.8 Upload fisiere
zod ^3.25.76 Validare schema
neverthrow ^8.1.1 Result types (Ok/Err)
ts-pattern ^5.6.0 Pattern matching

Configurare Docker

Dockerfile (productie)

Stage 1: node:20-alpine
  - npm install --legacy-peer-deps
  - react-scripts build (20+ ARG-uri pentru REACT_APP_*)
  - ARG REACT_APP_KEYCLOAK_REALM default = didi-admins (= realm-ul real); .env confirma aceeasi valoare
  - ARG REACT_APP_STAGING_MODE=false (+ ENV explicit — CRA altfel bake-uia ARG default in loc sa citeasca .env)

Stage 2: nginx:alpine
  - Copie build in /usr/share/nginx/html/admin si /usr/share/nginx/html
  - Copie nginx-ssl.conf + certificate SSL
  - Expose 443, 80

Variabile de mediu (.env)

<host-local> = mașina de deployment (host-ul local). Valorile reale din .env (bake-uite in build la build time):

# General
REACT_APP_SERVER_HOST=<host-local>
REACT_APP_HOST=<host-local>
REACT_APP_API_BASE_URL=https://<host-local>:3001   # prin Kong LOCAL (admin nginx /api/ → didi-kong:8000)
REACT_APP_STAGING_MODE=false

# Keycloak — LOCAL, proxiat prin admin nginx la /auth/
REACT_APP_KEYCLOAK_URL=https://<host-local>:3001/auth
REACT_APP_KEYCLOAK_REALM=didi-admins
REACT_APP_KEYCLOAK_CLIENT_ID=admin-dashboard

# Kong Gateway (LOCAL)
REACT_APP_KONG_PROXY_PORT=443
REACT_APP_KONG_ADMIN_PORT=18101
REACT_APP_KONG_MANAGER_PORT=18102

# Porturi servicii (afisate pe service cards)
REACT_APP_KEYCLOAK_PORT=28000
REACT_APP_POSTGRES_PORT=5000
REACT_APP_PGADMIN_PORT=5050
REACT_APP_REDIS_PORT=6379
REACT_APP_COMMANDER_PORT=8081
REACT_APP_RABBITMQ_MGMT_PORT=15672
REACT_APP_MINIO_CONSOLE_PORT=9001

Nota: REACT_APP_KEYCLOAK_URL este folosit de keycloak.ts (requireEnv), pointand spre /auth pe nginx-ul dashboard-ului, care proxiaza catre Keycloak LOCAL didi-keycloak.

REACT_APP_STAGING_MODE=false (real) → autentificarea Keycloak e ACTIVA; cand ar fi true, s-ar sari peste toata autentificarea (doar pentru testare locala).


Ce NU face

  • Nu are backend propriu (doar nginx reverse proxy + SPA static)
  • Nu scrie direct in baza de date (toate operatiile prin didiFramework sau orchestrator API)
  • Nu proceseaza analize (doar le lanseaza si monitorizeaza)
  • Nu gestioneaza fisiere (upload-urile merg prin orchestrator API -> MinIO)
  • Nu are SSR (Server Side Rendering) -- e un SPA clasic
  • Nu are teste unitare (doar un e2e dark-mode.spec.ts cu Playwright)
  • CostDashboard exista dar nu e rutata (pagina orfana)

Functionalitati suplimentare (in afara celor 9 module de caiet)

Functionalitate Unde in cod Note
CostDashboard (costuri LLM) src/pages/CostDashboard/ Pagina orfana — NU e rutata in App.tsx; consuma /api/v1/costs/* de pe orchestrator

(HIL Moderation din dashboard — ModerationQueue/Detail/Stats + ModerationSettings — este integrarea UI a Modulului de moderare din backend; ramane in sectiunile de mai sus.)


Recent Changes (2026-05-05)

  • Keycloak login fix CRITICAL: src/services/keycloak.ts ignora REACT_APP_KEYCLOAK_URL (folosea ${window.location.origin}/auth hardcoded) — cauza "Cookie not found" cross-domain. Acum foloseste requireEnv('REACT_APP_KEYCLOAK_URL') direct.
  • .env: REACT_APP_STAGING_MODE=false (era true -> bypass auth complet), REACT_APP_KEYCLOAK_REALM=didi-admins (era gresit didi-clients), REACT_APP_KEYCLOAK_URL=https://<host-local>:3001/auth (Keycloak LOCAL didi-keycloak prin admin nginx /auth; nu SSO cluster).
  • Dockerfile: ARG REACT_APP_STAGING_MODE=false (era true) + ENV REACT_APP_STAGING_MODE=$REACT_APP_STAGING_MODE adaugat (CRA bake-uia ARG default in loc sa citeasca .env).
  • Moderation/api.ts + ModerationSettings/api.ts: helper nou authedFetch() care injecteaza Authorization: Bearer ${localStorage.keycloak_token}. Inainte faceau fetch() fara auth -> 401 pe Kong.
  • Role-based UI guard AdminLayout.tsx: Dashboard + service groups (Data Layer, Gateway Layer, etc.) acum vizibile doar pentru admin. Moderator/senior_moderator vad doar Management section (Analysis History + Moderation).
  • App.tsx DefaultLanding: redirect automat la /moderation pentru non-admin (in loc de ServicesDashboard). Plus route /dashboard cere rol admin.
  • UI cosmetics: ModerationQueue.tsx Status/Priority labels cu display: block, mb: 0.5 (erau lipite de butoane); priority 1,2,3,4,5 (erau doar 1,3,4); AdminLayout.tsx sidebar logo + main navbar header ambele la height: 64px (linii divider aliniate); divider deasupra "Management" ascuns pentru non-admin.

User Management overhaul (2026-05-05)

UserManagement.tsx complet rescris (3 tabs) + 2 componente noi + UserEditModal.tsx extins. Toate hook-uite la endpoint-urile noi din didiFramework /api/admin/*.

Tab #1 — Users (extins)

Coloane: ☑ Checkbox (bulk), Email (+ keycloak_id snippet), Name, Sync chip (Synced/KC only — warning bg), Plan, Group chip, Roles chips (top-3 + "+N more"), Email Verified Switch, Active, Credits (tooltip "Spent: N"), Storage progress bar (>90% red / >70% warning), Actions (Edit modal / 🛡️ RolesDialog / 📜 UsageHistory / 🗑️ Delete hard).

Filter row: search + Plan + Sync filter (All/Synced/Keycloak only).

Bulk toolbar (apare pe selectare): activate / deactivate / mark email verified / set credits to N / delete. Sequential per id (evită hammer Keycloak).

Tab #2 — Subscription Plans (nemodificat)

Tab #3 — Audit Log (NOU)

Citește /api/admin/audit-log paginat. Filtre Action preset + Actor email (ILIKE) + Since (datetime-local). Coloane: When / Action chip color-coded / Target / Actor / Payload (truncat + tooltip JSON pretty) / IP.

Componente noi

File Rol
RolesDialog.tsx Multi-select check-list pe realm roles, diff summary (add/remove), save → PUT /:id/roles.
UsageHistoryModal.tsx Last 100 rows din bos_sysadmin.ai_credit_usage. Defensive render (input_type chip + credits + session_id + JSON fallback pe coloane necunoscute).

UserEditModal.tsx extins

În plus față de existent: Group select (dropdown grupuri Keycloak, "(no group)" = remove) + "Send password reset email" button (apelează POST /:id/reset-password lifespan 86400s, Snackbar succes).

SensitiveTopicsCard.tsx extins (Phase D1)

Rânduri rich cu volatility chip color-coded (volatile=red, evolving=warning, stable=success) + TTL/recency chips + iconul ⚙️ Tune → EditVolatilityDialog (Select tier auto-seed defaults + override fine pe ttl/recency/half_life). Add-form extins cu Volatility select.

Live state

20 users live. Reset-password fail cunoscut: cluster Keycloak SMTP not configured (502 cu detail în audit_log) — operațional, nu cod.