"""Global devices endpoint — cross-object device listing with filters.""" from typing import Optional from fastapi import APIRouter, Depends, Query from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload from app.dependencies import get_current_user, get_db from app.models.device import Device from app.models.object import Object from app.models.user import User from app.schemas.device import DeviceRead router = APIRouter(prefix="/api/v1/devices", tags=["devices-global"]) @router.get("", response_model=list[DeviceRead]) async def list_all_devices( category: Optional[list[str]] = Query(default=None), city: Optional[str] = None, client: Optional[str] = None, object_id: Optional[int] = None, status: Optional[str] = None, is_active: Optional[bool] = None, db: AsyncSession = Depends(get_db), _: User = Depends(get_current_user), ): """List devices across all objects with optional filters. Typical use cases: - All main_server devices: ?category=main_server - All bank terminals for a client: ?category=bank_terminal&client=Авангард - All devices in a city: ?city=Санкт-Петербург """ query = ( select(Device) .join(Object, Device.object_id == Object.id) .options(selectinload(Device.rack)) .order_by(Object.city, Object.name, Device.category, Device.ip) ) if category: query = query.where(Device.category.in_(category)) if city is not None: query = query.where(Object.city == city) if client is not None: query = query.where(Object.client == client) if object_id is not None: query = query.where(Device.object_id == object_id) if status is not None: query = query.where(Device.status == status) if is_active is not None: query = query.where(Device.is_active == is_active) result = await db.execute(query) return result.scalars().all()