147 lines
5.4 KiB
Python
147 lines
5.4 KiB
Python
# /opt/docker/dev/service_finder/backend/app/services/system_service.py
|
|
"""
|
|
Hierarchikus System Parameters szolgáltatás.
|
|
A rendszerparaméterek prioritásos felülbírálást támogatnak: User > Region > Country > Global.
|
|
"""
|
|
|
|
import logging
|
|
from typing import Optional, Any, Dict
|
|
from sqlalchemy import select, func # HOZZÁADVA: func a NOW() híváshoz
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy.orm import selectinload
|
|
|
|
from app.models.system import SystemParameter, ParameterScope
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class SystemService:
|
|
"""
|
|
Rendszerparaméterek kezelése hierarchikus scope-okkal.
|
|
"""
|
|
|
|
async def get_scoped_parameter(
|
|
self,
|
|
db: AsyncSession,
|
|
key: str,
|
|
user_id: Optional[str] = None,
|
|
region_id: Optional[str] = None,
|
|
country_code: Optional[str] = None,
|
|
default: Any = None,
|
|
) -> Any:
|
|
"""
|
|
Lekéri a paraméter értékét a következő prioritási sorrendben:
|
|
1. USER scope (ha user_id megadva)
|
|
2. REGION scope (ha region_id megadva)
|
|
3. COUNTRY scope (ha country_code megadva)
|
|
4. GLOBAL scope
|
|
|
|
Ha egy scope-ban nem található a paraméter, a következő scope-ot próbálja.
|
|
Visszaadja a paraméter JSON értékét (általában dict), vagy a default értéket.
|
|
|
|
:param db: Adatbázis munkamenet
|
|
:param key: A paraméter kulcsa
|
|
:param user_id: Felhasználó azonosítója (opcionális)
|
|
:param region_id: Régió azonosítója (opcionális)
|
|
:param country_code: Országkód (pl. 'HU', 'GB') (opcionális)
|
|
:param default: Alapértelmezett érték, ha a paraméter nem található
|
|
:return: A paraméter értéke (általában dict) vagy default
|
|
"""
|
|
# Prioritási sorrend: USER -> REGION -> COUNTRY -> GLOBAL
|
|
scopes = []
|
|
if user_id:
|
|
scopes.append((ParameterScope.USER, str(user_id)))
|
|
if region_id:
|
|
scopes.append((ParameterScope.REGION, str(region_id)))
|
|
if country_code:
|
|
scopes.append((ParameterScope.COUNTRY, str(country_code)))
|
|
scopes.append((ParameterScope.GLOBAL, None))
|
|
|
|
for scope_level, scope_id in scopes:
|
|
stmt = select(SystemParameter).where(
|
|
SystemParameter.key == key,
|
|
SystemParameter.scope_level == scope_level,
|
|
SystemParameter.is_active == True,
|
|
)
|
|
if scope_id is not None:
|
|
stmt = stmt.where(SystemParameter.scope_id == scope_id)
|
|
else:
|
|
stmt = stmt.where(SystemParameter.scope_id.is_(None))
|
|
|
|
result = await db.execute(stmt)
|
|
param = result.scalar_one_or_none()
|
|
if param is not None:
|
|
logger.debug(
|
|
f"Paraméter '{key}' található {scope_level.value} scope-ban (scope_id={scope_id})"
|
|
)
|
|
return param.value
|
|
else:
|
|
logger.debug(
|
|
f"Paraméter '{key}' nem található {scope_level.value} scope-ban (scope_id={scope_id})"
|
|
)
|
|
|
|
logger.info(f"Paraméter '{key}' nem található egyetlen scope-ban sem, default értéket használunk")
|
|
return default
|
|
|
|
async def set_scoped_parameter(
|
|
self,
|
|
db: AsyncSession,
|
|
key: str,
|
|
value: Dict,
|
|
scope_level: ParameterScope,
|
|
scope_id: Optional[str] = None,
|
|
category: str = "general",
|
|
description: Optional[str] = None,
|
|
last_modified_by: Optional[int] = None,
|
|
) -> SystemParameter:
|
|
"""
|
|
Létrehoz vagy frissít egy rendszerparamétert a megadott scope-ban.
|
|
Ha már létezik ugyanazzal a kulccsal, scope_level-lel és scope_id-vel, felülírja.
|
|
"""
|
|
from sqlalchemy.dialects.postgresql import insert
|
|
|
|
# UPSERT logika: ON CONFLICT DO UPDATE
|
|
insert_stmt = insert(SystemParameter).values(
|
|
key=key,
|
|
value=value,
|
|
scope_level=scope_level,
|
|
scope_id=scope_id,
|
|
category=category,
|
|
description=description,
|
|
last_modified_by=last_modified_by,
|
|
is_active=True,
|
|
)
|
|
upsert_stmt = insert_stmt.on_conflict_do_update(
|
|
constraint="uix_param_scope",
|
|
set_=dict(
|
|
value=value,
|
|
category=category,
|
|
description=description,
|
|
last_modified_by=last_modified_by,
|
|
updated_at=func.now(),
|
|
),
|
|
)
|
|
await db.execute(upsert_stmt)
|
|
await db.commit()
|
|
|
|
# Visszaolvassuk a létrehozott/frissített rekordot
|
|
stmt = select(SystemParameter).where(
|
|
SystemParameter.key == key,
|
|
SystemParameter.scope_level == scope_level,
|
|
SystemParameter.scope_id == scope_id,
|
|
)
|
|
result = await db.execute(stmt)
|
|
param = result.scalar_one()
|
|
return param
|
|
|
|
# --- GLOBÁLIS PÉLDÁNY ÉS SEGÉDFÜGGVÉNYEK ---
|
|
# Ezek a fájl legszélén vannak (0-s behúzás), így kívülről importálhatóak!
|
|
|
|
system_service = SystemService()
|
|
|
|
async def get_system_parameter(db: AsyncSession, key: str, default: Any = None) -> Any:
|
|
"""
|
|
Proxy függvény, amit a marketplace_service és más modulok közvetlenül importálnak.
|
|
A globális system_service példányt használja.
|
|
"""
|
|
return await system_service.get_scoped_parameter(db, key, default=default) |