Files
replypier/backend/app/models/schemas/workflow.py

202 lines
5.6 KiB
Python

"""
Copyright 2024-2026 ReplyPier
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any, Literal
from uuid import UUID
from datetime import datetime
from app.models.workflow import WorkflowStatus
from app.models.workflow_node import NodeType, ActionType
# ==============================
# Workflow schemas
# ==============================
class WorkflowBase(BaseModel):
name: str
description: Optional[str] = None
status: Optional[WorkflowStatus] = WorkflowStatus.DRAFT
is_template: bool = False
default_language: str = "en"
canvas_data: Dict[str, Any] = Field(default_factory=dict)
settings: Dict[str, Any] = Field(default_factory=dict)
class WorkflowCreate(WorkflowBase):
agent_id: UUID
# ==============================
# Operation schemas for batch updates
# ==============================
class WorkflowNodeOperation(BaseModel):
operation: Literal["create", "update", "delete"]
id: Optional[UUID] = None # Required for update/delete, optional for create
node_type: Optional[NodeType] = None
name: Optional[str] = None
description: Optional[str] = None
position_x: Optional[float] = None
position_y: Optional[float] = None
config: Optional[Dict[str, Any]] = None
# Landing Page node fields
landing_page_heading: Optional[str] = None
landing_page_content: Optional[str] = None
class WorkflowConnectionOperation(BaseModel):
operation: Literal["create", "update", "delete"]
id: Optional[UUID] = None # Required for update/delete, optional for create
source_node_id: Optional[UUID] = None
target_node_id: Optional[UUID] = None
label: Optional[str] = None
condition: Optional[str] = None
priority: Optional[int] = None
connection_metadata: Optional[Dict[str, Any]] = None
class WorkflowUpdate(BaseModel):
name: Optional[str] = None
description: Optional[str] = None
status: Optional[WorkflowStatus] = None
is_template: Optional[bool] = None
default_language: Optional[str] = None
canvas_data: Optional[Dict[str, Any]] = None
settings: Optional[Dict[str, Any]] = None
agent_id: Optional[UUID] = None
nodes: Optional[List[WorkflowNodeOperation]] = None
connections: Optional[List[WorkflowConnectionOperation]] = None
class WorkflowResponse(WorkflowBase):
id: UUID
organization_id: UUID
agent_id: UUID
created_by: UUID
created_at: datetime
updated_at: datetime
class Config:
orm_mode = True
# ==============================
# WorkflowNode schemas
# ==============================
class WorkflowNodeBase(BaseModel):
workflow_id: UUID
node_type: NodeType
name: str
description: Optional[str] = None
position_x: float = 0
position_y: float = 0
config: Dict[str, Any] = Field(default_factory=dict)
# Message node fields
message_text: Optional[str] = None
# Condition node fields
condition_expression: Optional[str] = None
# Action node fields
action_type: Optional[ActionType] = None
action_config: Optional[Dict[str, Any]] = None
# Transfer node fields
transfer_rules: Optional[Dict[str, Any]] = None
# Wait node fields
wait_duration: Optional[int] = None # Duration in seconds
wait_until_condition: Optional[str] = None
# Landing Page node fields
landing_page_heading: Optional[str] = None
landing_page_content: Optional[str] = None
class WorkflowNodeCreate(WorkflowNodeBase):
pass
class WorkflowNodeUpdate(BaseModel):
node_type: Optional[NodeType] = None
name: Optional[str] = None
description: Optional[str] = None
position_x: Optional[float] = None
position_y: Optional[float] = None
config: Optional[Dict[str, Any]] = None
# Landing Page node fields
landing_page_heading: Optional[str] = None
landing_page_content: Optional[str] = None
class WorkflowNodeResponse(WorkflowNodeBase):
id: UUID
created_at: datetime
updated_at: datetime
class Config:
orm_mode = True
# ==============================
# WorkflowConnection schemas
# ==============================
class WorkflowConnectionBase(BaseModel):
workflow_id: UUID
source_node_id: UUID
target_node_id: UUID
label: Optional[str] = None
condition: Optional[str] = None
priority: int = 0
connection_metadata: Dict[str, Any] = Field(default_factory=dict)
class WorkflowConnectionCreate(WorkflowConnectionBase):
pass
class WorkflowConnectionUpdate(BaseModel):
label: Optional[str] = None
condition: Optional[str] = None
priority: Optional[int] = None
connection_metadata: Optional[Dict[str, Any]] = None
class WorkflowConnectionResponse(WorkflowConnectionBase):
id: UUID
created_at: datetime
updated_at: datetime
class Config:
orm_mode = True
# ==============================
# Additional composite schemas
# ==============================
class WorkflowDetailResponse(WorkflowResponse):
nodes: List[WorkflowNodeResponse]
connections: List[WorkflowConnectionResponse]
class Config:
orm_mode = True