Files
roa2web-service-auto/tasks/prd-bulk-receipt-upload.md
Claude Agent 7b3541403f feat(data-entry): Bulk Receipt Upload cu Mobile UX Android Nativ
## Funcționalități Principale

### Bulk Upload & Processing
- Drag & drop pentru upload bonuri multiple oriunde pe pagină
- Batch processing cu job queue și worker pool
- Real-time updates via SSE (Server-Sent Events) cu fallback polling
- Duplicate detection via SHA-256 file hash
- Auto-retry pentru job-uri failed
- Cancel individual jobs sau batch complet

### Mobile UX - Android Native Style
- Top bar fixă cu hamburger, titlu centrat, acțiuni (search/filter)
- Bottom navigation cu 4 tab-uri (Bonuri, Upload, Rapoarte, Setări)
- FAB (Floating Action Button) cu hide/show on scroll
- Filter chips orizontal scrollabile
- Selecție multiplă prin long-press (500ms)
- Select All + Bulk Delete cu confirmare
- Layout Android pentru Create/Edit/View bon (Gmail compose style)

### Bug Fixes
- Refresh individual via SSE în loc de refresh total pagină
- Bonurile cu eroare OCR rămân vizibile pentru editare manuală
- Afișare nume fișier original pentru toate bonurile
- Upload stabil pe mobil (fix race condition File API)
- Păstrare ordine bonuri la refresh (nu se reordonează)

### Backend
- SSE endpoint pentru status updates real-time
- Bulk delete endpoint cu partial success
- Auto-cleanup bonuri failed după 7 zile
- Batch model cu tracking complet

### Testing
- E2E tests cu Playwright
- Unit tests pentru bulk upload, auto-create, cleanup

## Commits Squashed: 43 user stories (US-001 → US-043)
## Branch: ralph/bulk-receipt-upload
## Timp dezvoltare: ~3 zile (Ralph autonomous)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-12 08:33:17 +00:00

18 KiB
Raw Blame History

PRD: Bulk Receipt Upload & Auto-Processing

1. Introducere

Sistemul actual permite upload-ul și procesarea unui singur bon la un moment dat, cu intervenție manuală la editare/salvare. Această funcționalitate adaugă o pagină separată pentru upload multiple bonuri (PDF/PNG/JPG) care sunt procesate automat prin OCR și salvate direct în baza de date, fără intervenție manuală.

Context tehnic: Există deja infrastructura de job queue (SQLite) și worker pool pentru procesare paralelă OCR. Această funcționalitate va extinde sistemul existent.

2. Obiective

Obiectiv Principal

  • Permiterea upload-ului bulk de bonuri (10-50 fișiere) cu procesare automată end-to-end

Obiective Secundare

  • Reducerea timpului de introducere date cu 90%+ pentru batch-uri mari
  • Vizibilitate în timp real asupra progresului procesării
  • Separare clară între flow-ul manual (editare) și automat (bulk)

Metrici de Succes

  • Timp mediu per bon < 10 secunde (vs. 2-3 minute manual)
  • Rata de succes OCR > 80% (bonuri procesate fără erori)
  • Upload batch 50 bonuri în < 10 minute

3. User Stories

US-001: Upload Multiple Fișiere

Ca utilizator data-entry Vreau să selectez/trag multiple fișiere (PDF/PNG/JPG) într-o zonă de upload Pentru că vreau să procesez un lot întreg de bonuri dintr-o dată

Acceptance Criteria:

  • Drag & drop zone acceptă multiple fișiere simultan
  • Click pe zonă deschide file picker cu multi-select activat
  • Fișierele acceptate: PDF, PNG, JPG (max 10MB/fișier)
  • Fișierele invalide sunt ignorate cu mesaj de avertizare
  • Lista fișierelor selectate apare sub zona de upload
  • Buton "Șterge" per fișier pentru eliminare din batch
  • npm run typecheck passes
  • Verify in browser that files appear in list after selection
  • CSS: Drop zone folosește var(--surface-card) background, var(--surface-border) border
  • CSS: Drop zone hover/active folosește var(--blue-50) background
  • CSS: Spacing între elemente folosește tokens (--space-md, --space-lg)
  • CSS: Testează în dark mode - drop zone vizibilă și contrastantă

