Re_Backend/SKIP_AND_ADD_APPROVER.md

19 KiB

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:

-- 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:

status ENUM('PENDING', 'IN_PROGRESS', 'APPROVED', 'REJECTED', 'SKIPPED')

Example Data:

-- 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:

{
  "reason": "Approver on vacation - deadline approaching"
}

Response:

{
  "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:

{
  "email": "john@example.com",
  "tatHours": 48,
  "level": 3
}

Response:

{
  "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:

// 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:

interface AddApproverModalProps {
  open: boolean;
  onClose: () => void;
  onConfirm: (email: string, tatHours: number, level: number) => Promise<void>;
  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:

{/* Skip Approver Button - Only for active levels */}
{(isActive || step.status === 'pending') && !isCompleted && !isRejected && (
  <Button 
    variant="outline" 
    size="sm"
    className="w-full border-orange-300 text-orange-700 hover:bg-orange-50"
    onClick={() => {
      const reason = prompt('Provide reason for skipping:');
      if (reason !== null) {
        handleSkipApprover(step.levelId, reason);
      }
    }}
  >
    <AlertCircle className="w-4 h-4 mr-2" />
    Skip This Approver
  </Button>
)}

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:

# Initiator skips Mike
POST /api/v1/workflows/REQ-2025-001/approvals/LEVEL-ID-2/skip
Body: { "reason": "Approver on extended leave" }

Backend Processing:

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:

# 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:

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:

┌───────────────────────────────────────────┐
 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:

// 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:

// 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

# 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

# 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

# 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:

  1. Re_Figma_Code/src/services/workflowApi.ts - API client methods
  2. Re_Figma_Code/src/components/participant/AddApproverModal/AddApproverModal.tsx - Enhanced modal
  3. 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! 🚀