## 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>
407 lines
18 KiB
Markdown
407 lines
18 KiB
Markdown
# 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
|
||
```css
|
||
/* 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
|