69 lines
2.1 KiB
Python
69 lines
2.1 KiB
Python
"""通用 Pydantic 模型"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, List, Optional
|
|
|
|
from pydantic import AliasChoices, BaseModel, ConfigDict, Field, model_validator
|
|
|
|
|
|
class TaskBreakdownBusinessObject(BaseModel):
|
|
"""结构化任务拆解业务对象"""
|
|
|
|
model_config = ConfigDict(extra="ignore", populate_by_name=True)
|
|
|
|
task_key: str = Field(validation_alias=AliasChoices("task_key", "key"))
|
|
title: str = Field(validation_alias=AliasChoices("title", "task_name"))
|
|
description: Optional[str] = None
|
|
type: str = Field(validation_alias=AliasChoices("type", "task_type"))
|
|
estimated_hours: float
|
|
required_skill_names: List[str] = Field(default_factory=list)
|
|
required_skill_tag_ids: List[int] = Field(default_factory=list)
|
|
depends_on_task_keys: List[str] = Field(default_factory=list)
|
|
risk_level: str = "medium"
|
|
risk_notes: Optional[str] = None
|
|
confidence: float = 0.0
|
|
evidence_refs: List[str] = Field(default_factory=list)
|
|
priority: str = "medium"
|
|
|
|
@model_validator(mode="after")
|
|
def _fill_task_key(self) -> "TaskBreakdownBusinessObject":
|
|
key = str(self.task_key or "").strip()
|
|
if not key:
|
|
title = str(self.title or "").strip()
|
|
key = title.lower().replace(" ", "-") if title else "task"
|
|
self.task_key = key
|
|
return self
|
|
|
|
|
|
class TaskItem(TaskBreakdownBusinessObject):
|
|
"""兼容旧调用的任务项别名"""
|
|
|
|
pass
|
|
|
|
|
|
class TaskBreakdownPayload(BaseModel):
|
|
"""AI 任务拆解结构化载荷"""
|
|
|
|
model_config = ConfigDict(extra="ignore")
|
|
|
|
tasks: List[TaskBreakdownBusinessObject]
|
|
detected_skills: List[str] = Field(default_factory=list)
|
|
source_context: Optional[dict[str, Any]] = None
|
|
|
|
|
|
class TaskBreakdownRequest(BaseModel):
|
|
"""任务拆解请求"""
|
|
|
|
description: str
|
|
project_id: Optional[int] = None
|
|
charter_id: Optional[int] = None
|
|
sync_to_plane: bool = False
|
|
|
|
|
|
class TaskBreakdownResponse(BaseModel):
|
|
"""任务拆解响应"""
|
|
|
|
tasks: List[TaskBreakdownBusinessObject]
|
|
sync_result: Optional[dict] = None
|