from datetime import datetime from fastapi import APIRouter, Depends, HTTPException, Query from pydantic import BaseModel from sqlalchemy import func, select from sqlalchemy.orm import Session, joinedload from app.auth.jwt_auth import get_current_user from app.database import get_db from app.models import Problem router = APIRouter(prefix="/problems", tags=["problems"]) class ProblemSummary(BaseModel): id: int host_id: int | None hostname: str | None title: str summary: str severity: str status: str rule_id: str | None created_at: datetime updated_at: datetime model_config = {"from_attributes": True} class ProblemListResponse(BaseModel): items: list[ProblemSummary] total: int page: int page_size: int @router.get("", response_model=ProblemListResponse) def list_problems( page: int = Query(1, ge=1), page_size: int = Query(50, ge=1, le=200), status: str | None = Query(None), db: Session = Depends(get_db), _user: str = Depends(get_current_user), ) -> ProblemListResponse: stmt = select(Problem).options(joinedload(Problem.host)) count_stmt = select(func.count()).select_from(Problem) if status: stmt = stmt.where(Problem.status == status) count_stmt = count_stmt.where(Problem.status == status) total = db.scalar(count_stmt) or 0 rows = db.scalars( stmt.order_by(Problem.updated_at.desc()).offset((page - 1) * page_size).limit(page_size) ).all() items = [ ProblemSummary( id=p.id, host_id=p.host_id, hostname=p.host.hostname if p.host else None, title=p.title, summary=p.summary, severity=p.severity, status=p.status, rule_id=p.rule_id, created_at=p.created_at, updated_at=p.updated_at, ) for p in rows ] return ProblemListResponse(items=items, total=total, page=page, page_size=page_size) @router.post("/{problem_id}/ack") def ack_problem( problem_id: int, db: Session = Depends(get_db), _user: str = Depends(get_current_user), ) -> dict: problem = db.get(Problem, problem_id) if problem is None: raise HTTPException(status_code=404, detail="Problem not found") problem.status = "acknowledged" db.commit() return {"id": problem.id, "status": problem.status} @router.post("/{problem_id}/resolve") def resolve_problem( problem_id: int, db: Session = Depends(get_db), _user: str = Depends(get_current_user), ) -> dict: problem = db.get(Problem, problem_id) if problem is None: raise HTTPException(status_code=404, detail="Problem not found") problem.status = "resolved" db.commit() return {"id": problem.id, "status": problem.status}