from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.orm import Session from app.auth.dependencies import get_current_user, require_role from app.db.session import get_db from app.models import Asset, User from app.schemas.core import AssetCreate, AssetRead, AssetUpdate router = APIRouter(prefix="/assets", tags=["assets"]) def _asset_to_read(asset: Asset) -> AssetRead: return AssetRead( id=asset.id, name=asset.name, asset_type=asset.asset_type, address=asset.address, status=asset.status, metadata=asset.extra, created_at=asset.created_at, updated_at=asset.updated_at, ) @router.get("", response_model=list[AssetRead]) def list_assets(_: User = Depends(get_current_user), db: Session = Depends(get_db)) -> list[AssetRead]: assets = db.scalars(select(Asset).order_by(Asset.name)).all() return [_asset_to_read(asset) for asset in assets] @router.post("", response_model=AssetRead) def create_asset( payload: AssetCreate, _: User = Depends(require_role("admin")), db: Session = Depends(get_db), ) -> AssetRead: asset = Asset( name=payload.name, asset_type=payload.asset_type, address=payload.address, extra=payload.metadata, ) db.add(asset) db.commit() db.refresh(asset) return _asset_to_read(asset) @router.get("/{asset_id}", response_model=AssetRead) def get_asset(asset_id: int, _: User = Depends(get_current_user), db: Session = Depends(get_db)) -> AssetRead: asset = db.get(Asset, asset_id) if asset is None: raise HTTPException(status_code=404, detail="Asset not found") return _asset_to_read(asset) @router.patch("/{asset_id}", response_model=AssetRead) def update_asset( asset_id: int, payload: AssetUpdate, _: User = Depends(require_role("admin")), db: Session = Depends(get_db), ) -> AssetRead: asset = db.get(Asset, asset_id) if asset is None: raise HTTPException(status_code=404, detail="Asset not found") changes = payload.model_dump(exclude_unset=True) if "metadata" in changes: asset.extra = changes.pop("metadata") for field, value in changes.items(): setattr(asset, field, value) db.commit() db.refresh(asset) return _asset_to_read(asset) @router.delete("/{asset_id}", status_code=204) def delete_asset( asset_id: int, _: User = Depends(require_role("admin")), db: Session = Depends(get_db), ) -> None: asset = db.get(Asset, asset_id) if asset is None: raise HTTPException(status_code=404, detail="Asset not found") db.delete(asset) db.commit()