51 KiB
didiFramework - Index
Backend CRUD pentru managementul tuturor parametrilor platformei DIDI. Stocheaza configuratia in PostgreSQL si o sincronizeaza in Redis pentru acces rapid de catre agent-v3. Gestioneaza si utilizatorii, creditele, abonamentele si fisierele.
Port: 3005 Framework: Express 4 + TypeScript Container: didi-framework Schema principala: bos_parammgmt
Ce face serviciul
- CRUD parametri -- dimensiuni, tehnici, indicatori, reguli, verdicts, ponderi, surse, claims
- Sincronizare Redis -- incarca ierarhia completa in Redis ca agent-v3 sa o citeasca instant
- Managementul utilizatorilor -- integrare Keycloak, auto-inregistrare, credite, abonamente
- Stocare fisiere -- upload/download via MinIO, bucket-uri per utilizator
- Istoric analize -- acces la rezultatele salvate in bos_analysis
- Configurare LLM -- provideri, modele, assignments pe componente
- API keys extensie browser -- CRUD chei API pentru extensia Chrome
Structura fisierelor
src/
server.ts -- Express app, montare rute, middleware, error handling
config/
database.ts -- Pool PostgreSQL, query(), queryOne(), transaction()
minio.ts -- Client MinIO, operatii bucket, upload/download, bucket-uri user
jwt-verify.ts -- jwtVerifyGate(): middleware global RS256 vs Keycloak JWKS (Modul 7 Auth)
types/
index.ts -- Interfete TypeScript pentru toate entitatile
utils/
crud-factory.ts -- Generator automat de rute CRUD (GET/POST/PUT/DELETE)
dependency-checker.ts -- Verificare dependente inainte de stergere (safe delete)
routes/
dimensions.ts -- CRUD dimensiuni (nivel 1 ierarhie tehnici)
subdimensions.ts -- CRUD subdimensiuni (nivel 2)
techniques.ts -- CRUD tehnici (nivel 3, suporta cascade delete)
indicators.ts -- CRUD indicatori tehnica (leaf, bulk create)
validation-rules.ts -- CRUD reguli validare tehnica (leaf, bulk create)
verdicts.ts -- CRUD categorii verdict + risk mappings + severity
weights.ts -- CRUD ponderi componente + scenarii + multiplicatori
platforms.ts -- CRUD platforme social media
sources.ts -- CRUD tipuri sursa
source-assessment.ts -- CRUD platf. modifiers, credib. sursa, varsta domeniu, risk, red flags, autori
claims.ts -- CRUD status claim, tip claim, confidence, interpretare
sync-redis.ts -- Sincronizare framework PostgreSQL -> Redis
sync-analysis.ts -- Sincronizare rezultate analiza Redis -> PostgreSQL (legacy)
auth.ts -- Autentificare Keycloak, profil, credite, auto-inregistrare
admin.ts -- Management admin utilizatori + abonamente
history.ts -- Istoric analize (list paginat + detaliu)
subscriptions.ts -- Info abonament + credite ramase
uploads.ts -- Upload/download fisiere MinIO
providers.ts -- Configurare provideri LLM, modele, assignments, API keys
extension-keys.ts -- CRUD chei API extensie browser
prompts.ts -- Servire fisiere prompt (markdown) pentru pipeline
waitlist.ts -- Waitlist public (signup email)
overview.ts -- Statistici framework + health checks
input-profiles.ts -- CRUD profiluri verdict per input type + scoring-config GET/PUT
moderation-config.ts -- CRUD single-row config HIL triage + brain client
sensitive-topics.ts -- CRUD topics care declanseaza HIL review
moderation-roles.ts -- CRUD Keycloak role -> permisiuni HIL
skills.ts -- Catalog resurse AI (Modul 1): analysis_components + extractor_skills (probe live platforma Lot 1) + code_jobs
notifications.ts -- Health/test SMTP + trigger manual credit-reset (email notifications)
webhooks/stripe.ts -- Webhook Stripe (raw body) — plati/abonamente (suplimentar)
admin/social.ts -- Postare social media (Facebook DESI 6) din admin-dashboard (suplimentar)
data/ -- Fisiere date (seed, export)
scripts/ -- Scripturi utilitare
openapi.yaml -- Spec OpenAPI la radacina (documenteaza API-ul; Modulele 5-7)
sql/
migrations/ -- Migratii SQL schema
Nota: input-profiles.ts este montat sub DOUA prefixe — /api/input-profiles si aliasul /api/pipelines (Modul 1: definitiile de pipeline = input_type_profile).
Ierarhia de date (tehnici de manipulare)
dimension
└── subdimension
└── technique
├── technique_indicator (leaf)
└── technique_validation_rule (leaf)
Stergerea unui parinte este blocata daca are copii (safe delete).
Exceptie: DELETE /techniques/:id?cascade=true sterge copiii inainte.
API - Toate endpoint-urile
Health si documentatie
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Documentatie API completa | server.ts |
| GET | /health | Health check simplu | server.ts |
| GET | /health/all | Health PostgreSQL + MinIO | server.ts |
Overview (/api/overview)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /stats | Numar dimensiuni, tehnici, verdicte, platforme | routes/overview.ts |
| GET | /health | Health check baza de date | routes/overview.ts |
| GET | /docker-health | Status container Docker | routes/overview.ts |
Dimensiuni (/api/dimensions)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista toate dimensiunile | routes/dimensions.ts |
| GET | /with-counts | Lista cu numar subdimensiuni si tehnici | routes/dimensions.ts |
| GET | /:id | O singura dimensiune | routes/dimensions.ts |
| GET | /:id/dependencies | Verifica daca are subdimensiuni | routes/dimensions.ts |
| POST | / | Creeaza dimensiune | routes/dimensions.ts |
| PUT | /:id | Actualizeaza dimensiune | routes/dimensions.ts |
| DELETE | /:id | Sterge (blocat daca are copii) | routes/dimensions.ts |
Subdimensiuni (/api/subdimensions)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista toate subdimensiunile | routes/subdimensions.ts |
| GET | /with-counts | Lista cu numar tehnici | routes/subdimensions.ts |
| GET | /by-dimension/:dimensionId | Filtrate dupa dimensiune parinte | routes/subdimensions.ts |
| GET | /:id | O singura subdimensiune | routes/subdimensions.ts |
| GET | /:id/dependencies | Verifica daca are tehnici | routes/subdimensions.ts |
| POST | / | Creeaza subdimensiune | routes/subdimensions.ts |
| PUT | /:id | Actualizeaza subdimensiune | routes/subdimensions.ts |
| DELETE | /:id | Sterge (blocat daca are copii) | routes/subdimensions.ts |
Nota: Coloana din DB se numeste subdmiension_name (typo). Codul corecteaza in API ca subdimension_name.
Tehnici (/api/techniques)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista toate tehnicile | routes/techniques.ts |
| GET | /with-hierarchy | Lista cu dimensiune + subdimensiune + contor indicatori/reguli | routes/techniques.ts |
| GET | /by-subdimension/:subdimensionId | Filtrate dupa subdimensiune | routes/techniques.ts |
| GET | /:id | O singura tehnica | routes/techniques.ts |
| GET | /:id/dependencies | Verifica indicatori si reguli | routes/techniques.ts |
| POST | / | Creeaza tehnica | routes/techniques.ts |
| PUT | /:id | Actualizeaza tehnica | routes/techniques.ts |
| DELETE | /:id | Sterge (blocat daca are copii) | routes/techniques.ts |
| DELETE | /:id?cascade=true | Sterge cu toti copiii | routes/techniques.ts |
Indicatori (/api/indicators)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista toti indicatorii | routes/indicators.ts |
| GET | /by-technique/:id | Filtrati dupa tehnica | routes/indicators.ts |
| GET | /missing | Tehnici fara indicatori | routes/indicators.ts |
| GET | /stats | Statistici acoperire indicatori | routes/indicators.ts |
| POST | / | Creeaza indicator | routes/indicators.ts |
| POST | /bulk | Creeaza mai multi indicatori | routes/indicators.ts |
| POST | /bulk-for-technique/:id | Creeaza indicatori pentru o tehnica | routes/indicators.ts |
| PUT | /:techniqueId/:indicatorId | Actualizeaza indicator | routes/indicators.ts |
| DELETE | /:techniqueId/:indicatorId | Sterge indicator | routes/indicators.ts |
| DELETE | /by-technique/:id | Sterge toti indicatorii unei tehnici | routes/indicators.ts |
Reguli validare (/api/validation-rules)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista toate regulile | routes/validation-rules.ts |
| GET | /with-techniques | Lista cu numele tehnicii | routes/validation-rules.ts |
| GET | /by-technique/:techniqueId | Filtrate dupa tehnica | routes/validation-rules.ts |
| GET | /stats | Statistici acoperire reguli | routes/validation-rules.ts |
| GET | /:id | O singura regula | routes/validation-rules.ts |
| POST | / | Creeaza regula | routes/validation-rules.ts |
| POST | /bulk-for-technique/:techniqueId | Creeaza reguli pentru o tehnica | routes/validation-rules.ts |
| PUT | /:id | Actualizeaza regula | routes/validation-rules.ts |
| DELETE | /:id | Sterge regula | routes/validation-rules.ts |
| DELETE | /by-technique/:techniqueId | Sterge toate regulile unei tehnici | routes/validation-rules.ts |
Verdicts (/api/verdicts)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /all | Toate cele 3 tipuri combinate | routes/verdicts.ts |
| GET | /categories | Categorii verdict (RELIABLE, MIXED, DISINFO, etc.) | routes/verdicts.ts |
| GET | /categories/:id | O categorie | routes/verdicts.ts |
| POST | /categories | Creeaza categorie | routes/verdicts.ts |
| PUT | /categories/:id | Actualizeaza categorie | routes/verdicts.ts |
| DELETE | /categories/:id | Sterge categorie | routes/verdicts.ts |
| GET | /risk | Risk mappings (LOW, MODERATE, HIGH, CRITICAL) | routes/verdicts.ts |
| GET | /risk/:id | Un risk mapping | routes/verdicts.ts |
| POST | /risk | Creeaza risk mapping | routes/verdicts.ts |
| PUT | /risk/:id | Actualizeaza risk mapping | routes/verdicts.ts |
| DELETE | /risk/:id | Sterge risk mapping | routes/verdicts.ts |
| GET | /severity | Severity assessments | routes/verdicts.ts |
| POST,PUT,DELETE | /severity/... | CRUD severity | routes/verdicts.ts |
| GET | /runtime-config | Citeste jsonb din component_config (component_code='pipeline', config_key='verdict_config') |
routes/verdicts.ts |
| PUT | /runtime-config | Update full body (synergy + overrides + confidence + confidence_levels) cu validare chei obligatorii | routes/verdicts.ts |
| PATCH | /runtime-config/:section | Update partial pe sectiune (synergy, overrides, confidence, confidence_levels, false_claims, severe_techniques, undisclosed_ai, untrusted_domain, domain_red_flags) | routes/verdicts.ts |
Ponderi (/api/weights)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /all | Toate cele 3 tipuri combinate | routes/weights.ts |
| GET | /components | Ponderi componente (techniques 35%, claims 25%, etc.) | routes/weights.ts |
| POST,PUT,DELETE | /components/... | CRUD ponderi | routes/weights.ts |
| GET | /scenarios | Scenarii ponderi (combinatii per context) | routes/weights.ts |
| POST,PUT,DELETE | /scenarios/... | CRUD scenarii | routes/weights.ts |
| GET | /multipliers | Multiplicatori (topic, temporal, reach) | routes/weights.ts |
| GET | /multipliers/type/:type | Multiplicatori filtrati dupa tip | routes/weights.ts |
| POST,PUT,DELETE | /multipliers/... | CRUD multiplicatori | routes/weights.ts |
Platforme (/api/platforms)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista platforme cu modifier info | routes/platforms.ts |
| GET | /:id | O platforma | routes/platforms.ts |
| POST | / | Creeaza platforma | routes/platforms.ts |
| PUT | /:id | Actualizeaza platforma | routes/platforms.ts |
| DELETE | /:id | Sterge platforma | routes/platforms.ts |
Surse (/api/sources)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista tipuri sursa cu numar utilizari | routes/sources.ts |
| GET | /:id | Un tip sursa | routes/sources.ts |
| GET | /:id/dependencies | Verifica domain_attribute copii | routes/sources.ts |
| POST | / | Creeaza tip sursa | routes/sources.ts |
| PUT | /:id | Actualizeaza | routes/sources.ts |
| DELETE | /:id | Sterge (blocat daca are copii) | routes/sources.ts |
Evaluare surse (/api/source-assessment)
7 sub-resurse, fiecare cu CRUD complet:
| Sub-resursa | Tabela | Are copii in |
|---|---|---|
| /platform-modifiers | platform_modifier | platform |
| /source-credibility | source_credibility | domain_attribute |
| /domain-age-scores | domain_age_score | domain_attribute |
| /domain-risk-levels | domain_risk_level | domain_attribute |
| /domain-red-flags | domain_red_flag | domain_attribute |
| /author-classifications | author_classification | author |
| /author-credibility | author_credibility | author |
Fiecare are: GET /, GET /:id, POST /, PUT /:id, DELETE /:id Doar /platform-modifiers are si GET /:id/dependencies (singura sub-resursa cu copii directi in platform). Plus: GET /source-assessment-ranges -- tabel lookup cu range-uri evaluare sursa (leaf, read-only). Plus: GET /source-assessment/all -- combina toate cele 7 tipuri. Logica: routes/source-assessment.ts
Claims (/api/claims)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /all | Toate cele 4 tipuri combinate | routes/claims.ts |
| GET | /status | Statusuri claim (VT, LT, UV, LF, VF, OP, NV) | routes/claims.ts |
| POST,PUT,DELETE | /status/... | CRUD statusuri | routes/claims.ts |
| GET | /types | Tipuri claim (EF, VF, RE, SC, QA, CC, PC, OF, VC) | routes/claims.ts |
| POST,PUT,DELETE | /types/... | CRUD tipuri | routes/claims.ts |
| GET | /confidence | Nivele de incredere | routes/claims.ts |
| POST,PUT,DELETE | /confidence/... | CRUD confidence | routes/claims.ts |
| GET | /interpretation | Interpretari concordanta surse | routes/claims.ts |
| POST,PUT,DELETE | /interpretation/... | CRUD interpretari | routes/claims.ts |
Sincronizare Redis (/api/sync-redis)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| POST | / | Sincronizeaza tot framework-ul din PG in Redis | routes/sync-redis.ts |
| GET | /status | Cand s-a facut ultima sincronizare | routes/sync-redis.ts |
| GET | /data/:category | Citeste o categorie din Redis (debug) | routes/sync-redis.ts |
Categorii sincronizate: techniques (ierarhie completa), sources, claims, verdicts, weights, providers.
Tabele suplimentare citite la sync (schema bos_parammgmt):
component_stage_assignment-- assignment model LLM per componenta + etapa + tier (free/premium); fiecare tier are propriul fallback chaincomponent_prompt-- system prompt + user template per componenta + etapacomponent_config-- configurari JSONB per componenta (config_key / config_value)
Structura tier-nested a stage_assignments in Redis (dupa migration 006 care a adaugat coloana tier):
{
"techniques_screening": {
"free": { "stage": "...", "description": "...", "models": [{order:1, model_key:"qwen35:Qwen3.5-397B-A17B", ...}, ...] },
"premium": { "stage": "...", "description": "...", "models": [{order:1, model_key:"openrouter:google/gemini-3-flash-preview", ...}, ...] }
},
"techniques_deep": { "free": {...}, "premium": {...} }
}
sync-redis.ts fetchStageAssignments() citeste PG cu ORDER BY component_code, stage_code, tier, fallback_order si construieste obiectul nested pe tier. Grouping logic: result[component_code][stage_code][tier].models.push(...).
Componente acoperite (VERSION_MAP): techniques (v3), ai-tampered (v1), claims (v1), pipeline (v1), vision (v1), source-assessment (v1), verdict (v1). Fiecare componenta poate avea rows cu component_code dedicat (inclusiv vision + verdict care au fost adaugate in Etapele 4-5).
Chei Redis scrise:
didi:framework:manifest -- index categorii + timestamp sync
didi:framework:techniques -- ierarhie dimensiuni -> subdimensiuni -> tehnici -> indicatori/reguli
didi:framework:sources -- evaluare surse
didi:framework:claims -- parametri claims
didi:framework:verdicts -- categorii verdict + risk mappings
didi:framework:weights -- ponderi + scenarii + multiplicatori
didi:framework:providers -- configurare LLM (optional)
didi:framework:dimensions_compact -- lista compacta dimensiuni (pentru screening)
didi:config:<component>:<version>:stage_assignments -- TIER-NESTED assignments per stage per tier
didi:config:<component>:<version>:available_models -- modele unice din toate etapele si tierele (union)
didi:config:<component>:<version>:prompts:<stage> -- prompturi per etapa
didi:config:<component>:<version>:<config_key> -- configurari JSONB
didi:config:moderation:v1:settings -- single-row din moderation_config
didi:config:moderation:v1:sensitive_topics -- topics active, ordonate
didi:config:moderation:v1:roles -- toate rolurile cu permisiuni
Total config_keys count = 51 (era 48 inainte de phase 1.2). Sync-redis e idempotent: blocul moderation e wrapped in try/catch -- daca migration 011 nu e aplicat, sare silent (graceful degradation).
Sincronizare analiza (/api/sync-analysis) -- LEGACY
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| POST | /:sessionId | Muta o sesiune din Redis in PostgreSQL | routes/sync-analysis.ts |
| POST | /batch | Muta mai multe sesiuni | routes/sync-analysis.ts |
| GET | /pending | Lista sesiuni completate in Redis | routes/sync-analysis.ts |
| GET | /stats | Statistici analize | routes/sync-analysis.ts |
Nota: agent-v3 scrie acum direct in PG prin PersistService. Aceste rute sunt legacy.
Autentificare (/api/auth)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /me | Profil utilizator curent (auto-creeaza daca nu exista) | routes/auth.ts |
| POST | /register | Inregistrare utilizator in Keycloak + PG | routes/auth.ts |
| GET | /credits | Credite ramase | routes/auth.ts |
| POST | /use-credit | Deduce credite (necesita JWT) | routes/auth.ts |
| PUT | /profile | Actualizeaza profil | routes/auth.ts |
| GET | /verify-email | Pagina confirmare verificare email (HTML, query param: key) | routes/auth.ts |
| POST | /verify-email | Executa verificare email in Keycloak (body: key) | routes/auth.ts |
Auto-inregistrare la GET /me:
- Creeaza person + address + persoana_fizica + internet_user + user_credential + subscription + contact
- Plan default: Free, 100 credite, 1GB stocare
- Creeaza bucket MinIO: user-{internetUserId}
Schema PG: bos_sysadmin (user_credential, internet_user, subscription) + bos_subscriber (persoana_fizica, contact)
Autentificare interna (/api/auth/internal)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| POST | /check-credits | Verificare credite + returneaza planType pentru tier routing | routes/auth.ts |
| POST | /deduct-credits | Deducere credite (body: keycloak_id, media_type, session_id) | routes/auth.ts |
| POST | /get-bucket-info | Info bucket MinIO pentru upload (body: keycloak_id, mime_type) | routes/auth.ts |
check-credits response include planType (1-6) pe care agent-v3 il foloseste pentru a deriva searchTier (plan_type 1-3 = free, plan_type 4-6 = premium):
{
"success": true,
"data": {
"hasEnoughCredits": true,
"creditsRemained": 600,
"creditCost": 1,
"planName": "Pro/Protector",
"planType": 4,
"mediaType": "text"
}
}
Acesta e punctul unic de adevar pentru tier: agent-v3 nu determina tier-ul din JWT sau body, ci il primeste de aici. Asta previne escaladarea de privilegii (un utilizator nu poate trimite plan_type: 6 in request ca sa primeasca modele premium).
Admin (/api/admin)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /users | Lista utilizatori paginata (Keycloak + PG) | routes/admin.ts |
| GET | /users/:id | Detalii utilizator | routes/admin.ts |
| POST | /users/sync | Sincronizeaza utilizator din Keycloak in PG (body: keycloakId) | routes/admin.ts |
| PUT | /users/:id | Actualizeaza utilizator | routes/admin.ts |
| PUT | /users/:id/email-verified | Seteaza emailVerified in Keycloak (body: emailVerified) | routes/admin.ts |
| DELETE | /users/:id | Sterge utilizator (Keycloak + PG + MinIO bucket) | routes/admin.ts |
| PUT | /users/:id/subscription | Schimba abonament | routes/admin.ts |
| GET | /plans | Lista planuri abonament | routes/admin.ts |
| GET | /plans/:id | Detalii plan abonament | routes/admin.ts |
| PUT | /plans/:id | Actualizeaza plan abonament | routes/admin.ts |
Istoric analize (/api/history)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Istoric utilizator paginat (necesita ?user_id=) | routes/history.ts |
| GET | /admin | Istoric admin (toti utilizatorii, filtre) | routes/history.ts |
| GET | /:sessionId | Detaliu complet analiza (flat canonical types) | routes/history.ts |
| DELETE | /:sessionId | Sterge analiza (necesita ?user_id=, valideaza ownership) | routes/history.ts |
Filtre admin: user_id, search, status, risk_level, from_date, to_date Filtre user: user_id (obligatoriu), page, limit Lista light: fara JSONB-uri grele, doar scoruri sumare Schema PG: bos_analysis
Abonamente (/api/subscriptions)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /usage | Credite ramase, plan, statistici utilizare | routes/subscriptions.ts |
| GET | /plans | Lista planuri disponibile | routes/subscriptions.ts |
Fisiere (/api/uploads)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /health | Health MinIO | routes/uploads.ts |
| POST | / | Upload fisier singular (multipart, max 500MB video) | routes/uploads.ts |
| POST | /multipart | Upload fisiere multiple (max 10, camp: files) | routes/uploads.ts |
| GET | /:fileId | Download fisier | routes/uploads.ts |
| GET | /:fileId/url | URL presemnat download | routes/uploads.ts |
| DELETE | /:fileId | Sterge fisier | routes/uploads.ts |
| GET | / | Lista fisiere | routes/uploads.ts |
| GET | /buckets/stats | Statistici bucket-uri | routes/uploads.ts |
Limite: imagine 20MB, audio 100MB, video 500MB, text 10MB, document 50MB. Bucket-uri: uploads, image-files, audio-files, video-files, text-files, document-files, pipeline-artifacts.
Provideri LLM (/api/providers)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /all | Toate cele 4 tipuri combinate | routes/providers.ts |
| GET | /configs | Lista provideri (OpenRouter, Groq, Qwen, etc.) | routes/providers.ts |
| GET,POST,PUT,DELETE | /configs/... | CRUD provideri | routes/providers.ts |
| GET | /models | Lista modele LLM (include input_cost_per_1m, output_cost_per_1m pentru cost calc) | routes/providers.ts |
| GET,POST,PUT,DELETE | /models/... | CRUD modele | routes/providers.ts |
| GET | /assignments | Assignments componenta -> model, include tier; accepta `?tier=free | premium` pentru filtrare |
| GET,POST,PUT,DELETE | /assignments/... | CRUD assignments. POST/PUT accepta campul tier in body |
routes/providers.ts |
| GET | /keys | Lista API keys (mascate) | routes/providers.ts |
| GET,POST,PUT,DELETE | /keys/... | CRUD API keys | routes/providers.ts |
| POST | /test/:providerId | Test conexiune provider | routes/providers.ts |
| GET | /prompts | Prompturi componente (filtre: ?component=X&stage=Y) | routes/providers.ts |
| GET | /prompts/:id | Detalii prompt | routes/providers.ts |
| POST | /prompts | Creeaza prompt (component_code, stage_code, system_prompt, user_template) | routes/providers.ts |
| PUT | /prompts/:id | Actualizeaza prompt | routes/providers.ts |
| DELETE | /prompts/:id | Sterge prompt | routes/providers.ts |
Tier support in providers API:
GET /assignmentsreturneaza TOATE assignments cu campultier(free + premium in acelasi payload), ordonate pecomponent_code, stage_code, tier, fallback_order. Admin dashboard grupeaza per stage in 2 chain-uri si prezinta toggle Free/Premium.GET /assignments?tier=premiumfiltreaza server-side (folosit pentru debug sau integrari care vor doar o parte).POST /assignmentsacceptatierin body (defaults to 'free' daca lipseste).PUT /assignments/:idpoate schimbatierviaCOALESCE($tier, tier)— util pentru a muta un assignment dintr-un tier in altul.
Chei extensie browser (/api/extension-keys)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| POST | / | Creeaza cheie API (format: didi_ext_...) | routes/extension-keys.ts |
| GET | / | Lista chei (admin) | routes/extension-keys.ts |
| GET | /validate | Valideaza cheie si returneaza user info | routes/extension-keys.ts |
| GET | /user/:userId | Chei pentru un utilizator | routes/extension-keys.ts |
| PUT | /:id | Toggle activ/inactiv | routes/extension-keys.ts |
| DELETE | /:id | Revocare cheie | routes/extension-keys.ts |
| POST | /:id/usage | Incrementeaza contor utilizare (by ID) | routes/extension-keys.ts |
| POST | /usage-by-key | Incrementeaza contor utilizare (by API key value) | routes/extension-keys.ts |
Cache Redis: didi:extension:key:* Tabela PG: extension_api_key
Prompturi (/api/prompts)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista fisiere prompt disponibile | routes/prompts.ts |
| GET | /:step | Continut prompt pentru un pas (markdown) | routes/prompts.ts |
| GET | /:step/sections | Extrage sectiuni (headings) din fisierul prompt | routes/prompts.ts |
Pasi: intake, techniques, sources, claims, verdict
Waitlist (/api/waitlist)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| POST | / | Inscriere pe waitlist (public, email + name) | routes/waitlist.ts |
| GET | / | Lista inscrisi (admin) | routes/waitlist.ts |
| GET | /count | Numar total inscrisi (public) | routes/waitlist.ts |
| DELETE | /:id | Sterge inscris (admin) | routes/waitlist.ts |
Nota: Waitlist foloseste o baza de date separata (staging-dataLayer-postgres:5432/misinformation_db), nu baza principala didi-postgres:5432/DIDI.
Profiluri verdict per input type (/api/input-profiles)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista toate profilurile cu override-uri | routes/input-profiles.ts |
| GET | /:code | Un profil cu override-uri (text_no_url, image, video etc.) | routes/input-profiles.ts |
| PUT | /:code | Update profil (ponderi, reguli INCONCLUSIVE, disclosure multipliers) | routes/input-profiles.ts |
| GET | /:code/overrides | Override-uri per profil | routes/input-profiles.ts |
| PUT | /:code/overrides | Update override-uri per profil | routes/input-profiles.ts |
| GET | /scoring-config/:component | Citeste scoring_config per componenta din component_config PG | routes/input-profiles.ts |
| PUT | /scoring-config/:component | Update scoring_config per componenta | routes/input-profiles.ts |
6 profiluri fixe (nu se adauga/sterg): text_no_url, text_with_url, image, audio, video, url.
Fiecare profil defineste: ponderi componente (total=100%), override-uri active, reguli INCONCLUSIVE, AI disclosure multipliers, confidence config.
Sync to Redis: didi:config:pipeline:v1:input_profiles.
Moderation Config (/api/moderation-config)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Citeste tot rand-ul de config (single-row, config_id=1) | routes/moderation-config.ts |
| PUT | / | Update orice camp whitelisted; seteaza updated_by din header x-user-id |
routes/moderation-config.ts |
Campuri whitelisted: triage_enabled, confidence_low, risk_grey_min/max, queue_relax_at, queue_strict_at, auto_tune_enabled, brain_enabled, brain_url, brain_lookup_timeout_ms, brain_write_timeout_ms, brain_confidence_min_silver, brain_semantic_threshold, brain_per_component (JSONB).
Sensitive Topics (/api/sensitive-topics)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /?active=true|false|all | Lista topicuri (default active=true) | routes/sensitive-topics.ts |
| POST | / | Creeaza topic (valideaza topic_code regex [a-z0-9_]+, 409 la duplicat) |
routes/sensitive-topics.ts |
| PUT | /:id | Update label sau is_active | routes/sensitive-topics.ts |
| DELETE | /:id | Soft delete (set is_active=false) | routes/sensitive-topics.ts |
Moderation Roles (/api/moderation-roles)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | / | Lista toate rolurile cu permisiuni | routes/moderation-roles.ts |
| PUT | /:code | Update toggle fields (can_resolve, can_escalate, can_force_gold_brain, is_active) | routes/moderation-roles.ts |
Fara POST/DELETE -- rolurile sunt fixe (moderator, senior_moderator).
Catalog resurse AI (/api/skills) -- Modul 1
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /?health=true | Catalog complet resurse AI (health probe live optional) | routes/skills.ts |
Read-only registry care raspunde la cerinta de caiet "catalog resurse AI: modele / skills / code-jobs". Trei sectiuni:
analysis_components-- nodurile pipeline-ului de analiza (agent-v3), configurabile prin didiFramework (prompturi/modele/ponderi).extractor_skills-- modulele platformei AI (integrare Lot 1): fiecare un serviciu Python izolat pe host-ul platformei AI (AI_PLATFORM_HOST, default<HOST_IP>), apelabil prin API (llm-inference, embeddings, rerank, audio/Whisper, video/BusterX++, extractors, forensic-features, web, cloak, didi-brain). Cu?health=true, didiFramework probeaza live serviciile Lot 1 (fail-open). didiFramework nu descrie logica interna a acestor module — doar le cataloghează si le monitorizeaza prin URL din env.code_jobs-- executie cod = aceleasi module Python containerizate (izolare per container); job-uri ad-hoc pe roadmap.
Plus pointeri: models_catalog -> /api/providers/models, pipelines_catalog -> /api/pipelines.
Env: AI_PLATFORM_HOST (default <HOST_IP>), AI_PLATFORM_TOKEN (Bearer optional pentru gateway/catalog-api Lot 1).
Pipelines (/api/pipelines) -- alias input-profiles, Modul 1
Acelasi router ca /api/input-profiles, expus si sub /api/pipelines fiindca input_type_profile este definitia de pipeline in sensul caietului (Modul 1: creare/editare/clonare/versionare/publicare/activare). Endpoint-uri de lifecycle (pe langa GET/PUT din sectiunea input-profiles):
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| POST | /:code/clone | Cloneaza un profil sub cod nou | routes/input-profiles.ts |
| POST | /:code/activate | Activeaza profilul | routes/input-profiles.ts |
| POST | /:code/deactivate | Dezactiveaza profilul | routes/input-profiles.ts |
| GET | /:code/versions | Istoric versiuni (migration 016) | routes/input-profiles.ts |
| POST | /:code/versions/:versionId/restore | Restaureaza o versiune anterioara | routes/input-profiles.ts |
| POST | /import | Import profil din payload exportat | routes/input-profiles.ts |
Consumat de pagina "Pipelines" din admin-dashboard (dry-run via agent-v3).
Notificari (/api/notifications)
| Metoda | Path | Ce face | Logica in fisier |
|---|---|---|---|
| GET | /health | Verifica conexiunea SMTP (nu trimite) | routes/notifications.ts |
| POST | /test | Trimite email de test (body: to) | routes/notifications.ts |
| POST | /credit-reset | Trigger manual reset credite Free (debug) | routes/notifications.ts |
Autentificare JWT globala (Modul 7)
src/config/jwt-verify.ts exporta jwtVerifyGate(), montat global in server.ts inaintea tuturor rutelor (app.use(jwtVerifyGate())). Orice Bearer token care arata a JWT trebuie sa verifice semnatura RS256 + exp fata de JWKS-ul realm-ului emitent (KEYCLOAK_URL/realms/<realm>/protocol/openid-connect/certs), altfel request-ul primeste 401 (JWT_INVALID). Request-urile fara Bearer JWT (sau cu API key opac) trec neatinse — auth per-ruta (requireAdmin etc.) decide mai departe.
- Realm-uri permise:
JWT_ALLOWED_REALMS(defaultdidi-clients,didi-admins). - Escape hatch dev:
JWT_VERIFY_ENABLED=false(dezactiveaza gate-ul, cu warning zgomotos). - JWKS cache-uit per realm (
createRemoteJWKSetdinjose).
openapi.yaml
Spec OpenAPI la radacina serviciului (openapi.yaml), documenteaza suprafata de API livrata (Modulele 5-7 din caiet).
Utilitare interne
crud-factory.ts
Exporturi: createCrudRouter, createReadOnlyRouter
createCrudRouter -- genereaza automat rute CRUD standard pentru orice tabela:
- GET / -- lista cu count
- GET /:id -- get by ID
- GET /:id/dependencies -- verifica copii
- POST / -- create cu auto-ID (MAX+1) + parameter entry optional
- PUT /:id -- update partial
- DELETE /:id -- safe delete cu dependency check
- DELETE /:id?force=true -- forteaza stergerea
createReadOnlyRouter -- genereaza rute read-only (pentru tabele lookup):
- GET / -- lista cu count
- GET /:id -- get by ID
Configurat prin CrudConfig: tableName, primaryKey, columns[], parameterType, orderBy. Folosit de: verdicts.ts, weights.ts, claims.ts, source-assessment.ts (tabele leaf).
dependency-checker.ts
Verifica dependente intre tabele inainte de stergere:
checkDependencies(table, idColumn, id)-- returneaza canDelete + lista copiibatchCheckDependencies(table, idColumn, ids[])-- verificare batch pentru mai multe inregistrarisafeDelete(table, idColumn, id, force)-- sterge doar daca nu are copiiisLeafTable(table)-- daca nu are copii posibilihasDependencyRules(table)-- daca tabela are reguli de dependenta definitegetDependencyRules(table)-- returneaza regulile de dependentagetDependencySummary(table)-- sumar complet (hasRules, isLeaf, rules, canHaveChildren)
Ierarhia definita: dimension->subdimension->technique->indicator/rule, platform_modifier->platform, source_type->domain_attribute, etc.
Baza de date PostgreSQL
Schema bos_parammgmt (principala)
| Tabela | Scop | Parinte |
|---|---|---|
| dimension | Dimensiuni analiza (nivel 1) | - |
| subdimension | Subdimensiuni (nivel 2) | dimension |
| technique | Tehnici manipulare (nivel 3) | subdimension |
| technique_indicator | Indicatori per tehnica | technique |
| technique_validation_rule | Reguli validare per tehnica | technique |
| parameter | Tracking versiuni + tipuri parametri | referit de multe tabele |
| verdict_category | Categorii verdict (RELIABLE..DISINFO) | - |
| risk_mapping | Mapare scor -> nivel risc | - |
| severity_assessment | Nivele severitate | - |
| component_weight | Ponderi componente analiza | - |
| weight_scenario | Scenarii combinatii ponderi | - |
| multiplier | Multiplicatori (topic, temporal, reach) | - |
| platform | Platforme social media | platform_modifier |
| platform_modifier | Modificatori platforma | - |
| source_type | Tipuri sursa | - |
| source_credibility | Credibilitate sursa | - |
| domain_age_score | Scoruri varsta domeniu | - |
| domain_risk_level | Nivele risc domeniu | - |
| domain_red_flag | Red flags domeniu | - |
| domain_attribute | Atribute domeniu | sursa_type, credibility, age, risk, flag |
| author_classification | Clasificari autor | - |
| author_credibility | Credibilitate autor | - |
| author | Autori | author_classification, author_credibility |
| claim | Statusuri claim (VT, LT, UV, LF, VF) | - |
| claim_type | Tipuri claim (EF, VF, RE, SC, QA) | - |
| confidence | Nivele incredere | - |
| interpretation | Interpretari concordanta | - |
| llm_provider | Provideri LLM | - |
| llm_model | Modele LLM | llm_provider |
| component_provider_assignment | Assignment componenta -> model | llm_provider, llm_model |
| component_stage_assignment | Assignment model LLM per componenta + etapa (cu fallback order) | llm_provider, llm_model |
| component_prompt | Prompturi per componenta + etapa (system_prompt, user_template) | - |
| component_config | Configurari JSONB per componenta (config_key / config_value) | - |
| provider_api_key | Chei API provider | llm_provider |
| extension_api_key | Chei API extensie browser | - |
Tabele noi in bos_parammgmt (migration 011):
| Tabela | Scop | Rute CRUD |
|---|---|---|
moderation_config |
Single-row config (CHECK config_id=1) pentru HIL triage + brain client; 14 campuri inclusiv brain_enabled, brain_url, thresholds, brain_per_component (JSONB) | /api/moderation-config |
sensitive_topic |
Topics care declanseaza HIL review (5 seed: elections, health, war, covid, climate); soft-delete via is_active | /api/sensitive-topics |
moderation_role |
Keycloak role -> permisiuni (2 seed: moderator, senior_moderator); CHECK constraints pe toggles | /api/moderation-roles |
Schema bos_sysadmin (utilizatori)
| Tabela | Scop |
|---|---|
| user_credential | Credentiale utilizator (keycloak_id, parola) |
| internet_user | Profil utilizator (email, credite) |
| subscription | Abonament activ |
| subscription_plan | Planuri disponibile (Free, Pro, Enterprise) |
Schema bos_subscriber (date personale)
| Tabela | Scop |
|---|---|
| person | Date persoana (nume) |
| persoana_fizica | Persoana fizica + CNP |
| address | Adresa |
| contact | Contact (email, telefon) |
Schema bos_analysis (rezultate analize)
| Tabela | Scop |
|---|---|
| analysis_session | Sesiunea root |
| analysis_techniques | Rezultat componenta Techniques |
| analysis_ai_tampered | Rezultat componenta AI-Tampered |
| analysis_claims | Rezultat componenta Claims |
| analysis_domain | Rezultat componenta Domain |
| analysis_verdict | Verdict final |
| moderation_queue | Coada review HIL (FK la analysis_session.session_id UUID); campuri: queue_id BIGSERIAL, priority 1-5, enqueue_reason, status (pending|in_review|resolved|declined|auto_closed), resolution_action (approved|corrected|rejected), assigned_to/resolved_by, time tracking |
6 coloane noi pe analysis_session (migration 011): review_status, human_corrected, human_corrections (JSONB diff), verified_by, verified_at, review_notes.
Accesat prin: routes/history.ts (citire), routes/sync-analysis.ts (scriere legacy)
Servicii externe
| Serviciu | Scop | Unde in cod |
|---|---|---|
PostgreSQL (didi-postgres:5432, local) |
Stocare permanenta parametri + utilizatori + analize (PG17, DB DIDI, user bos_interface, schema bos_parammgmt) |
config/database.ts |
Redis (didi-cache:6379, local ACTIV) |
Cache framework pentru agent-v3 (via createRedisConnection) |
routes/sync-redis.ts |
RabbitMQ (staging-dataLayer-rabbitmq, local) |
Mesagerie analiza | (consumat de agent-v3) |
MinIO (staging-dataLayer-minio:9000, local) |
Stocare fisiere media | config/minio.ts, routes/uploads.ts |
Keycloak (didi-keycloak:8080/auth, local; port extern 28080) |
Autentificare OAuth2, management utilizatori, JWKS pentru jwtVerifyGate | routes/auth.ts, routes/admin.ts, config/jwt-verify.ts |
Kong (gateway local didi-kong) |
Verificare JWT inainte de request | implicit (nu apelat direct) |
Platforma AI (Lot 1, AI_PLATFORM_HOST, default <HOST_IP>) |
Module extractori/LLM probate de catalogul /api/skills |
routes/skills.ts |
Cum comunica cu agent-v3
Framework -> Redis -> agent-v3
- Admin modifica parametri in dashboard (CRUD pe didiFramework)
- Admin apasa "Sync Redis" (POST /api/sync-redis)
- didiFramework citeste toata ierarhia din PostgreSQL
- Scrie JSON-uri compacte in Redis (didi:framework:*)
- agent-v3 citeste din Redis la fiecare analiza
agent-v3 -> didiFramework (credite)
- agent-v3 primeste request de analiza
- Apeleaza POST /api/auth/internal/check-credits (body: keycloak_id, media_type)
- Daca hasEnoughCredits=true, ruleaza analiza
- Apeleaza POST /api/auth/internal/deduct-credits (body: keycloak_id, media_type, session_id)
agent-v3 -> didiFramework (extensie browser)
- Extensia browser trimite request cu X-API-Key la agent-v3
- agent-v3 apeleaza GET /api/extension-keys/validate?api_key=... (validare cheie)
- didiFramework returneaza user_id, user_email, is_active
- agent-v3 ruleaza analiza cu identitatea validata
Pattern-uri importante
- Safe delete -- orice parinte verifica copiii inainte de stergere, cu raspuns detaliat
- Parameter table -- fiecare entitate creata genereaza un record in
parameter(versionare) - CRUD factory -- tabele simple folosesc crud-factory.ts (un singur fisier configurat)
- Typo workaround -- coloana
subdmiension_namecorectata in cod lasubdimension_name - Auto-inregistrare -- GET /me creeaza utilizatorul daca exista in Keycloak dar nu in PG
- Bucket per user -- MinIO creeaza bucket
user-{id}cu folder-e tipizate la inregistrare - Light history -- listele de istoric nu includ JSONB-uri, doar scoruri sumare
- Flat canonical types -- detaliul unei analize returneaza acelasi format ca agent-v3
- Tier (free/premium) -- toate stage_assignments au coloana
tier. sync-redis emite structura nested{stage_code: {free: {...}, premium: {...}}}. agent-v3 rezolva tier-ul dinplanTypereturnat de check-credits si ruleaza chain-ul corespunzator cu fallback automat la 'free' daca 'premium' lipseste. - HIL triage in pipeline -- fiecare run de analiza trece prin
shouldEnqueueForReview()dupa persist. Wrapped in try/catch -- esecul NU blocheaza analiza. Citeste pragurile din Redis (60s cache). - Soft role check -- in staging (fara JWT) toate endpoint-urile de moderare permit; in productie cu JWT validat de Kong +
realm_access.roles, check strict.
Migration history (SQL)
Directorul sql/migrations/ contine migratiile aplicate manual pe cluster (nu rulate automat la startup):
| Migration | Descriere |
|---|---|
| 001_add_explanation_columns.sql | analysis_verdict.explanation_ro/_en + view v_analysis_full |
| 002_add_component_pilot_config.sql | component_stage_assignment, component_prompt, component_config tables |
| 003_add_source_assessment.sql | source_assessment component rows + source evaluation tables |
| 004_add_llm_usage.sql | analysis_session.llm_usage JSONB (tokens per componenta) |
| 005_add_bilingual_columns.sql | Coloane _ro / _en pe tehnici/prompts |
| 006_add_tier_column.sql | **component_stage_assignment.tier varchar(20) DEFAULT 'free' + unique constraint (component_code, stage_code, tier, fallback_order) + CHECK constraint (free |
| 007_seed_premium_assignments.sql | Seed 32 rows tier='premium' pentru cele 8 stages LLM (techniques/ai-tampered/claims/source-assessment) — Gemini 3 Flash + Claude Sonnet + Grok 4 Fast + Qwen local |
| 008_seed_vision_assignments.sql | Seed 7 rows pentru component vision stage image_analysis (3 free + 4 premium) — citit de agent-v3 vision.ts |
| 009_seed_verdict_assignments.sql | Seed 8 rows pentru component verdict stage verdict_review (4 free + 4 premium) — citit de verdict-explanation.ts |
| 010_add_user_storage_quota.sql | 2 coloane pe bos_sysadmin.internet_user pentru cota de stocare (arhitectura single-bucket MinIO post-2026-04-25, inlocuieste bucket tags) — acces instant la quota fara listare prefix |
| 011_add_moderation.sql | HIL Moderation foundation: 6 coloane pe analysis_session, tabela moderation_queue (in bos_analysis), 3 tabele config in bos_parammgmt cu seed-uri. Companion 011_rollback.sql. UUID type pentru FK. |
| 012_add_topic_volatility.sql | **Phase D1 — extends bos_parammgmt.sensitive_topic cu `volatility ('volatile' |
| 013_user_audit_log.sql | Phase U — bos_sysadmin.user_audit_log (audit_id bigserial, internet_user_id, target_email/keycloak_id, actor_keycloak_id/email, action, payload jsonb, request_ip, user_agent, created_at). 4 indexes (user, actor, action+time, time). Powers DIDI admin "Audit Log" tab. Companion 013_rollback.sql. |
| 014_add_atomic_path_prefix.sql | Punte sensitive_topic -> taxonomie atomic: coloana optionala atomic_path_prefix care mapeaza un topic_code policy-level (ex. 'health') la prefixul de path din atomic-server. Companion 014_rollback.sql. |
| 015_social_post.sql | DESI 6 — bos_sysadmin.social_post (post_id bigserial, session_id UUID optional, platform, continut, autor, timestamp, engagement) pentru postare social media (Facebook) din admin-dashboard + audit PNRR. Companion 015_rollback.sql. |
| 016_input_profile_versions.sql | Modul 1 — bos_parammgmt.input_type_profile_version: fiecare PUT pe /api/input-profiles(/pipelines)/:code face snapshot al randului anterior inainte de modificare (edit -> version -> restore -> activate/deactivate -> clone). Companion 016_rollback.sql. |
| 017_model_catalog_attributes.sql | Atribute de catalog cerute de caiet pe llm_model: deployment (local/remote), compute_target (gpu/cpu/hybrid), quantization, capabilities (jsonb). Companion 017_rollback.sql. |
Migrations 006-009 sunt cele care au introdus tier-based routing. Aplicare manual cu docker exec didi-framework node -e "fs.readFileSync + pool.query" (sync-redis nu ruleaza migrations automat).
Functionalitati suplimentare (in afara celor 9 module de caiet)
Elemente livrate care nu fac parte din cele 9 module ale caietului de sarcini, dar sunt operationale in serviciu:
| Functionalitate | Unde in cod | Note |
|---|---|---|
| Plati Stripe | routes/webhooks/stripe.ts (montat la /webhooks/stripe, raw body inaintea express.json) |
Test mode; secret in .env (STRIPE_*) |
| Postare social media (DESI 6) | routes/admin/social.ts + migration 015_social_post.sql |
Facebook Graph API (FACEBOOK_* in .env); audit PNRR cine/ce/cand |
| HIL moderation (triage + brain client) | routes/moderation-config.ts, routes/sensitive-topics.ts, routes/moderation-roles.ts + migration 011 |
Config expus si in dashboard (ModerationSettings) |
| Chei API extensie browser | routes/extension-keys.ts |
Format didi_ext_..., cache Redis didi:extension:key:* |
| Notificari email | routes/notifications.ts + config/email.ts + credit-reset cron |
SMTP mail.finesynergy.eu (SMTP_* in .env) |
Phase U — User management endpoints (2026-05-05)
src/routes/admin.ts extins masiv pentru a permite admin-ului să facă tot CRUD-ul de Keycloak fără să intre în consola Keycloak.
Helpers Keycloak (in-memory cache 10min)
listRealmRoles()— lista realm roles (filtrează default-uri Keycloak:offline_access,uma_authorization,default-roles-didi-clients).getUserRoles(keycloakId, force?)— current realm roles per user.setUserRoles(keycloakId, desiredNames[])— diff add/remove pe role-mappings. Returnează{added, removed, errors}.listKeycloakGroups()/getUserGroups()/setUserGroup()— același pattern pentru grupuri (single membership).sendResetPasswordEmail(keycloakId, {lifespanSeconds, redirectUri})— Keycloakexecute-actions-emailcuUPDATE_PASSWORD.logUserAudit(req, ctx)— extrage actor din JWT, INSERT înbos_sysadmin.user_audit_log. Best-effort (swallow errors). Apelat din toate mutațiile.
Endpoint-uri noi
GET /api/admin/realm-roles — lista roluri eligibile
GET /api/admin/groups — lista grupuri Keycloak
GET /api/admin/users/:id/roles — rolurile current
PUT /api/admin/users/:id/roles — body {roles: ["name", ...]} → diff add/remove (audit logged)
GET /api/admin/users/:id/group — grupul current (single)
PUT /api/admin/users/:id/group — body {group: "name" | null} (audit logged)
POST /api/admin/users/:id/reset-password — body {lifespanSeconds?, redirectUri?} → email Keycloak (audit logged)
GET /api/admin/users/:id/usage-history?limit=100 — citește bos_sysadmin.ai_credit_usage flexibly
GET /api/admin/audit-log?action=&actor=&since=&internet_user_id=&limit=&offset= — paginated browser
GET /api/admin/users extins
Răspunsul include acum storageUsedBytes, storageLimitBytes, storagePct, roles[], groups[] per user. Acceptă query ?sync_status=all|synced|keycloak_only și ?include_kc_meta=false pentru a sări over fan-out-ul Keycloak când nu e nevoie.
Endpoint-uri existente — acum loghează audit
PUT /:id, DELETE /:id, POST /sync, PUT /:id/email-verified, PUT /:id/subscription apelează logUserAudit cu payload ce conține diff-ul aplicat.
sensitive-topics.ts — 4 câmpuri noi în CRUD
GET returnează volatility/cache_ttl_hours/recency_window_days/half_life_days. POST și PUT acceptă acelea opționale + validare server-side a range-urilor (ttl 1-26280, recency 1-365, half_life > 0). validateVolatilityFields helper centralizează regulile alături de CHECK constraints PG.
sync-redis.ts — key Redis nou
didi:config:topics:volatility ← {topics: [{topic_code, topic_label, volatility, cache_ttl_hours,
recency_window_days, half_life_days}, ...], synced_at}
Brain (topic_volatility.py) citește prin HTTP la didi-framework:3005/api/sensitive-topics (cache 60s). Cheia legacy didi:config:moderation:v1:sensitive_topics e neschimbată ca shape — agent-v3 triage continuă să o citească identic.
Compose env
KEYCLOAK_URL=http://didi-keycloak:8080/auth ← Keycloak LOCAL pe didi-network, servit sub /auth (KC_HTTP_RELATIVE_PATH)
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=admin123
Trafic intern plain HTTP catre containerul local didi-keycloak — nu mai exista cert cluster auto-semnat, deci NODE_TLS_REJECT_UNAUTHORIZED=0 a fost eliminat.