879 lines
46 KiB
Markdown
879 lines
46 KiB
Markdown
# 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.
|