# /opt/docker/dev/service_finder/backend/app/api/v1/endpoints/system_parameters.py import logging from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, update, and_ from typing import List, Optional, Dict, Any from app.api import deps from app.api.deps import get_db, get_current_user from app.schemas.system import ( SystemParameterResponse, SystemParameterUpdate, SystemParameterCreate, ) from app.models.system import SystemParameter, ParameterScope from app.models.identity.address import GeoPostalCode from app.models.identity import UserRole router = APIRouter() logger = logging.getLogger(__name__) @router.get("/", response_model=List[SystemParameterResponse]) async def list_system_parameters( db: AsyncSession = Depends(get_db), scope_level: Optional[ParameterScope] = Query(None, description="Scope szint (global, country, region, user)"), scope_id: Optional[str] = Query(None, description="Scope azonosító (pl. 'HU', 'budapest', user_id)"), is_active: Optional[bool] = Query(True, description="Csak aktív paraméterek"), ): """ Listázza az összes aktív (vagy opcionálisan inaktív) rendszerparamétert. Szűrhető scope_level és scope_id alapján. """ query = select(SystemParameter) if scope_level is not None: query = query.where(SystemParameter.scope_level == scope_level) if scope_id is not None: query = query.where(SystemParameter.scope_id == scope_id) if is_active is not None: query = query.where(SystemParameter.is_active == is_active) result = await db.execute(query) parameters = result.scalars().all() return parameters @router.get("/zip-lookup", response_model=Dict[str, Any]) async def zip_lookup( country_code: str = Query("HU", description="Országkód (pl. HU, AT, DE)"), zip_code: str = Query(..., min_length=1, description="Irányítószám"), db: AsyncSession = Depends(get_db), ): """ Belső irányítószám lekérdező végpont. A system.geo_postal_codes táblában keres a megadott country_code és zip_code párosra. Ha megtalálja, visszaadja a várost: {"city": "Budapest"}. Ha nem találja, 404-es hibát dob. """ if not zip_code.strip(): raise HTTPException(status_code=400, detail="zip_code is required") stmt = select(GeoPostalCode).where( and_( GeoPostalCode.country_code == country_code, GeoPostalCode.zip_code == zip_code.strip(), ) ).limit(1) result = await db.execute(stmt) postal_code = result.scalar_one_or_none() if not postal_code: raise HTTPException( status_code=404, detail=f"No city found for country_code='{country_code}' and zip_code='{zip_code}'" ) return {"city": postal_code.city} @router.get("/{key}", response_model=SystemParameterResponse) async def get_system_parameter( key: str, db: AsyncSession = Depends(get_db), scope_level: ParameterScope = Query("global", description="Scope szint (alapértelmezett: global)"), scope_id: Optional[str] = Query(None, description="Scope azonosító"), ): """ Visszaad egy konkrét paramétert a key és scope_level (és opcionálisan scope_id) alapján. """ query = select(SystemParameter).where( SystemParameter.key == key, SystemParameter.scope_level == scope_level, ) if scope_id is not None: query = query.where(SystemParameter.scope_id == scope_id) else: query = query.where(SystemParameter.scope_id.is_(None)) result = await db.execute(query) parameter = result.scalar_one_or_none() if not parameter: raise HTTPException( status_code=404, detail=f"System parameter not found with key='{key}', scope_level='{scope_level}', scope_id='{scope_id}'" ) return parameter @router.put("/{key}", response_model=SystemParameterResponse) async def update_system_parameter( key: str, param_in: SystemParameterUpdate, db: AsyncSession = Depends(get_db), current_user=Depends(get_current_user), _ = Depends(deps.RequirePermission("system:manage")), scope_level: ParameterScope = Query("global", description="Scope szint (alapértelmezett: global)"), scope_id: Optional[str] = Query(None, description="Scope azonosító"), ): """ Módosítja egy létező paraméter value (JSONB) vagy is_active mezőjét (Admin funkció). Protected by RequirePermission("system:manage"). """ # Paraméter keresése query = select(SystemParameter).where( SystemParameter.key == key, SystemParameter.scope_level == scope_level, ) if scope_id is not None: query = query.where(SystemParameter.scope_id == scope_id) else: query = query.where(SystemParameter.scope_id.is_(None)) result = await db.execute(query) parameter = result.scalar_one_or_none() if not parameter: raise HTTPException( status_code=404, detail=f"System parameter not found with key='{key}', scope_level='{scope_level}', scope_id='{scope_id}'" ) # Frissítés update_data = {} if param_in.description is not None: update_data["description"] = param_in.description if param_in.value is not None: update_data["value"] = param_in.value if param_in.is_active is not None: update_data["is_active"] = param_in.is_active if update_data: stmt = ( update(SystemParameter) .where(SystemParameter.id == parameter.id) .values(**update_data) ) await db.execute(stmt) await db.commit() await db.refresh(parameter)