# Approval Workflow Architecture & Module Relationships

## 📋 **Overview**

Sistem approval workflow di MEDOLS menggunakan arsitektur multi-module yang saling terintegrasi untuk mengelola proses persetujuan artikel secara dinamis. Setiap module memiliki peran spesifik dalam alur approval yang kompleks.

## 🏗️ **Module Architecture**

### **1. Core Workflow Modules**

#### **`approval_workflows`** - Master Workflow Definition
- **Purpose**: Mendefinisikan template workflow approval
- **Key Fields**:
  - `id`: Primary key
  - `name`: Nama workflow (e.g., "Standard Approval", "Fast Track")
  - `description`: Deskripsi workflow
  - `is_default`: Apakah workflow default untuk client
  - `is_active`: Status aktif workflow
  - `client_id`: Client yang memiliki workflow

#### **`approval_workflow_steps`** - Workflow Steps Definition
- **Purpose**: Mendefinisikan step-step dalam workflow
- **Key Fields**:
  - `id`: Primary key
  - `workflow_id`: Foreign key ke `approval_workflows`
  - `step_order`: Urutan step (1, 2, 3, dst.)
  - `step_name`: Nama step (e.g., "Level 2 Review", "Level 1 Final Approval")
  - `required_user_level_id`: User level yang harus approve step ini
  - `is_required`: Apakah step wajib atau optional

### **2. Execution Modules**

#### **`article_approval_flows`** - Active Approval Instances
- **Purpose**: Instance aktif dari workflow yang sedang berjalan
- **Key Fields**:
  - `id`: Primary key
  - `article_id`: Foreign key ke `articles`
  - `workflow_id`: Foreign key ke `approval_workflows`
  - `current_step`: Step saat ini yang sedang menunggu approval
  - `status_id`: Status (1=pending, 2=approved, 3=rejected, 4=revision_requested)
  - `submitted_by_id`: User yang submit artikel
  - `submitted_at`: Waktu submit
  - `completed_at`: Waktu selesai (jika approved/rejected)

#### **`article_approval_step_logs`** - Step Execution History
- **Purpose**: Log setiap step yang telah dieksekusi
- **Key Fields**:
  - `id`: Primary key
  - `approval_flow_id`: Foreign key ke `article_approval_flows`
  - `step_order`: Urutan step yang dieksekusi
  - `step_name`: Nama step
  - `approved_by_id`: User yang approve step ini
  - `action`: Aksi yang dilakukan (approve, reject, auto_skip)
  - `message`: Pesan dari approver
  - `processed_at`: Waktu eksekusi

### **3. Legacy & Configuration Modules**

#### **`article_approvals`** - Legacy Approval System
- **Purpose**: Sistem approval legacy untuk backward compatibility
- **Key Fields**:
  - `id`: Primary key
  - `article_id`: Foreign key ke `articles`
  - `approval_by`: User yang approve
  - `status_id`: Status approval
  - `approval_at_level`: Level yang approve
  - `message`: Pesan approval

#### **`client_approval_settings`** - Client Configuration
- **Purpose**: Konfigurasi approval untuk setiap client
- **Key Fields**:
  - `id`: Primary key
  - `client_id`: Foreign key ke `clients`
  - `workflow_id`: Workflow default untuk client
  - `auto_approve_levels`: Level yang auto-approve
  - `notification_settings`: Konfigurasi notifikasi

## 🔄 **Approval Workflow Process Flow**

### **Phase 1: Setup & Configuration**

```mermaid
graph TD
    A[Client Setup] --> B[Create Approval Workflow]
    B --> C[Define Workflow Steps]
    C --> D[Set Required User Levels]
    D --> E[Configure Client Settings]
    E --> F[Activate Workflow]
```

**Steps:**
1. **Client Registration**: Client baru dibuat di sistem
2. **Workflow Creation**: Admin membuat workflow approval
3. **Step Definition**: Mendefinisikan step-step dengan user level requirement
4. **Client Configuration**: Set workflow default untuk client

### **Phase 2: Article Submission**

