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:
Agent Zero
2026-08-18 11:11:50 +02:00
parent 1bf776dff5
commit 59f05de621
5 changed files with 705 additions and 0 deletions
+91
View File
@@ -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)