livrare lot 2

This commit is contained in:
EVOTECH IT SRL 2026-07-10 03:39:53 -07:00
commit 8ecc78e729
763 changed files with 164593 additions and 0 deletions

View file

@ -0,0 +1,704 @@
# VERDICT UI SPECIFICATION
Design UI admin dashboard — tot ce se editeaza pentru a controla verdictul.
Pagina: `/admin/verdict-config` (tab nou in sidebar, sau sub-pagina in LLM Components Config)
---
## LAYOUT GENERAL
```
┌─────────────────────────────────────────────────────────────────────┐
│ SIDEBAR │ CONTENT │
│ │ │
│ [1] Input Profiles ◄────│ ┌─────────────────────────────────┐ │
│ [2] Override Rules │ │ Tab content here │ │
│ [3] AI Disclosure │ │ │ │
│ [4] Claims Weights │ │ │ │
│ [5] Verdict Categories │ │ │ │
│ [6] Risk & Severity │ │ │ │
│ [7] Confidence │ │ │ │
│ [8] Topic Multipliers │ │ │ │
│ [9] LLM Reviewer │ │ │ │
│ [10] Score Simulator ★ │ │ │ │
│ │ └─────────────────────────────────┘ │
│ ────────────────── │ │
│ [Sync to Redis] │ [Save] [Reset to defaults] │
└─────────────────────────────────────────────────────────────────────┘
```
---
## TAB 1: INPUT PROFILES — Ponderi per tip input
**Ce controleaza**: Cat conteaza fiecare componenta in scorul final, per tip de input.
**Formula afectata**: `risk_score = sum(component_risk × weight) / sum(weights)`
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ Input Profiles │
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ [Text] [Text+URL] [Image] [Audio] [Video] [URL] │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ▲ tab selectat: Image │
│ │
│ Profile: Image │
│ Description: "Analiza imagine — AI detection e componenta primara" │
│ │
│ ┌─ COMPONENT WEIGHTS ─────────────────────────────────────────┐ │
│ │ │ │
│ │ Techniques ████████░░░░░░░░░░░░ 20% [role: secondary]│ │
│ │ Claims ██████░░░░░░░░░░░░░ 15% [role: secondary]│ │
│ │ AI Tampered █████████████████████░░ 50% [role: PRIMARY ]│ │
│ │ Source ██████░░░░░░░░░░░░ 15% [role: secondary]│ │
│ │ ──── │ │
│ │ Total: 100% ✓ │ │
│ │ │ │
│ │ ⚠ Total must equal 100%. Drag sliders to adjust. │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ INCONCLUSIVE RULES ────────────────────────────────────────┐ │
│ │ │ │
│ │ Minimum components to produce verdict: [ 1 ] ▼ │ │
│ │ │ │
│ │ Primary component(s) — INCONCLUSIVE if ALL crash: │ │
│ │ [✓] AI Tampered │ │
│ │ [ ] Techniques │ │
│ │ [ ] Claims │ │
│ │ [ ] Source │ │
│ │ │ │
│ │ Required ANY (at least one must run): │ │
│ │ [✓] AI Tampered │ │
│ │ [ ] Techniques │ │
│ │ [ ] Claims │ │
│ │ [ ] Source │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ MISSING COMPONENT HANDLING ────────────────────────────────┐ │
│ │ │ │
│ │ When Techniques is missing: [Redistribute ] ▼ │ │
│ │ When Claims is missing: [Redistribute + penalty] ▼ │ │
│ │ When AI Tampered is missing: [→ INCONCLUSIVE ] ▼ │ │
│ │ When Source is missing: [Redistribute ] ▼ │ │
│ │ │ │
│ │ Options: Redistribute | Redistribute + confidence penalty │ │
│ │ | → INCONCLUSIVE | Ignore (weight=0) │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ [Save Profile] [Reset to Default] [Copy from: [Text ▼] ] │
└─────────────────────────────────────────────────────────────────────┘
```
### Tabel CRUD in PG
| Coloana | Tip | Exemplu | UI element |
|---|---|---|---|
| `profile_code` | VARCHAR PK | "image" | Tab selector |
| `profile_name` | VARCHAR | "Analiza imagine" | Text input |
| `description` | TEXT | "AI detection e componenta primara" | Textarea |
| `weight_techniques` | INTEGER | 20 | Slider 0-100 |
| `weight_claims` | INTEGER | 15 | Slider 0-100 |
| `weight_ai_tampered` | INTEGER | 50 | Slider 0-100 |
| `weight_source` | INTEGER | 15 | Slider 0-100 |
| `role_techniques` | VARCHAR | "secondary" | Dropdown |
| `role_claims` | VARCHAR | "secondary" | Dropdown |
| `role_ai_tampered` | VARCHAR | "primary" | Dropdown |
| `role_source` | VARCHAR | "secondary" | Dropdown |
| `min_components` | INTEGER | 1 | Number input |
| `primary_components` | TEXT[] | {"ai_tampered"} | Checkboxes |
| `required_any` | TEXT[] | {"ai_tampered"} | Checkboxes |
| `missing_techniques` | VARCHAR | "redistribute" | Dropdown |
| `missing_claims` | VARCHAR | "redistribute_penalty" | Dropdown |
| `missing_ai_tampered` | VARCHAR | "inconclusive" | Dropdown |
| `missing_source` | VARCHAR | "redistribute" | Dropdown |
| `is_active` | BOOLEAN | true | Toggle |
**6 profiluri default**: text_no_url, text_with_url, image, audio, video, url
---
## TAB 2: OVERRIDE RULES — Bonusuri de risc per profil
**Ce controleaza**: Ce override-uri se aplica si cu ce valori, per tip de input.
**Formula afectata**: `risk_score += sum(override_bonuses)` (dupa media ponderata, cap configurat)
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ Override Rules │
│ │
│ Profile: [Image ▼] Override Cap Total: [ 50 ] puncte │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Override │ Activ │ Parametri │ Impact │ │
│ ├───────────────────────┼───────┼────────────────────┼─────────┤ │
│ │ False Claims │ [ON] │ +[15]/claim max[40]│ MARE │ │
│ │ Unverified Verifiable │ [ON] │ prag[3] bonus[10] │ MEDIU │ │
│ │ Severe Techniques │ [ON] │ prag[2] bonus[10] │ MEDIU │ │
│ │ Undisclosed AI │ [ON] │ bonus [10] │ MEDIU │ │
│ │ Untrusted Source │ [OFF] │ bonus [20] │ — │ │
│ │ Blacklisted Source │ [OFF] │ bonus [25] │ — │ │
│ │ Source Red Flags │ [OFF] │ prag[2] +[5] mx[15]│ — │ │
│ │ Synergy (multi high) │ [ON] │ prag[70] +[5] mx[15│ MEDIU │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ Nota: Override-uri dezactivate (OFF) nu contribuie la scor │
│ indiferent de datele componentelor. │
│ │
│ ┌─ EXEMPLU LIVE ──────────────────────────────────────────────┐ │
│ │ Cu setarile curente, daca 2 claims false + undisclosed AI: │ │
│ │ Override total: 2×15 + 10 = +40 puncte (sub cap 50) ✓ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ [Save] [Copy overrides from: [Text ▼] ] │
└─────────────────────────────────────────────────────────────────────┘
```
### Tabel CRUD in PG
| Coloana | Tip | Exemplu |
|---|---|---|
| `profile_code` | VARCHAR FK | "image" |
| `override_code` | VARCHAR | "false_claims" |
| `enabled` | BOOLEAN | true |
| `threshold` | INTEGER NULL | 1 (min claims false pt activare) |
| `bonus_per_unit` | INTEGER NULL | 15 (per claim fals) |
| `bonus_fixed` | INTEGER NULL | NULL (foloseste per_unit) |
| `max_bonus` | INTEGER NULL | 40 |
| `override_cap` | INTEGER | 50 (pe intregul profil) |
**8 override-uri × 6 profiluri = 48 randuri** (pre-populate la creare profil)
---
## TAB 3: AI DISCLOSURE — Multiplicatori disclosure
**Ce controleaza**: Cat de mult conteaza AI detection cand AI-ul e declarat vs nedeclarat.
**Formula afectata**: `ai_risk = ai_probability × disclosure_multiplier`
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ AI Disclosure Impact │
│ │
│ Cand continutul AI e declarat, riscul scade proportional. │
│ Misinformarea prin AI vine din DECEPTIE, nu din AI in sine. │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Explicit disclosure ██░░░░░░░░░░░░░░░░ 0.15 (15%) │ │
│ │ ("Scris cu ChatGPT") │ │
│ │ Exemplu: AI prob=80 → risk = 80 × 0.15 = 12 │ │
│ │ │ │
│ │ Partial disclosure ████████░░░░░░░░░░ 0.40 (40%) │ │
│ │ ("Cu ajutorul AI") │ │
│ │ Exemplu: AI prob=80 → risk = 80 × 0.40 = 32 │ │
│ │ │ │
│ │ Implied disclosure ████████████░░░░░░ 0.60 (60%) │ │
│ │ (Mentionat ChatGPT) │ │
│ │ Exemplu: AI prob=80 → risk = 80 × 0.60 = 48 │ │
│ │ │ │
│ │ No disclosure ████████████████████ 1.00 (100%) │ │
│ │ (Nedeclarat) │ │
│ │ Exemplu: AI prob=80 → risk = 80 × 1.00 = 80 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ Acesti multiplicatori se aplica pe TOATE profilurile. │
│ Override-ul "Undisclosed AI" (tab Override Rules) se aplica │
│ suplimentar DOAR cand disclosure = none. │
│ │
│ [Save] [Reset to defaults] │
└─────────────────────────────────────────────────────────────────────┘
```
### CRUD
Se poate stoca in `component_config` existent (JSONB) sau tabel dedicat.
| Coloana | Tip | Exemplu |
|---|---|---|
| `disclosure_type` | VARCHAR PK | "explicit" |
| `multiplier` | NUMERIC | 0.15 |
| `description` | TEXT | "AI declarat clar — aproape zero risc" |
| `example` | TEXT | "Acest articol a fost scris cu ChatGPT" |
**4 randuri fixe** (explicit, partial, implied, none). Nu se adauga/sterg, doar se editeaza multiplicatorii.
---
## TAB 4: CLAIMS WEIGHTS — Ponderi credibilitate per status si tip
**Ce controleaza**: Cum contribuie fiecare claim la scorul de credibilitate.
**Formula afectata**: `credibility_score = sum(status_weight × type_weight) / sum(type_weight)`
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ Claims Scoring Configuration │
│ │
│ ┌─ STATUS WEIGHTS (cat valoreaza fiecare status) ─────────────┐ │
│ │ │ │
│ │ VT Verified True ████████████████████ [ 1.00 ] │ │
│ │ LT Likely True ███████████████░░░░░ [ 0.75 ] │ │
│ │ UV Unverified (per tip — vezi mai jos) │ │
│ │ OP Opinion as Fact ██████░░░░░░░░░░░░░ [ 0.30 ] │ │
│ │ LF Likely False █████░░░░░░░░░░░░░░ [ 0.25 ] │ │
│ │ VF Verified False ░░░░░░░░░░░░░░░░░░░ [ 0.00 ] │ │
│ │ NV Not Verifiable (exclus din calcul) │ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ UNVERIFIED WEIGHTS PER CLAIM TYPE ─────────────────────────┐ │
│ │ │ │
│ │ Tip claim │ Cod │ UV Weight │ Logica │ │
│ │ ──────────────────┼─────┼───────────┼─────────────────── │ │
│ │ Factual verificab.│ VF │ [0.25] ██ │ Suspect — faptele │ │
│ │ │ │ │ reale au surse web │ │
│ │ Stiintific │ SC │ [0.25] ██ │ Studiile sunt publice │ │
│ │ Cantitativ │ QA │ [0.30] ██ │ Statisticile au sursa │ │
│ │ Factual general │ EF │ [0.35] ██ │ Moderat suspect │ │
│ │ Cauzal │ CC │ [0.40] ██ │ Greu de verificat │ │
│ │ Reglementare │ RE │ [0.40] ██ │ Moderat │ │
│ │ Predictiv │ PC │ [0.50] ██ │ Viitorul nu se verif. │ │
│ │ Opinie/Valoare │ OP │ [0.50] ██ │ Opiniile nu se verif. │ │
│ │ │ │
│ │ ⚠ Valori mici (0.25) = "neverificat e suspect" │ │
│ │ Valori mari (0.50) = "neverificat e neutru" │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ CAZUL SPECIAL: TOATE NEVERIFICATE ─────────────────────────┐ │
│ │ │ │
│ │ Cand TOATE claims sunt UV si fara surse web: │ │
│ │ Comportament: [Calculeaza normal per tip ▼] │ │
│ │ │ │
│ │ Optiuni: │ │
│ │ • Calculeaza normal per tip (propus) │ │
│ │ • Forteaza credibility 75% (actual) │ │
│ │ • Forteaza credibility 50% (neutru strict) │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ [Save] [Reset to defaults] │
└─────────────────────────────────────────────────────────────────────┘
```
### CRUD — camp NOU in tabel existent
Tabelul `claim_type` din `bos_parammgmt` primeste coloana:
| Coloana noua | Tip | Default |
|---|---|---|
| `unverified_weight` | NUMERIC(3,2) | 0.50 |
Tabelul `claim` (statuses) primeste coloana:
| Coloana noua | Tip | Default |
|---|---|---|
| `credibility_weight` | NUMERIC(3,2) | 0.50 |
**Deja exista UI** in FrameworkDashboard → Claims → Types/Status. Se adauga doar coloana noua in tabelul CRUD existent.
---
## TAB 5: VERDICT CATEGORIES — Range-uri scor → categorie
**Ce controleaza**: Ce eticheta primeste scorul final (RELIABLE, MIXED, DISINFORMATION etc.)
**DEJA EXISTA** in FrameworkDashboard → Verdicts → Categories. Doar se regrupeaza aici.
### UI Layout (mutata din FrameworkDashboard)
```
┌─────────────────────────────────────────────────────────────────────┐
│ Verdict Categories │
│ │
│ Scor │ 0────15│16───30│31───55│56───75│76───90│91──100│ │
│ │ RELIAB │MOSTLY │ MIXED │QUESTI │UNRELI │DISINF│ │
│ │ verde │l.green│galben │portoc.│ rosu │bordo │ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Cod │ Range │ Culoare │ Descriere │ │
│ ├──────────────────┼──────────┼─────────┼─────────────────────┤ │
│ │ RELIABLE │ [0]-[15] │ [green] │ [Continut de incr.] │ │
│ │ MOSTLY_RELIABLE │ [16]-[30]│ [l.grn] │ [Preponderent cred] │ │
│ │ MIXED │ [31]-[55]│ [yellw] │ [Informatie mixta ] │ │
│ │ QUESTIONABLE │ [56]-[75]│ [ornge] │ [Indoielnic ] │ │
│ │ UNRELIABLE │ [76]-[90]│ [red ] │ [Putin credibil ] │ │
│ │ DISINFORMATION │ [91]-[100│ [dkred] │ [Probabil dezinf. ] │ │
│ │ INCONCLUSIVE │ special │ [gray ] │ [Date insuficiente] │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ⚠ Range-urile trebuie sa acopere 0-100 fara gap-uri. │
│ INCONCLUSIVE e setat algoritmic din profil, nu din range. │
│ │
│ [Save] [Add Category] [Reset to defaults] │
└─────────────────────────────────────────────────────────────────────┘
```
### CRUD — tabel existent `verdict_category`
Deja exista. Zero schimbari PG.
---
## TAB 6: RISK & SEVERITY — Nivele de risc + actiuni recomandate
**DEJA EXISTA** in FrameworkDashboard → Verdicts → Risk / Severity. Se regrupeaza.
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ Risk Levels & Severity │
│ │
│ ┌─ RISK LEVELS ───────────────────────────────────────────────┐ │
│ │ Nivel │ Range │ Culoare │ │ │
│ │ VERY_LOW │ [0]-[10] │ [green] │ │ │
│ │ LOW │ [11]-[25]│ [l.grn] │ │ │
│ │ MEDIUM │ [26]-[50]│ [yellw] │ │ │
│ │ HIGH │ [51]-[75]│ [ornge] │ │ │
│ │ VERY_HIGH │ [76]-[90]│ [red ] │ │ │
│ │ CRITICAL │ [91]-[100│ [dkred] │ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ SEVERITY + ACTIUNI ────────────────────────────────────────┐ │
│ │ Severity │ Range │ Actiune recomandata │ │
│ │ LOW │ [0]-[29] │ [MONITOR ] │ │
│ │ MEDIUM │ [30]-[59]│ [REVIEW ] │ │
│ │ HIGH │ [60]-[79]│ [ESCALATE ] │ │
│ │ CRITICAL │ [80]-[100│ [URGENT ] │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ [Save] [Reset to defaults] │
└─────────────────────────────────────────────────────────────────────┘
```
### CRUD — tabele existente `risk_mapping`, `severity_assessment`
Deja exista. Zero schimbari PG.
---
## TAB 7: CONFIDENCE — Cum se calculeaza increderea
**Ce controleaza**: Cat de siguri suntem pe verdictul dat.
**Formula afectata**: `confidence = base × components_ok - penalties + bonuses`
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ Confidence Configuration │
│ │
│ Profile: [Image ▼] (confidence se configureaza PER profil) │
│ │
│ ┌─ BASE ──────────────────────────────────────────────────────┐ │
│ │ Base per component available: [15] puncte │ │
│ │ (4 componente × 15 = 60 baza maxima) │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ PENALTIES (cand o componenta CRAPAT — nu lipsa, ci eroare) ┐ │
│ │ │ │
│ │ Claims crash: -[25] puncte (cel mai sever) │ │
│ │ Techniques crash: -[15] puncte │ │
│ │ AI Tampered crash: -[10] puncte │ │
│ │ Source crash: -[5] puncte │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ BONUSES (semnale puternice cresc increderea) ──────────────┐ │
│ │ │ │
│ │ Source verdict TRUSTED/UNTRUSTED (semnal clar): +[15] │ │
│ │ Source verdict NEUTRAL/SUSPICIOUS (semnal slab): +[8] │ │
│ │ Techniques: avg(confidence) / 100 × [12] max │ │
│ │ AI confidence HIGH: +[12] MEDIUM: +[8] LOW: +[4] │ │
│ │ Claims verified ratio × [11] max │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ LEVELS ────────────────────────────────────────────────────┐ │
│ │ HIGH: >= [75] │ │
│ │ MEDIUM: >= [50] │ │
│ │ LOW: < [50] │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ [Save] [Copy from: [Text ▼] ] [Reset to defaults] │
└─────────────────────────────────────────────────────────────────────┘
```
### CRUD
Stocat in `input_type_profile.confidence_config` (JSONB) sau tabel separat `profile_confidence_config`.
---
## TAB 8: TOPIC MULTIPLIERS — Amplificatori de context
**Ce controleaza**: Anumite topicuri (alegeri, sanatate) amplifica riscul.
**Formula afectata**: `risk_score = weighted_average × topic_multiplier` (INAINTE de override)
**DEJA EXISTA** in FrameworkDashboard → Weights → Multipliers. Se regrupeaza.
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ Topic Multipliers │
│ │
│ Acesti multiplicatori se aplica INAINTE de override-uri. │
│ Valoare > 100% = amplifica riscul. < 100% = reduce riscul.
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Topic │ Multiplicator │ Efect pe scor 50 │ │
│ ├───────────────┼───────────────┼─────────────────────────────┤ │
│ │ elections │ [150]% ████ │ 50 → 75 (+50%) │ │
│ │ health │ [130]% ███ │ 50 → 65 (+30%) │ │
│ │ climate │ [120]% ██ │ 50 → 60 (+20%) │ │
│ │ finance │ [110]% ██ │ 50 → 55 (+10%) │ │
│ │ entertainment │ [ 80]% █ │ 50 → 40 (-20%) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ [Add Topic] [Save] [Reset to defaults] │
└─────────────────────────────────────────────────────────────────────┘
```
### CRUD — tabel existent `multiplier`
Deja exista. Zero schimbari PG.
---
## TAB 9: LLM REVIEWER — Configurare reviewer final
**Ce controleaza**: Cata putere are LLM-ul sa ajusteze verdictul matematic.
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ LLM Verdict Reviewer │
│ │
│ ┌─ GENERAL ───────────────────────────────────────────────────┐ │
│ │ Enabled: [ON] │ │
│ │ Max adjustment: ±[20] puncte │ │
│ │ Confidence penalty -[10] puncte (daca LLM pica) │ │
│ │ on LLM failure: │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ MODEL CHAIN (ordinea de fallback) ─────────────────────────┐ │
│ │ 1. Primary: [local:qwen3-235b ▼] timeout [45]s │ │
│ │ 2. Fallback 1: [openrouter:gemini-flash ▼] timeout [30]s │ │
│ │ 3. Fallback 2: [openrouter:gpt-4o-mini ▼] timeout [30]s │ │
│ │ │ │
│ │ [Add fallback] [Test primary model] │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ CE PRIMESTE LLM-UL ───────────────────────────────────────┐ │
│ │ [✓] Scoruri componente │ │
│ │ [✓] Profilul input_type folosit │ │
│ │ [✓] Claims false cu text (max [3]) │ │
│ │ [✓] Claims neverificate verificabile │ │
│ │ [✓] Disclosure AI detalii │ │
│ │ [✓] Source Assessment complet │ │
│ │ [✓] Tehnici top cu dimensiuni │ │
│ │ [✓] Red flags din toate componentele │ │
│ │ [✓] Metadata media (transcript, frames) │ │
│ │ [✓] Limitari componente │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ CE PRODUCE LLM-UL ────────────────────────────────────────┐ │
│ │ [✓] Explicatie RO + EN (3-5 propozitii) │ │
│ │ [✓] Risk score ajustat (±max_adjustment) │ │
│ │ [✓] Key findings (bullet points) │ │
│ │ [✓] Warnings (avertismente pt utilizator) │ │
│ │ [✓] Reasoning (pentru audit intern) │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ [Save] [Edit System Prompt] [Edit User Prompt Template] │
└─────────────────────────────────────────────────────────────────────┘
```
### CRUD
Stocat in `component_config` existent (config_key = "verdict_config", config_value = JSONB).
Prompturile in `component_prompt` existent (component_code = "verdict", stage_code = "explanation").
Modelele in `component_stage_assignment` existent.
**Zero tabele noi** — totul in infrastructura existenta.
---
## TAB 10: SCORE SIMULATOR — Cel mai important tool
**Ce face**: Adminul introduce scoruri mock si vede instant ce verdict ar produce.
### UI Layout
```
┌─────────────────────────────────────────────────────────────────────┐
│ Score Simulator ★ │
│ │
│ ┌─ INPUT ─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Input Type: [Image ▼] Topic: [none ▼] │ │
│ │ │ │
│ │ ── Component Scores ── │ │
│ │ Techniques: [ 60 ] ████████████░░░░░░░░ │ │
│ │ Claims: [ N/A ] (dezactivat — nu a rulat) │ │
│ │ AI Tampered: [ 85 ] █████████████████░░░ │ │
│ │ Source: [ 40 ] ████████░░░░░░░░░░░░ │ │
│ │ │ │
│ │ ── Claims Details (optional) ── │ │
│ │ Total claims: [ 0 ] False: [ 0 ] Unverified: [ 0 ] │ │
│ │ │ │
│ │ ── AI Details ── │ │
│ │ AI Probability: [ 85 ] Disclosure: [none ▼] │ │
│ │ │ │
│ │ ── Source Details ── │ │
│ │ Verdict: [NEUTRAL ▼] Blacklisted: [ ] Red flags: [ 0 ] │ │
│ │ │ │
│ │ ── Failed Components ── │ │
│ │ [ ] Techniques [ ] Claims [ ] AI [ ] Source │ │
│ │ │ │
│ │ [CALCULATE] │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ RESULT ────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ RISK SCORE: 78 UNRELIABLE │ │ │
│ │ │ ████████████████░░░░ │ │ │
│ │ │ Risk Level: VERY_HIGH Severity: CRITICAL │ │ │
│ │ │ Confidence: 42 (LOW) Action: URGENT │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ── Breakdown ── │ │
│ │ │ │
│ │ Profil folosit: image │ │
│ │ Ponderi: AI=50% Tech=20% Claims=15%(→0) Source=15% │ │
│ │ Redistribuire: AI=58.8% Tech=23.5% Source=17.6% │ │
│ │ │ │
│ │ Step 1 - Scoruri risc: │ │
│ │ manipulation=60, ai_risk=85×1.0(none)=85, source=60 │ │
│ │ │ │
│ │ Step 2 - Media ponderata: │ │
│ │ 60×23.5% + 85×58.8% + 60×17.6% = 14.1 + 50.0 + 10.6 │ │
│ │ = 74.7 │ │
│ │ │ │
│ │ Step 3 - Multiplicator topic: (none) → × 1.0 = 74.7 │ │
│ │ │ │
│ │ Step 4 - Override-uri: │ │
│ │ ✓ Undisclosed AI: +10 │ │
│ │ ✗ False claims: 0 false (inactive) │ │
│ │ ✗ Severe techniques: coupling data not available │ │
│ │ Total override: +10 │ │
│ │ │ │
│ │ Step 5 - Final: round(74.7 + 10) = 85 │ │
│ │ Step 6 - Remap: 85 → UNRELIABLE (76-90) │ │
│ │ Step 7 - INCONCLUSIVE check: NU (AI=primary, AI ok) │ │
│ │ │ │
│ │ ── Comparatie cu formula actuala ── │ │
│ │ Formula actuala: 72 (QUESTIONABLE) + INCONCLUSIVE fortat │ │
│ │ Formula noua: 85 (UNRELIABLE) ← +13 puncte, fara INCONCL│ │
│ │ │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
```
### Logica
Score Simulator **NU apeleaza backend**. Ruleza formula in browser (JavaScript pur) folosind configuratia din Redis (incarcata la deschiderea paginii). Rezultat instant la fiecare schimbare de slider.
Optiune bonus: **"Compare with production"** — apeleaza backend-ul cu aceleasi scoruri si formula actuala, afiseaza diferenta.
---
## REZUMAT — CE E NOU VS CE EXISTA DEJA
### Exista deja in UI (se regrupeaza)
| Ce | Unde e acum | Unde va fi |
|---|---|---|
| Verdict Categories (ranges) | FrameworkDashboard → Verdicts | Tab 5 |
| Risk Mappings (ranges) | FrameworkDashboard → Verdicts | Tab 6 |
| Severity (ranges + actions) | FrameworkDashboard → Verdicts | Tab 6 |
| Topic Multipliers | FrameworkDashboard → Weights | Tab 8 |
| Component Weights (global) | FrameworkDashboard → Weights | Inlocuit de Tab 1 (per profil) |
| Claim Types (CRUD) | FrameworkDashboard → Claims | Tab 4 (camp nou) |
| Claim Statuses (CRUD) | FrameworkDashboard → Claims | Tab 4 (camp nou) |
| LLM Models + Prompts | LLM Components Config | Tab 9 |
### Nou (trebuie implementat)
| Ce | Tab | Effort |
|---|---|---|
| Input Type Profiles (ponderi per input) | Tab 1 | Tabel PG + CRUD + UI |
| Override Rules per profil | Tab 2 | Tabel PG + CRUD + UI |
| AI Disclosure Multipliers | Tab 3 | 4 randuri in config + UI |
| UV Weight per claim type | Tab 4 | 1 coloana noua + UI |
| Credibility weight per status | Tab 4 | 1 coloana noua + UI |
| Confidence config per profil | Tab 7 | JSONB in profil + UI |
| Score Simulator | Tab 10 | Frontend JS pur |
### Tabele PG noi
| Tabel | Coloane | Randuri default |
|---|---|---|
| `input_type_profile` | ~20 coloane (vezi Tab 1) | 6 (text, text+url, image, audio, video, url) |
| `profile_override_config` | 7 coloane | 48 (8 override × 6 profiluri) |
### Coloane noi in tabele existente
| Tabel | Coloana noua | Tip |
|---|---|---|
| `claim_type` | `unverified_weight` | NUMERIC(3,2) DEFAULT 0.50 |
| `claim` (statuses) | `credibility_weight` | NUMERIC(3,2) DEFAULT 0.50 |
### Chei Redis noi
| Cheie | Continut |
|---|---|
| `didi:config:pipeline:v1:input_profiles` | JSON cu toate profilurile + override-uri + confidence |
| `didi:config:pipeline:v1:disclosure_multipliers` | JSON cu 4 multiplicatori |
---
## FLOW COMPLET: ADMIN EDITEAZA → VERDICT SE SCHIMBA
```
1. Admin deschide /admin/verdict-config
2. Selecteaza Tab 1 → Profil "video"
3. Muta slider AI Tampered de la 40% la 50%
4. Ajusteaza Techniques de la 25% la 20% (total ramane 100%)
5. Click [Save Profile]
└→ PUT /api/profiles/video → PG update → response 200
6. Admin deschide Tab 10 → Score Simulator
7. Selecteaza Input: video, AI=90, Techniques=30, Claims=N/A
8. Vede instant: Risk=78 UNRELIABLE (in loc de INCONCLUSIVE)
9. Satisfacut cu rezultatul
10. Click [Sync to Redis] (sidebar)
└→ POST /api/sync-redis → citeste din PG → scrie in Redis
└→ `didi:config:pipeline:v1:input_profiles` actualizat
11. Urmatoarea analiza video in agent-v3:
└→ verdict-calculator citeste profil "video" din Redis
└→ aplica ponderi noi: AI=50%, Tech=20%
└→ verdict nou reflecta schimbarea
```
**Timp de la editare la efect**: ~5 secunde (save + sync + prima analiza).
**Rollback**: Admin poate [Reset to defaults] oricand.
**Audit**: Fiecare save in PG e versionat prin tabelul `parameter` existent.