Private Docs

03 — WorkflowService — Integration Contract

Integration contract ที่ orchestrator ต้องการจาก Workflow — ไม่ใช่ design ภายใน Workflow; จุด 🤝 = ต้อง confirm กับทีม

อัปเดต: 2026-06-15

อ่าน 00-OVERVIEW.md + CONTEXT.md ก่อน Scope (grill 2026-06-15): ไฟล์นี้ = integration contract ที่ orchestrator ต้องการจาก Workflow — ไม่ใช่ การออกแบบภายใน Workflow; รายละเอียด mapping ภายในเป็นของทีม Workflow ทีมเดียวกัน (ยืนยันแล้ว) แต่ design ภายใน Workflow ยังไม่ชัด → จุดที่มี 🤝 = ต้อง confirm กับทีม


Workflow model จริง (จาก code TakeActionHandler.cs — survey 2026-06-15)

ก่อนคุย contract ต้องเข้าใจว่า Workflow ไม่ได้มี action ตรงกับ vocab ของเรา:

  • multi-phase / multi-step: WfPhaseInstance → WfStepInstance → WfStepActionInstance (SEQUENTIAL/PARALLEL); assignee = UserId หรือ Role
  • action มีแค่ APPROVE / REJECT — ไม่มี Rework/SentToReviewer/Pickup เป็น action แยก
  • phase progression: APPROVE step สุดท้ายของ phase → เปิด phase ถัดไป; APPROVE phase สุดท้าย → COMPLETED
  • Rework = REJECT + OnRejectToPhaseOrder>0 (ย้อน phase + IsEditable=true); =0REJECTED ถาวร
  • webhook มีอยู่แล้ว: OnActionChangedPayload { StepInstanceId, ActionType, BusinessRefId, ActionBy, NextAssignees, IsEdit, Remark } ส่งผ่าน SendWorkflowEventAsync

Mapping ที่ orchestrator ต้องการ (Workflow publisher แปลง native → semantic)

Orchestrator ต้องการ (M3-M5)Workflow nativeหมายเหตุ 🤝
Pickup (→ InReview)ไม่มี nativeขึ้นกับ Workflow มี claim/pickup ไหม — ถ้าไม่มี InReview ตัดทิ้ง/ปรับ (open item)
SentToReviewer (→ Reviewed)APPROVE บน phase ที่ไม่ใช่ phase สุดท้ายmaker (phase 1) approve = ส่งต่อ reviewer (phase 2)
Decision: ApproveAPPROVE บน phase สุดท้าย → COMPLETED
Decision: RejectREJECT + OnRejectToPhaseOrder=0
Decision: ReworkREJECT + OnRejectToPhaseOrder>0 (+targets/note)reworkTargets map จาก step ที่ตีกลับ
Decision: Cancel(ยังไม่มีใน TakeAction)ต้องเพิ่ม cancel path

คำถามค้างกับทีม Workflow: (1) มี pickup/claim ไหม → ตัดสิน InReview; (2) แปลง native→semantic ที่ publisher ฝั่ง Workflow (แนะนำ — Workflow รู้ phase semantic ของตัวเอง); (3) mint decisionId; (4) occurredAt ทุก event (Lego ordering ใช้)


งานที่ Workflow ต้องทำ (contract obligations)

W1 — ASB publisher (emit semantic events)

สถานะเดิม: ASB = 0 (WebhookService no-op / webhook HTTP) → ต้องเพิ่ม ASB publisher emit:

Event (semantic)ยิงตอน (native)Payload หลัก
Pickup (ถ้ามี)maker claim งานflowInstanceId/refNo, makerIdentity, occurredAt
SentToReviewerAPPROVE non-final phaseflowInstanceId/refNo, reviewerIdentity (next assignees), occurredAt
DecisionAPPROVE final / REJECTflowInstanceId/refNo, action(Approve/Reject/Rework/Cancel), decisionId, reworkTargets, reason, occurredAt

W2 — Notify maker เอง (grill 2026-06-15 — Workflow เป็นเจ้าของ)

  • maker pool → notify ตอนงานเข้ากองกลาง (create instance, unassigned)
  • assignee (maker คนเดิม) → notify ตอน resubmit/resume
  • orchestrator ไม่ notify maker → Workflow ถือ maker identity เอง ยิงเอง

W3 — mint decisionId + map Rework

  • ปัจจุบัน TakeAction รับ APPROVE/REJECT, REJECT+OnRejectToPhaseOrder = rework → publisher ต้อง mint decisionId + แปลงเป็น Decision(Rework) พร้อม reworkTargets

W4 — HTTP endpoints ให้ orchestrator เรียก (M12-M14)

Endpointสถานะงาน
create instance (M12)⚠️ PostInstances คืน int idต้องคืน WfInstanceId ให้ orchestrator เก็บใน Correlations
resubmit (M13)Resubmit มียืนยัน contract (resume หลัง rework)
force-stop (M14)ForceStopStep มียืนยัน idempotent (stop ซ้ำ = no-op; ทน “ยังไม่ถูกสร้าง”)

W5 — Background sweep หมดอายุ

  • งาน expired → cancel local + publish Decision(Cancel, mode=Expiry) → orchestrator coordinate teardown

Open items (ต้องตัดสินกับทีม Workflow ก่อน lock contract)

  • pickup/claim มีไหม → ตัดสิน InReview (กระทบ status list ฝั่ง Lego)
  • แปลง native (APPROVE/REJECT/OnRejectToPhaseOrder) → Decision vocab ที่ publisher
  • payload M3-M5 field-level
  • reviewer = phase ถัดไป (assignee ของ next phase) — ยืนยัน model
  • create คืน WfInstanceId