# Workflow Routes Frontend Documentation
This document describes customer journeys for managing workflows through the frontend, focusing on how users interact with workflows and how the backend routes support these experiences. All UI components are dynamically generated from backend metadata—no hardcoding required.
## Table of Contents
1. [Overview](#overview)
2. [Customer Journey 1: Discovering and Browsing Workflows](#customer-journey-1-discovering-and-browsing-workflows)
3. [Customer Journey 2: Viewing Workflow Details](#customer-journey-2-viewing-workflow-details)
4. [Customer Journey 3: Monitoring Workflow Execution](#customer-journey-3-monitoring-workflow-execution)
5. [Customer Journey 4: Editing Workflow Properties](#customer-journey-4-editing-workflow-properties)
6. [Customer Journey 5: Managing Workflow Messages](#customer-journey-5-managing-workflow-messages)
7. [Customer Journey 6: Cleaning Up Workflows](#customer-journey-6-cleaning-up-workflows)
8. [Backend Metadata System](#backend-metadata-system)
9. [Implementation Patterns](#implementation-patterns)
---
## Overview
The workflow routes (`/api/workflows`) enable users to manage and monitor workflows that are already running or completed. These routes focus on **management and monitoring** rather than creation (workflows are created through the chat playground routes).
**Key Principles:**
- **User-Centric**: Documentation organized around what users want to accomplish
- **Backend-Driven**: All forms, tables, and UI components generated from backend metadata
- **No Hardcoding**: Field definitions, labels, validation rules, and options come from the backend
- **Real-Time Updates**: Support for polling and incremental data loading
- **Permission-Aware**: Backend enforces permissions; frontend handles gracefully
---
## Customer Journey 1: Discovering and Browsing Workflows
### User Goal
"I want to see all my workflows and find the one I'm looking for."
### User Story
As a user, I want to browse my workflows, search for specific workflows, filter by any field, sort them by different criteria, and quickly identify which ones are running, completed, or have errors.
### User Story Flow
```mermaid
sequenceDiagram
participant User
participant Frontend
participant Backend
User->>Frontend: Navigate to /workflows
Frontend->>Backend: GET /api/attributes/ChatWorkflow
Backend-->>Frontend: Attribute definitions (fields, labels, types)
Frontend->>Backend: GET /api/workflows/?pagination=...
Backend-->>Frontend: Paginated workflows list
Frontend->>Frontend: Generate table columns from attributes
Frontend->>Frontend: Generate filter controls from attributes
Frontend->>Frontend: Render workflows table + search + filters
Frontend-->>User: Display workflow list with search/filter UI
alt User performs general search
User->>Frontend: Type in search box (e.g., "invoice")
Frontend->>Frontend: Update search query
Frontend->>Backend: GET /api/workflows/?pagination=...filters:{"search":"invoice"}
Backend-->>Frontend: Filtered workflows list
Frontend-->>User: Display matching workflows
end
alt User applies field filter
User->>Frontend: Select filter field (e.g., "Status")
Frontend->>Frontend: Show filter options from attribute metadata
User->>Frontend: Select filter value (e.g., "running")
Frontend->>Frontend: Update filter parameters
Frontend->>Backend: GET /api/workflows/?pagination=...filters:{"status":"running"}
Backend-->>Frontend: Filtered workflows list
Frontend-->>User: Display filtered workflows
end
alt User combines search + filter + sort
User->>Frontend: Apply search + filter + sort
Frontend->>Frontend: Combine all parameters
Frontend->>Backend: GET /api/workflows/?pagination=...filters:{"search":"invoice","status":"running"}...sort:desc
Backend-->>Frontend: Filtered, sorted workflows list
Frontend-->>User: Display results
end
User->>Frontend: Click column header (e.g., "Last Activity")
Frontend->>Frontend: Update sort parameters
Frontend->>Backend: GET /api/workflows/?pagination=...sort:desc
Backend-->>Frontend: Sorted workflows list
Frontend-->>User: Display sorted workflows
User->>Frontend: Click workflow row
Frontend->>Frontend: Navigate to /workflows/workflowId
Frontend-->>User: Show workflow detail page
```
## Customer Journey 2: Viewing Workflow Details
### User Goal
"I want to see everything about a specific workflow—its current state, what it's doing, and what it has accomplished."
### User Story
As a user, I want to open a workflow and see its complete information, including its configuration, current status, messages, and logs, all in one place.
### User Story Flow
```mermaid
sequenceDiagram
participant User
participant Frontend
participant Backend
User->>Frontend: Click workflow from list
Frontend->>Backend: GET /api/workflows/workflowId
Backend-->>Frontend: Workflow object
Frontend->>Backend: GET /api/attributes/ChatWorkflow
Backend-->>Frontend: Field definitions
Frontend->>Backend: GET /api/workflows/workflowId/messages
Backend-->>Frontend: Messages list
Frontend->>Backend: GET /api/workflows/workflowId/logs
Backend-->>Frontend: Logs list
Frontend->>Frontend: Generate UI from metadata
Frontend->>Frontend: Render workflow info section
Frontend->>Frontend: Render messages section
Frontend->>Frontend: Render logs section
Frontend-->>User: Display complete workflow view
```
### Frontend Requirements
> **📋 Complete frontend requirements for this journey are documented in [Workflow Page Requirements](./workflow-page-requirements.md#customer-journey-2-viewing-workflow-details)**
The frontend must implement a workflow detail page that displays workflow information, messages, and logs. All UI components are generated from backend metadata—see the requirements document for complete details.
```typescript
// Fetch workflow and attributes
const [workflow, attributes] = await Promise.all([
fetch(`/api/workflows/${workflowId}`).then(r => r.json()),
fetch('/api/attributes/ChatWorkflow').then(r => r.json())
]);
// Separate editable vs read-only fields
const readOnlyFields = attributes.attributes.filter(attr =>
attr.visible && !attr.editable
);
const editableFields = attributes.attributes.filter(attr =>
attr.visible && attr.editable
);
// Render information section
"Delete 'Workflow Name'?"
User->>Frontend: Cancel deletion
Frontend-->>User: Dialog closed, no action
User->>Frontend: Click "Delete" button again
Frontend->>Backend: GET /api/workflows/workflowId
Backend-->>Frontend: Workflow data
Frontend->>Frontend: Show confirmation dialog
User->>Frontend: Confirm deletion
Frontend->>Frontend: Optimistic update: Remove workflow from UI immediately
Frontend->>Backend: DELETE /api/workflows/workflowId
alt Permission denied (403)
Backend-->>Frontend: 403 Forbidden
Frontend->>Frontend: Revert optimistic update: Restore workflow in UI
Frontend-->>User: Show permission error
else Not found (404)
Backend-->>Frontend: 404 Not Found
Frontend->>Frontend: Revert optimistic update: Restore workflow in UI
Frontend-->>User: Show not found error
else Success (200)
Backend-->>Frontend: Success response
Frontend->>Frontend: Keep optimistic update (workflow already removed)
Frontend->>Frontend: Show success message
Frontend->>Frontend: Navigate to /workflows (if on detail page)
Frontend-->>User: Display workflow list (without deleted workflow)
end
```
### Frontend Requirements
> **📋 Complete frontend requirements for this journey are documented in [Workflow Page Requirements](./workflow-page-requirements.md#customer-journey-6-cleaning-up-workflows)**
The frontend must implement workflow deletion with confirmation dialogs and proper error handling. See the requirements document for complete details.
### Backend Routes Used
| Route | Purpose | When Used |
|-------|---------|-----------|
| `DELETE /api/workflows/{workflowId}` | Delete workflow | User confirmation |
### User Navigation Flow
```mermaid
stateDiagram-v2
[*] --> WorkflowDetailPage
WorkflowDetailPage --> ViewingDeleteButton: Hover delete button
ViewingDeleteButton --> ClickingDelete: Click delete
ClickingDelete --> FetchingWorkflowName: Fetch workflow name
FetchingWorkflowName --> ShowingConfirmation: Show dialog
ShowingConfirmation --> WorkflowDetailPage: Cancel
ShowingConfirmation --> ConfirmingDeletion: Confirm
ConfirmingDeletion --> DeletingWorkflow: API call
DeletingWorkflow --> WorkflowListPage: Success
DeletingWorkflow --> ShowingError: Error (403/404)
ShowingError --> WorkflowDetailPage: Dismiss error
note right of ShowingConfirmation
ConfirmationDialog Component:
- Workflow name
- Warning message
- Cancel/Confirm buttons
end note
note right of DeletingWorkflow
DELETE /api/workflows/{id}
- Backend deletes workflow
- Deletes all associated data
- Returns success response
end note
note right of WorkflowListPage
List automatically refreshes
Deleted workflow removed
Success message shown
end note
```
### Example User Flow
```
1. User is on workflow detail page
2. User clicks "Delete" button
3. Frontend shows confirmation dialog: "Are you sure you want to delete 'Workflow Name'? This action cannot be undone."
4. User confirms deletion
5. Frontend calls: DELETE /api/workflows/{workflowId}
6. Backend deletes workflow and all associated data
7. Frontend receives success response
8. Frontend shows success message: "Workflow deleted successfully"
9. Frontend redirects to /workflows (list page)
10. User sees updated workflow list (without deleted workflow)
```
### Implementation Pattern
```typescript
function WorkflowDetailPage({ workflowId }) {
const navigate = useNavigate();
const handleDelete = async () => {
// Fetch workflow name for confirmation
const workflow = await fetch(`/api/workflows/${workflowId}`).then(r => r.json());
if (!confirm(`Are you sure you want to delete "${workflow.name || 'this workflow'}"? This action cannot be undone.`)) {
return;
}
try {
const response = await fetch(`/api/workflows/${workflowId}`, {
method: 'DELETE'
});
if (response.status === 403) {
showError('You do not have permission to delete this workflow');
return;
}
if (response.status === 404) {
showError('Workflow not found');
return;
}
if (!response.ok) {
const error = await response.json();
showError(error.detail || 'Failed to delete workflow');
return;
}
showSuccess('Workflow deleted successfully');
navigate('/workflows');
} catch (error) {
showError('Failed to delete workflow');
}
};
return (
| handleSort(col.key)}> {col.label} | ))}
|---|
| {col.render(row[col.key])} | ))}