# “Phase 6A + Technical Design Document : Workflow DSL (Mini-Language)”** ออกแบบสำหรับระบบ Workflow Engine กลางของโครงการ **ไม่มีโค้ดผูกกับ Framework** เพื่อให้สามารถนำไป Implement ใน NestJS หรือ Microservice ใด ๆ ได้ --- ## 📌 **Phase 6A – Workflow DSL Implementation Plan** ### 🎯 เป้าหมายของ Phase 6A ใน Phase นี้ จะเริ่มสร้าง “Workflow DSL (Domain-Specific Language)” สำหรับนิยามกฎการเดินงาน (Workflow Transition Rules) ให้สามารถ: * แยก **Business Workflow Logic** ออกจาก Source Code * แก้ไขกฎ Workflow ได้โดย **ไม่ต้องแก้โค้ดและไม่ต้อง Deploy ใหม่** * รองรับ Document หลายประเภท เช่น * Correspondence * RFA * Internal Circulation * Document Transmittal * รองรับ Multi-step routing, skip, reject, rollback, parallel assignments * สามารถนำไปใช้งานทั้งใน * Backend (NestJS) * Frontend (UI Driven) * External Microservices --- ### 📅 ระยะเวลา **1 สัปดาห์ (หลัง Phase 6.5)** --- ### 🧩 Output ของ Phase 6A * DSL Specification (Grammar) * JSON Schema for Workflow Definition * Workflow Rule Interpreter (Parser + Executor) * Validation Engine (Compile-time and Runtime) * Storage (DB Table / Registry) * Execution API: | Action | Description | | -------------------------------- | ------------------------------- | | compile() | ตรวจ DSL → สร้าง Execution Tree | | evaluate(state, action, context) | ประมวลผลและส่งสถานะใหม่ | | preview(state) | คำนวณ Next Possible Transitions | | validate() | ตรวจว่า DSL ถูกต้อง | --- ## 📘 **Technical Specification – Workflow DSL** --- ### 1️⃣ Requirements #### Functional Requirements * นิยาม Workflow เป็นภาษาคล้าย State Machine * แต่ละเอกสารมี **State, Actions, Entry/Exit Events** * สามารถมี: * Required approvals * Conditional transition * Auto-transition * Parallel approval * Return/rollback #### * Running time: < 20ms ต่อคำสั่ง * Hot reload ไม่ต้อง Compile ใหม่ทั้ง Backend * DSL ต้อง Debug ได้ง่าย * ต้อง Versioned * ต้องรองรับ Audit 100% --- ### 2️⃣ DSL Format (Human Friendly) ```yaml workflow: RFA version: 1.0 states: - name: DRAFT initial: true on: SUBMIT: to: IN_REVIEW require: - role: ENGINEER events: - notify: reviewer - name: IN_REVIEW on: APPROVE: to: APPROVED REJECT: to: DRAFT events: - notify: creator - name: APPROVED terminal: true ``` --- ### 3️⃣ Compiled Execution Model (Normalized JSON) ```json { "workflow": "RFA", "version": "1.0", "states": { "DRAFT": { "initial": true, "transitions": { "SUBMIT": { "to": "IN_REVIEW", "requirements": [ { "role": "ENGINEER" } ], "events": [ { "type": "notify", "target": "reviewer" } ] } } }, "IN_REVIEW": { "transitions": { "APPROVE": { "to": "APPROVED" }, "REJECT": { "to": "DRAFT", "events": [ { "type": "notify", "target": "creator" } ] } } }, "APPROVED": { "terminal": true } } } ``` Frontend และ Backend สามารถแชร์ JSON นี้ร่วมกันได้ --- ### 4️⃣ DSL Grammar Definition (EBNF) ```ebnf workflow = "workflow" ":" identifier ; version = "version" ":" number ; states = "states:" state_list ; state_list = { state } ; state = "- name:" identifier [ "initial:" boolean ] [ "terminal:" boolean ] [ "on:" transition_list ] ; transition_list = { transition } ; transition = action ":" indent "to:" identifier [ indent "require:" requirements ] [ indent "events:" event_list ] ; requirements = "- role:" identifier | "- user:" identifier ; event_list = { event } ; event = "- notify:" identifier ; ``` --- ### 5️⃣ Validation Rules (Compile-Time) #### 5.1 State Rules * ต้องมีอย่างน้อย 1 state ที่ `initial: true` * หาก `terminal: true` → ต้องไม่มี transition ต่อไป #### 5.2 Transition Rules ตรวจสอบว่า: * `to` ชี้ไปยัง state ที่มีอยู่ * `require.role` ต้องเป็น role ที่ระบบรู้จัก * Action name ต้องเป็น **UPPER_CASE** #### 5.3 Version Safety * ทุกชุด Workflow DSL ต้องขึ้นกับ version * แก้ไขต้องสร้าง version ใหม่ * ไม่ overwrite version เก่า * “Document ที่กำลังอยู่ใน step เดิมยังต้องใช้กฎเดิมได้” --- ### 6️⃣ Runtime Validation Rules เมื่อ execute(action): ``` input: current_state, action, context 1) ตรวจว่า state มี transition "action" 2) ตรวจว่าผู้ใช้มีสิทธิ์ตาม require[] 3) Compute next state 4) Execute events[] 5) Return next_state ``` --- ### 7️⃣ Context Model ```ts interface WorkflowContext { userId: string; roles: string[]; documentId: string; now: Date; payload?: any; } ``` --- ### 8️⃣ Execution API (Abstract) ```ts class WorkflowEngine { load(dsl: string | object): CompiledWorkflow compile(dsl: string | object): CompiledWorkflow evaluate(state: string, action: string, context: WorkflowContext): EvalResult getAvailableActions(state: string, context: WorkflowContext): string[] } ``` --- ### 9️⃣ Interpreter Execution Flow ```mermaid flowchart TD A[Receive Action] --> B[Load Compiled Workflow] B --> C[Check allowed actions] C -->|Invalid| E[Return Error] C --> D[Evaluate Requirements] D --> F[Transition to Next State] F --> G[Run Events] G --> H[Return Success] ``` --- ### 🔟 Events System รองรับ event หลายประเภท: | event.type | ตัวอย่าง | | ----------- | ------------------------- | | notify | ส่ง Email/Line | | assign | เปลี่ยนผู้รับผิดชอบ | | webhook | ยิง Webhook ไปยังระบบอื่น | | auto_action | ทำ action ซ้ำโดยอัตโนมัติ | --- ### 11️⃣ Database Schema #### Table: `workflow_definition` | Field | Type | Description | | ------------- | ----------- | --------------------- | | id | UUID | PK | | workflow_code | varchar(50) | เช่น `RFA`, `CORR` | | version | int | Version number | | dsl | JSON | YAML/JSON DSL เก็บดิบ | | compiled | JSON | JSON ที่ Compile แล้ว | | created_at | timestamp | | | is_active | boolean | ใช้อยู่หรือไม่ | #### Table: `workflow_history` เก็บ audit แบบ immutable append-only | Field | Description | | ----------- | --------------- | | workflow | Document Type | | document_id | เอกสารไหน | | from_state | เดิม | | to_state | ใหม่ | | action | คำสั่ง | | user | ใครเป็นคนทำ | | timestamp | เวลา | | metadata | เหตุการณ์อื่น ๆ | --- ### 12️⃣ Error Codes | Code | Meaning | | ----------------------- | ---------------------- | | WF_NO_TRANSITION | Action นี้ไม่ถูกต้อง | | WF_RESTRICTED | User ไม่มีสิทธิ์ | | WF_MISSING_REQUIREMENTS | ไม่ผ่านเงื่อนไข | | WF_STATE_NOT_FOUND | ไม่มี state ที่อ้างอิง | | WF_SYNTAX_ERROR | DSL ผิดรูปแบบ | --- ### 13️⃣ Testing Strategy #### Unit Tests * Parse DSL → JSON * Invalid syntax → throw error * Invalid transitions → throw error #### Integration Tests * Evaluate() ผ่าน 20+ cases * RFA ย้อนกลับ * Approve chain * Parallel review #### Load Tests * 1,000 documents running workflow * Evaluate < 20ms ต่อ action --- ### 14️⃣ Deployment Strategy #### Hot Reload Options * DSL stored in DB * Cache in Redis * Touched timestamp triggers: ``` invalidate cache → recompile ``` #### No downtime required --- ### 15️⃣ Microservice-Ready DSL Engine แยกเป็น: * `workflow-engine-core` → Pure JS library * `workflow-service` → NestJS module * API public: ``` POST /workflow/evaluate GET /workflow/preview POST /workflow/compile ``` ภายหลังสามารถนำไปวางบน: * Kubernetes * Worker Node * API Gateway --- ## 🎉 Summary ### สิ่งที่ Phase 6A เพิ่มเข้าในระบบ ✔ Workflow DSL ที่แก้ไขได้โดยไม่ต้อง Deploy ✔ Parser + Validator + Runtime Interpreter ✔ Database storage + Versioning ✔ Execution API สำหรับ Backend และ Frontend ✔ รองรับ Business Workflow ซับซ้อนทั้งหมด ✔ Ready สำหรับ Microservice model ในอนาคต