166 lines
6.3 KiB
Python
Executable File
166 lines
6.3 KiB
Python
Executable File
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from app.db.session import get_db
|
|
from app.services.asset_service import AssetService
|
|
from app.api import deps
|
|
from app.models.vehicle import BodyTypeDictionary
|
|
from typing import List, Optional
|
|
|
|
router = APIRouter()
|
|
|
|
# Secured endpoint: Closed premium ecosystem
|
|
@router.get("/makes", response_model=List[str])
|
|
async def list_makes(
|
|
vehicle_class: Optional[str] = None,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""1. Szint: Márkák listázása, opcionálisan vehicle_class szerint szűrve."""
|
|
return await AssetService.get_makes(db, vehicle_class)
|
|
|
|
# Secured endpoint: Closed premium ecosystem
|
|
@router.get("/models", response_model=List[str])
|
|
async def list_models(
|
|
make: str,
|
|
vehicle_class: str = None,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""2. Szint: Típusok listázása egy adott márkához, opcionálisan vehicle_class szerint szűrve."""
|
|
# Handle empty or invalid parameters gracefully
|
|
if not make or make.strip() == "":
|
|
return []
|
|
|
|
models = await AssetService.get_models(db, make, vehicle_class)
|
|
# Return empty list instead of 404 - frontend can handle empty dropdown
|
|
return models or []
|
|
|
|
# Secured endpoint: Closed premium ecosystem
|
|
@router.get("/generations", response_model=List[str])
|
|
async def list_generations(
|
|
make: str,
|
|
model: str,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""3. Szint: Generációk/Évjáratok listázása."""
|
|
# Handle empty or invalid parameters gracefully
|
|
if not make or not model or make.strip() == "" or model.strip() == "":
|
|
return []
|
|
|
|
generations = await AssetService.get_generations(db, make, model)
|
|
# Return empty list instead of 404 - frontend can handle empty dropdown
|
|
return generations or []
|
|
|
|
# Secured endpoint: Closed premium ecosystem
|
|
@router.get("/engines")
|
|
async def list_engines(
|
|
make: str,
|
|
model: str,
|
|
gen: str,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""4. Szint: Motorváltozatok és technikai specifikációk."""
|
|
engines = await AssetService.get_engines(db, make, model, gen)
|
|
if not engines:
|
|
raise HTTPException(status_code=404, detail="Nincs motorváltozat adat.")
|
|
|
|
# Itt visszaküldjük a teljes katalógus objektumokat (ID, motorváltozat, specifikációk)
|
|
return [
|
|
{
|
|
"id": e.id,
|
|
"variant": e.engine_variant,
|
|
"engine_code": e.engine_code,
|
|
"fuel_type": e.fuel_type,
|
|
"factory_data": e.factory_data
|
|
} for e in engines
|
|
]
|
|
|
|
|
|
# Secured endpoint: Closed premium ecosystem
|
|
@router.get("/body-types")
|
|
async def list_body_types(
|
|
vehicle_class: Optional[str] = Query(None, description="Szűrés járműosztályra (pl. personal, motorcycle, light_commercial)"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""Karosszéria-típus szótár lekérése. Opcionálisan szűrhető vehicle_class alapján."""
|
|
stmt = select(BodyTypeDictionary).order_by(BodyTypeDictionary.name_i18n)
|
|
if vehicle_class:
|
|
stmt = stmt.where(BodyTypeDictionary.vehicle_class == vehicle_class)
|
|
result = await db.execute(stmt)
|
|
rows = result.scalars().all()
|
|
return [
|
|
{
|
|
"id": r.id,
|
|
"vehicle_class": r.vehicle_class,
|
|
"code": r.code,
|
|
"name_i18n": r.name_i18n if r.name_i18n else {},
|
|
}
|
|
for r in rows
|
|
]
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# NEW: Cascading Catalog Endpoints for Vehicle Wizard (Drill-down UI)
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
@router.get("/brands", response_model=List[str])
|
|
async def list_catalog_brands(
|
|
vehicle_class: Optional[str] = Query(None, description="Szűrés járműosztályra (pl. personal, motorcycle)"),
|
|
q: Optional[str] = Query(None, description="Keresési szöveg (autocomplete)"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""Márkák listája a vehicle_model_definitions táblából, autocomplete-hez.
|
|
GET /catalog/brands?class=personal&q=bmw
|
|
"""
|
|
return await AssetService.get_catalog_brands(db, vehicle_class, q)
|
|
|
|
|
|
@router.get("/brands/{brand}/models")
|
|
async def list_catalog_models(
|
|
brand: str,
|
|
vehicle_class: Optional[str] = Query(None, description="Szűrés járműosztályra"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""Adott márkához tartozó modellek listája.
|
|
GET /catalog/brands/BMW/models
|
|
"""
|
|
if not brand or brand.strip() == "":
|
|
return []
|
|
return await AssetService.get_catalog_models(db, brand, vehicle_class)
|
|
|
|
|
|
@router.get("/brands/{brand}/models/{model}/years")
|
|
async def list_catalog_years(
|
|
brand: str,
|
|
model: str,
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""Adott márkához és modellhez tartozó elérhető évjáratok.
|
|
GET /catalog/brands/BMW/models/X5/years
|
|
"""
|
|
if not brand or not model or brand.strip() == "" or model.strip() == "":
|
|
return []
|
|
return await AssetService.get_catalog_years(db, brand, model)
|
|
|
|
|
|
@router.get("/brands/{brand}/models/{model}/trims")
|
|
async def list_catalog_trims(
|
|
brand: str,
|
|
model: str,
|
|
year: Optional[int] = Query(None, description="Szűrés évjáratra"),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user = Depends(deps.get_current_user)
|
|
):
|
|
"""Adott márkához, modellhez és opcionális évjárathoz tartozó felszereltségek/motorváltozatok.
|
|
GET /catalog/brands/BMW/models/X5/trims?year=2023
|
|
"""
|
|
if not brand or not model or brand.strip() == "" or model.strip() == "":
|
|
return []
|
|
return await AssetService.get_catalog_trims(db, brand, model, year) |