FEAT: Corporate onboarding implemented with Tax ID validation (HU) and isolated NAS storage
This commit is contained in:
104
backend/app/api/v1/endpoints/assets.py
Normal file
104
backend/app/api/v1/endpoints/assets.py
Normal file
@@ -0,0 +1,104 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from app.db.session import get_db
|
||||
from app.schemas.asset import AssetCreate, AssetResponse
|
||||
from app.models.vehicle import Asset, VehicleCatalog
|
||||
from app.models.organization import Organization
|
||||
from app.core.validators import VINValidator
|
||||
from app.core.config import settings
|
||||
import os
|
||||
import logging
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@router.post("/", response_model=AssetResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def create_asset(
|
||||
asset_in: AssetCreate,
|
||||
db: AsyncSession = Depends(get_db)
|
||||
# Később ide jön: current_user: User = Depends(get_current_active_user)
|
||||
):
|
||||
"""
|
||||
Új jármű (Asset) rögzítése a flottába.
|
||||
- Validálja a VIN-t (MOD 11 checksum).
|
||||
- Ellenőrzi a Katalógus elemet.
|
||||
- Létrehozza a NAS mappát a dokumentumoknak.
|
||||
"""
|
||||
|
||||
# 1. VIN Validáció (Szigorú Checksum)
|
||||
# A GEM protokoll szerint kötelező a validátor használata
|
||||
is_valid_vin = VINValidator.validate(asset_in.vin)
|
||||
if not is_valid_vin:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Érvénytelen alvázszám (VIN)! A Checksum ellenőrzés sikertelen."
|
||||
)
|
||||
|
||||
# 2. Katalógus elem ellenőrzése
|
||||
stmt_catalog = select(VehicleCatalog).where(VehicleCatalog.id == asset_in.catalog_id)
|
||||
result_catalog = await db.execute(stmt_catalog)
|
||||
catalog_item = result_catalog.scalar_one_or_none()
|
||||
|
||||
if not catalog_item:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="A kiválasztott járműtípus nem található a katalógusban."
|
||||
)
|
||||
|
||||
# 3. Szervezet ellenőrzése (Létezik-e, és van-e joga - jogultságkezelés később)
|
||||
stmt_org = select(Organization).where(Organization.id == asset_in.organization_id)
|
||||
result_org = await db.execute(stmt_org)
|
||||
org_item = result_org.scalar_one_or_none()
|
||||
|
||||
if not org_item:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="A megadott flotta/szervezet nem található."
|
||||
)
|
||||
|
||||
# 4. Asset Duplikáció ellenőrzése (Ugyanaz a VIN nem szerepelhet 2x aktívként)
|
||||
# Megj: A UAI mező tárolja a VIN-t (Unique Asset Identifier)
|
||||
stmt_exist = select(Asset).where(
|
||||
Asset.uai == asset_in.vin.upper(),
|
||||
Asset.status != "deleted"
|
||||
)
|
||||
result_exist = await db.execute(stmt_exist)
|
||||
if result_exist.scalar_one_or_none():
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Ez a jármű (VIN) már szerepel a rendszerben!"
|
||||
)
|
||||
|
||||
# 5. Mentés az adatbázisba
|
||||
new_asset = Asset(
|
||||
uai=asset_in.vin.upper(), # A VIN a fő azonosító
|
||||
catalog_id=asset_in.catalog_id,
|
||||
organization_id=asset_in.organization_id,
|
||||
asset_type=catalog_item.category, # 'car', 'van', 'motorcycle', etc.
|
||||
name=asset_in.name or f"{catalog_item.brand} {catalog_item.model}",
|
||||
current_plate_number=asset_in.license_plate.upper(),
|
||||
status="active",
|
||||
privacy_level="private" # Alapértelmezett
|
||||
)
|
||||
|
||||
db.add(new_asset)
|
||||
await db.commit()
|
||||
await db.refresh(new_asset)
|
||||
|
||||
# 6. NAS Tároló Létrehozása
|
||||
# Útvonal: /mnt/nas/app_data/assets/{uuid}/
|
||||
# A settings.NAS_STORAGE_PATH-ot használjuk (GEM protokoll)
|
||||
try:
|
||||
# Ha a settings-ben nincs definiálva, fallback a hardcoded path-ra (biztonsági háló)
|
||||
base_path = getattr(settings, "NAS_STORAGE_PATH", "/mnt/nas/app_data/assets")
|
||||
asset_path = os.path.join(base_path, str(new_asset.id))
|
||||
|
||||
os.makedirs(asset_path, exist_ok=True)
|
||||
logger.info(f"NAS mappa létrehozva: {asset_path}")
|
||||
|
||||
except OSError as e:
|
||||
logger.error(f"CRITICAL: Nem sikerült létrehozni a NAS mappát: {e}")
|
||||
# Nem dobunk hibát a usernek, mert az adatbázisba bekerült, de riasztunk logban
|
||||
|
||||
return new_asset
|
||||
Reference in New Issue
Block a user