from fastapi import APIRouter, Depends, HTTPException, Query, status from app.api.dependencies.auth import get_access_token from app.api.dependencies.permissions import require_permission from app.application.admin.releases import ReleaseService from app.schemas.auth import AuthenticatedUser from app.schemas.admin import BuildReleaseRequest, ReleaseLifecycleResponse, ReleaseListResponse, ReleaseRead router = APIRouter() service = ReleaseService() @router.get("", response_model=ReleaseListResponse) async def list_releases( experiment_id: str | None = Query(default=None), access_token: str = Depends(get_access_token), _: AuthenticatedUser = Depends(require_permission("can_manage_releases")), ) -> ReleaseListResponse: items = await service.list_releases(experiment_id=experiment_id, access_token=access_token) return ReleaseListResponse(items=items) @router.get("/{release_id}", response_model=ReleaseRead) async def get_release( release_id: str, access_token: str = Depends(get_access_token), _: AuthenticatedUser = Depends(require_permission("can_manage_releases")), ) -> ReleaseRead: item = await service.get_release(release_id, access_token=access_token) if not item: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Release '{release_id}' not found.") return item @router.post("/build", response_model=ReleaseRead, status_code=status.HTTP_201_CREATED) async def build_release( payload: BuildReleaseRequest, access_token: str = Depends(get_access_token), _: AuthenticatedUser = Depends(require_permission("can_manage_releases")), ) -> ReleaseRead: return await service.build_release(payload, access_token=access_token) @router.post("/{release_id}/publish", response_model=ReleaseLifecycleResponse) async def publish_release( release_id: str, access_token: str = Depends(get_access_token), _: AuthenticatedUser = Depends(require_permission("can_manage_releases")), ) -> ReleaseLifecycleResponse: item = await service.publish_release(release_id, access_token=access_token) if not item: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Release '{release_id}' not found.") return item @router.post("/{release_id}/rollback", response_model=ReleaseLifecycleResponse) async def rollback_release( release_id: str, access_token: str = Depends(get_access_token), _: AuthenticatedUser = Depends(require_permission("can_manage_releases")), ) -> ReleaseLifecycleResponse: item = await service.rollback_release(release_id, access_token=access_token) if not item: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Release '{release_id}' not found.") return item @router.post("/{release_id}/archive", response_model=ReleaseLifecycleResponse) async def archive_release( release_id: str, access_token: str = Depends(get_access_token), _: AuthenticatedUser = Depends(require_permission("can_manage_releases")), ) -> ReleaseLifecycleResponse: item = await service.archive_release(release_id, access_token=access_token) if not item: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Release '{release_id}' not found.") return item