""" Goal API — 目标管理接口 """ from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from pydantic import BaseModel, Field from typing import List, Optional, Dict, Any from datetime import datetime import logging from app.core.database import get_db from app.api.auth import get_current_user from app.models.user import User from app.services import goal_service logger = logging.getLogger(__name__) router = APIRouter( prefix="/api/v1/goals", tags=["goals"], responses={ 401: {"description": "未授权"}, 404: {"description": "资源不存在"}, 400: {"description": "请求参数错误"}, }, ) # ──────────────────────────── Schemas ──────────────────────────── class GoalCreate(BaseModel): title: str description: str = "" priority: int = Field(default=5, ge=1, le=10) deadline: Optional[datetime] = None main_agent_id: Optional[str] = None parent_goal_id: Optional[str] = None autonomy_config: Optional[Dict[str, Any]] = None class GoalUpdate(BaseModel): title: Optional[str] = None description: Optional[str] = None status: Optional[str] = None priority: Optional[int] = Field(default=None, ge=1, le=10) plan: Optional[List[Dict[str, Any]]] = None autonomy_config: Optional[Dict[str, Any]] = None deadline: Optional[datetime] = None main_agent_id: Optional[str] = None class GoalResponse(BaseModel): id: str title: str description: Optional[str] status: str priority: int progress: float plan: Optional[Any] autonomy_config: Optional[Any] creator_id: str main_agent_id: Optional[str] parent_goal_id: Optional[str] started_at: Optional[datetime] completed_at: Optional[datetime] deadline: Optional[datetime] created_at: datetime updated_at: datetime class Config: from_attributes = True class GoalTaskTreeResponse(BaseModel): goal: Dict[str, Any] tasks: List[Dict[str, Any]] # ──────────────────────────── Endpoints ──────────────────────────── @router.post("", response_model=GoalResponse, status_code=201) def create_goal( data: GoalCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """创建新目标""" return goal_service.create_goal( db=db, creator_id=current_user.id, title=data.title, description=data.description, priority=data.priority, deadline=data.deadline, main_agent_id=data.main_agent_id, parent_goal_id=data.parent_goal_id, autonomy_config=data.autonomy_config, ) @router.get("", response_model=List[GoalResponse]) def list_goals( status: Optional[str] = None, skip: int = Query(default=0, ge=0), limit: int = Query(default=20, ge=1, le=100), current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """列出目标""" return goal_service.list_goals( db=db, creator_id=current_user.id, status=status, skip=skip, limit=limit, ) @router.get("/{goal_id}", response_model=GoalResponse) def get_goal( goal_id: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """获取目标详情""" return goal_service.get_goal(db, goal_id) @router.put("/{goal_id}", response_model=GoalResponse) def update_goal( goal_id: str, data: GoalUpdate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """更新目标""" return goal_service.update_goal( db=db, goal_id=goal_id, title=data.title, description=data.description, status=data.status, priority=data.priority, plan=data.plan, autonomy_config=data.autonomy_config, deadline=data.deadline, main_agent_id=data.main_agent_id, ) @router.delete("/{goal_id}", status_code=204) def delete_goal( goal_id: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """删除目标""" goal_service.delete_goal(db, goal_id) return None @router.post("/{goal_id}/start", response_model=GoalResponse) def start_goal( goal_id: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """启动目标执行""" goal = goal_service.update_goal(db, goal_id, status="active") goal.started_at = datetime.now() db.commit() db.refresh(goal) logger.info(f"Goal started: {goal_id}") return goal @router.post("/{goal_id}/pause", response_model=GoalResponse) def pause_goal( goal_id: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """暂停目标执行""" return goal_service.update_goal(db, goal_id, status="paused") @router.post("/{goal_id}/resume", response_model=GoalResponse) def resume_goal( goal_id: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """恢复目标执行""" return goal_service.update_goal(db, goal_id, status="active") @router.get("/{goal_id}/tasks", response_model=GoalTaskTreeResponse) def get_goal_task_tree( goal_id: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """获取目标的任务树""" return goal_service.get_goal_task_tree(db, goal_id)