import uuid from datetime import datetime from pydantic import BaseModel, Field # --- Auth --- class LoginRequest(BaseModel): username: str password: str class TokenResponse(BaseModel): access_token: str token_type: str = "bearer" user: "UserOut" # --- User --- class UserCreate(BaseModel): username: str password: str display_name: str email: str | None = None phone: str | None = None wecom_user_id: str | None = None department_id: uuid.UUID | None = None position: str | None = None manager_id: uuid.UUID | None = None role_ids: list[uuid.UUID] = [] class UserUpdate(BaseModel): display_name: str | None = None email: str | None = None phone: str | None = None department_id: uuid.UUID | None = None position: str | None = None manager_id: uuid.UUID | None = None status: str | None = None role_ids: list[uuid.UUID] | None = None class UserOut(BaseModel): id: uuid.UUID username: str display_name: str email: str | None = None phone: str | None = None wecom_user_id: str | None = None department_id: uuid.UUID | None = None position: str | None = None manager_id: uuid.UUID | None = None status: str roles: list["RoleOut"] = [] created_at: datetime | None = None class Config: from_attributes = True # --- Department --- class DepartmentCreate(BaseModel): name: str parent_id: uuid.UUID | None = None sort_order: int = 0 class DepartmentUpdate(BaseModel): name: str | None = None parent_id: uuid.UUID | None = None sort_order: int | None = None class DepartmentOut(BaseModel): id: uuid.UUID name: str parent_id: uuid.UUID | None = None path: str level: int sort_order: int children: list["DepartmentOut"] = [] class Config: from_attributes = True # --- Role --- class RoleCreate(BaseModel): name: str code: str = "" description: str | None = None data_scope: str = "self_only" permission_ids: list[uuid.UUID] = [] class RoleUpdate(BaseModel): name: str | None = None description: str | None = None data_scope: str | None = None permission_ids: list[uuid.UUID] | None = None class RoleOut(BaseModel): id: uuid.UUID name: str code: str = "" description: str | None = None is_system: bool data_scope: str permissions: list[str] = [] class Config: from_attributes = True # --- Permission --- class PermissionOut(BaseModel): id: uuid.UUID code: str name: str resource: str action: str class Config: from_attributes = True # --- Task --- class TaskCreate(BaseModel): title: str content: str | None = None assignee_id: uuid.UUID priority: str = "normal" deadline: datetime | None = None push_to_wecom: bool = True class TaskUpdate(BaseModel): title: str | None = None content: str | None = None status: str | None = None priority: str | None = None deadline: datetime | None = None class TaskOut(BaseModel): id: uuid.UUID title: str content: str | None = None assigner_id: uuid.UUID | None = None assignee_id: uuid.UUID status: str priority: str deadline: datetime | None = None created_at: datetime | None = None updated_at: datetime | None = None class Config: from_attributes = True # --- Employee Analysis --- class EmployeeAnalysis(BaseModel): employee_name: str department: str period: str task_completion_rate: float active_days: int total_interactions: int main_topics: list[str] efficiency_trend: str efficiency_detail: str strengths: list[str] growth_suggestions: list[str] personality_traits: str # --- Flow --- class TriggerNodeConfig(BaseModel): event_type: str = "text_message" class LLMNodeConfig(BaseModel): system_prompt: str = "" model: str = "gpt-4o-mini" temperature: float = 0.7 agent_id: str = "" class ToolNodeConfig(BaseModel): tool_name: str = "" class MCPNodeConfig(BaseModel): mcp_server: str = "" tool_name: str = "" class WeComNotifyNodeConfig(BaseModel): message_template: str = "" target: str = "" class ConditionNodeConfig(BaseModel): condition: str = "" class RAGNodeConfig(BaseModel): knowledge_base: str = "" top_k: int = 5 class OutputNodeConfig(BaseModel): format: str = "text" class FlowNode(BaseModel): id: str | None = None type: str label: str | None = None config: dict = {} class FlowEdge(BaseModel): source: str | None = None target: str | None = None from_field: str | None = Field(None, alias="from") to_field: str | None = Field(None, alias="to") class Config: populate_by_name = True class FlowDefinitionCreate(BaseModel): name: str description: str | None = None trigger: dict = {} nodes: list[FlowNode] edges: list[FlowEdge] class FlowDefinitionUpdate(BaseModel): name: str | None = None description: str | None = None nodes: list[FlowNode] | None = None edges: list[FlowEdge] | None = None trigger: dict | None = None class FlowDefinitionOut(BaseModel): id: uuid.UUID name: str description: str | None = None version: int status: str definition_json: dict published_to_wecom: bool created_at: datetime | None = None updated_at: datetime | None = None class Config: from_attributes = True # --- MCP --- class MCPServiceCreate(BaseModel): name: str transport: str = "http" url: str | None = None command: str | None = None args: list[str] = [] env: dict[str, str] = {} class MCPServiceUpdate(BaseModel): transport: str | None = None url: str | None = None command: str | None = None args: list[str] | None = None env: dict[str, str] | None = None class MCPServiceOut(BaseModel): id: uuid.UUID name: str transport: str url: str | None = None command: str | None = None status: str = "disconnected" tools: list[dict] = [] creator_id: uuid.UUID | None = None created_at: datetime | None = None class Config: from_attributes = True # --- Agent Config --- class AgentConfigCreate(BaseModel): name: str description: str | None = None system_prompt: str = "" model: str = "gpt-4o-mini" temperature: float = 0.7 tools: list[str] = [] class AgentConfigUpdate(BaseModel): name: str | None = None description: str | None = None system_prompt: str | None = None model: str | None = None temperature: float | None = None tools: list[str] | None = None status: str | None = None class AgentConfigOut(BaseModel): id: uuid.UUID name: str description: str | None = None system_prompt: str model: str temperature: float tools: list[str] = [] status: str creator_id: uuid.UUID | None = None created_at: datetime | None = None updated_at: datetime | None = None class Config: from_attributes = True # --- Notification --- class NotificationTemplateCreate(BaseModel): name: str code: str channel: str = "wecom" title_template: str | None = None body_template: str variables: list[str] = [] class NotificationTemplateOut(BaseModel): id: uuid.UUID name: str code: str channel: str title_template: str | None = None body_template: str variables: list[str] = [] is_system: bool = False class Config: from_attributes = True # --- Document --- class DocumentUploadOut(BaseModel): file_id: uuid.UUID filename: str file_size: int content_type: str upload_time: datetime class DocumentParseResult(BaseModel): file_id: uuid.UUID filename: str content: str metadata: dict = {} # --- Audit --- class AuditQueryParams(BaseModel): page: int = 1 page_size: int = 20 action: str | None = None resource: str | None = None operator_id: uuid.UUID | None = None date_from: datetime | None = None date_to: datetime | None = None class AuditLogOut(BaseModel): id: uuid.UUID operator_id: uuid.UUID | None = None action: str resource: str | None = None resource_id: str | None = None detail: dict | None = None ip_address: str | None = None created_at: datetime | None = None class Config: from_attributes = True class AuditLogPage(BaseModel): items: list[AuditLogOut] total: int page: int page_size: int # --- System Metrics --- class SystemMetricOut(BaseModel): id: uuid.UUID metric_type: str value: dict collected_at: datetime class Config: from_attributes = True class SystemHealthOut(BaseModel): status: str service: str uptime_seconds: float db_connected: bool redis_connected: bool active_users: int memory_mb: float cpu_percent: float class UsageStatsOut(BaseModel): total_users: int active_users_today: int total_sessions: int total_messages: int total_tasks: int total_flows: int published_flows: int api_calls_today: int avg_response_time_ms: float # --- Generic Response --- class ApiResponse(BaseModel): code: int = 200 message: str = "success" data: dict | list | None = None