Commit Graph

23 Commits

Author SHA1 Message Date
Claude Agent
a0649279cf log 2026-03-16 15:51:15 +00:00
Claude Agent
db29822a5b fix(js): add ROOT_PATH to window.location navigations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:25:43 +00:00
Claude Agent
49471e9f34 fix(js): patch fetch to prepend ROOT_PATH for IIS reverse proxy
All relative /api/... calls automatically get /gomag prefix via
global fetch wrapper in shared.js. ROOT_PATH injected from template.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:19:50 +00:00
Claude Agent
ced6c0a2d4 fix(templates): use root_path for static assets instead of url_for
url_for generates absolute URLs with internal host (localhost:5003)
which browsers block via ERR_BLOCKED_BY_ORB. Using root_path prefix
generates correct relative paths (/gomag/static/...).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:15:56 +00:00
Claude Agent
a9d0cead79 chore: commit all pending changes including deploy scripts and Windows config
- deploy.ps1, iis-web.config: Windows Server deployment scripts
- api/app/routers/sync.py, dashboard.py: router updates
- api/app/services/import_service.py, sync_service.py: service updates
- api/app/static/css/style.css, js/*.js: UI updates
- api/database-scripts/08_PACK_FACTURARE.pck: Oracle package
- .gitignore: add .gittoken
- CLAUDE.md, agent configs: documentation updates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:05:04 +00:00
Claude Agent
ee60a17f00 fix(templates): use url_for for static assets and root_path for nav links
Fixes 404 errors for CSS/JS when served behind IIS reverse proxy with
/gomag prefix. Replaces hardcoded /static/ paths with request.url_for()
and nav links with request.scope root_path prefix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-16 15:04:03 +00:00
Claude Agent
926543a2e4 fix(mappings): resolve 409 error on multi-CODMAT edit and make SKU editable
Batch create after soft-delete was rejected because create_mapping()
treated soft-deleted records as conflicts. Added auto_restore param
that restores+updates instead of 409 when called from edit flow.
Also removed readOnly on SKU input in edit modal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 13:31:03 +00:00
Claude Agent
25aa9e544c feat(sync): add delivery cost, discount tracking and import settings
Parse delivery.total and discounts[] from GoMag JSON into new
delivery_cost/discount_total fields. Add app_settings table for
configuring transport/discount CODMAT codes. When configured,
transport and discount are appended as extra articles in the
Oracle import JSON. Reorder Total column in dashboard/logs tables
and show transport/discount breakdown in order detail modals.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:15:17 +00:00
Claude Agent
137c4a8b0b feat(ui): order totals, decimals, mobile modal cards, set editing
- Dashboard/Logs: Total column with 2 decimals (order_total)
- Order detail modal: totals summary row (items total + order total)
- Order detail modal mobile: compact article cards (d-md-none)
- Mappings: openEditModal loads all CODMATs for SKU, saveMapping
  replaces entire set via delete-all + batch POST
- Add project-specific team agents: ui-templates, ui-js, ui-verify,
  backend-api
- CLAUDE.md: mandatory preview approval before implementation,
  fix-loop after verification, server must start via start.sh

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-15 21:55:58 +00:00
Claude Agent
c4fa643eca feat(sync): add order_total field to SQLite tracking
Parse order total from GoMag JSON, store in SQLite orders table,
and expose via sync run API. Enables total display in mobile flat rows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:20:57 +00:00
Claude Agent
680f670037 feat(ui): mobile UI polish with segmented controls and responsive navbar
- Replace filter pills with btn-group segmented controls on mobile (all pages)
- Add renderMobileSegmented() shared utility with colored count badges
- Compact sync card and logs run selector on mobile
- Unified flat-row format: dot + date + name + count (0.875rem throughout)
- Responsive navbar with short labels on mobile (Acasa/Mapari/Lipsa/Jurnale)
- Vertical dots icon (bi-three-dots-vertical) without dropdown caret
- Shorter "Mapare" button text on mobile, Re-scan in context menu
- Top pagination on logs page, hide per-page selector on mobile
- Cache-bust static assets to v=5

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 21:20:24 +00:00
Claude Agent
5a0ea462e5 fix(validation): remove non-existent find_new_orders call
Replace broken asyncio.to_thread call with len(importable)
which already represents orders ready to process.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:59:05 +00:00
Claude Agent
452dc9b9f0 feat(mappings): strict validation + silent CSV skip for missing CODMAT
Add Pydantic validators and service-level checks that reject empty SKU/CODMAT
on create/edit (400). CSV import now silently skips rows without CODMAT and
counts them in skipped_no_codmat instead of treating them as errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:46:59 +00:00
Claude Agent
9cacc19d15 fix(ui): fix set pct badge logic and compact CODMAT form layout
- Fix is_complete check: use abs(pct-100)<=0.01 instead of >=99.99
  so sets with >100% total are correctly shown as incomplete
- Show pct badge with 2 decimals (e.g. "⚠️ 200.00%")
- Remove product name pre-fill in missing SKUs map modal CODMAT field
- Compact CODMAT lines to single row with placeholders instead of labels

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:21:49 +00:00
Claude Agent
15ccbe028a fix(dashboard): fix pill counts and Bootstrap UI cleanup
- IMPORTED pill now includes ALREADY_IMPORTED orders in count
- UNINVOICED filter includes ALREADY_IMPORTED orders
- Pill counts (Toate/Importate/Omise/Erori/Nefacturate) always reflect
  full period+search, independent of active status filter
- Nefacturate count computed from SQLite cache across full period,
  not just current page
- Bootstrap UI: design tokens, soft badge pills, consistent font sizes,
  purge inline styles from templates, move badge-pct to style.css

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 21:05:43 +00:00
Claude Agent
b69b5e7104 feat(sync): add GoMag API client with Phase 0 auto-download
- New gomag_client.py service: async httpx client that downloads orders
  from GoMag API with full pagination and 1s rate-limit sleep
- config.py: add GOMAG_API_KEY, GOMAG_API_SHOP, GOMAG_ORDER_DAYS_BACK,
  GOMAG_LIMIT, GOMAG_API_URL settings
- sync_service.py: Phase 0 downloads fresh orders before reading JSONs;
  graceful skip if API keys not configured
- start.sh: auto-detect INSTANTCLIENTPATH from .env, fallback to thin mode
- .env.example: document GoMag API variables

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 23:03:39 +00:00
2e65855fe2 feat(sync): already_imported tracking, invoice cache, path fixes, remove vfp
- Track already_imported/new_imported counts separately in sync_runs
  and surface them in status API + dashboard last-run card
- Cache invoice data in SQLite orders table (factura_* columns);
  dashboard falls back to Oracle only for uncached imported orders
- Resolve JSON_OUTPUT_DIR and SQLITE_DB_PATH relative to known
  anchored roots in config.py, independent of CWD (fixes WSL2 start)
- Use single Oracle connection for entire validation phase (perf)
- Batch upsert web_products instead of one-by-one
- Remove stale VFP scripts (replaced by gomag-vending.prg workflow)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 00:15:37 +02:00
8681a92eec fix(logs): use status_at_run for per-run order counts and filtering
orders.status preserves IMPORTED over ALREADY_IMPORTED to avoid
overwriting historical data, so per-run journal views must use
sync_run_orders.status_at_run to show what actually happened in
that specific run.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-14 00:12:10 +02:00
5f8b9b6003 feat(dashboard): redesign UI with smart polling, unified sync card, filter bar
Replace SSE with smart polling (30s idle / 3s when running). Unify sync
panel into single two-row card with live progress text. Add unified filter
bar (period dropdown, status pills, search) with period-total counts.
Add Client/Cont tooltip for different shipping/billing persons. Add SKU
mappings pct_total badges + complete/incomplete filter + 409 duplicate
check. Add missing SKUs search + rescan progress UX. Migrate SQLite
orders schema (shipping_name, billing_name, payment_method,
delivery_method). Fix JSON_OUTPUT_DIR path for server running from
project root. Fix pagination controls showing top+bottom with per-page
selector (25/50/100/250).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 17:55:36 +02:00
82196b9dc0 feat(sqlite): refactor orders schema + dashboard period filter
Replace import_orders (insert-per-run) with orders table (one row per
order, upsert on conflict). Eliminates dedup CTE on every dashboard
query and prevents unbounded row growth at 4-500 orders/sync.

Key changes:
- orders table: PK order_number, upsert via ON CONFLICT DO UPDATE;
  COALESCE preserves id_comanda once set; times_skipped auto-increments
- sync_run_orders: lightweight junction (sync_run_id, order_number)
  replaces sync_run_id column on orders
- order_items: PK changed to (order_number, sku), INSERT OR IGNORE
- Auto-migration in init_sqlite(): import_orders → orders on first boot,
  old table renamed to import_orders_bak
- /api/dashboard/orders: period_days param (3/7/30/0=all, default 7)
- Dashboard: period selector buttons in orders card header
- start.sh: stop existing process on port 5003 before restart;
  remove --reload (broken on WSL2 /mnt/e/)
- Add invoice_service, E2E Playwright tests, Oracle package updates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-13 16:18:57 +02:00
650e98539e feat(sync): add SSE live feed, unified logs page, fix Oracle connection
- Add SSE event bus in sync_service (subscribe/unsubscribe/_emit)
- Add GET /api/sync/stream SSE endpoint for real-time sync progress
- Rewrite logs.html: unified runs table + live feed + summary + filters
- Rewrite logs.js: SSE EventSource client, run selection, pagination
- Dashboard: clickable runs navigate to /logs?run=, sync started banner
- Remove "Import Comenzi" nav item, delete sync_detail.html
- Add error_message column to sync_runs table with migration
- Fix: export TNS_ADMIN as OS env var so oracledb finds tnsnames.ora
- Fix: use get_oracle_connection() instead of direct pool.acquire()
- Fix: CRM_POLITICI_PRET_ART INSERT to match actual table schema

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 18:08:09 +02:00
97699fa0e5 feat(dashboard): add logs page, pagination, quick mapping modal, price pre-validation
- Add /logs page with per-order sync run details, filters (Toate/Importate/Fara Mapare/Erori)
- Add price pre-validation (validate_prices + ensure_prices) to prevent ORA-20000 on direct articles
- Add find_new_orders() to detect orders not yet in Oracle COMENZI
- Extend missing_skus table with order context (order_count, order_numbers, customers)
- Add server-side pagination on /api/validate/missing-skus and /missing-skus page
- Replace confusing "Skip"/"Err" with "Fara Mapare"/"Erori" terminology
- Add inline mapping modal on dashboard (replaces navigation to /mappings)
- Add 2-row stat cards: orders (Comenzi Noi/Ready/Importate/Fara Mapare/Erori) + articles
- Add ID_POL/ID_GESTIUNE/ID_SECTIE to config.py and .env
- Update .gitignore (venv, *.db, api/api/, logs/)
- 33/33 unit tests pass, E2E verified with Playwright

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:59:08 +02:00
9c42187f02 feat: add FastAPI admin dashboard with sync orchestration and test suite
Replace Flask admin with FastAPI app (api/app/) featuring:
- Dashboard with stat cards, sync control, and history
- Mappings CRUD for ARTICOLE_TERTI with CSV import/export
- Article autocomplete from NOM_ARTICOLE
- SKU pre-validation before import
- Sync orchestration: read JSONs -> validate -> import -> log to SQLite
- APScheduler for periodic sync from UI
- File logging to logs/sync_comenzi_YYYYMMDD_HHMMSS.log
- Oracle pool None guard (503 vs 500 on unavailable)

Test suite:
- test_app_basic.py: 30 tests (imports + routes) without Oracle
- test_integration.py: 9 integration tests with Oracle

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:35:16 +02:00