From 6fc2f34ba9ee210eaecc919152ca91e2ad777334 Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Wed, 18 Mar 2026 15:48:33 +0000 Subject: [PATCH] docs: simplify CLAUDE.md, update README with accurate business rules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CLAUDE.md reduced from 214 to 60 lines — moved architecture, API endpoints, and detailed docs to README. Kept only AI-critical rules (TeamCreate, import flow gotchas, partner/pricing logic). README updated: added CANCELLED status, dual pricing policy, discount VAT splitting, stale error recovery, accurate partner/address logic, settings page references. Removed outdated Status Implementare section. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 224 +++++++++--------------------------------------------- README.md | 62 ++++++++------- 2 files changed, 69 insertions(+), 217 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 39892c8..ecb8a4e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,214 +1,60 @@ # CLAUDE.md -## REGULI OBLIGATORII - -**Pentru task-uri paralele foloseste INTOTDEAUNA TeamCreate + TaskCreate, NU Agent tool cu subagenti paraleli.** -Skill-ul `superpowers:dispatching-parallel-agents` NU se aplica in acest proiect. In loc de dispatch cu Agent tool, creeaza o echipa cu TeamCreate, defineste task-uri cu TaskCreate, si spawneaza teammates cu Agent tool + `team_name`. - ## Project Overview **System:** Import Comenzi Web GoMag → Sistem ROA Oracle +Stack: FastAPI + Jinja2 + Bootstrap 5.3 + Oracle PL/SQL + SQLite -Importa automat comenzi din GoMag in sistemul ERP ROA Oracle. Stack complet Python/FastAPI. +Documentatie completa: [README.md](README.md) -### Tech Stack -- **API + Admin:** FastAPI + Jinja2 + Bootstrap 5.3 -- **GoMag Integration:** Python (`gomag_client.py` — API download with pagination) -- **Sync Orchestrator:** Python (`sync_service.py` — download → parse → validate → import) -- **Database:** Oracle PL/SQL packages (IMPORT_PARTENERI, IMPORT_COMENZI) + SQLite (tracking) +## Implementare cu TeamCreate -## GStack Workflow (pentru features noi) +**OBLIGATORIU:** Folosim TeamCreate + TaskCreate, NU Agent tool cu subagenti paraleli. Skill-ul `superpowers:dispatching-parallel-agents` NU se aplica in acest proiect. -1. `/plan-ceo-review` — planning interactiv (alegi modul: expansion / hold scope / reducere) -2. Implementare cu TeamCreate (ca de obicei) -3. `/review` — code review pe diff înainte de ship -4. `/ship` — push + unit tests + crează PR automat -5. `/qa` — testează aplicația live în browser real (după ce rulează) +- Team lead citeste TOATE fisierele implicate, creeaza planul +- **ASTEAPTA aprobare explicita** de la user inainte de implementare +- Task-uri pe fisiere non-overlapping (evita conflicte) +- Cache-bust static assets (`?v=N`) la fiecare schimbare UI ## Development Commands ```bash -# Run FastAPI server — INTOTDEAUNA via start.sh (seteaza Oracle env vars) +# INTOTDEAUNA via start.sh (seteaza Oracle env vars) ./start.sh -# NU folosi uvicorn direct — lipsesc LD_LIBRARY_PATH si TNS_ADMIN pentru Oracle +# NU folosi uvicorn direct — lipsesc LD_LIBRARY_PATH si TNS_ADMIN # Tests -python api/test_app_basic.py # Test A - fara Oracle -python api/test_integration.py # Test C - cu Oracle +python api/test_app_basic.py # fara Oracle +python api/test_integration.py # cu Oracle ``` -## UI Development Workflow: Preview → Implement → Verify +## Reguli critice (nu le incalca) -**OBLIGATORIU**: Respecta ordinea exacta. NU treci la pasul urmator fara aprobare explicita. +### Flux import comenzi +1. Download GoMag API → JSON → parse → validate SKU-uri → import Oracle +2. Ordinea: **parteneri** (cauta/creeaza) → **adrese** → **comanda** → **factura cache** +3. SKU lookup: ARTICOLE_TERTI (mapped) are prioritate fata de NOM_ARTICOLE (direct) +4. Complex sets: un SKU → multiple CODMAT-uri cu `procent_pret` (trebuie sa fie sum=100%) +5. Comenzi anulate (GoMag statusId=7): verifica daca au factura inainte de stergere din Oracle -### 1. Plan & Preview — ASTEAPTA APROBARE -1. Citeste TOATE fisierele implicate -2. Scrie planul de implementare cu decizii de design -3. Genereaza **mockup-uri Markdown** care descriu rezultatul asteptat (tabele, liste, cod pseudo-CSS) — NU HTML static -4. **Prezinta mockup-urile userului si ASTEAPTA aprobare explicita** -5. Rafineaza planul daca userul cere modificari -6. **NU trece la implementare pana userul nu spune explicit "ok", "aprob", "executa" sau similar** +### Statusuri comenzi +`IMPORTED` / `ALREADY_IMPORTED` / `SKIPPED` / `ERROR` / `CANCELLED` / `DELETED_IN_ROA` +- Upsert: `IMPORTED` existent NU se suprascrie cu `ALREADY_IMPORTED` +- Recovery: la fiecare sync, comenzile ERROR sunt reverificate in Oracle -### 2. Implementation cu TeamCreate (Agent Teams) +### Parteneri +- Prioritate: **companie** (PJ, cod_fiscal + registru) daca exista in GoMag, altfel persoana fizica cu **shipping name** +- Adresa livrare: intotdeauna GoMag shipping +- Adresa facturare: daca shipping ≠ billing person → shipping pt ambele; altfel → billing din GoMag -Folosim **TeamCreate** (team agents), NU superpowers subagents. Diferenta: -- **TeamCreate**: agenti independenti cu task list partajat, comunicare directa intre ei, context propriu -- **Subagents (Agent tool)**: agenti care raporteaza doar la main — NU se folosesc +### Preturi +- Dual policy: articolele sunt rutate la `id_pol_vanzare` sau `id_pol_productie` pe baza contului contabil (341/345 = productie) +- Daca pretul lipseste, se insereaza automat pret=0 -#### Workflow TeamCreate: +### Invoice cache +- Coloanele `factura_*` pe `orders` (SQLite), populate lazy din Oracle (`vanzari WHERE sters=0`) +- Refresh complet: verifica facturi noi + facturi sterse + comenzi sterse din ROA -1. **Main agent** (team lead) citeste TOATE fisierele implicate, creeaza planul -2. **TeamCreate** creeaza echipa (ex: `ui-polish`) -3. **TaskCreate** creeaza task-uri independente, pe fisiere non-overlapping: - - Task 1: Templates + CSS (HTML templates, style.css, cache-bust) - - Task 2: JavaScript (shared.js, dashboard.js, logs.js, mappings.js) - - Task 3: Verificare Playwright (depinde de Task 1 + Task 2) -4. **Agent tool** cu `team_name` spawneaza teammates folosind agentii predefiniti din `.claude/agents/`: - - `subagent_type: ui-templates` → pentru Task 1 (templates + CSS) - - `subagent_type: ui-js` → pentru Task 2 (JavaScript) - - `subagent_type: ui-verify` → pentru Task 3 (Playwright verification) - - `subagent_type: backend-api` → pentru modificari backend/API (routers, services, Oracle/SQLite) - - `subagent_type: qa-tester` → pentru teste de integrare -5. Teammates lucreaza in paralel, comunica intre ei, marcheaza task-uri completate -6. Cand Task 1 + Task 2 sunt complete, teammate-ul de verificare preia Task 3 +## Deploy Windows -#### Teammate-ul de verificare (Task 3): -1. Navigheaza la fiecare pagina cu Playwright MCP la 375x812 (mobile) si 1440x900 (desktop) -2. **Foloseste browser_snapshot** (NU screenshot-uri) pentru a inspecta structura DOM -3. Verifica ca implementarea respecta fiecare punct din preview-ul aprobat (structura coloane, bold, dots, filtre etc.) -4. Raporteaza discrepante concrete la team lead (ce e diferit fata de preview) -5. NU salveaza screenshot-uri after/ - -#### Bucla de corectie (responsabilitatea team lead-ului): -1. Dupa ce verify-agent raporteaza, **team lead-ul analizeaza discrepantele** -2. Pentru fiecare discrepanta, creeaza un nou task de fix si spawneaza un agent sa-l rezolve -3. Dupa fix, spawneaza din nou verify-agent pentru re-verificare -4. **Repeta bucla** pana cand toate verificarile trec (implementare ≈ preview) -5. Abia atunci declara task-ul complet - -``` -screenshots/ -└── preview/ # Mockup-uri Markdown aprobate de user (referinta pentru verificare) -``` - -### Principii -- Team lead citeste TOATE fisierele inainte sa creeze task-uri -- Task-uri pe fisiere non-overlapping (evita conflicte) -- Fiecare task contine prompt detaliat, self-contained -- Desktop-ul nu trebuie sa se schimbe cand se adauga imbunatatiri mobile -- Cache-bust static assets (increment `?v=N`) la fiecare schimbare UI -- Teammates comunica intre ei cu SendMessage, nu doar cu team lead-ul - -## Architecture - -``` -[GoMag API] → [Python Sync Service] → [Oracle PL/SQL] → [FastAPI Admin] - ↓ ↓ ↑ ↑ - JSON Orders Download/Parse/Import Store/Update Dashboard + Config - ↓ - [SQLite — tracking DB] - orders, sync_runs, missing_skus, - order_items, web_products, - invoice cache, app_settings -``` - -### FastAPI App Structure -- **Routers:** health, dashboard, mappings, articles, validation, sync -- **Services:** gomag_client, sync, order_reader, import, mapping, article, validation, invoice, sqlite, scheduler -- **Templates:** Jinja2 (dashboard, mappings, missing_skus, logs) -- **Static:** CSS (`style.css`), JS (`shared.js`, `dashboard.js`, `logs.js`, `mappings.js`) -- **Databases:** Oracle (ERP data) + SQLite (order tracking, sync runs) - -## API Endpoints — Sync & Comenzi - -### Sync -| Method | Path | Descriere | -|--------|------|-----------| -| POST | `/api/sync/start` | Porneste sync in background | -| POST | `/api/sync/stop` | Trimite semnal de stop | -| GET | `/api/sync/status` | Status curent + last_run | -| GET | `/api/sync/history` | Istoric run-uri (paginat) | -| GET | `/api/sync/run/{run_id}` | Detalii run | -| GET | `/api/sync/run/{run_id}/log` | Log per comanda (JSON) | -| GET | `/api/sync/run/{run_id}/text-log` | Log text (live sau din SQLite) | -| GET | `/api/sync/run/{run_id}/orders` | Comenzi run filtrate/paginate | -| GET | `/api/sync/order/{order_number}` | Detaliu comanda + items + factura | - -### Dashboard Comenzi -| Method | Path | Descriere | -|--------|------|-----------| -| GET | `/api/dashboard/orders` | Comenzi cu date factura (cache SQLite → Oracle fallback) | -| POST | `/api/dashboard/refresh-invoices` | Force-refresh stare facturi + comenzi sterse din ROA | - -**Parametri `/api/dashboard/orders`:** -- `period_days`: 3/7/30/90 sau 0 (all / custom range) -- `period_start`, `period_end`: interval custom (cand `period_days=0`) -- `status`: `all` / `IMPORTED` / `SKIPPED` / `ERROR` / `UNINVOICED` / `INVOICED` -- `search`, `sort_by`, `sort_dir`, `page`, `per_page` - -**`POST /api/dashboard/refresh-invoices` face:** -1. Necacturate → verifica Oracle daca au primit factura -2. Cacturate → verifica Oracle daca factura a fost stearsa -3. Toate importate → verifica Oracle daca comanda a fost stearsa (→ `DELETED_IN_ROA`) - -### Scheduler -| Method | Path | Descriere | -|--------|------|-----------| -| PUT | `/api/sync/schedule` | Configureaza scheduler (enabled, interval_minutes) | -| GET | `/api/sync/schedule` | Status curent scheduler | - -### Settings -| Method | Path | Descriere | -|--------|------|-----------| -| GET | `/api/settings` | Citeste setari aplicatie | -| PUT | `/api/settings` | Salveaza setari | -| GET | `/api/settings/sectii` | Lista sectii Oracle (dropdown) | -| GET | `/api/settings/politici` | Lista politici preturi Oracle (dropdown) | - -## Invoice Cache (SQLite) - -Facturile sunt cacate in coloana `factura_*` pe tabelul `orders`: -- `factura_serie`, `factura_numar`, `factura_data` -- `factura_total_fara_tva`, `factura_total_tva`, `factura_total_cu_tva` - -**Sursa Oracle:** `SELECT ... FROM vanzari WHERE id_comanda IN (...) AND sters=0` - -**Populare cache:** -- La fiecare cerere `/api/dashboard/orders` — comenzile fara cache sunt verificate live si cacate -- La deschidere detaliu comanda `/api/sync/order/{order_number}` — verifica live daca nu e caat -- La `POST /api/dashboard/refresh-invoices` — refresh complet pentru toate comenzile - -## Business Rules - -### Partners -- Search priority: cod_fiscal → denumire → create new -- Individuals (CUI 13 digits): separate nume/prenume -- Default address: Bucuresti Sectorul 1 -- All new partners: ID_UTIL = -3 - -### Articles & Mappings -- Simple SKUs: found directly in nom_articole (not stored in ARTICOLE_TERTI) -- Repackaging: SKU → CODMAT with different quantities -- Complex sets: One SKU → multiple CODMATs with percentage pricing (must sum to 100%) -- Inactive articles: activ=0 (soft delete) - -### Orders -- Default: ID_GESTIUNE=1, ID_SECTIE=1, ID_POL=0 -- Delivery date = order date + 1 day -- All orders: INTERNA=0 (external) -- **Statuses:** `IMPORTED` / `ALREADY_IMPORTED` / `SKIPPED` / `ERROR` / `DELETED_IN_ROA` -- Upsert rule: daca status=`IMPORTED` exista, nu se suprascrie cu `ALREADY_IMPORTED` - -## Configuration - -```bash -# .env -ORACLE_USER=CONTAFIN_ORACLE -ORACLE_PASSWORD=******** -ORACLE_DSN=ROA_ROMFAST -TNS_ADMIN=/app -``` - -## Deploy & Depanare Windows - -Vezi [README.md](README.md#deploy-windows) pentru instructiuni complete de deploy si depanare pe Windows Server. +Vezi [README.md](README.md#deploy-windows) diff --git a/README.md b/README.md index 75b7814..5030fe3 100644 --- a/README.md +++ b/README.md @@ -101,11 +101,11 @@ gomag-vending/ │ │ ├── database.py # Oracle pool + SQLite schema + migrari │ │ ├── routers/ # Endpoint-uri HTTP │ │ │ ├── health.py # GET /health -│ │ │ ├── dashboard.py # GET / (HTML) +│ │ │ ├── dashboard.py # GET / (HTML) + /settings (HTML) │ │ │ ├── mappings.py # /mappings, /api/mappings │ │ │ ├── articles.py # /api/articles/search │ │ │ ├── validation.py # /api/validate/* -│ │ │ └── sync.py # /api/sync/* + /api/dashboard/orders +│ │ │ └── sync.py # /api/sync/* + /api/dashboard/* + /api/settings │ │ ├── services/ │ │ │ ├── gomag_client.py # Download comenzi GoMag API │ │ │ ├── sync_service.py # Orchestrare: download→validate→import @@ -117,8 +117,8 @@ gomag-vending/ │ │ │ ├── article_service.py │ │ │ ├── invoice_service.py # Verificare facturi ROA │ │ │ └── scheduler_service.py # APScheduler timer -│ │ ├── templates/ # Jinja2 HTML -│ │ └── static/ # CSS + JS +│ │ ├── templates/ # Jinja2 (dashboard, mappings, missing_skus, logs, settings) +│ │ └── static/ # CSS (style.css) + JS (dashboard, logs, mappings, settings, shared) │ ├── database-scripts/ # Oracle SQL (ARTICOLE_TERTI, packages) │ ├── data/ # SQLite DB (import.db) + JSON orders │ ├── .env # Configurare locala (nu in git) @@ -165,12 +165,16 @@ gomag-vending/ ## Fluxul de Import ``` -1. gomag_client.py descarca comenzi GoMag API → JSON files -2. order_reader.py parseaza JSON-urile -3. validation_service.py valideaza SKU-uri contra ARTICOLE_TERTI + NOM_ARTICOLE -4. import_service.py 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) +1. gomag_client.py descarca comenzi GoMag API → JSON files (paginat) +2. order_reader.py parseaza JSON-urile, sorteaza cronologic (cele mai vechi primele) +3. Comenzi anulate (GoMag statusId=7) → separate, sterse din Oracle daca nu au factura +4. validation_service.py valideaza SKU-uri: ARTICOLE_TERTI (mapped) → NOM_ARTICOLE (direct) → missing +5. Verificare existenta in Oracle (COMENZI by date range) → deja importate se sar +6. Stale error recovery: comenzi ERROR reverificate in Oracle (crash recovery) +7. Validare preturi + dual policy: articole rutate la id_pol_vanzare sau id_pol_productie +8. import_service.py: cauta/creeaza partener → adrese → importa comanda in Oracle +9. Invoice cache: verifica facturi + comenzi sterse din ROA +10. Rezultate salvate in SQLite (orders, sync_run_orders, order_items) ``` ### Statuses Comenzi @@ -180,17 +184,30 @@ gomag-vending/ | `IMPORTED` | Importata nou in ROA in acest run | | `ALREADY_IMPORTED` | Existenta deja in Oracle, contorizata | | `SKIPPED` | SKU-uri lipsa → neimportata | -| `ERROR` | Eroare la import | +| `ERROR` | Eroare la import (reverificate automat la urmatorul sync) | +| `CANCELLED` | Comanda anulata in GoMag (statusId=7) | | `DELETED_IN_ROA` | A fost importata dar comanda a fost stearsa din ROA | **Regula upsert:** daca statusul existent este `IMPORTED`, nu se suprascrie cu `ALREADY_IMPORTED`. ### 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 + +**Parteneri & Adrese:** +- Prioritate partener: daca exista **companie** in GoMag (billing.company_name) → firma (PJ, cod_fiscal + registru). Altfel → persoana fizica, cu **shipping name** ca nume partener +- Adresa livrare: intotdeauna din GoMag shipping +- Adresa facturare: daca shipping name ≠ billing name → adresa shipping pt ambele; daca aceeasi persoana → adresa billing din GoMag +- Cautare partener in Oracle: cod_fiscal → denumire → create new (ID_UTIL = -3) + +**Articole & Mapari:** +- SKU lookup: ARTICOLE_TERTI (mapped, activ=1) are prioritate fata de NOM_ARTICOLE (direct) +- SKU simplu: gasit direct in NOM_ARTICOLE → nu se stocheaza in ARTICOLE_TERTI +- SKU cu repackaging: un SKU → CODMAT cu cantitate diferita (`cantitate_roa`) +- SKU set complex: un SKU → multiple CODMAT-uri cu `procent_pret` (trebuie sum = 100%) + +**Preturi & Discounturi:** +- Dual policy: articolele sunt rutate la `id_pol_vanzare` sau `id_pol_productie` pe baza contului contabil (341/345 = productie) +- Daca pretul lipseste in politica, se insereaza automat pret=0 +- Discount VAT splitting: daca `split_discount_vat=1`, discountul se repartizeaza proportional pe cotele TVA din comanda --- @@ -271,18 +288,7 @@ Configuratia este persistata in SQLite (`scheduler_config`). | GET | `/api/settings/sectii` | Lista sectii Oracle | | GET | `/api/settings/politici` | Lista politici preturi Oracle | -**Setari disponibile:** `transport_codmat`, `transport_vat`, `discount_codmat`, `discount_vat`, `transport_id_pol`, `discount_id_pol`, `id_pol`, `id_sectie`, `gomag_api_key`, `gomag_api_shop`, `gomag_order_days_back`, `gomag_limit` - ---- - -## Status Implementare - -| Faza | Status | Descriere | -|------|--------|-----------| -| Phase 1: Database Foundation | Complet | ARTICOLE_TERTI, PACK_IMPORT_PARTENERI, PACK_IMPORT_COMENZI | -| Phase 2: Python Integration | Complet | gomag_client.py, sync_service.py | -| Phase 3-4: FastAPI Dashboard | Complet | UI responsive, smart polling, filter bar, paginare | -| Phase 5: Production | In Progress | Logging done, Auth + SMTP pending | +**Setari disponibile:** `transport_codmat`, `transport_vat`, `discount_codmat`, `discount_vat`, `transport_id_pol`, `discount_id_pol`, `id_pol`, `id_pol_productie`, `id_sectie`, `split_discount_vat`, `gomag_api_key`, `gomag_api_shop`, `gomag_order_days_back`, `gomag_limit` ---