US-002: Vizualizare Batch Înainte de Submit

Ca utilizator Vreau să văd lista fișierelor selectate cu preview Pentru că vreau să verific că am selectat fișierele corecte înainte de procesare

Acceptance Criteria:

  • Lista arată: thumbnail (pentru imagini), nume fișier, mărime
  • Pentru PDF-uri se arată icon generic PDF
  • Counter total: "X fișiere selectate (Y MB)"
  • Buton "Golește lista" pentru resetare completă
  • Buton "Adaugă fișiere" pentru a adăuga la selecție existentă
  • npm run typecheck passes
  • Verify in browser that thumbnails render correctly
  • CSS: Lista folosește pattern .card din cards.css
  • CSS: Thumbnail cu border-radius: var(--radius-md)
  • CSS: File size text cu color: var(--color-text-secondary), font-size: var(--text-sm)
  • CSS: Butoane folosesc clasele .btn .btn-secondary și .btn .btn-primary
  • CSS: Testează în dark mode - thumbnails și text lizibile

US-003: Submit Batch pentru Procesare

Ca utilizator Vreau să trimit toate fișierele pentru procesare cu un singur click Pentru că vreau să declanșez procesarea automată a întregului lot

Acceptance Criteria:

  • Buton "Procesează X bonuri" submit-ează batch-ul
  • La submit, toate fișierele se uploadează și se creează câte un OCR job per fișier
  • După submit, UI-ul trece în modul "progres" (nu mai permite adăugare fișiere)
  • Dacă un upload individual eșuează (network error), se reîncearcă automat (max 3 retry)
  • npm run typecheck passes
  • Verify in browser that submit disables file addition

US-004: Progres Real-Time per Fișier

Ca utilizator Vreau să văd progresul fiecărui fișier în timp real Pentru că vreau să știu câte bonuri s-au procesat și câte mai sunt în așteptare

Acceptance Criteria:

  • Fiecare fișier din listă arată status: "În așteptare" / "Se procesează..." / "Completat" / "Eroare"
  • Status vizual diferențiat: badge/icon color-coded (gri/albastru/verde/roșu)
  • La completare se arată confidence score overall (ex: "87% confidence")
  • Progress bar global: "15/50 procesate"
  • Timpul estimat rămas bazat pe average processing time
  • npm run typecheck passes
  • Verify in browser that status updates in real-time without page refresh
  • CSS: Status badges folosesc culorile din tabel (vezi secțiunea 6):
    • Pending: background: var(--surface-hover), color: var(--color-text-secondary)
    • Processing: background: var(--blue-50), color: var(--blue-600) + spinner
    • Success: background: var(--green-50), color: var(--green-600)
    • Error: background: var(--red-50), color: var(--red-600)
  • CSS: Progress bar folosește PrimeVue ProgressBar (stilizat global)
  • CSS: Confidence score cu font-family: var(--font-mono) pentru numere
  • CSS: Testează în dark mode - badges vizibile și contrastate

US-005: Salvare Automată a Bonurilor Procesate

Ca sistem Vreau să salvez automat bonurile procesate cu succes în baza de date Pentru că utilizatorul dorește procesare 100% automată fără intervenție

Acceptance Criteria:

  • După OCR completat cu succes, se creează automat un receipt în DB
  • Receipt-ul primește status "DRAFT" (poate fi editat ulterior dacă e nevoie)
  • Se atașează automat fișierul original la receipt
  • Se salvează toate câmpurile extrase: vendor, CUI, dată, sumă, TVA
  • Se generează automat accounting entries (ca la flow-ul manual)
  • npm run typecheck passes
  • Verify that receipts appear in receipt list after bulk processing

US-006: Gestionare Erori OCR

Ca utilizator Vreau ca bonurile cu erori OCR să fie marcate pentru review manual Pentru că vreau să procesez restul batch-ului fără blocaj, dar să nu pierd bonurile problematice

