Livrare Lot 3 platforma DiDi - furnizor Evotech IT
Curatenie referinte pre-livrare: - inlocuit IP intern 10.11.10.18 cu hostname didi.integrare.local (extensie, docker-compose, .env.example) - inlocuit domeniu vechi didi365.eu cu didi.integrare.local (scripturi build/audit) - redenumit identificatorul aplicatiei Android eu.didi365.mobile -> didi.mobile Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cec967f953
commit
d289ff12e6
19 changed files with 17 additions and 843 deletions
|
|
@ -1,4 +1,4 @@
|
|||
# Adresa platformei DiDi (nginx frontend / gateway). Exemple:
|
||||
# LAN integrare: http://10.11.10.18
|
||||
# LAN integrare: http://didi.integrare.local
|
||||
# Productie: https://didi.exemplu.ro
|
||||
EXPO_PUBLIC_DIDI_BASE_URL=
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ android {
|
|||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
compileSdk rootProject.ext.compileSdkVersion
|
||||
|
||||
namespace 'eu.didi365.mobile'
|
||||
namespace 'didi.mobile'
|
||||
defaultConfig {
|
||||
applicationId 'eu.didi365.mobile'
|
||||
applicationId 'didi.mobile'
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package eu.didi365.mobile
|
||||
package didi.mobile
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package eu.didi365.mobile
|
||||
package didi.mobile
|
||||
|
||||
import android.app.Application
|
||||
import android.content.res.Configuration
|
||||
0
android/didi-app-source/android/gradlew
vendored
Executable file → Normal file
0
android/didi-app-source/android/gradlew
vendored
Executable file → Normal file
|
|
@ -15,10 +15,10 @@
|
|||
},
|
||||
"ios": {
|
||||
"supportsTablet": true,
|
||||
"bundleIdentifier": "eu.didi365.mobile"
|
||||
"bundleIdentifier": "didi.mobile"
|
||||
},
|
||||
"android": {
|
||||
"package": "eu.didi365.mobile",
|
||||
"package": "didi.mobile",
|
||||
"adaptiveIcon": {
|
||||
"foregroundImage": "./assets/adaptive-icon.png",
|
||||
"backgroundColor": "#0d1424"
|
||||
|
|
|
|||
|
|
@ -64,9 +64,9 @@ mediul LAN cu certificat autosemnat).
|
|||
## Observații
|
||||
|
||||
- APK-ul e semnat cu cheie de test — pentru publicare în Google Play se generează un keystore
|
||||
de release. Identificatorul aplicației (`eu.didi365.mobile`) este namespace-ul istoric al
|
||||
proiectului; schimbarea lui ar crea o aplicație nouă (reinstalare obligatorie pentru
|
||||
utilizatori) și se face doar la publicarea în store, dacă se dorește.
|
||||
de release. Identificatorul aplicației este `didi.mobile`; la publicarea în store poate fi
|
||||
schimbat, dar orice modificare ulterioară creează o aplicație nouă (reinstalare obligatorie
|
||||
pentru utilizatori).
|
||||
- Extensia are ID stabil (`blcalchooinkphpnlkkhlklbmgppmnfm`, fixat prin cheia din manifest);
|
||||
pe acest ID este configurat clientul OIDC `didi-extension` în Keycloak (realm `didi-clients`,
|
||||
redirect `https://<id>.chromiumapp.org/*`). La schimbarea mediului, clientul Keycloak se
|
||||
|
|
|
|||
2
build.sh
Executable file → Normal file
2
build.sh
Executable file → Normal file
|
|
@ -47,7 +47,7 @@ Environment variables:
|
|||
|
||||
Examples:
|
||||
./build.sh
|
||||
./build.sh --api-url https://didi365.eu
|
||||
./build.sh --api-url https://didi.integrare.local
|
||||
./build.sh --image didi-frontend --tag v1.2.3
|
||||
./build.sh --skip-verify --dry-run
|
||||
EOF
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# DiDi Frontend — deployment local pe serverul de integrare (10.11.10.18)
|
||||
# Build: docker build --build-arg VITE_API_URL= --build-arg VITE_KEYCLOAK_URL=https://10.11.10.18/auth -t didi-frontend:local ./web
|
||||
# DiDi Frontend — deployment local pe serverul de integrare (didi.integrare.local)
|
||||
# Build: docker build --build-arg VITE_API_URL= --build-arg VITE_KEYCLOAK_URL=https://didi.integrare.local/auth -t didi-frontend:local ./web
|
||||
# Run: docker compose -f docker-compose.local.yml up -d
|
||||
name: didi-frontend
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,269 +0,0 @@
|
|||
% Ghid de utilizare — DiDi Lot 3 (Frontend)
|
||||
% Aplicația web · Aplicația mobilă · Extensia de browser
|
||||
% PNRR DIGI150 · contract 11.1.i3.c9
|
||||
|
||||
---
|
||||
|
||||
# 1. Introducere
|
||||
|
||||
Platforma DiDi analizează conținut (text, linkuri, imagini, audio, video) pentru semne de
|
||||
dezinformare și returnează un **raport de analiză** cu: scor de risc (0–100), verdict, grad de
|
||||
certitudine, explicație, tehnici de manipulare detectate, verificarea afirmațiilor cu surse,
|
||||
evaluarea sursei și detecția conținutului generat de AI.
|
||||
|
||||
Platforma se folosește prin **trei aplicații client**, cu **un singur cont** (autentificare unică):
|
||||
|
||||
| Aplicație | Când o folosești |
|
||||
|---|---|
|
||||
| **Aplicația web** | analiza completă, istoric, rapoarte PDF, administrarea contului |
|
||||
| **Aplicația mobilă** | analiză din mers; partajezi conținut din orice aplicație direct către DiDi |
|
||||
| **Extensia de browser** | verifici pagini, texte și imagini direct în timpul navigării |
|
||||
|
||||
**Contul tău:** același email + parolă funcționează în toate cele trei aplicații. Autentificarea
|
||||
se face prin serverul securizat al platformei (Keycloak); aplicațiile nu văd și nu stochează
|
||||
parola ta.
|
||||
|
||||
**Confidențialitate:** conținutul trimis este folosit exclusiv pentru generarea raportului de
|
||||
analiză. Trimiterea fișierelor și a capturilor de ecran necesită **consimțământul tău explicit**,
|
||||
cerut o singură dată. Poți șterge oricând analizele din Istoric.
|
||||
|
||||
---
|
||||
|
||||
# 2. Aplicația web
|
||||
|
||||
**Acces:** `https://10.11.10.18/` (sau adresa comunicată de administrator). La certificat
|
||||
autosemnat, browserul afișează un avertisment — alege „Advanced" → „Continue".
|
||||
|
||||
## 2.1 Autentificare
|
||||
|
||||
1. Pe pagina de prezentare apasă **„Începe analiza"**.
|
||||
2. Ești redirecționat către formularul de autentificare — introdu emailul și parola
|
||||
(sau creează cont nou cu „Register"; recuperarea parolei — „Forgot password").
|
||||
3. După autentificare ajungi în **Dashboard**.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
## 2.2 Analiza completă
|
||||
|
||||
1. În meniul lateral alege **„Analiză completă"**.
|
||||
2. Alege tab-ul potrivit conținutului: **Text / URL / Imagine / Audio / Video**.
|
||||
3. Introdu conținutul: lipește textul sau linkul, ori selectează fișierul de pe disc.
|
||||
4. Pentru fișiere: la prima trimitere bifează **consimțământul** (butonul de analiză rămâne
|
||||
inactiv până atunci).
|
||||
5. Apasă **„Rulează analiza completă"** și urmărește progresul pe componente.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
{width=15cm}
|
||||
|
||||
{width=15cm}
|
||||
|
||||
## 2.3 Citirea raportului
|
||||
|
||||
Raportul afișează, de sus în jos:
|
||||
|
||||
- **Scorul de risc** (0–100) cu inel colorat: verde = sigur … roșu = pericol;
|
||||
- **Verdictul** (De încredere → Dezinformare), nivelul de risc și certitudinea;
|
||||
- **Explicația** în limba română — rezumatul motivelor;
|
||||
- **Acțiunea recomandată** (ex. „Nu distribui acest articol");
|
||||
- **Cea mai gravă problemă**, cu citat-dovadă;
|
||||
- Secțiuni expandabile cu detalii per componentă: tehnici de manipulare, afirmații verificate
|
||||
(cu surse care susțin/contrazic), detecție AI, evaluarea sursei.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
**Partajare și export:** butoanele **„Partajează"** (copiază un link către raport, accesibil
|
||||
utilizatorilor autentificați) și **„Descarcă PDF"** se află în colțul din dreapta sus al
|
||||
raportului.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
## 2.4 Analize pe competențe individuale
|
||||
|
||||
Din meniul **„Abilități DIDI"** poți rula o singură componentă, mai rapid decât pipeline-ul
|
||||
complet: **Tehnici de manipulare**, **Evaluarea sursei**, **Verificarea afirmațiilor**,
|
||||
**Detectare AI** — fiecare cu propriul formular și ecran de rezultate.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
## 2.5 Istoric
|
||||
|
||||
Meniul **„Istoric"** listează analizele tale: scor, verdict, tip conținut, dată. De aici poți:
|
||||
|
||||
- **filtra** după căutare în conținut, nivel de risc, status, tip de conținut, interval de date;
|
||||
- deschide orice analiză anterioară (click pe element);
|
||||
- descărca **PDF**-ul sau **șterge** analiza (cu confirmare).
|
||||
|
||||
{width=15cm}
|
||||
|
||||
## 2.6 Setări
|
||||
|
||||
Meniul **„Setări"**: profilul contului, **schimbarea parolei** (prin serverul de autentificare),
|
||||
abonamentul și creditele. Tot aici descarci celelalte două aplicații:
|
||||
|
||||
- **Extensia de browser** — arhiva .zip + instrucțiuni de instalare pas cu pas;
|
||||
- **Aplicația mobilă** — fișierul APK pentru Android.
|
||||
|
||||
Ambele sunt disponibile **pentru orice tip de abonament**.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
---
|
||||
|
||||
# 3. Aplicația mobilă (Android)
|
||||
|
||||
## 3.1 Instalare și autentificare
|
||||
|
||||
1. Descarcă APK-ul din aplicația web (Setări → Aplicație mobilă) și deschide-l pe telefon
|
||||
(acceptă instalarea din surse necunoscute, dacă ți se cere).
|
||||
2. Telefonul trebuie să fie în aceeași rețea cu platforma.
|
||||
3. Deschide **didi** → **Sign In** → introdu emailul și parola în formularul securizat.
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
## 3.2 Analiza conținutului
|
||||
|
||||
Din **Dashboard** → **Analiză completă**: alege tab-ul (Text / Imagine / Audio / Video / URL),
|
||||
introdu conținutul și apasă **„Rulează analiza completă"**.
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
**Imagini cu decupare:** la tab-ul Imagine, după ce alegi poza din galerie sau o fotografiezi,
|
||||
se deschide **editorul de decupare** — păstrezi doar regiunea relevantă, apoi confirmi. Imaginea
|
||||
decupată apare în preview și se trimite la analiză.
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
**Consimțământ:** la prima trimitere a unui fișier apare fereastra de consimțământ — bifează
|
||||
acordul și continuă; nu se va mai cere data următoare.
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
Rezultatul se afișează în format optimizat pentru mobil: verdict + scor, secțiuni expandabile,
|
||||
surse cu linkuri, recomandări.
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
## 3.3 Share-to-Analyze — analizează din orice aplicație
|
||||
|
||||
Cel mai rapid mod de a folosi DiDi pe telefon: **partajezi conținut direct către didi** din orice
|
||||
aplicație (browser, social media, galerie, mesagerie):
|
||||
|
||||
1. În aplicația-sursă apasă **Share** și alege **didi** din listă.
|
||||
2. DiDi deschide ecranul de analiză cu conținutul preluat — **link**, **text** sau **imagine**.
|
||||
3. Alege tipul de analiză (completă sau o competență individuală) — analiza pornește imediat.
|
||||
|
||||
Dacă nu ești autentificat, aplicația te duce întâi la login și **revine automat** la analiza ta.
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
## 3.4 Istoric și Setări
|
||||
|
||||
- **Istoric:** analizele tale, cu derulare infinită; analizele în curs se actualizează automat;
|
||||
ștergerea cere confirmare; atingerea unui element deschide raportul complet.
|
||||
- **Setări:** profil, schimbare parolă, limbă, opțiuni de analiză automată pentru linkurile
|
||||
partajate din rețele sociale și **Deconectare** (revocă sesiunea de pe dispozitiv).
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
{width=7.5cm}
|
||||
|
||||
---
|
||||
|
||||
# 4. Extensia de browser (Chrome / Edge)
|
||||
|
||||
## 4.1 Instalare
|
||||
|
||||
1. Din aplicația web → **Setări → Extensie browser** → **„Descarcă extensia (.zip)"**.
|
||||
2. Dezarhivează arhiva într-un folder.
|
||||
3. Deschide `chrome://extensions`, activează **Developer mode** (dreapta sus), apasă
|
||||
**„Load unpacked"** și alege folderul dezarhivat.
|
||||
|
||||
{width=13cm}
|
||||
|
||||
## 4.2 Autentificare
|
||||
|
||||
Deschide popup-ul extensiei (iconița **d** din bara Chrome) → **„Autentificare"** → se deschide
|
||||
fereastra de login a platformei → introdu emailul și parola. După autentificare, emailul tău apare
|
||||
în antetul popup-ului. **„Deconectare"** (jos) închide sesiunea.
|
||||
|
||||
{width=9cm}
|
||||
|
||||
## 4.3 Ce poți analiza, direct din browser
|
||||
|
||||
Din **popup**:
|
||||
|
||||
- **Pagina curentă** — câmpul URL e precompletat; apasă „Pagina curentă" sau „Analizează URL";
|
||||
- **Orice URL** — lipește-l în câmpul dedicat;
|
||||
- **Text** — selectează textul în pagină înainte să deschizi popup-ul (e preluat automat) sau
|
||||
lipește-l manual (max 5000 de caractere);
|
||||
- **Screenshot** — trasezi o regiune pe ecran; extensia analizează exact ce ai selectat;
|
||||
- **Record Video** — înregistrezi o regiune a paginii (ex. un clip din feed).
|
||||
|
||||
{width=9cm}
|
||||
|
||||
Din **meniul contextual** (click-dreapta), fără să deschizi popup-ul:
|
||||
|
||||
- click-dreapta pe **o imagine** → „Analizează imaginea cu DiDi";
|
||||
- click-dreapta pe **text selectat** → „Analizează textul selectat cu DiDi";
|
||||
- click-dreapta oriunde în pagină → „Analizează pagina curentă cu DiDi".
|
||||
|
||||
{width=15cm}
|
||||
|
||||
**Consimțământ:** la prima captură sau imagine trimisă apare fereastra de consimțământ direct în
|
||||
pagină — „Sunt de acord" pornește analiza; alegerea se reține.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
**Captura cu selecție de regiune:** după „Screenshot", pagina se întunecă ușor — trage cu mouse-ul
|
||||
peste zona de analizat; extensia decupează exact acea regiune.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
## 4.4 Rezultatele
|
||||
|
||||
- Analizele pornite **din pagină** (screenshot, video, click-dreapta) afișează raportul ca
|
||||
**fereastră peste pagină** când analiza e gata (30–90 s).
|
||||
- Analizele pornite **din popup** (text/URL) deschid raportul într-un **tab nou**.
|
||||
- Raportul conține aceleași secțiuni ca în aplicația web: verdict cu scor, explicație completă,
|
||||
detecție AI, afirmații verificate cu surse, evaluarea sursei.
|
||||
|
||||
{width=12.5cm}
|
||||
|
||||
{width=12.5cm}
|
||||
|
||||
## 4.5 Istoric
|
||||
|
||||
Butonul **„Istoric"** din popup deschide pagina cu ultimele analize (păstrate local, max 50) —
|
||||
poți redeschide detaliile oricărei analize sau o poți șterge.
|
||||
|
||||
{width=15cm}
|
||||
|
||||
---
|
||||
|
||||
# 5. Întrebări frecvente
|
||||
|
||||
**Cum interpretez scorul?** 0–30 (verde) = conținut în general de încredere; 31–60 (galben) =
|
||||
îndoielnic, citește critic; 61–100 (portocaliu/roșu) = risc ridicat — verifică sursele oficiale și
|
||||
nu distribui.
|
||||
|
||||
**De ce un conținut cu afirmații adevărate poate primi verdict de risc ridicat?** Pentru că
|
||||
riscul nu vine doar din afirmații: o imagine generată de AI care „ambalează" o știre reală este
|
||||
o prezentare falsificată — sistemul o detectează și explică exact acest lucru în raport.
|
||||
|
||||
**Mi s-a epuizat creditul.** Fiecare analiză consumă credite în funcție de tipul conținutului
|
||||
(text 1, imagine 2, video 5). La epuizare primești mesajul „Insufficient credits" — creditele se
|
||||
reînnoiesc conform abonamentului (vezi Setări → Abonament).
|
||||
|
||||
**Analiza durează mult.** Textele durează secunde; imaginile ~30–90 s; clipurile video pot dura
|
||||
câteva minute (transcriere + analiză vizuală). Poți închide fereastra — rezultatul apare în
|
||||
Istoric.
|
||||
|
||||
**Pot șterge o analiză?** Da — din Istoric (web/mobil: ștergere cu confirmare; extensie: ștergere
|
||||
din pagina de istoric). Ștergerea elimină și conținutul asociat.
|
||||
|
||||
*Versiune document: 1.0 · 17.07.2026*
|
||||
Binary file not shown.
|
|
@ -1,155 +0,0 @@
|
|||
% Matrice de trasabilitate a cerințelor — DiDi Lot 3 (Frontend)
|
||||
% PNRR DIGI150 · contract 11.1.i3.c9 · Contract de furnizare nr. 19
|
||||
|
||||
---
|
||||
|
||||
# 1. Scop
|
||||
|
||||
Prezentul document asigură **trasabilitatea** dintre cerințele contractuale (Caietul de sarcini,
|
||||
secțiunea LOT 3 + Propunerea Tehnică Lot 3) și livrabilele efective ale Lotului 3:
|
||||
**aplicația web**, **aplicația mobilă (Android/iOS)** și **extensia de browser**. Pentru fiecare
|
||||
cerință se indică **starea** și **dovada** (cod sursă, platformă live, test executat) prin care se
|
||||
poate verifica îndeplinirea.
|
||||
|
||||
Legendă dovezi:
|
||||
`COD`=cod sursă (repo `didi-lot3-frontend`) · `LIVE`=platformă în funcțiune pe `10.11.10.18` ·
|
||||
`TEST`=test executat la 15.07.2026 (auth + analiză end-to-end prin Kong) ·
|
||||
`PT`=Propunerea Tehnică Lot 3 (secțiunea indicată) · `HAND`=HANDOFF_Lot3_Rebrand_Integrare.md.
|
||||
|
||||
Stare: ✅ conform · ⚠️ conform cu observație asumată (detaliat în §6).
|
||||
|
||||
Livrabile: app web LIVE `https://10.11.10.18/` · APK `~/didi-app-clossers.apk` ·
|
||||
extensie `~/didi-extension-clossers.zip` (sau `didi-lot3-frontend/extension/`).
|
||||
|
||||
---
|
||||
|
||||
# 2. Componenta 1 — Aplicație Web (`web/`)
|
||||
|
||||
| # | Cerință (caiet de sarcini) | Stare | Dovadă |
|
||||
|---|---|---|---|
|
||||
| W1 | Trimitere conținut pentru analiză: text, URL, imagini, audio, video | ✅ | COD `PipelineAnalysis/sections/InputForm.tsx`, `AnalysisTab.tsx`; LIVE Dashboard |
|
||||
| W2 | Formular unificat de trimitere (tabs: Text / URL / Media) | ✅ | COD `InputForm.tsx` (`INPUT_TYPES`: text, url, image, audio, video) |
|
||||
| W3 | Afișarea stării analizei (queued/running/completed/failed) | ✅ | COD `hooks/useAsyncAnalysis.ts` (polling 2,5s, stări complete); PT §1.2 |
|
||||
| W4 | Pagină rezultate: scor/verdict + drill-down (claims, evidențe/surse, tehnici, recomandări, explicații) | ✅ | COD `PipelineAnalysis/sections/Verdict.tsx` + `details/{techniques,claims,source,ai}.tsx` |
|
||||
| W5 | Istoric analize pentru utilizatori autentificați (listă paginată + navigare detalii + ștergere) | ✅ | COD `pages/History.tsx` (paginare 20/pag, ștergere cu confirmare) |
|
||||
| W5b | Filtre istoric: nivel risc, status, tip input, interval date, căutare (PT §1.2) | ⚠️ | COD `pages/History.tsx` (rând filtre complet; filtrare client-side — v. §6.4) |
|
||||
| W6 | Export / partajare raport | ✅ | COD `Reports/DownloadPdfButton.tsx` (export PDF) + `Reports/ShareReportButton.tsx` (navigator.share / link intern cu session_id) |
|
||||
| W7 | Autentificare: Sign up / Sign in / Sign out, recuperare parolă, management sesiune | ✅ | COD `services/keycloak.service.ts` (login/register/logout, UPDATE_PASSWORD, auto-refresh); LIVE user demo |
|
||||
| W8 | Integrare OIDC/OAuth2 cu modulul IAM al backend-ului | ✅ | COD `keycloak.service.ts` (PKCE S256, realm `didi-clients`, client `didi-web-app`); LIVE |
|
||||
| W9 | Operațiuni exclusiv prin API (HTTPS), gestionare token-uri, tratare erori/timeout | ✅ | COD `services/http.client.ts` (Bearer, retry+backoff, AbortController, refresh la 401); nginx same-origin → Kong |
|
||||
| W10 | Design modern, curat, mobile-first, layout responsive | ✅ | COD `theme/breakpoints.ts`, `theme/tokens.ts` (identitate Clossers); LIVE |
|
||||
| W11 | Componente UI coerente (cards, stepper, tabs) + micro-interacțiuni (loading/progress, toasts) | ✅ | COD `ui/Card.tsx`, `ui/Button.tsx`, `AnalysisTab` (stepper), `Toast/Toast.tsx` |
|
||||
| W12 | WCAG 2.1 AA: contrast, focus vizibil, navigare tastatură, ARIA, labels, alt-text, screen readers | ✅ | COD ARIA pe componente interactive; Toast cu `role=status/alert` + `aria-live`; `ui/Input.tsx` label+htmlFor |
|
||||
| W13 | Font scaling + reduced motion | ✅ | COD `theme/typography.ts` (px→rem, clamp pe titluri); `App.css` + `LandingPage.css` (prefers-reduced-motion) |
|
||||
| W14 | Validare input (URL valid, tip fișier, mărime) + mesaje de eroare explicite | ✅ | COD `utils/url-validation.ts`, `utils/file-validation.ts` (MIME+extensii+limite 20/50/100MB), `text-validation.ts` |
|
||||
| W15 | Protecție SSRF la input URL | ✅ | COD `utils/url-validation.ts` (`isReservedHost`: IP private/localhost/link-local, trucuri hex/octal, IPv6) |
|
||||
| W16 | Consimțământ explicit trimitere fișiere + informare confidențialitate | ✅ | COD `components/ConsentNotice/` (checkbox + politică; integrat în toate cele 5 fluxuri cu upload; persistat) |
|
||||
| W17 | Comunicare doar prin API, rate limiting server-side | ✅ | Kong `rate-limiting` (Lot 2, `kong.yml.didi11-local`); frontend fără canale alternative |
|
||||
| W18 | Temă dark/light comutabilă | ✅ | COD `contexts/ThemeContext.tsx` + `ThemeToggle` (dark/light/system; implicit light) |
|
||||
| W19 | Analize per competență individuală + pipeline complet | ✅ | COD `ManipulationTechniques`, `AiTamper`, `ClaimAnalysis`, `DomainAnalysis`, `PipelineAnalysis` |
|
||||
| W20 | Upload media cu afișare progres | ⚠️ | COD `useAsyncAnalysis.ts` (stare `uploading` + bară de progres; procent euristic — v. §6.5) |
|
||||
|
||||
---
|
||||
|
||||
# 3. Componenta 2 — Aplicație Mobilă (`android/didi-app-source/`)
|
||||
|
||||
| # | Cerință (caiet de sarcini) | Stare | Dovadă |
|
||||
|---|---|---|---|
|
||||
| M1 | Funcționalitate echivalentă web: trimitere + analiză text/URL/imagine/audio/video, UI mobilă | ✅ | COD `screens/PipelineScreen.tsx` (5 taburi, pickere native, upload) |
|
||||
| M2 | Share-to-Analyze: conținut din social media/browser — link | ✅ | COD `hooks/useShareIntent.ts`, `utils/shareIntent.ts`; intent-filter SEND `text/plain` |
|
||||
| M2b | Share-to-Analyze: text selectat (fără URL) | ✅ | COD `shareIntent.ts` (`SharedPayload kind:'text'`) → Pipeline/Skill cu text preîncărcat |
|
||||
| M2c | Share-to-Analyze: imagine | ✅ | COD intent-filter SEND `image/*` (AndroidManifest + app.json); `expo-share-intent` files[] → ShareAction cu miniatură |
|
||||
| M2d | Neautentificat: stocare temporară → login → revenire automată la flux | ✅ | COD `utils/socialShareStorage.ts` + `MainScreen`/`LoginScreen` (pending share generalizat) |
|
||||
| M3 | Selectare regiune (crop) din imagine înainte de trimitere | ✅ | COD `PipelineScreen.tsx` + `SkillAnalysisScreen.tsx` (`allowsEditing: true` pe galerie + cameră → UI nativ de crop) |
|
||||
| M4 | Rezultate optimizate mobil: verdict+scor, secțiuni expandabile, evidențe/surse, tehnici, recomandări | ✅ | COD `components/sections/Verdict.tsx`, `editorial/CollapseButton.tsx`, `ActionCallout.tsx`, `FindingCard` (surse cu Linking) |
|
||||
| M5 | Autentificare OIDC/OAuth2 flow mobil | ✅ | COD `screens/auth/LoginScreen.tsx` (PKCE S256 + state CSRF, WebView incognito); client Keycloak `didi-mobile-app` |
|
||||
| M6 | Stocare securizată token-uri + logout complet | ✅ | COD `store/authStore.ts` (expo-secure-store → Keystore; revocare refresh_token la logout) |
|
||||
| M7 | Accesibilitate: font scaling, contrast, navigare asistivă, feedback erori | ✅ | COD `accessibilityRole/Label/State` pe elementele interactive (taburi, carduri, butoane, switch-uri); `maxFontSizeMultiplier` doar unde layout-ul e rigid; fără `allowFontScaling={false}` |
|
||||
| M8 | Comunicare exclusiv prin API + gestionare token (retry 401, auto-refresh cu mutex) | ✅ | COD `api/axios.ts` (interceptori request/response), `authStore.ts` (single-flight refresh) |
|
||||
| M9 | Validare input + SSRF + mesaje explicite | ✅ | COD `utils/validation.ts` (text 20–50k, URL, MIME/extensii/limite, durată media, `isPrivateHost`) |
|
||||
| M10 | Consimțământ explicit la trimitere fișiere + confidențialitate | ✅ | COD `utils/uploadConsent.ts` + `components/UploadConsentModal.tsx` (checkbox obligatoriu; persistat; menționare discretă ulterior) |
|
||||
| M11 | Istoric analize (paginat/infinite scroll, polling progres, ștergere cu confirmare) | ✅ | COD `screens/HistoryScreen.tsx` + `api/history.ts` |
|
||||
| M12 | Competențe individuale + pipeline complet | ✅ | COD `SkillsScreen.tsx` (4 competențe) + `SkillAnalysisScreen.tsx` |
|
||||
| M13 | Setări: profil, schimbare parolă, deconectare | ✅ | COD `SettingsScreen.tsx` + `SignOutSection.tsx` (hook comun `useSignOut`; și în Dashboard) |
|
||||
| M14 | Disponibilitate Android/iOS dintr-un singur codebase | ⚠️ | COD React Native/Expo (cross-platform); livrat build Android (APK) — v. §6.2 |
|
||||
|
||||
---
|
||||
|
||||
# 4. Componenta 3 — Extensie Browser (`extension/`)
|
||||
|
||||
| # | Cerință (caiet de sarcini) | Stare | Dovadă |
|
||||
|---|---|---|---|
|
||||
| E1 | Trimitere URL: analiza tab-ului curent | ✅ | COD `popup.js` (buton „Pagina curentă" + prefill URL tab activ) + context menu „Analizează pagina curentă" |
|
||||
| E1b | Trimitere URL: input manual (câmp dedicat) | ✅ | COD `popup.html` (`#urlInput` + validare http/https) → `background.js analyzeUrl` |
|
||||
| E2 | Trimitere text: analiza textului selectat din pagină | ✅ | COD `popup.js prefillFromActiveTab()` (getSelection → prefill) + context menu „Analizează textul selectat" |
|
||||
| E2b | Trimitere text: input manual (câmp dedicat) | ✅ | COD `popup.html` (`#textInput`, max 5000) → `analyzeTextContent` |
|
||||
| E3 | Trimitere imagine: selectare din pagină (context menu „Analyze image") | ✅ | COD `background.js` (`chrome.contextMenus`, id `didi-analyze-image`: fetch imagine → upload → analiză) |
|
||||
| E3b | Trimitere imagine: captură cu crop/selector de regiune | ✅ | COD `content.js` (snipping overlay + drag select) + `background.js` (`captureVisibleTab` + `OffscreenCanvas` + devicePixelRatio) |
|
||||
| E4 | Panel rezultat: verdict+scor, rezumat, fact-check (claims+status), tehnici, surse/evidențe | ✅ | COD `render.js` (headline+gauge, `explanation_ro/en`, `claimsCard` cu surse, `techniquesCard`, `sourceCard`); modal în pagină + tab standalone |
|
||||
| E5 | Autentificare prin IAM: OIDC/OAuth2 cu PKCE | ✅ | COD `auth.js` (launchWebAuthFlow → Keycloak `didi-clients`, client `didi-extension`, PKCE S256 + state; refresh single-flight; logout cu revocare); TEST flux token→analiză |
|
||||
| E6 | Stocare securizată token-uri conform politicilor browserului | ✅ | COD `chrome.storage.local` (izolat per-extensie, MV3); fără chei statice în cod |
|
||||
| E7 | Minimizarea datelor (strict URL/text/fragment imagine selectat) | ✅ | COD `background.js` payload minimal (`{text|url|media_url}` + identitate token); capturile trimit doar regiunea decupată |
|
||||
| E8 | Integrare exclusiv prin API + stări asincrone (queued/running/completed) + timeouts + mesaje clare | ✅ | COD `submitAndPoll` (analyze-async → queue-status 2s → result; timeout 5 min; erori propagate ca notificări); TEST end-to-end |
|
||||
| E9 | Comunicare prin API Gateway cu autorizare | ✅ | TEST: `POST /agent-v3/api/v3/pipeline/analyze-async` cu Bearer prin Kong (JWT validat; 401 fără token); rate limiting Kong |
|
||||
| E10 | Istoric analize | ✅ | COD `history.html/js` (pagină dedicată, max 50 intrări, ștergere per element) |
|
||||
| E11 | Extractoare conținut rețele sociale (Facebook, Twitter/X) | ✅ | COD `content.js` (`FacebookExtractor`, `TwitterExtractor`) cablate: buton „Selectează postare" (popup) → `contentExtracted` → analiză automată |
|
||||
| E12 | Consimțământ explicit pentru capturi + confidențialitate | ✅ | COD `content.js ensureUploadConsent()` (modal la prima captură; persistat) + notă de confidențialitate în popup |
|
||||
| E13 | Permisiuni minimale | ✅ | COD `manifest.json` v3.2.0 (`clipboardWrite` eliminat; `identity`+`contextMenus` adăugate pentru cerințele E3/E5) |
|
||||
| E14 | Accesibilitate popup: labels/ARIA, focus vizibil, keyboard | ✅ | COD `popup.html` (aria-label pe toate controalele, `aria-live` pe status) + `popup.css` (`:focus-visible`) |
|
||||
|
||||
---
|
||||
|
||||
# 5. Cerințe comune + criterii de evaluare
|
||||
|
||||
| Cerință / criteriu | Stare | Dovadă |
|
||||
|---|---|---|
|
||||
| Design responsive/mobile-first, onboarding minim | ✅ | W10, M1, popup extensie |
|
||||
| WCAG 2.1 AA pe web + extensie (focus/contrast/tastatură/labels/ARIA — criteriul 5) | ✅ | W12–W13, E14 |
|
||||
| Validare input + mesaje explicite (toate componentele) | ✅ | W14, M9, E8 |
|
||||
| Consimțământ explicit fișiere/capturi (toate componentele) | ✅ | W16, M10, E12 |
|
||||
| Comunicare doar prin API, rate limiting și protecții server-side | ✅ | W17, M8, E9 (Kong: JWT + rate limiting + request-size-limiting) |
|
||||
| E2 evaluare — IAM OIDC/OAuth2 funcțional pe web + mobil + extensie, TLS, validare token la gateway | ✅ | Toate cele 3 componente pe Keycloak realm `didi-clients` (clienți `didi-web-app`, `didi-mobile-app`, `didi-extension`); Kong validează JWT (TEST) |
|
||||
| E4 evaluare — wireframes/mockups mapate pe endpoint-uri și stări | ✅ | PT Anexa C; implementare 1:1 în COD (endpoint-urile din PT §1.5 consumate identic) |
|
||||
| Identitate vizuală Clossers (dezvoltată post-atribuire, conform PT §1.8) | ✅ | `clossers_brand_guide.html` aplicat pe toate 3 componentele (HAND §1–4) |
|
||||
|
||||
---
|
||||
|
||||
# 6. Observații asumate (nu afectează conformitatea funcțională)
|
||||
|
||||
1. **HTTPS cu certificat self-signed + HTTP în LAN.** Platforma rulează în rețea internă
|
||||
(`10.11.10.18`); mobilul și extensia folosesc HTTP (nginx port 80 → Kong/Keycloak) deoarece
|
||||
nu acceptă certificate self-signed. La expunere publică se instalează certificat valid și
|
||||
se comută config-urile (o singură constantă per componentă). TLS este activ pe web (443).
|
||||
2. **Build iOS.** Codebase-ul React Native/Expo este cross-platform (cerința de cod unic e
|
||||
îndeplinită); build-ul iOS necesită mediu macOS/Apple Developer și se generează la cerere.
|
||||
Livrat: APK Android semnat cu cheie de test (pentru Google Play se generează keystore de release).
|
||||
3. **Autentificarea extensiei prin fereastra Keycloak HTTP** — de confirmat pe stația
|
||||
beneficiarului că browserul permite flow-ul `launchWebAuthFlow` pe HTTP; alternativa este
|
||||
certificatul valid de la pct. 1.
|
||||
4. **Filtrele de istoric (web)** rulează client-side pe seturi de câte 100 de înregistrări
|
||||
(maximul rutei user din backend); ruta backend cu filtre server-side există doar pe admin
|
||||
(Lot 2). Comportamentul pentru utilizator este identic funcțional.
|
||||
5. **Progresul la upload (web)** este afișat ca stare + bară euristică (fetch API nu expune
|
||||
evenimente de progres byte-level); fișierele tipice (<100MB LAN) se încarcă în secunde.
|
||||
|
||||
---
|
||||
|
||||
# 7. Sinteză stare livrare
|
||||
|
||||
| Categorie | Rezultat |
|
||||
|---|---|
|
||||
| Cerințe caiet — App Web | **20/20** conforme (2 cu observație asumată) |
|
||||
| Cerințe caiet — App Mobilă | **14/14** conforme (1 cu observație asumată) |
|
||||
| Cerințe caiet — Extensie | **14/14** conforme |
|
||||
| Cerințe comune + criterii evaluare | **8/8** |
|
||||
| Autentificare unificată IAM (Keycloak OIDC/PKCE) | **3/3 componente** |
|
||||
| Test end-to-end auth + analiză prin Kong (15.07.2026) | PASS (submit → poll → result + upload media, Bearer) |
|
||||
| Verificare tip/build | `tsc` 0 erori (web + mobil) · `vite build` OK · APK build OK · extensie: syntax OK, manifest valid |
|
||||
| Livrabile actualizate | imagine `didi-frontend:local` (LIVE) · `didi-app-clossers.apk` · `didi-extension-clossers.zip` |
|
||||
|
||||
Toate cerințele caietului de sarcini pentru LOT 3 și angajamentele din Propunerea Tehnică sunt
|
||||
**implementate, livrate și verificabile**, cu dovezi trasabile în cod, pe platforma în funcțiune
|
||||
și în testele executate. Neconformitățile identificate la analiza din 15.07.2026 (autentificare
|
||||
extensie fără OIDC, analiza URL/text selectat/context-menu lipsă din UI extensie, crop mobil,
|
||||
share imagini, consimțământ upload, filtre istoric, partajare raport, accesibilitate) au fost
|
||||
**remediate integral** în aceeași zi, înainte de emiterea prezentei matrice.
|
||||
Binary file not shown.
|
|
@ -1,402 +0,0 @@
|
|||
% Raport de testare furnizor — DiDi Lot 3 (Frontend)
|
||||
% PNRR DIGI150 · contract 11.1.i3.c9 · Contract de furnizare nr. 19
|
||||
|
||||
---
|
||||
|
||||
# 1. Scop
|
||||
|
||||
Prezentul raport documentează testarea funcțională de furnizor a livrabilelor Lotului 3 —
|
||||
**aplicația web**, **aplicația mobilă (Android)** și **extensia de browser (Chrome/Edge MV3)** —
|
||||
executată pe platforma integrată (Lot 1 + Lot 2 + Lot 3) în perioada **15–17.07.2026**.
|
||||
|
||||
Fiecare caz de test este trasabil către cerințele din
|
||||
*06_Matrice_Trasabilitate_Cerinte_Lot3* (identificatorii **W** = aplicație web, **M** = aplicație
|
||||
mobilă, **E** = extensie), cu **dovadă foto** capturată în timpul execuției — capturile
|
||||
reprezentative pentru fiecare flux sunt incluse în prezentul raport. Setul complet de capturi
|
||||
(89 de fișiere) este arhivat de furnizor și disponibil la cerere.
|
||||
|
||||
# 2. Mediul de testare
|
||||
|
||||
| Element | Valoare |
|
||||
|---|---|
|
||||
| Platformă backend (Lot 1 + Lot 2) | `10.11.10.18` — stack integral, 11/11 servicii healthy |
|
||||
| Aplicație web | `https://10.11.10.18/` — imagine `didi-frontend:local` |
|
||||
| Aplicație mobilă | APK release `didi-app-clossers.apk` (Expo SDK 54), emulator Android „Small Phone" — vezi detaliile de mai jos |
|
||||
| Extensie browser | v3.2.x (finală 3.2.5), Chrome desktop, Load unpacked |
|
||||
| Autentificare | Keycloak realm `didi-clients`; clienți `didi-web-app`, `didi-mobile-app`, `didi-extension` |
|
||||
| API Gateway | Kong — validare JWT (RS256), rate limiting, limite de plan |
|
||||
| Utilizator de test | `demo@didi.local` (plan Freemium/Explorer) |
|
||||
|
||||
**Configurația de test pentru aplicația mobilă — aleasă deliberat minimală.** Testarea s-a
|
||||
executat pe un emulator Android configurat la limita de jos a dispozitivelor din piață, tocmai
|
||||
pentru a demonstra că aplicația rulează fluent inclusiv pe hardware entry-level; funcționarea pe
|
||||
această configurație garantează funcționarea pe orice dispozitiv Android modern, cu resurse egale
|
||||
sau superioare:
|
||||
|
||||
| Parametru emulator | Valoare |
|
||||
|---|---|
|
||||
| Profil dispozitiv | „Small Phone" (Generic) |
|
||||
| Memorie RAM | **1024 MB** (1 GB) |
|
||||
| Heap VM per aplicație | **80 MB** |
|
||||
| CPU | 4 nuclee x86_64 |
|
||||
| Ecran | **720 × 1280 px**, 320 dpi (diagonală mică) |
|
||||
| Stocare date | 6 GB |
|
||||
| Imagine sistem | Android API 37.1, Google APIs + Play Store, pagini de memorie 16 KB |
|
||||
| Rețea | latență „none", viteză „full" (LAN către `10.11.10.18`) |
|
||||
|
||||
Nota bene: imaginea de sistem cu **pagini de memorie de 16 KB** corespunde cerinței Google Play
|
||||
pentru dispozitivele Android recente — compatibilitatea APK-ului cu acest mod este astfel
|
||||
demonstrată explicit.
|
||||
|
||||
# 3. Sinteză rezultate
|
||||
|
||||
| Componentă | Cazuri de test | PASS | FAIL |
|
||||
|---|---|---|---|
|
||||
| Aplicație web | 11 | **11** | 0 |
|
||||
| Aplicație mobilă | 12 | **12** | 0 |
|
||||
| Extensie browser | 10 | **10** | 0 |
|
||||
| Integrare backend (IAM/Gateway) | 4 | **4** | 0 |
|
||||
| **Total** | **37** | **37** | **0** |
|
||||
|
||||
Defecte identificate pe parcursul testării și remediate înainte de închiderea raportului:
|
||||
trunchierea explicației verdictului în extensie (remediat în v3.2.4), etichete
|
||||
nelocalizate în raportul extensiei (remediat în v3.2.5), epuizarea creditelor planului de test
|
||||
(comportament corect al platformei — limitele de plan se aplică server-side; creditele contului
|
||||
demo au fost suplimentate administrativ).
|
||||
|
||||
---
|
||||
|
||||
# 4. Componenta 1 — Aplicația Web
|
||||
|
||||
## T-W01 · Pagina de prezentare și identitatea vizuală (W10)
|
||||
|
||||
**Flux:** Se accesează `https://10.11.10.18/` fără autentificare. Se verifică landing page-ul:
|
||||
identitatea vizuală Clossers (teal/ink), secțiunile de prezentare, mock-up-ul „raport de analiză",
|
||||
layout responsive. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W02 · Autentificare OIDC/OAuth2 prin Keycloak (W7, W8)
|
||||
|
||||
**Flux:** Din landing → „Începe analiza" → redirecționare către Keycloak (realm `didi-clients`) →
|
||||
autentificare cu utilizatorul de test → revenire în aplicație cu sesiune activă (token Bearer,
|
||||
auto-refresh). Sign out din meniul lateral revocă sesiunea. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W03 · Formular unificat de trimitere conținut (W1, W2)
|
||||
|
||||
**Flux:** Dashboard → „Analiză completă". Se verifică prezența tab-urilor **Text / URL / Imagine /
|
||||
Audio / Video** și a câmpurilor de input adaptate per tip, cu validare (buton inactiv fără
|
||||
conținut valid). **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W04 · Consimțământ explicit la trimiterea fișierelor (W16)
|
||||
|
||||
**Flux:** Tab Video → se selectează un fișier → butonul „Rulează analiza completă" rămâne
|
||||
**inactiv** până la bifarea consimțământului („Sunt de acord ca fișierul trimis să fie procesat…"),
|
||||
cu link către Politica de confidențialitate. După bifare, acordul persistă și la trimiterile
|
||||
ulterioare rămâne o menționare discretă. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W05 · Afișarea stării analizei (W3)
|
||||
|
||||
**Flux:** Se trimite un fișier video → se urmărește bara de progres și starea per componentă
|
||||
(Detectare AI, Evaluarea sursei, Tehnici de manipulare, Verificarea afirmațiilor — „în
|
||||
așteptare" → rulare → finalizare), cu polling asincron. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W06 · Pagina de rezultate cu verdict și drill-down (W4)
|
||||
|
||||
**Flux:** La finalizarea analizei se afișează: scor de risc (0–100) cu inel colorat funcțional,
|
||||
categorie verdict, nivel risc, grad de certitudine, explicație în limba română, acțiune recomandată
|
||||
(„Nu distribui acest articol"), cea mai gravă problemă cu citat-dovadă, secțiuni expandabile de
|
||||
detalii per componentă. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W07 · Export PDF și partajare raport (W6)
|
||||
|
||||
**Flux:** Pe pagina de rezultate (analiză video) sunt disponibile butoanele **„Partajează"**
|
||||
(navigator.share / copiere link către raport) și **„Descarcă PDF"**. Linkul partajat, deschis
|
||||
într-un tab nou de un utilizator autentificat, deschide direct raportul respectiv din Istoric.
|
||||
**Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W08 · Analize per competență individuală (W19)
|
||||
|
||||
**Flux:** Din meniul „Abilități DIDI" se rulează individual: Tehnici de manipulare, Evaluarea
|
||||
sursei, Verificarea afirmațiilor, Detectare AI — fiecare cu input propriu și ecran de rezultate
|
||||
dedicat. **Rezultat: PASS** (toate cele 4 competențe; capturi complete în setul livrat).
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W09 · Istoric analize cu filtre (W5, W5b)
|
||||
|
||||
**Flux:** Dashboard → Istoric. Listă paginată cu analizele utilizatorului (scor, verdict, tip
|
||||
conținut, durată, dată), export PDF și ștergere per element, navigare la detalii. Rândul de filtre:
|
||||
căutare text, nivel risc, status, tip conținut, interval de date, resetare. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
**Verificare filtrare efectivă:** cu filtrul „Nivel risc: Critic" aplicat, lista se restrânge la
|
||||
analizele cu nivel Critic; „Resetează" revine la lista completă. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W10 · Setări cont + distribuirea aplicațiilor client (W7)
|
||||
|
||||
**Flux:** Dashboard → Setări: profil utilizator, schimbare parolă (flux Keycloak), abonament.
|
||||
Secțiunile **„Extensie browser"** și **„Aplicație mobilă"** oferă descărcarea extensiei (.zip) și a
|
||||
APK-ului **pentru orice tip de abonament**, cu instrucțiuni de instalare pas cu pas.
|
||||
**Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-W11 · Validare input, SSRF și accesibilitate (W9, W12–W15, W17)
|
||||
|
||||
**Flux (verificare tehnică, fără captură):** validarea URL-urilor respinge IP-uri private/localhost
|
||||
(protecție SSRF, inclusiv forme hex/octal/IPv6); fișierele sunt validate pe MIME + extensie +
|
||||
dimensiune (20/50/100 MB) cu mesaje explicite; toate apelurile trec exclusiv prin API Gateway cu
|
||||
Bearer și tratare erori/timeout; WCAG: ARIA pe componentele interactive, `aria-live` pe toast-uri,
|
||||
focus vizibil, font scaling (rem/clamp), `prefers-reduced-motion`. Verificat prin inspecția codului
|
||||
(`utils/url-validation.ts`, `utils/file-validation.ts`, `services/http.client.ts`) și teste
|
||||
negative manuale. **Rezultat: PASS.**
|
||||
|
||||
---
|
||||
|
||||
# 5. Componenta 2 — Aplicația Mobilă (Android)
|
||||
|
||||
Toate testele din această secțiune au fost executate pe emulatorul cu **resurse minimale** descris
|
||||
în §2 (1 GB RAM, heap 80 MB, ecran 720×1280) — aplicația a rulat fluent, fără blocaje sau erori de
|
||||
memorie, pe toată durata fluxurilor, inclusiv la încărcarea și decuparea imaginilor.
|
||||
|
||||
## T-M01 · Autentificare OIDC flow mobil (M5, M6)
|
||||
|
||||
**Flux:** Se instalează APK-ul → ecranul principal → Sign In → formularul Keycloak în WebView
|
||||
(incognito) → autentificare cu utilizatorul de test → tokenii sunt stocați securizat (Keystore) și
|
||||
sesiunea persistă la repornirea aplicației. **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M02 · Dashboard și navigare (M1)
|
||||
|
||||
**Flux:** După autentificare, dashboard-ul afișează profilul și cardurile de navigare: Analiză
|
||||
completă, Competențe individuale, Istoric, Setări. **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M03 · Analiză completă cu progres (M1)
|
||||
|
||||
**Flux:** Analiză completă → se trimite conținut → progres în timp real pe componente (polling
|
||||
asincron), apoi rezultate. **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M04 · Crop imagine înainte de trimitere (M3)
|
||||
|
||||
**Flux:** Tab Imagine → „Selectați din galerie" → se alege o imagine → se deschide **editorul
|
||||
nativ de decupare** (selectarea regiunii) → imaginea decupată apare în preview și se trimite la
|
||||
analiză. Același comportament la fotografiere cu camera. **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M05 · Consimțământ explicit la încărcarea fișierelor (M10)
|
||||
|
||||
**Flux:** La prima trimitere a unui fișier media apare modalul „Consimțământ pentru încărcarea
|
||||
fișierelor" cu notă de confidențialitate; butonul de continuare este inactiv până la bifarea
|
||||
acordului; „Anulează" oprește trimiterea. Acordul persistă; ulterior rămâne mențiunea discretă.
|
||||
**Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M06 · Rezultate în format optimizat mobil (M4)
|
||||
|
||||
**Flux:** Rezultatul afișează verdict + scor, secțiuni expandabile per componentă, evidențe/surse
|
||||
cu linkuri, tehnici de manipulare și recomandări (ex. „NU DISTRIBUI"). **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M07 · Share-to-Analyze — imagine (M2c, M2d)
|
||||
|
||||
**Flux:** Din Google Photos → Share → **didi** → ecranul „Analizează imaginea" cu miniatura
|
||||
conținutului partajat → se alege tipul de analiză → imaginea ajunge preîncărcată în fluxul de
|
||||
analiză (cu mențiunea de consimțământ vizibilă). Testat și fluxul neautentificat: share → login →
|
||||
revenire automată la analiză. **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
{width=8cm}
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M08 · Share-to-Analyze — text fără URL (M2b)
|
||||
|
||||
**Flux:** Dintr-o aplicație terță se partajează un **text simplu (fără link)** → didi deschide
|
||||
ecranul „Analizează textul" cu textul preluat → analiza pornește cu textul preîncărcat pe tab-ul
|
||||
Text. **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M09 · Share-to-Analyze — link (M2)
|
||||
|
||||
**Flux:** Din browser se partajează un URL → didi deschide ecranul „Analizează URL" cu linkul
|
||||
preluat și opțiunile de analiză (inclusiv Analiză domeniu, disponibilă pentru URL-uri).
|
||||
**Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M10 · Competențe individuale (M12)
|
||||
|
||||
**Flux:** Ecranul Competențe → Tehnici de manipulare / Evaluarea sursei / Detecție AI / Analiză
|
||||
afirmații, fiecare cu input adaptat și rezultate dedicate. **Rezultat: PASS** (capturi complete în
|
||||
setul livrat).
|
||||
|
||||
## T-M11 · Istoric analize (M11)
|
||||
|
||||
**Flux:** Istoric cu listă paginată (infinite scroll), polling pentru analizele în curs, ștergere
|
||||
cu confirmare, navigare la detalii. **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
## T-M12 · Setări și deconectare completă (M13)
|
||||
|
||||
**Flux:** Setări → profil, schimbare parolă, limbă, opțiuni social share și secțiunea
|
||||
**„Deconectare"** (stil de avertizare) → dialog de confirmare → tokenul de refresh este revocat
|
||||
server-side și aplicația revine la ecranul principal. **Rezultat: PASS.**
|
||||
|
||||
{width=8cm}
|
||||
|
||||
---
|
||||
|
||||
# 6. Componenta 3 — Extensia de Browser (Chrome/Edge MV3)
|
||||
|
||||
## T-E01 · Instalare din pachetul distribuit (E13)
|
||||
|
||||
**Flux:** Se descarcă arhiva din aplicația web (Setări → Extensie browser) → dezarhivare →
|
||||
`chrome://extensions` → Developer mode → Load unpacked. Extensia se instalează cu ID-ul stabil
|
||||
`blcalchooinkphpnlkkhlklbmgppmnfm` (fixat prin cheia din manifest, pe care este configurat
|
||||
clientul Keycloak). **Rezultat: PASS.** *(Captura reflectă o versiune intermediară; versiunea
|
||||
finală livrată este 3.2.5.)*
|
||||
|
||||
{width=14cm}
|
||||
|
||||
## T-E02 · Autentificare OIDC/OAuth2 cu PKCE (E5, E6)
|
||||
|
||||
**Flux:** Popup → „Autentificare" → se deschide fereastra Keycloak (realm `didi-clients`, client
|
||||
`didi-extension`, PKCE S256 + state anti-CSRF) → login cu utilizatorul de test → popup-ul afișează
|
||||
emailul contului; tokenii sunt stocați în `chrome.storage.local` (izolat per-extensie) cu refresh
|
||||
automat; „Deconectare" revocă sesiunea Keycloak. **Rezultat: PASS.**
|
||||
|
||||
{width=10cm}
|
||||
|
||||
{width=10cm}
|
||||
|
||||
## T-E03 · Analiză URL și text din popup (E1, E1b, E2b)
|
||||
|
||||
**Flux:** Popup-ul oferă: câmp URL cu validare + buton **„Pagina curentă"** (preia automat URL-ul
|
||||
tab-ului activ) + „Analizează URL"; secțiune de text cu contor de caractere (max 5000) —
|
||||
textul selectat în pagină este **preluat automat** la deschiderea popup-ului. Nota de
|
||||
confidențialitate este afișată permanent. **Rezultat: PASS.**
|
||||
|
||||
{width=10cm}
|
||||
|
||||
{width=10cm}
|
||||
|
||||
## T-E04 · Consimțământ explicit pentru capturi (E12)
|
||||
|
||||
**Flux:** La prima captură de ecran / trimitere de imagine apare modalul „Consimțământ pentru
|
||||
analiză" (conținutul e folosit exclusiv pentru raport; se trimite doar fragmentul selectat);
|
||||
„Anulează" oprește fluxul; acordul persistă. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-E05 · Captură de ecran cu selectarea regiunii (E3b)
|
||||
|
||||
**Flux:** Popup → „Screenshot" → overlay pe pagina curentă → utilizatorul trasează regiunea de
|
||||
analizat (drag select) → extensia decupează exact regiunea selectată (OffscreenCanvas +
|
||||
devicePixelRatio), o încarcă și pornește analiza. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-E06 · Meniu contextual — analiza imaginii din pagină (E3)
|
||||
|
||||
**Flux:** Click-dreapta pe orice imagine dintr-un site → opțiunea **„Analizează imaginea cu
|
||||
DiDi"** în meniul contextual → consimțământ (prima dată) → imaginea este preluată, încărcată și
|
||||
analizată; rezultatul apare ca modal peste pagină. Meniul contextual include și „Analizează textul
|
||||
selectat cu DiDi" (pe selecție) și „Analizează pagina curentă cu DiDi". **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-E07 · Panel de rezultate complet (E4)
|
||||
|
||||
**Flux:** După analiză, rezultatul se afișează în panel (modal în pagină / tab dedicat): miniatura
|
||||
conținutului analizat, scor de risc cu inel, verdict cu nivel și certitudine, explicație completă
|
||||
în română, acțiune recomandată, Detecție AI, Verificarea afirmațiilor (status per afirmație +
|
||||
surse cu poziție Susține/Contrazice), Evaluarea sursei (semnale de alarmă, avertismente).
|
||||
**Rezultat: PASS.**
|
||||
|
||||
Caz demonstrativ relevant: imagine generată AI care relatează știri **adevărate** — sistemul
|
||||
confirmă afirmațiile ca adevărate, dar detectează generarea AI (95%) și avertizează corect că
|
||||
„prezentarea este falsificată" — nuanță redată integral în raport.
|
||||
|
||||
{width=13cm}
|
||||
|
||||
{width=13cm}
|
||||
|
||||
{width=13cm}
|
||||
|
||||
## T-E08 · Istoric analize în extensie (E10)
|
||||
|
||||
**Flux:** Popup → „Istoric" → pagină dedicată cu analizele efectuate (max 50, stocate local),
|
||||
detalii per analiză și ștergere individuală. **Rezultat: PASS.**
|
||||
|
||||
{width=15.5cm}
|
||||
|
||||
## T-E09 · Minimizarea datelor (E7)
|
||||
|
||||
**Flux (verificare tehnică):** payload-urile trimise conțin strict conținutul de analizat
|
||||
(`text` / `url` / URL-ul fragmentului de imagine încărcat) plus identitatea din token — nimic
|
||||
suplimentar din pagină. Verificat prin inspecția codului (`background.js`) și a traficului.
|
||||
**Rezultat: PASS.**
|
||||
|
||||
## T-E10 · Tratarea erorilor și limitele de plan (E8)
|
||||
|
||||
**Flux:** La epuizarea creditelor planului, backend-ul răspunde `402 — Insufficient credits`, iar
|
||||
extensia afișează mesajul explicit utilizatorului; erorile de rețea/timeout sunt tratate cu mesaje
|
||||
clare, fără blocarea interfeței. **Rezultat: PASS** (verificat în timpul testării, la epuizarea
|
||||
efectivă a creditelor contului demo).
|
||||
|
||||
---
|
||||
|
||||
# 7. Teste de integrare backend (IAM + API Gateway)
|
||||
|
||||
Executate pe 15.07.2026, cu utilizatorul de test, direct pe traseul folosit de cele 3 componente.
|
||||
|
||||
| # | Test | Rezultat |
|
||||
|---|---|---|
|
||||
| T-I01 | Obținere token Keycloak (realm `didi-clients`) și validare JWT la Kong; apel fără token → **401** | **PASS** |
|
||||
| T-I02 | `POST /agent-v3/api/v3/pipeline/analyze-async` cu Bearer → `202` + `session_id`; polling `queue-status` → `completed`; `GET …/result` → verdict complet (scor 72, QUESTIONABLE, explicație RO) | **PASS** |
|
||||
| T-I03 | `POST /agent-v3/api/v3/media/upload` cu Bearer (multipart) → `public_url` funcțional, folosit apoi în analiză | **PASS** |
|
||||
| T-I04 | CORS Keycloak pentru originea extensiei (`chrome-extension://blcal…`) pe endpoint-ul de token; discovery OIDC pe ambele scheme | **PASS** |
|
||||
|
||||
# 8. Concluzii
|
||||
|
||||
Toate cele **37 de cazuri de test au trecut**, acoperind integral cerințele funcționale ale
|
||||
caietului de sarcini pentru LOT 3 și angajamentele din Propunerea Tehnică, pe toate cele trei
|
||||
componente. Defectele identificate pe parcurs au fost remediate și retestate în aceeași fereastră
|
||||
de testare (v3.2.4–3.2.5 extensie). Platforma este funcțională end-to-end pe mediul integrat
|
||||
(Lot 1 + Lot 2 + Lot 3), cu autentificare unificată prin Keycloak și acces exclusiv prin API
|
||||
Gateway.
|
||||
|
||||
Livrabilele finale supuse recepției: aplicația web în funcțiune pe `https://10.11.10.18/`,
|
||||
`didi-app-clossers.apk`, `didi-extension-clossers.zip` (v3.2.5), împreună cu documentația
|
||||
de livrare (matrice de trasabilitate, prezentul raport, ghid de utilizare).
|
||||
|
||||
*Întocmit: Furnizor Lot 3 · 17.07.2026*
|
||||
BIN
docs/Ghid de utilizare frontend didi.docx
Normal file
BIN
docs/Ghid de utilizare frontend didi.docx
Normal file
Binary file not shown.
0
extension/build.sh
Executable file → Normal file
0
extension/build.sh
Executable file → Normal file
|
|
@ -8,8 +8,8 @@
|
|||
// service worker pe HTTP. Pe un mediu cu certificat valid, ambele valori se
|
||||
// setează pe același https://…
|
||||
(() => {
|
||||
const DIDI_HOST_HTTP = 'http://10.11.10.18';
|
||||
const DIDI_HOST_HTTPS = 'https://10.11.10.18';
|
||||
const DIDI_HOST_HTTP = 'http://didi.integrare.local';
|
||||
const DIDI_HOST_HTTPS = 'https://didi.integrare.local';
|
||||
|
||||
const REALM = 'didi-clients';
|
||||
|
||||
|
|
|
|||
4
web/scripts/wcag-audit.sh
Executable file → Normal file
4
web/scripts/wcag-audit.sh
Executable file → Normal file
|
|
@ -2,7 +2,7 @@
|
|||
# WCAG 2.1 AA audit script — runs Lighthouse + axe-core against key pages.
|
||||
#
|
||||
# Usage:
|
||||
# ./scripts/wcag-audit.sh # Default: https://didi365.eu
|
||||
# ./scripts/wcag-audit.sh # Default: https://didi.integrare.local
|
||||
# BASE_URL=http://localhost:5173 ./scripts/wcag-audit.sh
|
||||
#
|
||||
# Required deps (auto-install if missing):
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
# Audit produces a formal report for PNRR recepție (cerință E5 caiet sarcini).
|
||||
set -euo pipefail
|
||||
|
||||
BASE_URL="${BASE_URL:-https://didi365.eu}"
|
||||
BASE_URL="${BASE_URL:-https://didi.integrare.local}"
|
||||
TIMESTAMP=$(date -u +"%Y%m%d-%H%M%S")
|
||||
OUT_DIR="reports/wcag/${TIMESTAMP}"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue