# app/schemas/automation.py from datetime import datetime from typing import List, Optional, Dict, Any from pydantic import BaseModel, Field from app.models.enums import TaskStatus, ScenarioScope, ActionType # ---------------------------- # Scenario Schemas # ---------------------------- class ScenarioBase(BaseModel): title: str = Field(..., max_length=255, description="场景标题") trigger: Dict[str, Any] = Field(..., description="触发条件(事件/时间)") actions: List[Dict[str, Any]] = Field(default_factory=list, description="执行动作模板列表") notes: Optional[str] = Field(None, description="备注") is_global: bool = Field(True, description="是否全局场景") owner_user_id: Optional[str] = Field(None, max_length=64, description="归属用户ID(非全局时有效)") enabled: bool = Field(True, description="是否启用") scope: ScenarioScope = Field(ScenarioScope.ALL, description="作用角色范围") class ScenarioCreate(ScenarioBase): pass class ScenarioUpdate(BaseModel): id: int = Field(..., description="场景ID") title: Optional[str] = Field(None, max_length=255) trigger: Optional[Dict[str, Any]] = None actions: Optional[List[Dict[str, Any]]] = None notes: Optional[str] = None is_global: Optional[bool] = None owner_user_id: Optional[str] = Field(None, max_length=64) enabled: Optional[bool] = None scope: Optional[ScenarioScope] = None # model_config = {"extra": "forbid"} # 禁止传入未定义字段 class ScenarioCopy(BaseModel): id: int = Field(..., description="场景ID") # model_config = {"extra": "forbid"} # 禁止传入未定义字段 class ScenarioRead(ScenarioBase): id: int created_at: datetime updated_at: datetime model_config = {"from_attributes": True} # ---------------------------- # Task Schemas # ---------------------------- class TaskBase(BaseModel): title: str = Field(..., max_length=255, description="待办标题") # actions: List[Dict[str, Any]] = Field(default_factory=list, description="动作列表(动态组件渲染用)") event_data: Optional[Dict[str, Any]] = Field(default_factory=dict, description="事件数据") notes: Optional[str] = Field(None, description="备注") reason: Optional[str] = Field(None, description="触发原因") # 关联字段 source_scenario_id: Optional[int] = Field(None, description="来源场景ID") owner_user_id: Optional[str] = Field(None, max_length=64, description="归属用户ID") # 分配与状态 assignee_user_id: Optional[str] = Field(None, max_length=64, description="指派人用户ID") assignee_username: Optional[str] = Field(None, max_length=64, description="指派人用户名") status: TaskStatus = Field(TaskStatus.PENDING, description="任务状态") # 自动化控制 due_at: Optional[datetime] = Field(None, description="截止时间") auto_closeable: bool = Field(True, description="是否允许自动消除") closed_by: Optional[str] = Field(None, max_length=32, description="关闭方式: manual/auto/expired") class TaskCreate(TaskBase): pass class TaskUpdate(BaseModel): title: Optional[str] = Field(None, max_length=255) content: Optional[List[Dict[str, Any]]] = None notes: Optional[str] = None source_scenario_id: Optional[int] = None related_order_id: Optional[str] = Field(None, max_length=64) related_customer_id: Optional[str] = Field(None, max_length=64) group_id: Optional[str] = Field(None, max_length=64) assignee_user_id: Optional[str] = Field(None, max_length=64) assignee_username: Optional[str] = Field(None, max_length=64) status: Optional[TaskStatus] = None due_at: Optional[datetime] = None auto_closeable: Optional[bool] = None closed_by: Optional[str] = Field(None, max_length=32) completed_at: Optional[datetime] = None # model_config = {"extra": "forbid"} class TaskRead(TaskBase): id: int created_at: datetime updated_at: datetime completed_at: Optional[datetime] = None model_config = {"from_attributes": True} # ---------------------------- # Action Schemas # ---------------------------- class ActionBase(BaseModel): type: Optional[ActionType] = Field(None, description="操作类型") detail: Dict[str, Any] = Field(default_factory=dict, description="操作详情") done: bool = Field(False, description="是否已完成") done_at: Optional[datetime] = Field(None, description="完成时间") result: Dict[str, Any] = Field(default_factory=dict, description="操作结果") userid: Optional[str] = Field(None, max_length=64, description="操作用户ID") username: Optional[str] = Field(None, max_length=64, description="操作用户名称") notes: Optional[str] = Field(None, description="操作备注") task_id: int = Field(..., description="所属任务ID") action_template_id: Optional[str] = Field(None, max_length=64, description="操作模板ID") class ActionCreate(ActionBase): pass class ActionUpdate(BaseModel): type: Optional[ActionType] = None detail: Optional[Dict[str, Any]] = None done: Optional[bool] = None done_at: Optional[datetime] = None result: Optional[Dict[str, Any]] = None userid: Optional[str] = Field(None, max_length=64) username: Optional[str] = Field(None, max_length=64) notes: Optional[str] = None task_id: Optional[int] = None action_template_id: Optional[str] = Field(None, max_length=64) model_config = {"extra": "forbid"} class ActionRead(ActionBase): id: int created_at: datetime updated_at: datetime model_config = {"from_attributes": True} class NotifyAction(BaseModel): platform: str = Field(..., description="平台类型") webhook_url: str = Field(..., description="Webhook URL") template: str = Field(..., description="模板内容") need_at: bool = Field(False, description="是否需要@用户") __meta_mapping__ = { "template": {"type": "text"} }