Acceptance Criteria:

  • La eroare OCR, fișierul primește status "Eroare" cu mesaj explicativ
  • Bonurile cu erori rămân în lista vizibilă, nu sunt șterse
  • Buton "Deschide în editor" pentru fiecare bon cu eroare (redirect la pagina de editare manuală)
  • Procesarea celorlalte bonuri continuă independent
  • La final se arată sumar: "45 procesate cu succes, 5 cu erori"
  • npm run typecheck passes
  • Verify in browser that error files show retry/edit options
  • CSS: Error row cu background: var(--red-50), border-left: 3px solid var(--red-500)
  • CSS: Error message cu color: var(--red-600), font-size: var(--text-sm)
  • CSS: Action buttons în error row folosesc .btn .btn-sm pattern
  • CSS: Testează în dark mode - erori vizibile dar nu agresive

US-007: Rezumat Final Batch

Ca utilizator Vreau să văd un rezumat la finalul procesării batch-ului Pentru că vreau să știu câte bonuri s-au salvat și ce acțiuni mai am de făcut

Acceptance Criteria:

  • Modal/panel de rezumat cu statistici: procesate OK, erori, total sumă
  • Link direct la lista de receipts filtrat pe batch-ul curent (by date/user)
  • Opțiune "Încarcă alt batch" pentru a începe de la zero
  • Opțiune "Vezi bonurile cu erori" pentru review rapid
  • npm run typecheck passes
  • Verify in browser that summary modal shows correct counts
  • CSS: Modal folosește PrimeVue Dialog (stilizat global) sau pattern .card
  • CSS: Statistici success cu color: var(--green-600), errors cu color: var(--red-600)
  • CSS: Total sumă cu font-size: var(--text-2xl), font-weight: var(--font-bold), font-family: var(--font-mono)
  • CSS: Spacing consistent: padding: var(--space-lg), gap: var(--space-md)
  • CSS: Testează în dark mode - modal și conținut lizibile

US-008: Backend - Endpoint Batch Upload

Ca developer Vreau un endpoint optimizat pentru upload multiple fișiere Pentru că upload-ul secvențial ar fi prea lent pentru 50+ fișiere

Acceptance Criteria:

  • POST /api/data-entry/bulk/upload acceptă multipart cu multiple fișiere
  • Returnează lista de job_id-uri pentru tracking
  • Validare: max 100 fișiere per batch, max 10MB per fișier
  • Jobs se creează atomic (toate sau niciunul)
  • Returnează și un batch_id pentru grouping
  • pytest tests pass
  • API returns correct response schema

US-009: Backend - Auto-Save Receipt din OCR Result

Ca developer Vreau un service care creează automat receipt-uri din rezultatele OCR Pentru că flow-ul bulk trebuie să fie end-to-end fără intervenție UI

Acceptance Criteria:

  • ReceiptAutoCreateService.create_from_ocr_result(job_id, ocr_result, user)
  • Mapare completă OCR fields → Receipt fields
  • Creare attachment cu fișierul original
  • Generare accounting entries via existing logic
  • Validare minimă: suma > 0, dată validă
  • Return receipt_id sau error message
  • pytest tests pass

US-010: Backend - Batch Status Endpoint

Ca developer Vreau un endpoint pentru status-ul întregului batch Pentru că frontend-ul trebuie să poll-eze eficient pentru toate fișierele

Acceptance Criteria:

  • GET /api/data-entry/bulk/batches/{batch_id}/status
  • Returnează status agregat: pending_count, processing_count, completed_count, failed_count
  • Include lista de job_id + status pentru fiecare fișier
  • Include receipt_id pentru jobs completate cu succes
  • Suportă long-polling (wait param) pentru eficiență
  • pytest tests pass

4. Cerințe Funcționale

  1. [REQ-001] Sistemul trebuie să accepte upload simultan de până la 100 fișiere
  2. [REQ-002] Fiecare fișier trebuie să fie max 10MB
  3. [REQ-003] Formatele acceptate: PDF, PNG, JPG, JPEG
  4. [REQ-004] Procesarea trebuie să fie paralelă (max N workers din config)
  5. [REQ-005] Bonurile procesate cu succes se salvează automat cu status DRAFT
  6. [REQ-006] Bonurile cu erori rămân disponibile pentru retry/editare manuală
  7. [REQ-007] Fișierele originale se atașează automat la receipt-uri
  8. [REQ-008] Se generează automat accounting entries pentru fiecare receipt
  9. [REQ-009] Batch-urile trebuie să fie tracked per user (nu se văd batch-urile altora)
  10. [REQ-010] Job files se curăță automat după 24h (cleanup existing)