```mermaid
graph TD
    A[User Creates Article] --> B{User Level Requires Approval?}
    B -->|Yes| C[Create Article Approval Flow]
    B -->|No| D[Auto Publish]
    C --> E[Set Current Step = 1]
    E --> F[Status = Pending]
    F --> G[Create Legacy Approval Record]
    G --> H[Notify Approvers]
```

**Database Changes:**
- `articles`: `workflow_id`, `current_approval_step = 1`, `status_id = 1`
- `article_approval_flows`: New record dengan `current_step = 1`
- `article_approvals`: Legacy record untuk backward compatibility

### **Phase 3: Step-by-Step Approval**

```mermaid
graph TD
    A[Approver Reviews Article] --> B{Approve or Reject?}
    B -->|Approve| C[Create Step Log]
    B -->|Reject| D[Update Status to Rejected]
    C --> E{More Steps?}
    E -->|Yes| F[Move to Next Step]
    E -->|No| G[Complete Approval]
    F --> H[Update Current Step]
    H --> I[Notify Next Approver]
    G --> J[Update Article Status to Approved]
    D --> K[Notify Submitter]
```

**Database Changes per Step:**
- `article_approval_step_logs`: New log record
- `article_approval_flows`: Update `current_step` dan `status_id`
- `articles`: Update `current_approval_step`

### **Phase 4: Completion**

```mermaid
graph TD
    A[All Steps Approved] --> B[Update Final Status]
    B --> C[Set Completed At]
    C --> D[Publish Article]
    D --> E[Send Notifications]
    E --> F[Update Analytics]
```

## 📊 **Module Relationships Diagram**

```mermaid
erDiagram
    CLIENTS ||--o{ APPROVAL_WORKFLOWS : "has"
    CLIENTS ||--o{ CLIENT_APPROVAL_SETTINGS : "configures"
    
    APPROVAL_WORKFLOWS ||--o{ APPROVAL_WORKFLOW_STEPS : "contains"
    APPROVAL_WORKFLOWS ||--o{ ARTICLE_APPROVAL_FLOWS : "instantiates"
    
    ARTICLES ||--o{ ARTICLE_APPROVAL_FLOWS : "has"
    ARTICLES ||--o{ ARTICLE_APPROVALS : "has_legacy"
    
    ARTICLE_APPROVAL_FLOWS ||--o{ ARTICLE_APPROVAL_STEP_LOGS : "logs"
    ARTICLE_APPROVAL_FLOWS }o--|| APPROVAL_WORKFLOWS : "uses"
    
    USERS ||--o{ ARTICLE_APPROVAL_FLOWS : "submits"
    USERS ||--o{ ARTICLE_APPROVAL_STEP_LOGS : "approves"
    
    USER_LEVELS ||--o{ APPROVAL_WORKFLOW_STEPS : "requires"
    USER_LEVELS ||--o{ USERS : "defines"
```

## 🔧 **Technical Implementation Details**

### **1. Dynamic Workflow Assignment**

```go
// Ketika artikel dibuat
if userLevel.RequiresApproval {
    // 1. Cari workflow default untuk client
    workflow := getDefaultWorkflow(clientId)
    
    // 2. Buat approval flow instance
    approvalFlow := ArticleApprovalFlows{
        ArticleId: articleId,
        WorkflowId: workflow.ID,
        CurrentStep: 1,
        StatusId: 1, // pending
    }
    
    // 3. Buat legacy record
    legacyApproval := ArticleApprovals{
        ArticleId: articleId,
        ApprovalAtLevel: nextApprovalLevel,
    }
}
```

### **2. Step Progression Logic**

```go
// Ketika step di-approve
func ApproveStep(flowId, approvedById, message) {
    // 1. Log step yang di-approve
    stepLog := ArticleApprovalStepLogs{
        ApprovalFlowId: flowId,
        StepOrder: currentStep,
        ApprovedById: approvedById,
        Action: "approve",
    }
    
    // 2. Cek apakah ada next step
    nextStep := getNextStep(workflowId, currentStep)
    
    if nextStep != nil {
        // 3. Pindah ke step berikutnya
        updateCurrentStep(flowId, nextStep.StepOrder)
    } else {
        // 4. Complete approval
        completeApproval(flowId)
    }
}
```

