refaktorálás javításai
This commit is contained in:
147
backend/app/services/system_service.py
Normal file
147
backend/app/services/system_service.py
Normal file
@@ -0,0 +1,147 @@
|
||||
# /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)
|
||||
Reference in New Issue
Block a user