# Simplified Workflow API - Postman Guide ## ✅ Updated Simplified Format The API has been updated to make workflow creation much simpler. You now only need to provide **email** and **tatHours** for approvers, and **email** for spectators. The backend automatically handles: - User lookup/creation from Okta/Azure AD - Fetching user details (name, department, designation) - Auto-generating level names based on designation/department - Auto-detecting final approver (last level) - Proper validation with clear error messages --- ## Authentication ### Login ```http POST {{baseUrl}}/auth/login Content-Type: application/json { "email": "your-email@example.com", "password": "your-password" } ``` **Response:** ```json { "success": true, "data": { "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "user": { "userId": "...", "email": "...", ... } } } ``` --- ## Create Workflow - Simplified Format ### Example 1: Simple Workflow (JSON) **POST** `{{baseUrl}}/workflows` **Headers:** ``` Content-Type: application/json Authorization: Bearer ``` **Body:** ```json { "templateType": "CUSTOM", "title": "Purchase Order Approval - Office Equipment", "description": "Approval needed for purchasing new office equipment including laptops and monitors. Total budget: $50,000", "priority": "STANDARD", "approvalLevels": [ { "email": "manager@royalenfield.com", "tatHours": 24 }, { "email": "director@royalenfield.com", "tatHours": 48 }, { "email": "cfo@royalenfield.com", "tatHours": 72 } ], "spectators": [ { "email": "hr@royalenfield.com" }, { "email": "finance@royalenfield.com" } ] } ``` --- ### Example 2: Express Priority with Final Approver Flag ```json { "templateType": "CUSTOM", "title": "Urgent: Server Infrastructure Upgrade", "description": "Critical server infrastructure upgrade required immediately", "priority": "EXPRESS", "approvalLevels": [ { "email": "it-manager@royalenfield.com", "tatHours": 8 }, { "email": "cto@royalenfield.com", "tatHours": 16, "isFinalApprover": true } ] } ``` --- ### Example 3: With Custom Level Names ```json { "templateType": "CUSTOM", "title": "Vendor Contract Approval", "description": "New vendor contract for manufacturing components", "priority": "STANDARD", "approvalLevels": [ { "email": "procurement@royalenfield.com", "tatHours": 24, "levelName": "Procurement Review" }, { "email": "legal@royalenfield.com", "tatHours": 48, "levelName": "Legal Compliance" }, { "email": "vp@royalenfield.com", "tatHours": 72, "levelName": "Executive Approval", "isFinalApprover": true } ] } ``` --- ### Example 4: Multipart with Files **POST** `{{baseUrl}}/workflows/multipart` **Headers:** ``` Authorization: Bearer ``` **Body (form-data):** | Key | Type | Value | |-----|------|-------| | `payload` | Text | `{"templateType":"CUSTOM","title":"Budget Request 2025","description":"Annual budget request","priority":"STANDARD","approvalLevels":[{"email":"finance-manager@royalenfield.com","tatHours":48},{"email":"cfo@royalenfield.com","tatHours":72}]}` | | `files` | File | Select PDF/Excel file(s) | | `category` | Text | `SUPPORTING` | --- ## Field Reference ### Required Fields | Field | Type | Description | Example | |-------|------|-------------|---------| | `templateType` | string | Workflow type | `"CUSTOM"` or `"TEMPLATE"` | | `title` | string | Request title (max 500 chars) | `"Purchase Order Approval"` | | `description` | string | Detailed description | `"Approval needed for..."` | | `priority` | string | Request priority | `"STANDARD"` or `"EXPRESS"` | | `approvalLevels` | array | List of approvers (min 1, max 10) | See below | ### Approval Level Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `email` | string | ✅ Yes | Approver's email address | | `tatHours` | number | ✅ Yes | Turn-around time in hours (positive number) | | `isFinalApprover` | boolean | ❌ No | Explicitly mark as final approver (auto-detected if last level) | | `levelName` | string | ❌ No | Custom level name (auto-generated if not provided) | **Auto-generated `levelName` logic:** - If approver has **designation**: `"{Designation} Approval"` (e.g., "Manager Approval") - If approver has **department**: `"{Department} Approval"` (e.g., "Finance Approval") - Otherwise: `"Level {N} Approval"` (e.g., "Level 1 Approval") ### Spectator Fields | Field | Type | Required | Description | |-------|------|----------|-------------| | `email` | string | ✅ Yes | Spectator's email address | --- ## Validation & Error Handling The backend automatically validates and provides clear error messages: ### ✅ Successful Response ```json { "success": true, "message": "Workflow created successfully", "data": { "requestId": "uuid", "requestNumber": "REQ-2025-12-0001", "title": "...", "status": "PENDING", ... } } ``` ### ❌ Error: Invalid Email ```json { "success": false, "error": "Failed to create workflow", "details": "Approver email 'invalid@example.com' not found in organization directory. Please verify the email address." } ``` ### ❌ Error: Duplicate Email ```json { "success": false, "error": "Failed to create workflow", "details": "Duplicate approver email found: manager@example.com. Each approver must have a unique email." } ``` ### ❌ Error: Invalid Initiator ```json { "success": false, "error": "Failed to create workflow", "details": "Invalid initiator: User with ID '...' not found. Please ensure you are logged in with a valid account." } ``` ### ❌ Error: Validation Failed ```json { "success": false, "error": "Validation failed", "details": "approvalLevels.0.email: Valid email is required; approvalLevels.0.tatHours: TAT hours must be positive" } ``` --- ## What Happens Behind the Scenes When you create a workflow, the backend: 1. **Validates Initiator**: Ensures the logged-in user exists 2. **Enriches Approval Levels**: - Searches for each approver in the local database - If not found, fetches from Okta/Azure AD - Creates user record if they exist in AD but not in DB - Extracts: `userId`, `displayName`, `designation`, `department` - Auto-generates `levelName` if not provided - Auto-detects `isFinalApprover` (last level = true) 3. **Enriches Spectators**: - Same lookup/creation process as approvers - Sets default permissions (view + comment, no download) 4. **Creates Workflow**: - Saves workflow request - Creates approval levels - Creates participants - Sends notifications - Logs activity --- ## Migration from Old Format ### ❌ Old Format (No Longer Required) ```json { "approvalLevels": [ { "levelNumber": 1, "levelName": "Manager Approval", "approverId": "uuid-123", "approverEmail": "manager@example.com", "approverName": "John Doe", "tatHours": 24, "isFinalApprover": false } ] } ``` ### ✅ New Simplified Format ```json { "approvalLevels": [ { "email": "manager@example.com", "tatHours": 24 } ] } ``` **The backend handles everything else automatically!** --- ## Tips & Best Practices 1. **Use Valid Email Addresses**: Ensure all approver/spectator emails exist in your Okta/Azure AD 2. **TAT Hours**: Set realistic turn-around times based on priority: - STANDARD: 24-72 hours per level - EXPRESS: 8-24 hours per level 3. **Final Approver**: Last level is automatically marked as final approver (you can override with `isFinalApprover: true` on any level) 4. **Level Names**: Let the system auto-generate based on designation/department, or provide custom names 5. **Spectators**: Add users who need visibility but not approval authority 6. **Documents**: Use `/multipart` endpoint for file uploads --- ## Testing in Postman 1. **Set Environment Variables**: - `baseUrl`: `http://localhost:5000/api/v1` - `token`: Your auth token from login 2. **Login First**: - Call `POST /auth/login` - Copy the `token` from response - Set as environment variable 3. **Create Workflow**: - Use simplified format - Only provide email + tatHours - Backend handles the rest 4. **Check Response**: - Verify `requestNumber` is generated - Check `approvalLevels` are enriched with user data - Confirm `participants` includes spectators --- ## Add Approver/Spectator After Request Creation These endpoints allow adding approvers or spectators to an existing request. They follow the same simplified pattern - just provide email, and the backend handles user lookup/creation. ### Add Approver at Specific Level **POST** `{{baseUrl}}/workflows/:requestId/approvers/at-level` **Headers:** ``` Authorization: Bearer Content-Type: application/json ``` **Body:** ```json { "email": "newapprover@royalenfield.com", "tatHours": 24, "level": 2 } ``` **What Happens:** - ✅ Finds user by email in DB, or syncs from Okta/AD if not found - ✅ Auto-generates levelName based on designation/department - ✅ Shifts existing levels if needed - ✅ Updates final approver flag - ✅ Sends notification to new approver - ✅ Logs activity **Response:** ```json { "success": true, "message": "Approver added successfully", "data": { "levelId": "uuid", "levelNumber": 2, "levelName": "Manager Approval", "approverId": "uuid", "approverEmail": "newapprover@royalenfield.com", "approverName": "John Doe", "tatHours": 24, "status": "PENDING" } } ``` --- ### Add Simple Approver (General) **POST** `{{baseUrl}}/workflows/:requestId/participants/approver` **Headers:** ``` Authorization: Bearer Content-Type: application/json ``` **Body:** ```json { "email": "approver@royalenfield.com" } ``` *Note: This adds them as a general approver participant, not at a specific level.* --- ### Add Spectator **POST** `{{baseUrl}}/workflows/:requestId/participants/spectator` **Headers:** ``` Authorization: Bearer Content-Type: application/json ``` **Body:** ```json { "email": "spectator@royalenfield.com" } ``` **What Happens:** - ✅ Finds user by email in DB, or syncs from Okta/AD if not found - ✅ Sets spectator permissions (view + comment, no download) - ✅ Sends notification to new spectator - ✅ Logs activity **Response:** ```json { "success": true, "data": { "participantId": "uuid", "userId": "uuid", "userEmail": "spectator@royalenfield.com", "userName": "Jane Doe", "participantType": "SPECTATOR", "canComment": true, "canViewDocuments": true, "canDownloadDocuments": false } } ``` --- ### Error Handling for Add Operations **❌ User Not Found in AD:** ```json { "success": false, "error": "Failed to add approver", "details": "Approver email 'invalid@example.com' not found in organization directory. Please verify the email address." } ``` **❌ User Already a Participant:** ```json { "success": false, "error": "Failed to add spectator", "details": "User is already a participant in this request" } ``` **❌ Invalid Level:** ```json { "success": false, "error": "Failed to add approver at level", "details": "Cannot add approver at level 1 - level has already been completed" } ``` --- ## Complete Flow Example ### 1. Login ```bash POST /api/v1/auth/login Body: { "email": "user@example.com", "password": "pass" } ``` ### 2. Create Workflow (Simplified) ```bash POST /api/v1/workflows Body: { "templateType": "CUSTOM", "title": "Purchase Order", "description": "Office equipment", "priority": "STANDARD", "approvalLevels": [ { "email": "manager@example.com", "tatHours": 24 } ] } ``` ### 3. Add Additional Approver (After Creation) ```bash POST /api/v1/workflows/:requestId/approvers/at-level Body: { "email": "director@example.com", "tatHours": 48, "level": 2 } ``` ### 4. Add Spectator ```bash POST /api/v1/workflows/:requestId/participants/spectator Body: { "email": "hr@example.com" } ``` --- ## Need Help? If you encounter any issues: 1. Check the error message - it will tell you exactly what's wrong 2. Verify emails exist in your organization directory 3. Ensure you're logged in with a valid token 4. Check backend logs for detailed error information