kontenhumas-be/docs/ENHANCED_APPROVAL_PRACTICAL...

424 lines
11 KiB
Markdown

# Enhanced Approval Actions - Practical Usage Guide
## 🎯 **Overview**
Panduan praktis untuk menggunakan Enhanced Approval Actions API yang mendukung 3 jenis action: **Approve**, **Revision**, dan **Reject**.
## 🔄 **Action Types & Behavior**
| Action | Behavior | Use Case | Result |
|--------|----------|----------|---------|
| **`approve`** | Naik ke step berikutnya | Content sudah sesuai | Workflow berlanjut |
| **`revision`** | Mundur 1 step | Content perlu diperbaiki | Workflow mundur 1 step |
| **`reject`** | Balik ke Draft | Content tidak sesuai | Workflow dihentikan, artikel jadi draft |
## 🧪 **Practical Examples**
### **Scenario 1: Normal Approval Flow**
#### **Step 1: Editor Review**
```bash
curl -X POST "http://localhost:8080/api/article-approval-flows/articles/10/approve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer EDITOR_TOKEN" \
-d '{
"action": "approve",
"message": "Content is well-written and follows our guidelines"
}'
```
**Response:**
```json
{
"success": true,
"messages": ["Article successfully approve through active approval flow"],
"data": {
"article_id": 10,
"flow_id": 1,
"action": "approve",
"current_step": 2,
"current_branch": "Final_Approval",
"workflow_id": 1
}
}
```
#### **Step 2: Senior Editor Review**
```bash
curl -X POST "http://localhost:8080/api/article-approval-flows/articles/10/approve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer SENIOR_EDITOR_TOKEN" \
-d '{
"action": "approve",
"message": "Final approval granted. Ready for publication."
}'
```
**Result:** Article published successfully! 🎉
---
### **Scenario 2: Request Update Flow**
#### **Step 1: Editor Review**
```bash
curl -X POST "http://localhost:8080/api/article-approval-flows/articles/11/approve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer EDITOR_TOKEN" \
-d '{
"action": "approve",
"message": "Content is good, moving to next level"
}'
```
#### **Step 2: Senior Editor Review (Request Revision)**
```bash
curl -X POST "http://localhost:8080/api/article-approval-flows/articles/11/approve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer SENIOR_EDITOR_TOKEN" \
-d '{
"action": "revision",
"message": "Please add more examples in section 3 and improve the conclusion"
}'
```
**Response:**
```json
{
"success": true,
"messages": ["Article successfully revision through active approval flow"],
"data": {
"article_id": 11,
"flow_id": 2,
"action": "revision",
"current_step": 1,
"current_branch": "Branch_A",
"workflow_id": 1
}
}
```
**Result:** Article kembali ke step 1 untuk revisi! 📝
#### **Step 3: After Revision, Approve Again**
```bash
curl -X POST "http://localhost:8080/api/article-approval-flows/articles/11/approve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer EDITOR_TOKEN" \
-d '{
"action": "approve",
"message": "Revisions completed, content improved significantly"
}'
```
---
### **Scenario 3: Reject Flow**
#### **Step 1: Editor Review (Reject)**
```bash
curl -X POST "http://localhost:8080/api/article-approval-flows/articles/12/approve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer EDITOR_TOKEN" \
-d '{
"action": "reject",
"message": "Content does not meet our quality standards. Please rewrite with better research and clearer structure."
}'
```
**Response:**
```json
{
"success": true,
"messages": ["Article successfully reject through active approval flow"],
"data": {
"article_id": 12,
"flow_id": 3,
"action": "reject",
"current_step": 1,
"current_branch": "Branch_A",
"workflow_id": 1
}
}
```
**Result:** Article dikembalikan ke status Draft! ❌
---
## 🔍 **Database State Changes**
### **After Approve:**
```sql
-- Article Approval Flows
UPDATE article_approval_flows
SET current_step = 2,
updated_at = NOW()
WHERE id = 1;
-- Article Approval Step Logs
INSERT INTO article_approval_step_logs
(approval_flow_id, step_order, action, action_by_id, message, created_at)
VALUES (1, 1, 'approve', 5, 'Content is well-written', NOW());
```
### **After Revision:**
```sql
-- Article Approval Flows
UPDATE article_approval_flows
SET current_step = 1,
revision_requested = true,
revision_message = 'Please add more examples',
updated_at = NOW()
WHERE id = 2;
-- Article Approval Step Logs
INSERT INTO article_approval_step_logs
(approval_flow_id, step_order, action, action_by_id, message, created_at)
VALUES (2, 2, 'revision', 6, 'Please add more examples', NOW());
```
### **After Reject:**
```sql
-- Article Approval Flows
UPDATE article_approval_flows
SET status_id = 3,
rejection_reason = 'Content does not meet quality standards',
completed_at = NOW(),
updated_at = NOW()
WHERE id = 3;
-- Articles
UPDATE articles
SET status_id = 1,
is_draft = true,
workflow_id = NULL,
current_approval_step = NULL,
updated_at = NOW()
WHERE id = 12;
-- Article Approval Step Logs
INSERT INTO article_approval_step_logs
(approval_flow_id, step_order, action, action_by_id, message, created_at)
VALUES (3, 1, 'reject', 5, 'Content does not meet quality standards', NOW());
```
## 🎯 **Frontend Integration Examples**
### **React Component:**
```jsx
import React, { useState } from 'react';
const ApprovalActions = ({ articleId, onActionComplete }) => {
const [action, setAction] = useState('approve');
const [message, setMessage] = useState('');
const handleSubmit = async () => {
try {
const response = await fetch(`/api/article-approval-flows/articles/${articleId}/approve`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ action, message })
});
const result = await response.json();
if (result.success) {
onActionComplete(result.data);
alert(`Article ${action} successfully!`);
} else {
alert(`Error: ${result.messages[0]}`);
}
} catch (error) {
alert('Failed to process approval action');
}
};
return (
<div className="approval-actions">
<h3>Approval Actions</h3>
<div className="action-buttons">
<button
className={action === 'approve' ? 'active' : ''}
onClick={() => setAction('approve')}
>
Approve
</button>
<button
className={action === 'revision' ? 'active' : ''}
onClick={() => setAction('revision')}
>
📝 Revision
</button>
<button
className={action === 'reject' ? 'active' : ''}
onClick={() => setAction('reject')}
>
Reject
</button>
</div>
<textarea
placeholder="Enter your message..."
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
<button onClick={handleSubmit}>
Submit {action}
</button>
</div>
);
};
```
### **Vue.js Component:**
```vue
<template>
<div class="approval-actions">
<h3>Approval Actions</h3>
<div class="action-buttons">
<button
v-for="actionType in actions"
:key="actionType.value"
:class="{ active: selectedAction === actionType.value }"
@click="selectedAction = actionType.value"
>
{{ actionType.icon }} {{ actionType.label }}
</button>
</div>
<textarea
v-model="message"
placeholder="Enter your message..."
/>
<button @click="submitAction" :disabled="!selectedAction">
Submit {{ selectedAction }}
</button>
</div>
</template>
<script>
export default {
data() {
return {
selectedAction: 'approve',
message: '',
actions: [
{ value: 'approve', label: 'Approve', icon: '✅' },
{ value: 'revision', label: 'Revision', icon: '📝' },
{ value: 'reject', label: 'Reject', icon: '❌' }
]
}
},
methods: {
async submitAction() {
try {
const response = await fetch(`/api/article-approval-flows/articles/${this.articleId}/approve`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`
},
body: JSON.stringify({
action: this.selectedAction,
message: this.message
})
});
const result = await response.json();
if (result.success) {
this.$emit('action-complete', result.data);
alert(`Article ${this.selectedAction} successfully!`);
} else {
alert(`Error: ${result.messages[0]}`);
}
} catch (error) {
alert('Failed to process approval action');
}
}
}
}
</script>
```
## 🚨 **Error Handling Examples**
### **Invalid Action:**
```bash
curl -X POST "http://localhost:8080/api/article-approval-flows/articles/123/approve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"action": "invalid_action",
"message": "Test"
}'
```
**Response:**
```json
{
"success": false,
"messages": ["Validation failed: [Action must be one of: approve, revision, reject]"]
}
```
### **Missing Action:**
```bash
curl -X POST "http://localhost:8080/api/article-approval-flows/articles/123/approve" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"message": "Test"
}'
```
**Response:**
```json
{
"success": false,
"messages": ["Validation failed: [Action is required]"]
}
```
## 📊 **Testing Scenarios**
### **Test Case 1: Complete Approval Flow**
1. Create article dengan user level 5
2. Editor (level 3) approve → step 2
3. Senior Editor (level 2) approve → published
### **Test Case 2: Revision Flow**
1. Create article dengan user level 5
2. Editor (level 3) approve → step 2
3. Senior Editor (level 2) revision → step 1
4. Editor (level 3) approve again → step 2
5. Senior Editor (level 2) approve → published
### **Test Case 3: Reject Flow**
1. Create article dengan user level 5
2. Editor (level 3) reject → article jadi draft
3. Workflow dihentikan
## 🎉 **Summary**
Enhanced Approval Actions API memberikan:
-**3 Action Types**: Approve, Revision, Reject
-**Flexible Workflow**: Support untuk berbagai skenario
-**Better UX**: User bisa memberikan feedback yang spesifik
-**Quality Control**: Reject option untuk content yang tidak sesuai
-**Revision Support**: Revision untuk perbaikan tanpa menghentikan workflow
-**Audit Trail**: Semua action dicatat dalam logs
**Sekarang approver memiliki kontrol penuh atas workflow dengan 3 pilihan action yang berbeda!** 🚀