"""任务 Pydantic Schemas — 支持无限嵌套子任务、裂变转交、驳回返工""" from __future__ import annotations import uuid from datetime import datetime from typing import Optional from pydantic import BaseModel, Field # ============================================================ # 请求模型 # ============================================================ class TaskCreate(BaseModel): """创建任务""" product_id: uuid.UUID = Field(..., description="所属产品ID") parent_task_id: uuid.UUID | None = Field(None, description="父任务ID(用于嵌套子任务/裂变分支)") task_name: str = Field(..., max_length=200, description="任务名称") assignee_id: str | None = Field(None, max_length=64, description="负责人ID(逻辑外键→老系统)") notify_parent_on_complete: bool = Field(False, description="完成后是否通知父任务") is_rework: bool = Field(False, description="是否为返工任务") model_config = {"from_attributes": True} class TaskUpdate(BaseModel): """更新任务""" task_name: str | None = Field(None, max_length=200) assignee_id: str | None = Field(None, max_length=64) status: str | None = Field(None, max_length=50, description="任务状态") notify_parent_on_complete: bool | None = Field(None) model_config = {"from_attributes": True} class TaskCompleteRequest(BaseModel): """完成任务请求 — 携带转交信息(保留兼容旧版单步转交)""" operator_id: str | None = Field(None, max_length=64, description="操作人ID") next_assignee_id: str | None = Field(None, max_length=64, description="下一步任务负责人ID") next_task_name: str | None = Field(None, max_length=200, description="下一步任务名称") remark: str | None = Field(None, description="完成备注") class SubtaskCreate(BaseModel): """创建子任务""" task_name: str = Field(..., max_length=200, description="子任务名称") assignee_id: str | None = Field(None, max_length=64, description="负责人ID") notify_parent_on_complete: bool = Field(False, description="完成后是否通知父任务") class TaskRejectRequest(BaseModel): """品质驳回请求""" reason: str = Field(..., min_length=1, max_length=500, description="驳回原因(必填)") class TaskTransferRequest(BaseModel): """完工裂变转交请求""" next_assignees: list[str] = Field(..., min_length=1, description="下一道工序接收人列表(必填)") next_task_name: str = Field(..., min_length=1, max_length=200, description="下一道工序名称(必填)") note: str | None = Field(None, description="交接备注") # ============================================================ # 响应模型 # ============================================================ class TaskSummaryResponse(BaseModel): """任务摘要 — 扫码时用,不含嵌套子任务""" id: uuid.UUID product_id: uuid.UUID parent_task_id: uuid.UUID | None task_name: str assignee_id: str | None status: str notify_parent_on_complete: bool is_rework: bool = False reject_reason: str | None = None received_at: datetime | None = None completed_at: datetime | None = None created_at: datetime model_config = {"from_attributes": True} class TaskResponse(BaseModel): """任务详情响应 — 递归包含所有子任务""" id: uuid.UUID product_id: uuid.UUID parent_task_id: uuid.UUID | None task_name: str assignee_id: str | None status: str notify_parent_on_complete: bool is_rework: bool = False reject_reason: str | None = None received_at: datetime | None = None completed_at: datetime | None = None created_at: datetime child_tasks: list[TaskResponse] = [] model_config = {"from_attributes": True} class TaskCompleteResponse(BaseModel): """任务完成响应""" completed_task: TaskResponse next_task: TaskResponse | None = None message: str class TaskTransferResponse(BaseModel): """裂变转交响应""" completed_task: TaskResponse created_tasks: list[TaskResponse] = [] message: str class TaskListResponse(BaseModel): """任务列表响应""" tasks: list[TaskResponse] total: int