555 lines
15 KiB
Markdown
555 lines
15 KiB
Markdown
# Multi-Branch Approval System Documentation
|
|
|
|
## Overview
|
|
|
|
Sistem Multi-Branch Approval memungkinkan pembuatan workflow approval yang dapat bercabang berdasarkan User Level dari submitter artikel. Sistem ini mendukung:
|
|
|
|
- **Conditional Routing**: Approval flow dapat mengikuti jalur berbeda berdasarkan level user yang submit artikel
|
|
- **Hierarchical Branching**: Support untuk struktur cabang yang kompleks dengan multiple level
|
|
- **Parallel Processing**: Kemampuan untuk menjalankan multiple approval secara parallel
|
|
- **Dynamic Configuration**: Workflow dapat dikonfigurasi secara dinamis tanpa mengubah kode
|
|
|
|
## Database Schema Changes
|
|
|
|
### 1. ApprovalWorkflowSteps Table
|
|
|
|
Field baru yang ditambahkan untuk mendukung multi-branch:
|
|
|
|
```sql
|
|
-- Multi-branch support fields
|
|
ALTER TABLE approval_workflow_steps ADD COLUMN parent_step_id INT REFERENCES approval_workflow_steps(id);
|
|
ALTER TABLE approval_workflow_steps ADD COLUMN condition_type VARCHAR(50); -- 'user_level', 'user_level_hierarchy', 'always', 'custom'
|
|
ALTER TABLE approval_workflow_steps ADD COLUMN condition_value TEXT; -- JSON string for conditions
|
|
ALTER TABLE approval_workflow_steps ADD COLUMN is_parallel BOOLEAN DEFAULT false;
|
|
ALTER TABLE approval_workflow_steps ADD COLUMN branch_name VARCHAR(100);
|
|
ALTER TABLE approval_workflow_steps ADD COLUMN branch_order INT; -- Order within the same branch
|
|
```
|
|
|
|
### 2. ArticleApprovalFlows Table
|
|
|
|
Field baru untuk tracking branch:
|
|
|
|
```sql
|
|
-- Multi-branch support fields
|
|
ALTER TABLE article_approval_flows ADD COLUMN current_branch VARCHAR(100); -- Current active branch
|
|
ALTER TABLE article_approval_flows ADD COLUMN branch_path TEXT; -- JSON array tracking the path taken
|
|
ALTER TABLE article_approval_flows ADD COLUMN is_parallel_flow BOOLEAN DEFAULT false; -- Whether this is a parallel approval flow
|
|
ALTER TABLE article_approval_flows ADD COLUMN parent_flow_id INT REFERENCES article_approval_flows(id); -- For parallel flows
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### 1. Create Multi-Branch Workflow
|
|
|
|
**Endpoint**: `POST /api/approval-workflows/with-steps`
|
|
|
|
**Description**: Membuat workflow dengan steps yang mendukung multi-branch routing
|
|
|
|
**Request Body**:
|
|
```json
|
|
{
|
|
"name": "Multi-Branch Article Approval",
|
|
"description": "Approval workflow dengan cabang berdasarkan user level",
|
|
"isActive": true,
|
|
"isDefault": false,
|
|
"requiresApproval": true,
|
|
"autoPublish": false,
|
|
"steps": [
|
|
{
|
|
"stepOrder": 1,
|
|
"stepName": "Level 2 Branch",
|
|
"requiredUserLevelId": 2,
|
|
"canSkip": false,
|
|
"isActive": true,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [4,5,6,7,8,9]}",
|
|
"branchName": "Branch_A",
|
|
"branchOrder": 1
|
|
},
|
|
{
|
|
"stepOrder": 1,
|
|
"stepName": "Level 3 Branch",
|
|
"requiredUserLevelId": 3,
|
|
"canSkip": false,
|
|
"isActive": true,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [10,11,12,13,14,15]}",
|
|
"branchName": "Branch_B",
|
|
"branchOrder": 1
|
|
},
|
|
{
|
|
"stepOrder": 2,
|
|
"stepName": "Level 1 Final Approval",
|
|
"requiredUserLevelId": 1,
|
|
"canSkip": false,
|
|
"isActive": true,
|
|
"conditionType": "always",
|
|
"branchName": "Final_Approval",
|
|
"branchOrder": 1
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Curl Example**:
|
|
```bash
|
|
curl -X POST "http://localhost:8080/api/approval-workflows/with-steps" \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
-d '{
|
|
"name": "Multi-Branch Article Approval",
|
|
"description": "Approval workflow dengan cabang berdasarkan user level",
|
|
"isActive": true,
|
|
"isDefault": false,
|
|
"requiresApproval": true,
|
|
"autoPublish": false,
|
|
"steps": [
|
|
{
|
|
"stepOrder": 1,
|
|
"stepName": "Level 2 Branch",
|
|
"requiredUserLevelId": 2,
|
|
"canSkip": false,
|
|
"isActive": true,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [4,5,6,7,8,9]}",
|
|
"branchName": "Branch_A",
|
|
"branchOrder": 1
|
|
},
|
|
{
|
|
"stepOrder": 1,
|
|
"stepName": "Level 3 Branch",
|
|
"requiredUserLevelId": 3,
|
|
"canSkip": false,
|
|
"isActive": true,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [10,11,12,13,14,15]}",
|
|
"branchName": "Branch_B",
|
|
"branchOrder": 1
|
|
},
|
|
{
|
|
"stepOrder": 2,
|
|
"stepName": "Level 1 Final Approval",
|
|
"requiredUserLevelId": 1,
|
|
"canSkip": false,
|
|
"isActive": true,
|
|
"conditionType": "always",
|
|
"branchName": "Final_Approval",
|
|
"branchOrder": 1
|
|
}
|
|
]
|
|
}'
|
|
```
|
|
|
|
### 2. Submit Article for Multi-Branch Approval
|
|
|
|
**Endpoint**: `POST /api/articles/{id}/submit-approval`
|
|
|
|
**Description**: Submit artikel untuk approval dengan multi-branch workflow
|
|
|
|
**Curl Example**:
|
|
```bash
|
|
curl -X POST "http://localhost:8080/api/articles/123/submit-approval" \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
-d '{
|
|
"workflowId": 1
|
|
}'
|
|
```
|
|
|
|
### 3. Process Multi-Branch Approval
|
|
|
|
**Endpoint**: `POST /api/article-approval-flows/{id}/multi-branch-approve`
|
|
|
|
**Description**: Proses approval dengan multi-branch logic
|
|
|
|
**Request Body**:
|
|
```json
|
|
{
|
|
"message": "Article looks good, approved for next level"
|
|
}
|
|
```
|
|
|
|
**Curl Example**:
|
|
```bash
|
|
curl -X POST "http://localhost:8080/api/article-approval-flows/456/multi-branch-approve" \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer YOUR_TOKEN" \
|
|
-d '{
|
|
"message": "Article looks good, approved for next level"
|
|
}'
|
|
```
|
|
|
|
### 4. Get Next Steps Preview
|
|
|
|
**Endpoint**: `GET /api/article-approval-flows/{id}/next-steps-preview`
|
|
|
|
**Description**: Mendapatkan preview next steps berdasarkan user level submitter
|
|
|
|
**Curl Example**:
|
|
```bash
|
|
curl -X GET "http://localhost:8080/api/article-approval-flows/456/next-steps-preview" \
|
|
-H "Authorization: Bearer YOUR_TOKEN"
|
|
```
|
|
|
|
**Response Example**:
|
|
```json
|
|
{
|
|
"success": true,
|
|
"messages": ["Next steps preview successfully retrieved"],
|
|
"data": {
|
|
"current_step": 1,
|
|
"submitter_level_id": 5,
|
|
"next_steps": [
|
|
{
|
|
"id": 2,
|
|
"stepOrder": 2,
|
|
"stepName": "Level 1 Final Approval",
|
|
"requiredUserLevelId": 1,
|
|
"branchName": "Final_Approval",
|
|
"conditionType": "always"
|
|
}
|
|
],
|
|
"total_next_steps": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
## Condition Types
|
|
|
|
### 1. `user_level`
|
|
Steps yang berlaku untuk user level tertentu.
|
|
|
|
**Condition Value Format**:
|
|
```json
|
|
[4, 5, 6, 7, 8, 9]
|
|
```
|
|
|
|
### 2. `user_level_hierarchy`
|
|
Steps yang berlaku berdasarkan hierarki user level dengan kondisi yang lebih kompleks.
|
|
|
|
**Condition Value Format**:
|
|
```json
|
|
{
|
|
"applies_to_levels": [4, 5, 6, 7, 8, 9],
|
|
"min_level": 4,
|
|
"max_level": 9
|
|
}
|
|
```
|
|
|
|
### 3. `always`
|
|
Steps yang selalu berlaku untuk semua user level.
|
|
|
|
**Condition Value**: `null` atau `"{}"`
|
|
|
|
### 4. `custom`
|
|
Steps dengan kondisi custom (untuk ekstensi masa depan).
|
|
|
|
## Workflow Examples
|
|
|
|
### Example 1: Simple Two-Branch Workflow
|
|
|
|
```json
|
|
{
|
|
"name": "Simple Two-Branch Approval",
|
|
"description": "Workflow dengan 2 cabang berdasarkan user level",
|
|
"steps": [
|
|
{
|
|
"stepOrder": 1,
|
|
"stepName": "Branch A - Level 2",
|
|
"requiredUserLevelId": 2,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [4,5,6]}",
|
|
"branchName": "Branch_A"
|
|
},
|
|
{
|
|
"stepOrder": 1,
|
|
"stepName": "Branch B - Level 3",
|
|
"requiredUserLevelId": 3,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [7,8,9]}",
|
|
"branchName": "Branch_B"
|
|
},
|
|
{
|
|
"stepOrder": 2,
|
|
"stepName": "Final Approval",
|
|
"requiredUserLevelId": 1,
|
|
"conditionType": "always",
|
|
"branchName": "Final"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Example 2: Complex Multi-Level Branching
|
|
|
|
```json
|
|
{
|
|
"name": "Complex Multi-Level Branching",
|
|
"description": "Workflow dengan multiple level branching",
|
|
"steps": [
|
|
{
|
|
"stepOrder": 1,
|
|
"stepName": "Level 2 Branch",
|
|
"requiredUserLevelId": 2,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [4,5,6,7,8,9]}",
|
|
"branchName": "Branch_A"
|
|
},
|
|
{
|
|
"stepOrder": 1,
|
|
"stepName": "Level 3 Branch",
|
|
"requiredUserLevelId": 3,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [10,11,12,13,14,15]}",
|
|
"branchName": "Branch_B"
|
|
},
|
|
{
|
|
"stepOrder": 2,
|
|
"stepName": "Sub-branch A1",
|
|
"requiredUserLevelId": 4,
|
|
"parentStepId": 1,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [4,5,6]}",
|
|
"branchName": "SubBranch_A1"
|
|
},
|
|
{
|
|
"stepOrder": 2,
|
|
"stepName": "Sub-branch A2",
|
|
"requiredUserLevelId": 5,
|
|
"parentStepId": 1,
|
|
"conditionType": "user_level_hierarchy",
|
|
"conditionValue": "{\"applies_to_levels\": [7,8,9]}",
|
|
"branchName": "SubBranch_A2"
|
|
},
|
|
{
|
|
"stepOrder": 3,
|
|
"stepName": "Level 1 Final Approval",
|
|
"requiredUserLevelId": 1,
|
|
"conditionType": "always",
|
|
"branchName": "Final_Approval"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
## Flow Logic
|
|
|
|
### 1. Article Submission Flow
|
|
|
|
1. User dengan level tertentu submit artikel
|
|
2. Sistem menentukan workflow yang akan digunakan
|
|
3. Sistem mencari step pertama yang applicable berdasarkan user level submitter
|
|
4. Artikel masuk ke approval flow dengan step yang sesuai
|
|
|
|
### 2. Approval Processing Flow
|
|
|
|
1. Approver melakukan approval pada step saat ini
|
|
2. Sistem mencari next steps yang applicable berdasarkan:
|
|
- User level submitter
|
|
- Condition type dan value
|
|
- Branch logic
|
|
3. Jika ada multiple next steps, sistem akan:
|
|
- Untuk parallel branches: buat multiple approval flows
|
|
- Untuk sequential branches: pilih step pertama yang applicable
|
|
4. Update artikel status sesuai dengan step yang dicapai
|
|
|
|
### 3. Branch Determination Logic
|
|
|
|
```go
|
|
func IsStepApplicableForLevel(step *ApprovalWorkflowSteps, submitterLevelId uint) bool {
|
|
switch step.ConditionType {
|
|
case "user_level":
|
|
// Check if submitter level is in allowed levels
|
|
return contains(allowedLevels, submitterLevelId)
|
|
|
|
case "user_level_hierarchy":
|
|
// Check based on hierarchy rules
|
|
return checkHierarchyRules(submitterLevelId, step.ConditionValue)
|
|
|
|
case "always":
|
|
return true
|
|
|
|
default:
|
|
return true
|
|
}
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
### Common Error Responses
|
|
|
|
1. **Invalid Condition Value**:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"messages": ["Invalid condition value format"],
|
|
"error": "CONDITION_VALUE_INVALID"
|
|
}
|
|
```
|
|
|
|
2. **No Applicable Steps**:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"messages": ["No applicable next steps found for this user level"],
|
|
"error": "NO_APPLICABLE_STEPS"
|
|
}
|
|
```
|
|
|
|
3. **Workflow Not Found**:
|
|
```json
|
|
{
|
|
"success": false,
|
|
"messages": ["Workflow not found"],
|
|
"error": "WORKFLOW_NOT_FOUND"
|
|
}
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Test Scenarios
|
|
|
|
1. **Basic Branching Test**:
|
|
- Submit artikel dari user level 5
|
|
- Verify artikel masuk ke Branch A (Level 2)
|
|
- Approve dan verify masuk ke Final Approval
|
|
|
|
2. **Multiple Branch Test**:
|
|
- Submit artikel dari user level 8
|
|
- Verify artikel masuk ke Branch A (Level 2)
|
|
- Submit artikel dari user level 12
|
|
- Verify artikel masuk ke Branch B (Level 3)
|
|
|
|
3. **Condition Validation Test**:
|
|
- Test dengan condition value yang invalid
|
|
- Test dengan user level yang tidak ada di condition
|
|
- Test dengan condition type yang tidak supported
|
|
|
|
### Test Data Setup
|
|
|
|
```sql
|
|
-- Insert test user levels
|
|
INSERT INTO user_levels (name, level_number, is_active) VALUES
|
|
('Level 1', 1, true),
|
|
('Level 2', 2, true),
|
|
('Level 3', 3, true),
|
|
('Level 4', 4, true),
|
|
('Level 5', 5, true);
|
|
|
|
-- Insert test users
|
|
INSERT INTO users (username, email, user_level_id) VALUES
|
|
('user_level_5', 'user5@test.com', 5),
|
|
('user_level_8', 'user8@test.com', 8),
|
|
('user_level_12', 'user12@test.com', 12);
|
|
```
|
|
|
|
## Migration Guide
|
|
|
|
### From Linear to Multi-Branch
|
|
|
|
1. **Backup existing data**:
|
|
```sql
|
|
CREATE TABLE approval_workflow_steps_backup AS SELECT * FROM approval_workflow_steps;
|
|
CREATE TABLE article_approval_flows_backup AS SELECT * FROM article_approval_flows;
|
|
```
|
|
|
|
2. **Add new columns**:
|
|
```sql
|
|
-- Run the ALTER TABLE statements mentioned above
|
|
```
|
|
|
|
3. **Migrate existing workflows**:
|
|
```sql
|
|
-- Set default values for existing steps
|
|
UPDATE approval_workflow_steps SET
|
|
condition_type = 'always',
|
|
branch_name = 'default_branch',
|
|
branch_order = step_order
|
|
WHERE condition_type IS NULL;
|
|
```
|
|
|
|
4. **Test migration**:
|
|
- Verify existing workflows still work
|
|
- Test new multi-branch functionality
|
|
- Rollback if issues found
|
|
|
|
## Performance Considerations
|
|
|
|
1. **Database Indexes**:
|
|
```sql
|
|
CREATE INDEX idx_approval_workflow_steps_condition ON approval_workflow_steps(condition_type, branch_name);
|
|
CREATE INDEX idx_article_approval_flows_branch ON article_approval_flows(current_branch);
|
|
```
|
|
|
|
2. **Caching**:
|
|
- Cache workflow steps by condition type
|
|
- Cache user level mappings
|
|
- Cache branch determination results
|
|
|
|
3. **Query Optimization**:
|
|
- Use proper JOINs for branch queries
|
|
- Limit result sets with pagination
|
|
- Use prepared statements for repeated queries
|
|
|
|
## Security Considerations
|
|
|
|
1. **Access Control**:
|
|
- Validate user permissions for each approval step
|
|
- Ensure users can only approve steps they're authorized for
|
|
- Log all approval actions for audit
|
|
|
|
2. **Data Validation**:
|
|
- Validate condition values before processing
|
|
- Sanitize JSON input in condition_value
|
|
- Check for SQL injection in dynamic queries
|
|
|
|
3. **Audit Trail**:
|
|
- Log all branch decisions
|
|
- Track condition evaluations
|
|
- Maintain approval history with branch information
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Steps Not Found**:
|
|
- Check condition_type and condition_value
|
|
- Verify user level mapping
|
|
- Check workflow activation status
|
|
|
|
2. **Infinite Loops**:
|
|
- Validate step dependencies
|
|
- Check for circular references in parent_step_id
|
|
- Ensure proper step ordering
|
|
|
|
3. **Performance Issues**:
|
|
- Check database indexes
|
|
- Optimize condition evaluation queries
|
|
- Consider caching strategies
|
|
|
|
### Debug Commands
|
|
|
|
```bash
|
|
# Check workflow steps
|
|
curl -X GET "http://localhost:8080/api/approval-workflows/1/with-steps" \
|
|
-H "Authorization: Bearer YOUR_TOKEN"
|
|
|
|
# Check next steps for specific flow
|
|
curl -X GET "http://localhost:8080/api/article-approval-flows/123/next-steps-preview" \
|
|
-H "Authorization: Bearer YOUR_TOKEN"
|
|
|
|
# Check user level
|
|
curl -X GET "http://localhost:8080/api/users/456" \
|
|
-H "Authorization: Bearer YOUR_TOKEN"
|
|
```
|
|
|
|
## Future Enhancements
|
|
|
|
1. **Visual Workflow Designer**: UI untuk membuat workflow secara visual
|
|
2. **Condition Builder**: UI untuk membuat kondisi tanpa JSON manual
|
|
3. **Workflow Templates**: Template workflow untuk berbagai use case
|
|
4. **Advanced Branching**: Support untuk conditional branching yang lebih kompleks
|
|
5. **Parallel Processing**: True parallel approval processing
|
|
6. **Workflow Analytics**: Analytics untuk workflow performance dan bottlenecks
|