# Skip Approver & Dynamic Approver Addition ## Overview This feature allows initiators and approvers to manage approval workflows dynamically when approvers are unavailable or additional approval is needed. ### **Key Features:** 1. **Skip Approver** - Skip non-responding approvers and move to next level 2. **Add Approver at Specific Level** - Insert new approver at any position 3. **Automatic Level Shifting** - Existing approvers are automatically renumbered 4. **Smart Validation** - Cannot modify completed levels (approved/rejected/skipped) 5. **TAT Management** - New approvers get their own TAT, jobs scheduled automatically --- ## Use Cases ### **Use Case 1: Approver on Leave** **Scenario:** ``` Level 1: Sarah (Approved) ✅ Level 2: Mike (Pending) ⏳ ← On vacation, not responding Level 3: Lisa (Waiting) ⏸️ ``` **Solution:** ``` Initiator clicks "Skip This Approver" on Level 2 → Mike is marked as SKIPPED → Level 3 (Lisa) becomes active → Lisa receives notification → TAT jobs cancelled for Mike, scheduled for Lisa ``` **Result:** ``` Level 1: Sarah (Approved) ✅ Level 2: Mike (Skipped) ⏭️ ← Skipped Level 3: Lisa (In Review) ⏳ ← Now active ``` --- ### **Use Case 2: Add Additional Reviewer** **Scenario:** ``` Level 1: Sarah (Approved) ✅ Level 2: Mike (In Review) ⏳ Level 3: Lisa (Waiting) ⏸️ ``` **Need:** Add Finance Manager (John) between Mike and Lisa **Solution:** ``` Click "Add Approver" → Email: john@example.com → TAT: 48 hours → Level: 3 (between Mike and Lisa) → Submit ``` **Result:** ``` Level 1: Sarah (Approved) ✅ Level 2: Mike (In Review) ⏳ ← Still at level 2 Level 3: John (Waiting) ⏸️ ← NEW! Inserted here Level 4: Lisa (Waiting) ⏸️ ← Shifted from 3 to 4 ``` --- ### **Use Case 3: Replace Skipped Approver** **Scenario:** ``` Level 1: Sarah (Approved) ✅ Level 2: Mike (Skipped) ⏭️ Level 3: Lisa (In Review) ⏳ ``` **Need:** Add replacement for Mike at level 2 **Solution:** ``` Click "Add Approver" → Email: john@example.com → TAT: 24 hours → Level: 2 (Mike's old position) → Submit ``` **Result:** ``` Level 1: Sarah (Approved) ✅ Level 2: John (Waiting) ⏸️ ← NEW! Inserted at level 2 Level 3: Mike (Skipped) ⏭️ ← Shifted from 2 to 3 Level 4: Lisa (In Review) ⏳ ← Shifted from 3 to 4 ``` --- ## Database Schema ### **New Fields in `approval_levels` Table:** ```sql -- Migration: add_is_skipped_to_approval_levels.sql ALTER TABLE approval_levels ADD COLUMN is_skipped BOOLEAN DEFAULT FALSE, ADD COLUMN skipped_at TIMESTAMP, ADD COLUMN skipped_by UUID REFERENCES users(user_id), ADD COLUMN skip_reason TEXT; ``` ### **Status Enum Update:** Already includes `SKIPPED` status: ```sql status ENUM('PENDING', 'IN_PROGRESS', 'APPROVED', 'REJECTED', 'SKIPPED') ``` ### **Example Data:** ```sql -- Level 2 was skipped SELECT level_number, approver_name, status, is_skipped, skipped_at, skip_reason FROM approval_levels WHERE request_id = 'xxx'; -- Results: -- 1 | Sarah | APPROVED | FALSE | NULL | NULL -- 2 | Mike | SKIPPED | TRUE | 2025-11-05 | On vacation -- 3 | Lisa | PENDING | FALSE | NULL | NULL ``` --- ## API Endpoints ### **1. Skip Approver** **Endpoint:** ``` POST /api/v1/workflows/:id/approvals/:levelId/skip ``` **Request Body:** ```json { "reason": "Approver on vacation - deadline approaching" } ``` **Response:** ```json { "success": true, "message": "Approver skipped successfully", "data": { "levelId": "...", "levelNumber": 2, "status": "SKIPPED", "skippedAt": "2025-11-05T10:30:00Z" } } ``` **Logic:** 1. ✅ Mark level as `SKIPPED` 2. ✅ Cancel TAT jobs for skipped level 3. ✅ Activate next level (move to level+1) 4. ✅ Schedule TAT jobs for next level 5. ✅ Notify next approver 6. ✅ Log activity **Validation:** - ❌ Cannot skip already approved/rejected/skipped levels - ❌ Cannot skip future levels (only current level) - ✅ Only INITIATOR or APPROVER can skip --- ### **2. Add Approver at Specific Level** **Endpoint:** ``` POST /api/v1/workflows/:id/approvers/at-level ``` **Request Body:** ```json { "email": "john@example.com", "tatHours": 48, "level": 3 } ``` **Response:** ```json { "success": true, "message": "Approver added successfully", "data": { "levelId": "...", "levelNumber": 3, "approverName": "John Doe", "tatHours": 48, "status": "PENDING" } } ``` **Logic:** 1. ✅ Find user by email 2. ✅ Validate target level (must be after completed levels) 3. ✅ Shift existing levels at and after target level (+1) 4. ✅ Create new approval level at target position 5. ✅ Add as participant (APPROVER type) 6. ✅ If new level is current level, schedule TAT jobs 7. ✅ Notify new approver 8. ✅ Log activity **Validation:** - ❌ User must exist in system - ❌ User cannot be existing participant - ❌ Level must be after completed levels (approved/rejected/skipped) - ✅ Automatic level shifting for existing approvers --- ## Level Shifting Logic ### **Example: Add at Level 3** **Before:** ``` Level 1: Sarah (Approved) ✅ Level 2: Mike (In Review) ⏳ Level 3: Lisa (Waiting) ⏸️ Level 4: Tom (Waiting) ⏸️ ``` **Action:** ``` Add John at Level 3 with 48h TAT ``` **Backend Processing:** ```typescript // Step 1: Get levels to shift (levelNumber >= 3) levelsToShift = [Lisa (Level 3), Tom (Level 4)] // Step 2: Shift each level Lisa: Level 3 → Level 4 Tom: Level 4 → Level 5 // Step 3: Insert new approver John: Create at Level 3 // Step 4: Update workflow.totalLevels totalLevels: 4 → 5 ``` **After:** ``` Level 1: Sarah (Approved) ✅ Level 2: Mike (In Review) ⏳ Level 3: John (Waiting) ⏸️ ← NEW! Level 4: Lisa (Waiting) ⏸️ ← Shifted from 3 Level 5: Tom (Waiting) ⏸️ ← Shifted from 4 ``` --- ## Frontend Implementation ### **AddApproverModal Enhancements:** **New Props:** ```typescript interface AddApproverModalProps { open: boolean; onClose: () => void; onConfirm: (email: string, tatHours: number, level: number) => Promise; currentLevels?: ApprovalLevelInfo[]; // ✅ NEW! } interface ApprovalLevelInfo { levelNumber: number; approverName: string; status: string; tatHours: number; } ``` **UI Components:** 1. **Current Levels Display** - Shows all existing levels with status badges 2. **Level Selector** - Dropdown with available levels (after completed) 3. **TAT Hours Input** - Number input for TAT (1-720 hours) 4. **Email Search** - Existing @ mention search **Example Modal:** ``` ┌─────────────────────────────────────────────────┐ │ Add Approver │ ├─────────────────────────────────────────────────┤ │ Current Approval Levels │ │ ┌─────────────────────────────────────────────┐ │ │ │ [1] Sarah 50h TAT [✓] approved │ │ │ │ [2] Mike 24h TAT [⏳] pending │ │ │ │ [3] Lisa 36h TAT [⏸] waiting │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ Approval Level * │ │ [Select: Level 2 (will shift existing Level 2)] │ │ │ │ TAT (Turn Around Time) * │ │ [48] hours │ │ │ │ Email Address * │ │ [@john or john@example.com] │ │ │ │ [Cancel] [Add at Level 2] │ └─────────────────────────────────────────────────┘ ``` --- ### **RequestDetail Skip Button:** Added to Workflow tab for each pending/in-review level: ```tsx {/* Skip Approver Button - Only for active levels */} {(isActive || step.status === 'pending') && !isCompleted && !isRejected && ( )} ``` --- ## Validation Rules ### **Skip Approver Validation:** | Rule | Validation | Error Message | |------|-----------|---------------| | Already completed | ❌ Cannot skip APPROVED level | "Cannot skip approver - level is already APPROVED" | | Already rejected | ❌ Cannot skip REJECTED level | "Cannot skip approver - level is already REJECTED" | | Already skipped | ❌ Cannot skip SKIPPED level | "Cannot skip approver - level is already SKIPPED" | | Future level | ❌ Cannot skip level > currentLevel | "Cannot skip future approval levels" | | Authorization | ✅ Only INITIATOR or APPROVER | 403 Forbidden | --- ### **Add Approver Validation:** | Rule | Validation | Error Message | |------|-----------|---------------| | User exists | ✅ User must exist in system | "User not found with this email" | | Already participant | ❌ Cannot add existing participant | "User is already a participant" | | Level range | ❌ Level must be ≥ (completed levels + 1) | "Cannot add at level X. Minimum is Y" | | TAT hours | ✅ 1 ≤ hours ≤ 720 | "TAT hours must be between 1 and 720" | | Email format | ✅ Valid email format | "Please enter a valid email" | | Authorization | ✅ Only INITIATOR or APPROVER | 403 Forbidden | --- ## Examples ### **Example 1: Skip Current Approver** **Initial State:** ``` Request: REQ-2025-001 Current Level: 2 Level 1: Sarah (APPROVED) ✅ Level 2: Mike (IN_PROGRESS) ⏳ ← Taking too long Level 3: Lisa (PENDING) ⏸️ ``` **Action:** ```bash # Initiator skips Mike POST /api/v1/workflows/REQ-2025-001/approvals/LEVEL-ID-2/skip Body: { "reason": "Approver on extended leave" } ``` **Backend Processing:** ```typescript 1. Get Level 2 (Mike) → Status: IN_PROGRESS ✅ 2. Validate: Not already completed ✅ 3. Update Level 2: - status: 'SKIPPED' - is_skipped: TRUE - skipped_at: NOW() - skipped_by: initiator userId - skip_reason: "Approver on extended leave" 4. Cancel TAT jobs for Level 2 5. Get Level 3 (Lisa) 6. Activate Level 3: - status: 'IN_PROGRESS' - levelStartTime: NOW() - tatStartTime: NOW() 7. Schedule TAT jobs for Level 3 8. Update workflow.currentLevel = 3 9. Notify Lisa 10. Log activity: "Level 2 approver (Mike) was skipped" ``` **Final State:** ``` Request: REQ-2025-001 Current Level: 3 Level 1: Sarah (APPROVED) ✅ Level 2: Mike (SKIPPED) ⏭️ ← Skipped! Level 3: Lisa (IN_PROGRESS) ⏳ ← Now active! ``` --- ### **Example 2: Add Approver Between Levels** **Initial State:** ``` Request: REQ-2025-001 Current Level: 2 Level 1: Sarah (APPROVED) ✅ Level 2: Mike (IN_PROGRESS) ⏳ Level 3: Lisa (PENDING) ⏸️ ``` **Action:** ```bash # Add John at Level 3 (between Mike and Lisa) POST /api/v1/workflows/REQ-2025-001/approvers/at-level Body: { "email": "john@example.com", "tatHours": 48, "level": 3 } ``` **Backend Processing:** ```typescript 1. Find user: john@example.com ✅ 2. Validate: Not existing participant ✅ 3. Validate: Level 3 ≥ minLevel (2) ✅ 4. Get levels to shift: [Lisa (Level 3)] 5. Shift Lisa: - Level 3 → Level 4 - levelName: "Level 4" 6. Create new Level 3: - levelNumber: 3 - approverId: John's userId - approverEmail: john@example.com - tatHours: 48 - status: PENDING (not current level) 7. Update workflow.totalLevels: 3 → 4 8. Add John to participants (APPROVER type) 9. Notify John 10. Log activity: "John added as approver at Level 3 with TAT of 48 hours" ``` **Final State:** ``` Request: REQ-2025-001 Current Level: 2 Level 1: Sarah (APPROVED) ✅ Level 2: Mike (IN_PROGRESS) ⏳ ← Still working Level 3: John (PENDING) ⏸️ ← NEW! Will review after Mike Level 4: Lisa (PENDING) ⏸️ ← Shifted from 3 to 4 ``` --- ### **Example 3: Complex Scenario - Skip and Add** **Initial State:** ``` Level 1: Sarah (APPROVED) ✅ Level 2: Mike (APPROVED) ✅ Level 3: David (IN_PROGRESS) ⏳ ← Taking too long Level 4: Lisa (PENDING) ⏸️ Level 5: Tom (PENDING) ⏸️ ``` **Action 1: Skip David** ``` Result: Level 1: Sarah (APPROVED) ✅ Level 2: Mike (APPROVED) ✅ Level 3: David (SKIPPED) ⏭️ Level 4: Lisa (IN_PROGRESS) ⏳ ← Now active Level 5: Tom (PENDING) ⏸️ ``` **Action 2: Add John at Level 4 (before Tom)** ``` Result: Level 1: Sarah (APPROVED) ✅ Level 2: Mike (APPROVED) ✅ Level 3: David (SKIPPED) ⏭️ Level 4: Lisa (IN_PROGRESS) ⏳ Level 5: John (PENDING) ⏸️ ← NEW! Level 6: Tom (PENDING) ⏸️ ← Shifted ``` --- ## UI/UX ### **RequestDetail - Workflow Tab:** **Skip Button Visibility:** - ✅ Shows for levels with status: `pending` or `in-review` - ❌ Hidden for `approved`, `rejected`, `skipped`, or `waiting` - ✅ Orange/amber styling to indicate caution - ✅ Requires reason via prompt **Button Appearance:** ```tsx ┌───────────────────────────────────────────┐ │ Level 2: Mike (In Review) │ │ TAT: 24h • Elapsed: 15h │ │ │ │ [⚠ Skip This Approver] │ │ Skip if approver is unavailable... │ └───────────────────────────────────────────┘ ``` --- ### **AddApproverModal - Enhanced UI:** **Sections:** 1. **Current Levels** - Scrollable list showing all existing levels with status 2. **Level Selector** - Dropdown with available levels (grayed out completed levels) 3. **TAT Input** - Hours input with validation (1-720) 4. **Email Search** - @ mention search (existing) **Features:** - ✅ Auto-selects first available level - ✅ Shows which existing level will be shifted - ✅ Visual indicators for completed vs pending levels - ✅ Prevents selecting invalid levels - ✅ Real-time validation --- ## Activity Log Examples ### **Skip Approver Log:** ``` Action: Approver Skipped Details: Level 2 approver (Mike Johnson) was skipped by Sarah Smith. Reason: Approver on extended leave Timestamp: 2025-11-05 10:30:00 User: Sarah Smith (Initiator) ``` ### **Add Approver Log:** ``` Action: Added new approver Details: John Doe (john@example.com) has been added as approver at Level 3 with TAT of 48 hours by Sarah Smith Timestamp: 2025-11-05 11:15:00 User: Sarah Smith (Initiator) ``` --- ## Notifications ### **Skip Approver Notifications:** **To Next Approver:** ``` Title: Request Escalated Body: Previous approver was skipped. Request REQ-2025-001 is now awaiting your approval. ``` --- ### **Add Approver Notifications:** **To New Approver:** ``` Title: New Request Assignment Body: You have been added as Level 3 approver to request REQ-2025-001: New Office Location Approval ``` --- ## TAT Handling ### **Skip Approver:** ```typescript // Skipped level's TAT jobs are cancelled await tatSchedulerService.cancelTatJobs(requestId, skippedLevelId); // Next level's TAT jobs are scheduled await tatSchedulerService.scheduleTatJobs( requestId, nextLevelId, nextApproverId, nextLevelTatHours, now, workflowPriority ); ``` ### **Add Approver:** ```typescript // If new approver is at current level, schedule TAT immediately if (newLevel === currentLevel) { await tatSchedulerService.scheduleTatJobs( requestId, newLevelId, newApproverId, tatHours, now, workflowPriority ); } // Otherwise, jobs will be scheduled when level becomes active ``` --- ## Testing Scenarios ### **Test 1: Skip Current Approver** ```bash # 1. Create workflow with 3 approvers # 2. Level 1 approves # 3. Level 2 receives notification # 4. Level 2 doesn't respond for extended time # 5. Initiator clicks "Skip This Approver" # 6. Provide reason: "On vacation" # 7. Verify: # ✅ Level 2 status = SKIPPED # ✅ Level 3 status = IN_PROGRESS # ✅ Level 3 receives notification # ✅ TAT jobs scheduled for Level 3 # ✅ Activity logged ``` ### **Test 2: Add Approver at Middle Level** ```bash # 1. Workflow has 3 levels # 2. Level 1 approved # 3. Click "Add Approver" # 4. Select Level 2 (between current levels) # 5. Enter TAT: 48 # 6. Enter email: new@example.com # 7. Submit # 8. Verify: # ✅ Old Level 2 becomes Level 3 # ✅ Old Level 3 becomes Level 4 # ✅ New approver at Level 2 # ✅ totalLevels increased by 1 # ✅ New approver receives notification ``` ### **Test 3: Cannot Add Before Completed Level** ```bash # 1. Workflow: Level 1 (Approved), Level 2 (Pending) # 2. Try to add at Level 1 # 3. Modal shows: "Minimum allowed level is 2" # 4. Level 1 is grayed out in selector # 5. Cannot submit ✅ ``` --- ## Files Modified ### **Backend:** 1. `Re_Backend/src/migrations/add_is_skipped_to_approval_levels.sql` - Database migration 2. `Re_Backend/src/services/workflow.service.ts` - Skip and add approver logic 3. `Re_Backend/src/routes/workflow.routes.ts` - API endpoints ### **Frontend:** 4. `Re_Figma_Code/src/services/workflowApi.ts` - API client methods 5. `Re_Figma_Code/src/components/participant/AddApproverModal/AddApproverModal.tsx` - Enhanced modal 6. `Re_Figma_Code/src/pages/RequestDetail/RequestDetail.tsx` - Skip button and handlers --- ## Summary | Feature | Description | Benefit | |---------|-------------|---------| | **Skip Approver** | Mark approver as skipped, move to next | Handle unavailable approvers | | **Add at Level** | Insert approver at specific position | Flexible workflow modification | | **Auto Shifting** | Existing levels automatically renumbered | No manual level management | | **Smart Validation** | Cannot modify completed levels | Data integrity | | **TAT Management** | Jobs cancelled/scheduled automatically | Accurate time tracking | | **Activity Logging** | All actions tracked in audit trail | Full transparency | | **Notifications** | Affected users notified automatically | Keep everyone informed | --- ## Benefits 1. ✅ **Flexibility** - Handle real-world workflow changes 2. ✅ **No Bottlenecks** - Skip unavailable approvers 3. ✅ **Dynamic Addition** - Add approvers mid-workflow 4. ✅ **Data Integrity** - Cannot modify completed levels 5. ✅ **Audit Trail** - Full history of all changes 6. ✅ **Automatic Notifications** - All affected parties notified 7. ✅ **TAT Accuracy** - Time tracking updated correctly 8. ✅ **User-Friendly** - Intuitive UI with clear feedback The approval workflow is now fully dynamic and can adapt to changing business needs! 🚀