### **3. User Level Hierarchy**

```go
// Level hierarchy (level_number field)
Level 1: Highest Authority (POLDAS)
Level 2: Mid Authority (POLDAS)  
Level 3: Lower Authority (POLRES)

// Approval flow
Level 3 → Level 2 → Level 1 → Approved
```

## 📈 **Data Flow Examples**

### **Example 1: Standard 3-Step Approval**

```
1. User Level 3 creates article
   ├── article_approval_flows: {current_step: 1, status: pending}
   ├── article_approvals: {approval_at_level: 2}
   └── articles: {current_approval_step: 1, status: pending}

2. User Level 2 approves
   ├── article_approval_step_logs: {step_order: 1, action: approve}
   ├── article_approval_flows: {current_step: 2, status: pending}
   └── articles: {current_approval_step: 2}

3. User Level 1 approves
   ├── article_approval_step_logs: {step_order: 2, action: approve}
   ├── article_approval_flows: {status: approved, completed_at: now}
   └── articles: {status: approved, published: true}
```

### **Example 2: Auto-Skip Logic**

```
1. User Level 1 creates article (highest authority)
   ├── Check: Can skip all steps?
   ├── article_approval_flows: {status: approved, completed_at: now}
   └── articles: {status: approved, published: true}
```

## 🚀 **API Endpoints Flow**

### **Article Creation**
```
POST /api/articles
├── Check user level
├── Create article
├── Assign workflow (if needed)
├── Create approval flow
└── Return article data
```

### **Approval Process**
```
PUT /api/article-approval-flows/{id}/approve
├── Validate approver permissions
├── Create step log
├── Check for next step
├── Update flow status
└── Send notifications
```

### **Status Checking**
```
GET /api/articles/{id}/approval-status
├── Get current flow
├── Get step logs
├── Get next step info
└── Return status data
```

## 🔍 **Debugging & Monitoring**

### **Key Queries for Monitoring**

```sql
-- Active approval flows
SELECT aaf.*, a.title, ul.name as current_approver_level
FROM article_approval_flows aaf
JOIN articles a ON aaf.article_id = a.id
JOIN approval_workflow_steps aws ON aaf.workflow_id = aws.workflow_id 
    AND aaf.current_step = aws.step_order
JOIN user_levels ul ON aws.required_user_level_id = ul.id
WHERE aaf.status_id = 1;

-- Approval history
SELECT aasl.*, u.name as approver_name, ul.name as level_name
FROM article_approval_step_logs aasl
JOIN users u ON aasl.approved_by_id = u.id
JOIN user_levels ul ON aasl.user_level_id = ul.id
WHERE aasl.approval_flow_id = ?;
```

## ⚠️ **Common Issues & Solutions**

### **Issue 1: Step Not Progressing**
- **Cause**: `getUserLevelId` returning wrong level
- **Solution**: Fix user level mapping logic

### **Issue 2: Wrong Approval Level**
- **Cause**: `findNextApprovalLevel` logic incorrect
- **Solution**: Fix level hierarchy comparison

### **Issue 3: Missing Step Logs**
- **Cause**: Step log not created during approval
- **Solution**: Ensure step log creation in `ApproveStep`

## 📝 **Best Practices**

1. **Always create step logs** for audit trail
2. **Validate user permissions** before approval
3. **Use transactions** for multi-table updates
4. **Implement proper error handling** for edge cases
5. **Log all approval actions** for debugging
6. **Test with different user level combinations**

## 🎯 **Summary**

Sistem approval workflow MEDOLS menggunakan arsitektur modular yang memisahkan:
- **Configuration** (workflows, steps, settings)
- **Execution** (flows, logs)
- **Legacy Support** (article_approvals)

Setiap module memiliki tanggung jawab spesifik, dan mereka bekerja sama untuk menciptakan sistem approval yang fleksibel dan dapat di-audit.
