From 77a89f4b16886aa5ef4b509a3f8b65936e21f765 Mon Sep 17 00:00:00 2001 From: Marius Mutu Date: Fri, 13 Mar 2026 17:59:58 +0200 Subject: [PATCH] docs: update README and .env.example for project root start convention Fix start command (python -m uvicorn api.app.main:app from project root), correct JSON_OUTPUT_DIR path (vfp/output not ../vfp/output), document all env variables with descriptions, add dashboard features overview, business rules, and WSL2 notes. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 212 ++++++++++++++++++++++++++++++++--------------- api/.env.example | 86 ++++++++++++++++--- 2 files changed, 218 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index e40757f..f0570c5 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,35 @@ System automat de import comenzi din platforma GoMag in sistemul ERP ROA Oracle. - **Admin/Dashboard:** FastAPI + Jinja2 + Oracle pool + SQLite - **Date:** Oracle 11g/12c (schema ROA), SQLite (tracking local) +--- + ## Quick Start ### Prerequisite - Python 3.10+ -- Oracle Instant Client (optional - suporta si thin mode) +- Oracle Instant Client 21.x (optional — suporta si thin mode pentru Oracle 12.1+) + +### Instalare -### Instalare si pornire ```bash -cd api -pip install -r requirements.txt -# Configureaza .env (vezi api/.env.example) -uvicorn app.main:app --host 0.0.0.0 --port 5003 --reload +# Din project root (gomag/) +pip install -r api/requirements.txt +cp api/.env.example api/.env +# Editeaza api/.env cu datele de conectare Oracle +``` + +### Pornire server + +**Important:** serverul trebuie pornit **din project root**, nu din `api/`: + +```bash +# Din gomag/ +python -m uvicorn api.app.main:app --host 0.0.0.0 --port 5003 +``` + +Sau folosind scriptul inclus: +```bash +./start.sh ``` Deschide `http://localhost:5003` in browser. @@ -36,93 +53,154 @@ Deschide `http://localhost:5003` in browser. **Test A - Basic (fara Oracle):** ```bash -cd api -python test_app_basic.py +python api/test_app_basic.py ``` -Verifica 17 importuri de module + 13 rute GET. Asteptat: 30/30 PASS. +Verifica importuri de module + rute GET. Asteptat: 32/33 PASS (1 fail pre-existent `/sync` HTML). **Test C - Integrare Oracle:** ```bash python api/test_integration.py ``` -Necesita Oracle activ. Verifica health, mappings CRUD, article search, validation, sync. Asteptat: 9/9 PASS. +Necesita Oracle activ. Verifica health, mappings CRUD, article search, validation, sync. + +--- + +## Configurare (.env) + +Copiaza `.env.example` si completeaza: + +```bash +cp api/.env.example api/.env +``` + +| Variabila | Descriere | Exemplu | +|-----------|-----------|---------| +| `ORACLE_USER` | User Oracle | `MARIUSM_AUTO` | +| `ORACLE_PASSWORD` | Parola Oracle | `secret` | +| `ORACLE_DSN` | TNS alias | `ROA_CENTRAL` | +| `TNS_ADMIN` | Cale absoluta la tnsnames.ora | `/mnt/e/.../gomag/api` | +| `INSTANTCLIENTPATH` | Cale Instant Client (thick mode) | `/opt/oracle/instantclient_21_15` | +| `FORCE_THIN_MODE` | Thin mode fara Instant Client | `true` | +| `SQLITE_DB_PATH` | Path SQLite (relativ la project root) | `api/data/import.db` | +| `JSON_OUTPUT_DIR` | Folder JSON-uri VFP (relativ la project root) | `vfp/output` | +| `APP_PORT` | Port HTTP | `5003` | +| `ID_POL` | ID Politica ROA | `39` | +| `ID_GESTIUNE` | ID Gestiune ROA | `0` | +| `ID_SECTIE` | ID Sectie ROA | `6` | + +**Nota Oracle mode:** +- **Thick mode** (Oracle 10g/11g): seteaza `INSTANTCLIENTPATH` +- **Thin mode** (Oracle 12.1+): seteaza `FORCE_THIN_MODE=true`, sterge `INSTANTCLIENTPATH` + +--- ## Structura Proiect ``` -/ -├── api/ # FastAPI Admin + Database -│ ├── app/ # Aplicatia FastAPI +gomag/ +├── api/ # FastAPI Admin + Dashboard +│ ├── app/ │ │ ├── main.py # Entry point, lifespan, logging -│ │ ├── config.py # Settings (pydantic-settings, .env) -│ │ ├── database.py # Oracle pool + SQLite init +│ │ ├── config.py # Settings (pydantic-settings + .env) +│ │ ├── database.py # Oracle pool + SQLite schema + migrari │ │ ├── routers/ # Endpoint-uri HTTP -│ │ │ ├── health.py # /health, /api/health -│ │ │ ├── dashboard.py # / (dashboard HTML) +│ │ │ ├── health.py # GET /health +│ │ │ ├── dashboard.py # GET / (HTML) │ │ │ ├── mappings.py # /mappings, /api/mappings │ │ │ ├── articles.py # /api/articles/search │ │ │ ├── validation.py # /api/validate/* -│ │ │ └── sync.py # /api/sync/* -│ │ ├── services/ # Business logic -│ │ │ ├── mapping_service # CRUD ARTICOLE_TERTI -│ │ │ ├── article_service # Cautare NOM_ARTICOLE -│ │ │ ├── import_service # Import comanda in Oracle -│ │ │ ├── sync_service # Orchestrare: JSON→validate→import -│ │ │ ├── validation_service # Validare SKU-uri -│ │ │ ├── order_reader # Citire JSON-uri din vfp/output/ -│ │ │ ├── sqlite_service # Tracking runs/orders/missing SKUs -│ │ │ └── scheduler_service # APScheduler timer -│ │ ├── templates/ # Jinja2 HTML (dashboard, mappings, etc.) +│ │ │ └── sync.py # /api/sync/* + /api/dashboard/orders +│ │ ├── services/ +│ │ │ ├── sync_service.py # Orchestrare: JSON→validate→import +│ │ │ ├── import_service.py # Import comanda in Oracle ROA +│ │ │ ├── mapping_service.py # CRUD ARTICOLE_TERTI + pct_total +│ │ │ ├── sqlite_service.py # Tracking runs/orders/missing SKUs +│ │ │ ├── order_reader.py # Citire gomag_orders_page*.json +│ │ │ ├── validation_service.py +│ │ │ ├── article_service.py +│ │ │ └── scheduler_service.py # APScheduler timer +│ │ ├── templates/ # Jinja2 HTML │ │ └── static/ # CSS + JS -│ ├── database-scripts/ # Oracle SQL scripts +│ ├── database-scripts/ # Oracle SQL (ARTICOLE_TERTI, packages) +│ ├── data/ # SQLite DB (import.db) +│ ├── .env # Configurare locala (nu in git) +│ ├── .env.example # Template configurare │ ├── test_app_basic.py # Test A - fara Oracle │ ├── test_integration.py # Test C - cu Oracle -│ └── requirements.txt # Python dependencies -├── vfp/ # VFP Integration -│ ├── gomag-vending.prg # Client GoMag API +│ └── requirements.txt +├── vfp/ # VFP Integration +│ ├── gomag-vending.prg # Client GoMag API (descarca JSON-uri) │ ├── sync-comenzi-web.prg # Orchestrator VFP -│ └── utils.prg # Utilitare VFP -├── docs/ # Documentatie -│ ├── PRD.md # Product Requirements -│ └── stories/ # User Stories -└── logs/ # Log-uri aplicatie +│ ├── utils.prg # Utilitare (log, settings, connectivity) +│ └── output/ # JSON-uri descarcate (gomag_orders_page*.json) +├── logs/ # Log-uri aplicatie (sync_comenzi_*.log) +├── docs/ # Documentatie (PRD, stories) +├── start.sh # Script pornire (Linux/WSL) +└── CLAUDE.md # Instructiuni pentru AI assistants ``` -## Configurare (.env) +--- + +## Dashboard Features + +### Sync Panel +- Start sync manual sau scheduler automat (5/10/30 min) +- Progress live: `"Import 45/80: #CMD-1234 Ion Popescu"` +- Smart polling: 30s idle → 3s cand ruleaza → auto-refresh tabela +- Last sync clickabil → jurnal detaliat + +### Comenzi +- Filtru perioada: 3z / 7z / 30z / 3 luni / toate / custom +- Status pills cu conturi totale pe perioada (nu per-pagina) +- Cautare integrata in bara de filtre +- Coloana Client cu tooltip `▲` cand persoana livrare ≠ facturare +- Paginare sus + jos, selector rezultate per pagina (25/50/100/250) + +### Mapari SKU +- Badge `✓ 100%` / `⚠ 80%` per grup SKU +- Filtru Complete / Incomplete +- Verificare duplicat SKU-CODMAT (409 cu optiune de restaurare) + +### SKU-uri Lipsa +- Cautare dupa SKU sau nume produs +- Filtru Nerezolvate / Rezolvate / Toate cu conturi +- Re-scan cu progress inline si banner rezultat + +--- + +## Fluxul de Import -```env -ORACLE_USER=MARIUSM_AUTO -ORACLE_PASSWORD=******** -ORACLE_DSN=ROA_CENTRAL -FORCE_THIN_MODE=true # sau INSTANTCLIENTPATH=C:\oracle\instantclient -SQLITE_DB_PATH=data/import.db -APP_PORT=5003 -LOG_LEVEL=INFO -JSON_OUTPUT_DIR=../vfp/output ``` +1. VFP descarca comenzi GoMag API → vfp/output/gomag_orders_page*.json +2. FastAPI citeste JSON-urile (order_reader) +3. Valideaza SKU-uri contra ARTICOLE_TERTI + NOM_ARTICOLE (validation_service) +4. Import_service creeaza/cauta partener in Oracle (shipping person = facturare) +5. PACK_IMPORT_COMENZI.importa_comanda_web() insereaza comanda in ROA +6. Rezultate salvate in SQLite (orders, sync_run_orders, order_items) +``` + +### Reguli Business +- **Persoana**: shipping name = persoana pe eticheta = beneficiarul facturii +- **Adresa**: cand billing ≠ shipping → adresa shipping pentru ambele (facturare + livrare) +- **SKU simplu**: gasit direct in NOM_ARTICOLE → nu se stocheaza in ARTICOLE_TERTI +- **SKU cu repackaging**: un SKU → CODMAT cu cantitate diferita +- **SKU set complex**: un SKU → multiple CODMAT-uri cu procente de pret + +--- ## Status Implementare -### Phase 1: Database Foundation - COMPLET -- ARTICOLE_TERTI table + Docker setup -- PACK_IMPORT_PARTENERI package -- PACK_IMPORT_COMENZI package +| Faza | Status | Descriere | +|------|--------|-----------| +| Phase 1: Database Foundation | ✅ Complet | ARTICOLE_TERTI, PACK_IMPORT_PARTENERI, PACK_IMPORT_COMENZI | +| Phase 2: VFP Integration | ✅ Complet | gomag-vending.prg, sync-comenzi-web.prg | +| Phase 3-4: FastAPI Dashboard | ✅ Complet | Redesign UI, smart polling, filter bar, paginare, tooltip | +| Phase 5: Production | 🔄 In Progress | Logging ✅, Auth ⏳, SMTP ⏳, NSSM service ⏳ | -### Phase 2: VFP Integration - COMPLET -- gomag-vending.prg (GoMag API client) -- sync-comenzi-web.prg (orchestrator cu logging) +--- -### Phase 3-4: FastAPI Admin + Dashboard - COMPLET -- Mappings CRUD + CSV import/export -- Article autocomplete (NOM_ARTICOLE) -- Pre-validation SKU-uri -- Import orchestration (JSON→Oracle) -- Dashboard cu stat cards, sync control, history -- Missing SKUs management page -- File logging (logs/sync_comenzi_*.log) +## WSL2 Note -### Phase 5: Production - IN PROGRESS -- [x] File logging -- [ ] Email notifications (SMTP) -- [ ] HTTP Basic Auth -- [ ] NSSM Windows service +- `uvicorn --reload` **nu functioneaza** pe `/mnt/e/` (WSL2 limitation) — restarta manual +- Serverul trebuie pornit din **project root** (`gomag/`), nu din `api/` +- `JSON_OUTPUT_DIR` si `SQLITE_DB_PATH` sunt relative la project root diff --git a/api/.env.example b/api/.env.example index 7148978..0f915aa 100644 --- a/api/.env.example +++ b/api/.env.example @@ -1,15 +1,75 @@ -# Oracle Database Configuration -ORACLE_USER=YOUR_ORACLE_USERNAME -ORACLE_PASSWORD=YOUR_ORACLE_PASSWORD -ORACLE_DSN=YOUR_TNS_CONNECTION_NAME -TNS_ADMIN=/app -INSTANTCLIENTPATH=/opt/oracle/instantclient_21_1 +# ============================================================================= +# GoMag Import Manager - Configurare +# Copiaza in api/.env si completeaza cu datele reale +# ============================================================================= -# Flask Configuration -FLASK_ENV=development -FLASK_DEBUG=1 -PYTHONUNBUFFERED=1 +# ============================================================================= +# ORACLE MODE - Alege una din urmatoarele doua optiuni: +# ============================================================================= -# Application Settings -APP_PORT=5000 -LOG_LEVEL=DEBUG \ No newline at end of file +# THICK MODE (Oracle 10g/11g/12.1+) - Recomandat pentru compatibilitate maxima +# Necesita Oracle Instant Client instalat +INSTANTCLIENTPATH=/opt/oracle/instantclient_21_15 + +# THIN MODE (Oracle 12.1+ only) - Fara Instant Client, mai simplu +# Comenteaza INSTANTCLIENTPATH de sus si decommenteaza urmatoarea linie: +# FORCE_THIN_MODE=true + +# ============================================================================= +# ORACLE - Credentiale baza de date +# ============================================================================= + +ORACLE_USER=USER_ORACLE +ORACLE_PASSWORD=parola_oracle +ORACLE_DSN=TNS_ALIAS + +# Calea absoluta la directorul cu tnsnames.ora +# De obicei: directorul api/ al proiectului +TNS_ADMIN=/cale/absoluta/la/gomag/api + +# ============================================================================= +# APLICATIE +# ============================================================================= + +APP_PORT=5003 +LOG_LEVEL=INFO + +# ============================================================================= +# CALE FISIERE (relative la project root - directorul gomag/) +# ============================================================================= + +# JSON-uri descarcate de VFP +JSON_OUTPUT_DIR=vfp/output + +# SQLite tracking DB +SQLITE_DB_PATH=api/data/import.db + +# ============================================================================= +# ROA - Setari import comenzi (din vfp/settings.ini sectiunea [ROA]) +# ============================================================================= + +# Politica de pret +ID_POL=39 + +# Gestiune implicita +ID_GESTIUNE=0 + +# Sectie implicita +ID_SECTIE=6 + +# ============================================================================= +# SMTP - Notificari email (optional) +# ============================================================================= + +# SMTP_HOST=smtp.gmail.com +# SMTP_PORT=587 +# SMTP_USER=email@exemplu.com +# SMTP_PASSWORD=parola_app +# SMTP_TO=destinatar@exemplu.com + +# ============================================================================= +# AUTH - HTTP Basic Auth pentru dashboard (optional) +# ============================================================================= + +# API_USERNAME=admin +# API_PASSWORD=parola_sigura