from __future__ import annotations from .shared import * from .schemas import PMOCadenceRunRequest @router.post("/cadence/run") async def run_cadence( request: PMOCadenceRunRequest, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_tenant_id), ): _ = current_user service = AIPMOCadenceService(db, tenant_id=tenant_id) try: snapshot = await service.generate_snapshot( cadence_type=request.cadence_type, project_id=request.project_id, ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc await db.commit() return success_response(snapshot) @router.get("/cadence/latest") async def get_latest_cadence_snapshot( cadence_type: str, project_id: Optional[int] = None, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_tenant_id), ): _ = current_user service = AIPMOCadenceService(db, tenant_id=tenant_id) snapshot = await service.get_latest_snapshot( cadence_type=cadence_type, project_id=project_id, ) return success_response(snapshot) @router.get("/portfolio/program-view") async def get_program_view( current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_tenant_id), ): _ = current_user service = AIPMOCadenceService(db, tenant_id=tenant_id) return success_response(await service.build_program_view()) @router.get("/portfolio/latest") async def get_latest_portfolio_snapshot( scope_type: str = "tenant", project_id: Optional[int] = None, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_tenant_id), ): _ = current_user scope_ref = f"project:{int(project_id)}" if project_id is not None else f"tenant:{tenant_id}" row = ( await db.execute( select(PortfolioSnapshot).where( and_( PortfolioSnapshot.tenant_id == tenant_id, PortfolioSnapshot.scope_type == scope_type, PortfolioSnapshot.scope_ref == scope_ref, ) ).order_by(PortfolioSnapshot.id.desc()).limit(1) ) ).scalar_one_or_none() if row is None: return success_response(None) return success_response( { "id": int(row.id), "scope_type": row.scope_type, "scope_ref": row.scope_ref, "summary": row.summary, "payload": row.payload, "created_at": row.created_at.isoformat() if row.created_at else None, } )