Integrate shared JWT authentication into data-entry-app: - Add Oracle pool initialization for auth service - Add AuthenticationMiddleware to protect API routes - Update all receipt endpoints to use CurrentUser from JWT - Add shared auth router (/api/auth/login, /api/auth/refresh) Add nomenclature synchronization feature: - Create SQLite models for synced suppliers, local suppliers, and cash registers - Add nomenclature router with sync triggers and CRUD endpoints - Add sync service for Oracle → SQLite nomenclature data - Update nomenclature_service to use synced SQLite data with fallbacks Create shared frontend components: - Add shared/frontend/ with LoginView.vue, auth store factory, login.css - Integrate shared login and auth into data-entry-app frontend - Add axios-based API service with token refresh interceptor 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 KiB
Plan: Implementare Auth SSO + Nomenclatoare Sync
Plan Handover Document - Salvat pentru continuare în altă sesiune Data: 2025-12-13 | Branch:
feature/data-entry-receipts
Obiectiv
Integrare autentificare SSO și sincronizare nomenclatoare Oracle în data-entry-app conform IMPLEMENTATION_PLAN_AUTH_UNITAR.md.
Instrucțiuni Implementare
Metodologie
- Execută fazele în paralel unde e posibil (Faza 1+2 pot rula simultan, Faza 3+4 pot rula simultan)
- Folosește agenți Task pentru viteza - lansează agenți în paralel pentru task-uri independente
- Testează după fiecare fază - nu trece la următoarea fără validare
- Urmărește progresul în acest fișier - marchează task-urile completate cu ✅
Comenzi de Start
# Asigură-te că SSH tunnel rulează (pentru Oracle)
./ssh_tunnel.sh start
# Backend reports (pentru auth API - port 8001)
cd reports-app/backend && uvicorn app.main:app --reload --port 8001
# Backend data-entry (port 8003)
cd data-entry-app/backend && uvicorn app.main:app --reload --port 8003
# Frontend data-entry (port 3010)
cd data-entry-app/frontend && npm run dev
Progres Implementare
- FAZA 1: Auth Backend - ✅ 6/6 task-uri COMPLETE
- FAZA 2: Auth Frontend - ✅ 6/6 task-uri COMPLETE
- FAZA 3: Nomenclatoare Sync - ✅ 6/6 task-uri COMPLETE
- FAZA 4: OCR + Supplier Search - ✅ 2/2 task-uri COMPLETE
Status: ✅ IMPLEMENTARE COMPLETĂ - 2025-12-13
Stare Curentă (IMPLEMENTAT)
Backend Data-Entry ✅
- ✅ Models: Receipt, ReceiptAttachment, AccountingEntry - complete
- ✅ CRUD operations - complete
- ✅ API Routers: receipts.py, ocr.py, nomenclature.py
- ✅ Services: receipt_service, ocr_service, sync_service
- ✅ Workflow: DRAFT → PENDING → APPROVED/REJECTED
- ✅ Auth: Integrare shared/auth (middleware + CurrentUser)
- ✅ Nomenclatoare: SQLite sync (SyncedSupplier, LocalSupplier, SyncedCashRegister)
- ✅
sys.path.insertpentru shared/ în main.py
Frontend Data-Entry ✅
- ✅ Views: List, Create, Detail, Approval, LoginView
- ✅ Components: OCR components + Create Supplier Dialog
- ✅ Store: receiptsStore.js + auth.js
- ✅ Router: routes + auth guards + /login
- ✅ Auth Store:
src/stores/auth.js- creat - ✅ Login View:
src/views/LoginView.vue- creat - ✅ Router Guards: beforeEach cu requiresAuth
- ✅ API Service:
src/services/api.js- creat cu interceptors
Shared Auth (disponibil pentru integrare)
- ✅
shared/auth/routes.py-create_auth_router()(linia 39-430) - ✅
shared/auth/middleware.py-AuthenticationMiddleware - ✅
shared/auth/dependencies.py-get_current_user - ✅
shared/auth/models.py-CurrentUser,TokenResponse
Referință Reports-App (pentru copiere)
reports-app/frontend/src/stores/auth.js- 119 liniireports-app/frontend/src/services/api.js- 141 liniireports-app/frontend/src/views/LoginView.vue- 367 liniireports-app/frontend/src/router/index.js- auth guard la liniile 96-114
Faze Implementare
FAZA 1: Auth Backend (6 task-uri)
Task 1.1: Adaugă AuthenticationMiddleware în main.py
Fișier: data-entry-app/backend/app/main.py
Acțiune: După CORS middleware (linia 75), adaugă:
from auth.middleware import AuthenticationMiddleware
app.add_middleware(
AuthenticationMiddleware,
excluded_paths=["/docs", "/redoc", "/openapi.json", "/health", "/", "/api/auth/login", "/api/auth/refresh"]
)
Task 1.2: Adaugă Auth Router în main.py
Fișier: data-entry-app/backend/app/main.py
Acțiune: După include_router pentru ocr (linia 98), adaugă:
from auth.routes import create_auth_router
auth_router = create_auth_router()
app.include_router(auth_router, prefix="/api/auth", tags=["auth"])
Task 1.3: Înlocuiește get_current_user în receipts.py
Fișier: data-entry-app/backend/app/routers/receipts.py
Acțiune: Șterge liniile 38-59 și înlocuiește cu:
from auth.dependencies import get_current_user
from auth.models import CurrentUser
Apoi actualizează type hints: current_user: str → current_user: CurrentUser
Și accesează current_user.username în loc de current_user
Task 1.4: Înlocuiește get_current_user în ocr.py
Fișier: data-entry-app/backend/app/routers/ocr.py
Acțiune: Similar cu receipts.py, adaugă importurile auth și folosește CurrentUser
Task 1.5: Actualizează type hints în toate endpoint-urile
Actualizează toate funcțiile care folosesc current_user: str să folosească current_user: CurrentUser
Task 1.6: Testare backend auth
cd data-entry-app/backend
uvicorn app.main:app --reload --port 8003
# Test: curl http://localhost:8003/api/receipts/ → 401 Unauthorized
FAZA 2: Auth Frontend (6 task-uri)
Task 2.1: Crează API service
Fișier NOU: data-entry-app/frontend/src/services/api.js
Acțiune: Copiază din reports-app/frontend/src/services/api.js cu modificări:
- Schimbă BASE_URL pentru a funcționa cu proxy-ul
- Modifică refresh token URL
Task 2.2: Crează Auth Store
Fișier NOU: data-entry-app/frontend/src/stores/auth.js
Acțiune: Copiază din reports-app/frontend/src/stores/auth.js
- Modifică import apiService din
../services/api
Task 2.3: Crează LoginView
Fișier NOU: data-entry-app/frontend/src/views/LoginView.vue
Acțiune: Copiază din reports-app/frontend/src/views/LoginView.vue
- Schimbă titlul: "ROA Reports" → "Data Entry"
- Schimbă subtitle: "Rapoarte ERP" → "Introducere Bonuri Fiscale"
- Schimbă redirect după login: "/dashboard" → "/"
Task 2.4: Actualizează Router cu auth guards
Fișier: data-entry-app/frontend/src/router/index.js
Acțiune: Adaugă auth guard similar cu reports-app (liniile 96-114)
import { useAuthStore } from '@/stores/auth'
// Adaugă rută login
// Adaugă meta: { requiresAuth: true } la rutele protejate
// Adaugă beforeEach guard
Task 2.5: Actualizează vite.config.js pentru auth proxy
Fișier: data-entry-app/frontend/vite.config.js
Acțiune: Adaugă proxy pentru auth:
'/api/auth': {
target: 'http://localhost:8001',
changeOrigin: true,
}
Task 2.6: Testare frontend auth
cd data-entry-app/frontend
npm run dev
# Test: Accesează http://localhost:3010 → Redirect la /login
# Login cu credențiale Oracle → Redirect la /
FAZA 3: Nomenclatoare Oracle→SQLite (6 task-uri)
Task 3.1: Crează modele SQLModel
Fișier NOU: data-entry-app/backend/app/db/models/nomenclature.py
SyncedSupplier- furnizori sincronizați din OracleLocalSupplier- furnizori creați local (din OCR)SyncedCashRegister- case/bănci sincronizate
Task 3.2: Crează Alembic migration
cd data-entry-app/backend
alembic revision --autogenerate -m "add nomenclature tables"
alembic upgrade head
Task 3.3: Crează Sync Service
Fișier NOU: data-entry-app/backend/app/services/sync_service.py
sync_suppliers(company_id, schema)- sync furnizori Oracle→SQLitesync_cash_registers(company_id, schema)- sync case/bănciget_schema_for_company(company_id)- lookup schema
Task 3.4: Crează Nomenclature Router
Fișier NOU: data-entry-app/backend/app/routers/nomenclature.py
GET /suppliers/search- căutare furnizor (SQLite + Oracle live)POST /suppliers/local- creare furnizor localPOST /sync/suppliers- trigger manual sync
Task 3.5: Înregistrează router în main.py
from app.routers import nomenclature
app.include_router(nomenclature.router, prefix="/api/nomenclature", tags=["nomenclature"])
Task 3.6: Actualizare nomenclature_service.py existent
Înlocuiește mock data cu query-uri din tabelele SQLite sincronizate
FAZA 4: Integrare OCR + Supplier Search (2 task-uri)
Task 4.1: Actualizare ReceiptCreateView.vue
Fișier: data-entry-app/frontend/src/views/receipts/ReceiptCreateView.vue
Acțiune: După OCR result, caută automat furnizor după CUI:
async function handleOCRResult(ocrData) {
if (ocrData.cui) {
const result = await receiptsStore.searchSupplier(ocrData.cui);
if (result.found) {
form.partner_id = result.supplier.id;
form.partner_name = result.supplier.name;
} else {
showCreateSupplierDialog(ocrData);
}
}
}
Task 4.2: Adaugă supplier search în receiptsStore.js
Fișier: data-entry-app/frontend/src/stores/receiptsStore.js
Acțiune: Adaugă action searchSupplier(fiscalCode) și createLocalSupplier(data)
Sumar Fișiere
De Modificat
| Fișier | Faza |
|---|---|
data-entry-app/backend/app/main.py |
1, 3 |
data-entry-app/backend/app/routers/receipts.py |
1 |
data-entry-app/backend/app/routers/ocr.py |
1 |
data-entry-app/frontend/src/router/index.js |
2 |
data-entry-app/frontend/vite.config.js |
2 |
data-entry-app/frontend/src/views/receipts/ReceiptCreateView.vue |
4 |
data-entry-app/frontend/src/stores/receiptsStore.js |
4 |
De Creat (NOU)
| Fișier | Faza |
|---|---|
data-entry-app/frontend/src/services/api.js |
2 |
data-entry-app/frontend/src/stores/auth.js |
2 |
data-entry-app/frontend/src/views/LoginView.vue |
2 |
data-entry-app/backend/app/db/models/nomenclature.py |
3 |
data-entry-app/backend/app/services/sync_service.py |
3 |
data-entry-app/backend/app/routers/nomenclature.py |
3 |
migrations/versions/xxx_nomenclature.py |
3 |
Ordine Execuție
Faza 1 + 2 (Auth) → Faza 3 + 4 (Nomenclatoare)
Fazele 1-2 sunt blocante pentru funcționalitatea completă, dar Faza 3-4 poate fi amânată dacă e nevoie (nomenclatoarele rămân mock data temporar).
Strategie Execuție cu Agenți
Agenți Paraleli Recomandați
Round 1 - Auth (Backend + Frontend simultan):
Agent A: Faza 1 - Task 1.1-1.5 (Backend auth)
Agent B: Faza 2 - Task 2.1-2.3 (Frontend auth files)
După Round 1, testare manuală auth flow.
Round 2 - Finalizare Auth + Start Nomenclatoare:
Agent A: Faza 2 - Task 2.4-2.5 (Router guards, vite config)
Agent B: Faza 3 - Task 3.1-3.2 (Modele SQLModel + migration)
Round 3 - Nomenclatoare + Integration:
Agent A: Faza 3 - Task 3.3-3.6 (Sync service + router)
Agent B: Faza 4 - Task 4.1-4.2 (Frontend OCR supplier)
Validare După Fiecare Fază
După Faza 1:
curl http://localhost:8003/api/receipts/
# Expected: 401 Unauthorized
După Faza 2:
# Browser: http://localhost:3010
# Expected: Redirect to /login
# Login cu credențiale Oracle → Redirect la /
După Faza 3:
curl http://localhost:8003/api/nomenclature/suppliers/search?fiscal_code=RO12345678
# Expected: Search result sau sugestie creare local
După Faza 4:
# Browser: Crează bon nou → Upload poză → OCR
# Expected: Furnizor găsit automat sau dialog creare
Context pentru Sesiune Următoare
Fișiere Cheie de Citit
- Acest plan:
/home/marius/.claude/plans/unified-orbiting-sonnet.md - CLAUDE.md principal:
/mnt/e/proiecte/roa2web/CLAUDE.md - CLAUDE.md data-entry:
/mnt/e/proiecte/roa2web/data-entry-app/CLAUDE.md
Comenzi Quick Start
cd /mnt/e/proiecte/roa2web
git status # Verifică branch feature/data-entry-receipts
./ssh_tunnel.sh start # SSH tunnel pentru Oracle
Dependențe Servicii
- reports-backend:8001 - NECESAR pentru auth API (login, refresh)
- data-entry-backend:8003 - Backend principal
- Oracle DB - Via SSH tunnel, necesar pentru auth + nomenclatoare