690503:1036 Update workflow #02
This commit is contained in:
@@ -127,7 +127,7 @@ describe('WorkflowEngineService', () => {
|
|||||||
provide: getRepositoryToken(Attachment),
|
provide: getRepositoryToken(Attachment),
|
||||||
useValue: {
|
useValue: {
|
||||||
find: jest.fn(),
|
find: jest.fn(),
|
||||||
update: jest.fn(),
|
update: jest.fn().mockResolvedValue({ affected: 0 }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ provide: WorkflowDslService, useValue: mockDslService },
|
{ provide: WorkflowDslService, useValue: mockDslService },
|
||||||
@@ -727,7 +727,9 @@ describe('WorkflowEngineService', () => {
|
|||||||
|
|
||||||
it('T024d: should rollback attachments to temp when DB transaction fails (FR-019)', async () => {
|
it('T024d: should rollback attachments to temp when DB transaction fails (FR-019)', async () => {
|
||||||
// Arrange: commit ล้มเหลว — คาดว่า attachments จะถูก revert กลับเป็น temp
|
// Arrange: commit ล้มเหลว — คาดว่า attachments จะถูก revert กลับเป็น temp
|
||||||
(instanceRepo.findOne as jest.Mock).mockResolvedValue(null); // no pre-check needed (no attachment state)
|
(instanceRepo.findOne as jest.Mock).mockResolvedValue({
|
||||||
|
currentState: 'PENDING_REVIEW',
|
||||||
|
}); // ผ่าน pre-check, transaction จะ fail ที่ commit
|
||||||
mockQueryRunner.manager.findOne.mockResolvedValue({
|
mockQueryRunner.manager.findOne.mockResolvedValue({
|
||||||
...baseInstance,
|
...baseInstance,
|
||||||
versionNo: 5,
|
versionNo: 5,
|
||||||
@@ -759,7 +761,7 @@ describe('WorkflowEngineService', () => {
|
|||||||
// FR-019: attachmentRepo.update ต้องถูกเรียกเพื่อ revert ไฟล์กลับเป็น temp
|
// FR-019: attachmentRepo.update ต้องถูกเรียกเพื่อ revert ไฟล์กลับเป็น temp
|
||||||
expect(attachmentRepo.update).toHaveBeenCalledWith(
|
expect(attachmentRepo.update).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
publicId: ['att-rollback-1', 'att-rollback-2'],
|
publicId: In(['att-rollback-1', 'att-rollback-2']),
|
||||||
}),
|
}),
|
||||||
expect.objectContaining({ isTemporary: true })
|
expect.objectContaining({ isTemporary: true })
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
// EDITOR SETTINGS
|
// EDITOR SETTINGS
|
||||||
// ========================================
|
// ========================================
|
||||||
|
|
||||||
"editor.fontSize": 19,
|
"editor.fontSize": 18,
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"editor.lineHeight": 1.6,
|
"editor.lineHeight": 1.6,
|
||||||
"editor.rulers": [80, 120],
|
"editor.rulers": [80, 120],
|
||||||
|
|||||||
@@ -1724,6 +1724,7 @@ erDiagram
|
|||||||
| current_state | VARCHAR(50) | NOT NULL | สถานะปัจจุบัน |
|
| current_state | VARCHAR(50) | NOT NULL | สถานะปัจจุบัน |
|
||||||
| status | ENUM | DEFAULT 'ACTIVE' | ACTIVE, COMPLETED, CANCELLED, TERMINATED |
|
| status | ENUM | DEFAULT 'ACTIVE' | ACTIVE, COMPLETED, CANCELLED, TERMINATED |
|
||||||
| context | JSON | NULL | ตัวแปร Context สำหรับตัดสินใจ (รวม contractId, projectId, initiatorId เป็นต้น) |
|
| context | JSON | NULL | ตัวแปร Context สำหรับตัดสินใจ (รวม contractId, projectId, initiatorId เป็นต้น) |
|
||||||
|
| **version_no** | **INT** | **NOT NULL, DEFAULT 1** | **[ADR-001 v1.1 FR-002] Optimistic lock counter — incremented on every successful transition. Client sends current value; server rejects with 409 if mismatch.** |
|
||||||
| created_at | TIMESTAMP | DEFAULT NOW | เวลาที่สร้าง |
|
| created_at | TIMESTAMP | DEFAULT NOW | เวลาที่สร้าง |
|
||||||
| updated_at | TIMESTAMP | ON UPDATE | เวลาที่อัปเดตล่าสุด |
|
| updated_at | TIMESTAMP | ON UPDATE | เวลาที่อัปเดตล่าสุด |
|
||||||
|
|
||||||
@@ -1737,12 +1738,11 @@ erDiagram
|
|||||||
|
|
||||||
- PRIMARY KEY (id)
|
- PRIMARY KEY (id)
|
||||||
- FOREIGN KEY (definition_id) REFERENCES workflow_definitions(id) ON DELETE CASCADE
|
- FOREIGN KEY (definition_id) REFERENCES workflow_definitions(id) ON DELETE CASCADE
|
||||||
- **FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE SET NULL** [delta-07]
|
- FOREIGN KEY (contract_id) REFERENCES contracts(id) ON DELETE SET NULL
|
||||||
- INDEX (entity_type, entity_id)
|
- INDEX (entity_type, entity_id)
|
||||||
- INDEX (current_state)
|
- INDEX (current_state)
|
||||||
- **INDEX (contract_id, entity_type, status)** — `idx_wf_inst_contract` [delta-07]
|
- INDEX (contract_id, entity_type, status)
|
||||||
|
- INDEX (id, version_no) — `idx_wf_inst_version` [ADR-001 v1.1 FR-002] — Supports CAS check: WHERE id = ? AND version_no = ?
|
||||||
---
|
|
||||||
|
|
||||||
### 10.3 workflow_histories
|
### 10.3 workflow_histories
|
||||||
|
|
||||||
@@ -1756,6 +1756,7 @@ erDiagram
|
|||||||
| to_state | VARCHAR(50) | NOT NULL | สถานะปลายทาง |
|
| to_state | VARCHAR(50) | NOT NULL | สถานะปลายทาง |
|
||||||
| action | VARCHAR(50) | NOT NULL | Action ที่กระทำ |
|
| action | VARCHAR(50) | NOT NULL | Action ที่กระทำ |
|
||||||
| action_by_user_id | INT | FK, NULL | User ID ผู้กระทำ |
|
| action_by_user_id | INT | FK, NULL | User ID ผู้กระทำ |
|
||||||
|
| **action_by_user_uuid** | **VARCHAR(36)** | **NULL** | **[ADR-019 FR-003] UUID ของ User ผู้ดำเนินการ — ใช้ใน API Response แทน INT FK. NULL = System Action หรือ Pre-migration record** |
|
||||||
| comment | TEXT | NULL | ความเห็น |
|
| comment | TEXT | NULL | ความเห็น |
|
||||||
| metadata | JSON | NULL | Snapshot ข้อมูล ณ ขณะนั้น |
|
| metadata | JSON | NULL | Snapshot ข้อมูล ณ ขณะนั้น |
|
||||||
| created_at | TIMESTAMP | DEFAULT NOW | เวลาที่กระทำ |
|
| created_at | TIMESTAMP | DEFAULT NOW | เวลาที่กระทำ |
|
||||||
|
|||||||
@@ -1381,6 +1381,7 @@ CREATE TABLE workflow_instances (
|
|||||||
'TERMINATED'
|
'TERMINATED'
|
||||||
) DEFAULT 'ACTIVE' COMMENT 'สถานะภาพรวม',
|
) DEFAULT 'ACTIVE' COMMENT 'สถานะภาพรวม',
|
||||||
context JSON NULL COMMENT 'ตัวแปร Context สำหรับตัดสินใจ',
|
context JSON NULL COMMENT 'ตัวแปร Context สำหรับตัดสินใจ',
|
||||||
|
version_no INT NOT NULL DEFAULT 1 COMMENT 'Optimistic lock counter — incremented on every successful transition (ADR-001 v1.1 FR-002). Client sends current value; server rejects with 409 if mismatch.',
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
CONSTRAINT fk_wf_inst_def FOREIGN KEY (definition_id) REFERENCES workflow_definitions (id) ON DELETE CASCADE,
|
CONSTRAINT fk_wf_inst_def FOREIGN KEY (definition_id) REFERENCES workflow_definitions (id) ON DELETE CASCADE,
|
||||||
@@ -1394,6 +1395,9 @@ CREATE INDEX idx_wf_inst_contract ON workflow_instances (contract_id, entity_typ
|
|||||||
|
|
||||||
CREATE INDEX idx_wf_inst_state ON workflow_instances (current_state);
|
CREATE INDEX idx_wf_inst_state ON workflow_instances (current_state);
|
||||||
|
|
||||||
|
-- Index เพื่อรองรับ CAS check: WHERE id = ? AND version_no = ?
|
||||||
|
CREATE INDEX idx_wf_inst_version ON workflow_instances (id, version_no);
|
||||||
|
|
||||||
-- 3. ตารางเก็บประวัติ (Audit Log / History)
|
-- 3. ตารางเก็บประวัติ (Audit Log / History)
|
||||||
CREATE TABLE workflow_histories (
|
CREATE TABLE workflow_histories (
|
||||||
id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID',
|
id CHAR(36) NOT NULL PRIMARY KEY COMMENT 'UUID',
|
||||||
@@ -1402,6 +1406,7 @@ CREATE TABLE workflow_histories (
|
|||||||
to_state VARCHAR(50) NOT NULL COMMENT 'สถานะปลายทาง',
|
to_state VARCHAR(50) NOT NULL COMMENT 'สถานะปลายทาง',
|
||||||
ACTION VARCHAR(50) NOT NULL COMMENT 'Action ที่กระทำ',
|
ACTION VARCHAR(50) NOT NULL COMMENT 'Action ที่กระทำ',
|
||||||
action_by_user_id INT NULL COMMENT 'User ID ผู้กระทำ',
|
action_by_user_id INT NULL COMMENT 'User ID ผู้กระทำ',
|
||||||
|
action_by_user_uuid VARCHAR(36) NULL COMMENT 'UUID ของ User ผู้ดำเนินการ — ใช้ใน API Response แทน INT FK (ADR-019). NULL = System Action หรือ Pre-migration record',
|
||||||
COMMENT TEXT NULL COMMENT 'ความเห็น',
|
COMMENT TEXT NULL COMMENT 'ความเห็น',
|
||||||
metadata JSON NULL COMMENT 'Snapshot ข้อมูล ณ ขณะนั้น',
|
metadata JSON NULL COMMENT 'Snapshot ข้อมูล ณ ขณะนั้น',
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
|||||||
Reference in New Issue
Block a user