5. Non-Goals (Ce NU facem)

  • NU facem aprobare automată (bonurile rămân DRAFT, nu APPROVED)
  • NU facem machine learning pentru îmbunătățirea OCR-ului
  • NU facem procesare pe server extern (totul rămâne local)
  • NU facem notificări (email/push) la finalizare batch
  • NU facem preview/editare în bulk page - pentru asta există pagina individuală
  • NU facem undo/rollback batch (bonurile create pot fi șterse individual)
  • NU facem scheduling (procesare imediată, nu amânată)
  • NU facem duplicate detection (poate fi adăugat ulterior)

6. Considerații Tehnice

Stack/Tehnologii

  • Frontend: Vue 3 Composition API, PrimeVue (FileUpload, ProgressBar, DataTable)
  • Backend: FastAPI, SQLite (job queue existent), SQLModel (receipts)
  • State: Pinia store pentru batch progress tracking

Patterns de Urmat

  • Folosește OCRJobQueue existent pentru job management
  • Extinde job_worker.py pentru auto-save la completare
  • Folosește pattern-ul de polling din OCRUploadZone.vue existent

⚠️ REGULI CSS OBLIGATORII

CITEȘTE ÎNTÂI: docs/ONBOARDING_CSS.md și docs/DESIGN_TOKENS.md

Golden Rules

✅ Folosește DOAR design tokens - NICIODATĂ valori hardcodate
✅ Verifică CSS_PATTERNS.md înainte de a scrie CSS nou
✅ Testează în AMBELE teme (light + dark mode)
❌ NICIODATĂ :deep() în componente (PrimeVue → vendor/)
❌ NICIODATĂ duplicate CSS (write once, use everywhere)

Design Tokens Obligatorii

Categorie GREȘIT CORECT
Spacing padding: 8px padding: var(--space-sm)
Spacing margin: 16px margin: var(--space-md)
Spacing gap: 24px gap: var(--space-lg)
Font size font-size: 14px font-size: var(--text-sm)
Font weight font-weight: 500 font-weight: var(--font-medium)
Font weight font-weight: 600 font-weight: var(--font-semibold)
Colors color: #111827 color: var(--color-text)
Colors color: #6b7280 color: var(--color-text-secondary)
Colors background: #ffffff background: var(--surface-card)
Colors background: #f0fdf4 background: var(--green-50)
Colors border: #e5e7eb border-color: var(--surface-border)
Radius border-radius: 8px border-radius: var(--radius-md)
Shadow box-shadow: 0 4px 6px... box-shadow: var(--shadow-md)
Transition transition: 0.2s transition: var(--transition-fast)

Spacing Scale Reference

Token Value Use Case
--space-xs 4px Icon gaps, badges
--space-sm 8px Between related items
--space-md 16px Component padding
--space-lg 24px Section padding, cards
--space-xl 32px Page margins

Status Colors (pentru progres/erori)

Status Background Text/Icon
Pending var(--surface-hover) var(--color-text-secondary)
Processing var(--blue-50) var(--blue-600)
Success var(--green-50) var(--green-600)
Error var(--red-50) var(--red-600)
Warning var(--yellow-50) var(--yellow-600)

Dark Mode - OBLIGATORIU

  • Folosește --surface-* tokens pentru backgrounds (auto-switch în dark mode)
  • Testează cu theme toggle din header (auto → light → dark)
  • NU folosi culori hardcodate care nu se schimbă în dark mode

Patterns Existente de Folosit

Pattern File Use Case
.card cards.css Container principal
.btn, .btn-primary buttons.css Butoane
.form-group, .form-label forms.css Formulare
.spinner spinners.css Loading states
.trend, .trend-up trends.css Indicators
Utility classes utilities/ gap-md, text-center, etc.

PrimeVue Components

  • FileUpload, ProgressBar, DataTable, Tag, Badge - toate sunt stilizate global
  • NU adăuga :deep() în componente
  • Modificări PrimeVue → src/assets/css/vendor/primevue-overrides.css

