Files
gomag-vending/api/app/services/article_service.py
Marius Mutu 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

28 lines
1021 B
Python

import logging
from fastapi import HTTPException
from .. import database
logger = logging.getLogger(__name__)
def search_articles(query: str, limit: int = 20):
"""Search articles in NOM_ARTICOLE by codmat or denumire."""
if database.pool is None:
raise HTTPException(status_code=503, detail="Oracle unavailable")
if not query or len(query) < 2:
return []
with database.pool.acquire() as conn:
with conn.cursor() as cur:
cur.execute("""
SELECT id_articol, codmat, denumire
FROM nom_articole
WHERE (UPPER(codmat) LIKE UPPER(:q) || '%'
OR UPPER(denumire) LIKE '%' || UPPER(:q) || '%')
AND ROWNUM <= :lim
ORDER BY CASE WHEN UPPER(codmat) LIKE UPPER(:q) || '%' THEN 0 ELSE 1 END, codmat
""", {"q": query, "lim": limit})
columns = [col[0].lower() for col in cur.description]
return [dict(zip(columns, row)) for row in cur.fetchall()]