feat(G): G-WORK/G-HUMAN-DEC/G-UI-TEMPL/G-DOC — workflow workstream, decision guard, template gallery (3 templates), API docs, 43 tests passing
This commit is contained in:
@@ -578,3 +578,94 @@ async def reject_workflow_step(
|
||||
instance_id=instance_id,
|
||||
is_system_admin=current_user.get("is_system_admin", False),
|
||||
)
|
||||
|
||||
|
||||
# ─── G-UI-TEMPL: Template Gallery ─────────────────────────────────────────────
|
||||
|
||||
|
||||
WORKFLOW_TEMPLATES = [
|
||||
{
|
||||
"id": "welcome_email",
|
||||
"name": "Welcome Email",
|
||||
"description": "Send a welcome email when a new contact is created",
|
||||
"trigger_event": "contact.after_create",
|
||||
"steps": [
|
||||
{"name": "Wait 1 hour", "type": "wait", "config": {"duration_seconds": 3600}},
|
||||
{"name": "Send Welcome", "type": "mail", "config": {
|
||||
"to": "{{context.email}}",
|
||||
"subject": "Welcome to our service!",
|
||||
"body": "Hello {{context.name}},\n\nWelcome aboard! We're excited to have you.\n\nBest regards,\nThe Team",
|
||||
}},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "contact_followup",
|
||||
"name": "Contact Follow-Up",
|
||||
"description": "Create a follow-up task 3 days after contact creation",
|
||||
"trigger_event": "contact.after_create",
|
||||
"steps": [
|
||||
{"name": "Wait 3 days", "type": "wait", "config": {"duration_seconds": 259200}},
|
||||
{"name": "Create Follow-Up Task", "type": "crm", "config": {
|
||||
"action": "create_contact",
|
||||
"data": {"title": "Follow up with {{context.name}}", "priority": "medium"},
|
||||
}},
|
||||
{"name": "Notify Owner", "type": "notification", "config": {
|
||||
"title": "Follow-up reminder",
|
||||
"body": "Time to follow up with {{context.name}}",
|
||||
}},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "approval_chain",
|
||||
"name": "Approval Chain",
|
||||
"description": "Two-step approval: manager approves, then sends notification",
|
||||
"trigger_event": "manual",
|
||||
"steps": [
|
||||
{"name": "Manager Approval", "type": "approval", "config": {}},
|
||||
{"name": "Send Result", "type": "mail", "config": {
|
||||
"to": "{{context.initiator_email}}",
|
||||
"subject": "Your request has been approved",
|
||||
"body": "Your request has been approved by management.",
|
||||
}},
|
||||
{"name": "Log Completion", "type": "event", "config": {
|
||||
"event_name": "approval_chain.completed",
|
||||
"payload": {},
|
||||
}},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@router.get("/templates")
|
||||
async def list_workflow_templates(
|
||||
current_user: dict = Depends(require_permission("workflows:read")),
|
||||
):
|
||||
"""List available workflow templates (G-UI-TEMPL)."""
|
||||
return {"items": WORKFLOW_TEMPLATES, "total": len(WORKFLOW_TEMPLATES)}
|
||||
|
||||
|
||||
@router.post("/templates/{template_id}/instantiate", status_code=status.HTTP_201_CREATED)
|
||||
async def instantiate_template(
|
||||
template_id: str,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: dict = Depends(require_permission("workflows:write")),
|
||||
):
|
||||
"""Instantiate a workflow template — creates a workflow from the template."""
|
||||
template = next((t for t in WORKFLOW_TEMPLATES if t["id"] == template_id), None)
|
||||
if template is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail={"detail": "Template not found", "code": "not_found"},
|
||||
)
|
||||
|
||||
tenant_id = uuid.UUID(current_user["tenant_id"])
|
||||
user_id = uuid.UUID(current_user["user_id"])
|
||||
|
||||
data = {
|
||||
"name": template["name"],
|
||||
"description": template["description"],
|
||||
"trigger_event": template["trigger_event"],
|
||||
"steps": template["steps"],
|
||||
"is_active": True,
|
||||
}
|
||||
return await workflow_service.create_workflow(db, tenant_id, user_id, data)
|
||||
|
||||
Reference in New Issue
Block a user