feat(fase4): add validation nodes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
82
services/flow-engine/app/nodes/validation.py
Normal file
82
services/flow-engine/app/nodes/validation.py
Normal file
@@ -0,0 +1,82 @@
|
||||
import re
|
||||
from typing import Optional, Any
|
||||
from datetime import datetime
|
||||
from app.nodes.base import NodeExecutor
|
||||
from app.context import FlowContext
|
||||
|
||||
|
||||
class ValidateEmailExecutor(NodeExecutor):
|
||||
async def execute(self, config: dict, context: FlowContext, session: Any) -> Optional[str]:
|
||||
variable = config.get("variable", "")
|
||||
value = context.get(variable) or context.message.get("content", "")
|
||||
email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
|
||||
if re.match(email_pattern, str(value).strip()):
|
||||
return "valid"
|
||||
return "invalid"
|
||||
|
||||
|
||||
class ValidatePhoneExecutor(NodeExecutor):
|
||||
async def execute(self, config: dict, context: FlowContext, session: Any) -> Optional[str]:
|
||||
variable = config.get("variable", "")
|
||||
value = context.get(variable) or context.message.get("content", "")
|
||||
cleaned = re.sub(r'[\s\-\(\)\+]', '', str(value))
|
||||
if cleaned.isdigit() and 8 <= len(cleaned) <= 15:
|
||||
return "valid"
|
||||
return "invalid"
|
||||
|
||||
|
||||
class ValidateNumberExecutor(NodeExecutor):
|
||||
async def execute(self, config: dict, context: FlowContext, session: Any) -> Optional[str]:
|
||||
variable = config.get("variable", "")
|
||||
value = context.get(variable) or context.message.get("content", "")
|
||||
min_val = config.get("min")
|
||||
max_val = config.get("max")
|
||||
try:
|
||||
num = float(str(value).strip())
|
||||
if min_val is not None and num < float(min_val):
|
||||
return "invalid"
|
||||
if max_val is not None and num > float(max_val):
|
||||
return "invalid"
|
||||
return "valid"
|
||||
except ValueError:
|
||||
return "invalid"
|
||||
|
||||
|
||||
class ValidateDateExecutor(NodeExecutor):
|
||||
async def execute(self, config: dict, context: FlowContext, session: Any) -> Optional[str]:
|
||||
variable = config.get("variable", "")
|
||||
value = context.get(variable) or context.message.get("content", "")
|
||||
date_format = config.get("format", "%Y-%m-%d")
|
||||
try:
|
||||
datetime.strptime(str(value).strip(), date_format)
|
||||
return "valid"
|
||||
except ValueError:
|
||||
return "invalid"
|
||||
|
||||
|
||||
class ValidateRegexExecutor(NodeExecutor):
|
||||
async def execute(self, config: dict, context: FlowContext, session: Any) -> Optional[str]:
|
||||
variable = config.get("variable", "")
|
||||
value = context.get(variable) or context.message.get("content", "")
|
||||
pattern = config.get("pattern", ".*")
|
||||
try:
|
||||
if re.match(pattern, str(value).strip()):
|
||||
return "valid"
|
||||
return "invalid"
|
||||
except re.error:
|
||||
return "invalid"
|
||||
|
||||
|
||||
class ValidateOptionsExecutor(NodeExecutor):
|
||||
async def execute(self, config: dict, context: FlowContext, session: Any) -> Optional[str]:
|
||||
variable = config.get("variable", "")
|
||||
value = context.get(variable) or context.message.get("content", "")
|
||||
options = config.get("options", [])
|
||||
case_sensitive = config.get("case_sensitive", False)
|
||||
value_str = str(value).strip()
|
||||
if not case_sensitive:
|
||||
value_str = value_str.lower()
|
||||
options = [str(o).lower() for o in options]
|
||||
if value_str in options:
|
||||
return "valid"
|
||||
return "invalid"
|
||||
Reference in New Issue
Block a user