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>
This commit is contained in:
2026-03-14 00:15:37 +02:00
parent 8681a92eec
commit 2e65855fe2
24 changed files with 485 additions and 3458 deletions

View File

@@ -1,9 +1,12 @@
from pydantic_settings import BaseSettings
from pydantic import model_validator
from pathlib import Path
import os
# Resolve .env relative to this file (api/app/config.py → api/.env)
_env_path = Path(__file__).resolve().parent.parent / ".env"
# Anchored paths - independent of CWD
_api_root = Path(__file__).resolve().parent.parent # .../gomag/api/
_project_root = _api_root.parent # .../gomag/
_env_path = _api_root / ".env"
class Settings(BaseSettings):
# Oracle
@@ -15,12 +18,12 @@ class Settings(BaseSettings):
TNS_ADMIN: str = ""
# SQLite
SQLITE_DB_PATH: str = str(Path(__file__).parent.parent / "data" / "import.db")
SQLITE_DB_PATH: str = "data/import.db"
# App
APP_PORT: int = 5003
LOG_LEVEL: str = "INFO"
JSON_OUTPUT_DIR: str = ""
JSON_OUTPUT_DIR: str = "output"
# SMTP (optional)
SMTP_HOST: str = ""
@@ -38,6 +41,17 @@ class Settings(BaseSettings):
ID_GESTIUNE: int = 0
ID_SECTIE: int = 0
@model_validator(mode="after")
def resolve_paths(self):
"""Resolve relative paths against known roots, independent of CWD."""
# SQLITE_DB_PATH: relative to api/ root
if self.SQLITE_DB_PATH and not os.path.isabs(self.SQLITE_DB_PATH):
self.SQLITE_DB_PATH = str(_api_root / self.SQLITE_DB_PATH)
# JSON_OUTPUT_DIR: relative to project root
if self.JSON_OUTPUT_DIR and not os.path.isabs(self.JSON_OUTPUT_DIR):
self.JSON_OUTPUT_DIR = str(_project_root / self.JSON_OUTPUT_DIR)
return self
model_config = {"env_file": str(_env_path), "env_file_encoding": "utf-8", "extra": "ignore"}
settings = Settings()