Dependențe

  • Job Queue existent: backend/modules/data_entry/services/ocr/job_queue.py
  • Worker Pool existent: backend/modules/data_entry/services/ocr/ocr_worker_pool.py
  • Receipt CRUD: backend/modules/data_entry/db/crud/receipt.py
  • Attachment CRUD: backend/modules/data_entry/db/crud/attachment.py

Riscuri Tehnice

  • Memory pressure: Upload simultan de 100 fișiere × 10MB = 1GB potențial
    • Mitigare: Upload secvențial intern, buffer 5 fișiere max în memorie
  • Queue overflow: 100 jobs noi pot încetini procesarea existentă
    • Mitigare: Worker pool deja limitează concurența
  • Browser crash: Tab închis pierde tracking progress
    • Mitigare: Jobs persistă în DB, refresh poate recupera status

7. Considerații UI/UX

Layout

  1. Header: Titlu "Upload Bulk Bonuri" + link înapoi la lista principală
  2. Drop Zone: Mare, centrată, cu icon și text instructiv
  3. File List: Tabel/listă sub drop zone cu progres per fișier
  4. Actions Bar: Butoane "Procesează", "Golește lista" - sticky la bottom

Layout CSS Structure

.bulk-upload-page
├── .page-header (pattern existent)
│   └── h1 + breadcrumb
├── .card (drop zone container)
│   └── .upload-zone (dashed border, centered)
├── .card (file list container)
│   └── DataTable sau custom list
└── .form-actions (sticky footer cu butoane)

Stări UI cu CSS

Stare Background Border Elements
Empty var(--surface-card) 2px dashed var(--surface-border) Icon mare + text instructiv
Drag Over var(--blue-50) 2px dashed var(--blue-500) Border evidențiat
Files Selected var(--surface-card) 1px solid var(--surface-border) Lista + action buttons
Processing var(--surface-card) - Spinner global + per-file status
Complete var(--green-50) subtle - Summary card
Has Errors - - Error items highlighted

Status Badge Styles

/* Folosește PrimeVue Tag sau custom badges */
.status-pending    { background: var(--surface-hover); color: var(--color-text-secondary); }
.status-processing { background: var(--blue-50); color: var(--blue-600); }
.status-success    { background: var(--green-50); color: var(--green-600); }
.status-error      { background: var(--red-50); color: var(--red-600); }

Accesibilitate

  • Keyboard navigation pentru file list
  • Screen reader announcements la status changes
  • Focus management la modal rezumat
  • WCAG contrast ratios respectate (toate token-urile sunt compliant)

8. Success Metrics

  • Upload Success Rate: > 99% (fișierele ajung în queue)
  • OCR Success Rate: > 80% (bonuri procesate fără erori)
  • Average Processing Time: < 8 secunde/bon
  • User Satisfaction: Reducere timp introducere date cu 90%

9. Open Questions

  • Limita de 100 fișiere este suficientă sau trebuie mărită?
  • Dorim să afișăm preview al datelor extrase înainte de save (ar contrazice "100% automat")?
  • Ce facem cu bonurile duplicate detectate ulterior (același număr bon + dată)?
  • Trebuie un "dry run" mode care procesează dar nu salvează?

10. Dependențe între User Stories

US-001 (Upload Files)
   ↓
US-002 (Preview List) ← independent
   ↓
US-003 (Submit Batch) → US-008 (Backend Upload Endpoint)
   ↓
US-004 (Progress) ← US-010 (Backend Status Endpoint)
   ↓
US-005 (Auto-Save) ← US-009 (Backend Auto-Create Service)
   ↓
US-006 (Error Handling)
   ↓
US-007 (Summary)

Ordine recomandată de implementare:

  1. US-008: Backend - Batch Upload Endpoint
  2. US-010: Backend - Batch Status Endpoint
  3. US-009: Backend - Auto-Save Service
  4. US-001: Frontend - Upload Zone
  5. US-002: Frontend - File Preview
  6. US-003: Frontend - Submit Batch
  7. US-004: Frontend - Progress Tracking
  8. US-005: Integration - Auto-Save Flow
  9. US-006: Frontend - Error Handling
  10. US-007: Frontend - Summary Modal

Last Updated: 2026-01-09 Author: Claude Code Status: Draft - Pending Review