Files
lcbp3/backend/src/modules/workflow-engine/workflow-engine.service.ts
2025-11-20 17:14:15 +07:00

93 lines
3.3 KiB
TypeScript

import { Injectable, BadRequestException } from '@nestjs/common';
import {
WorkflowStep,
WorkflowAction,
StepStatus,
TransitionResult,
} from './interfaces/workflow.interface.js';
@Injectable()
export class WorkflowEngineService {
/**
* คำนวณสถานะถัดไป (Next State Transition)
* @param currentSequence ลำดับปัจจุบัน
* @param totalSteps จำนวนขั้นตอนทั้งหมด
* @param action การกระทำ (Approve/Reject/Return)
* @param returnToSequence (Optional) ถ้า Return จะให้กลับไปขั้นไหน
*/
processAction(
currentSequence: number,
totalSteps: number,
action: WorkflowAction,
returnToSequence?: number,
): TransitionResult {
switch (action) {
case WorkflowAction.APPROVE:
case WorkflowAction.ACKNOWLEDGE:
// ถ้าเป็นขั้นตอนสุดท้าย -> จบ Workflow
if (currentSequence >= totalSteps) {
return {
nextStepSequence: null, // ไม่มีขั้นต่อไปแล้ว
shouldUpdateStatus: true,
documentStatus: 'COMPLETED', // หรือ APPROVED
};
}
// ถ้ายังไม่จบ -> ไปขั้นต่อไป
return {
nextStepSequence: currentSequence + 1,
shouldUpdateStatus: false,
};
case WorkflowAction.REJECT:
// จบ Workflow ทันทีแบบไม่สวย
return {
nextStepSequence: null,
shouldUpdateStatus: true,
documentStatus: 'REJECTED',
};
case WorkflowAction.RETURN:
// ย้อนกลับไปขั้นตอนก่อนหน้า (หรือที่ระบุ)
const targetStep = returnToSequence || currentSequence - 1;
if (targetStep < 1) {
throw new BadRequestException('Cannot return beyond the first step');
}
return {
nextStepSequence: targetStep,
shouldUpdateStatus: true,
documentStatus: 'REVISE_REQUIRED', // สถานะเอกสารเป็น "รอแก้ไข"
};
default:
throw new BadRequestException(`Invalid action: ${action}`);
}
}
/**
* ตรวจสอบว่า User คนนี้ มีสิทธิ์กด Action ในขั้นตอนนี้ไหม
* (Logic เบื้องต้น - เดี๋ยวเราจะเชื่อมกับ RBAC จริงๆ ใน Service หลัก)
*/
validateAccess(
step: WorkflowStep,
userOrgId: number,
userId: number,
): boolean {
// ถ้าขั้นตอนนี้ยังไม่ Active (เช่น PENDING หรือ SKIPPED) -> ห้ามยุ่ง
if (step.status !== StepStatus.IN_PROGRESS) {
return false;
}
// เช็คว่าตรงกับ Organization ที่กำหนดไหม
if (step.organizationId && step.organizationId !== userOrgId) {
return false;
}
// เช็คว่าตรงกับ User ที่กำหนดไหม (ถ้าระบุ)
if (step.assigneeId && step.assigneeId !== userId) {
return false;
}
return true;
}
}