Files
solution-erp/docs/changelog/sessions/2026-05-08-1100-pe-workflow-v2-end-to-end.md
pqhuy1987 8680f4c849 [CLAUDE] Docs: Session 17 wrap-up — PE Workflow V2 end-to-end consolidation
User chốt MD wrap-up Session 17 (13 commit từ c847dc0de0f38d) — PE
Workflow V2 schema + Service wire + UX iteration đầy đủ.

MD updates:
- STATUS.md — header counts (24 mig, 58 tables, 81 test, 43 gotcha) +
  Recently Done row consolidate Session 17 wrap-up (gộp 4 row iter cũ
  thành 1 row tổng, không cắt narrative quan trọng)
- HANDOFF.md — TL;DR Session 17 + Chunk E (Designer iter + State
  machine + Service wire + UX) + Pending Session 18+
- CLAUDE.md — count (22→24 mig, 77→81 test) + V2 schema overview
- changelog/migration-todos.md — section  Session 17 done với 7 task
  ticked + Defer Session 18+ explicit
- database/schema-diagram.md — §14 ApprovalWorkflow V2 schema (3 bảng
  + 2 column PE + state transitions + Service branch + Designer
  constraints + match approver V2 vs V1 table)
- gotchas.md — +#42 Dual schema branch + #43 Step.Order ≠ index 0-based
- skill contract-workflow — +section "Phase 9+ done Mig 22-24" với V2
  spec + Service branch + match logic table + Designer constraints +
  UX V2-aware + Defer Session 18+
- changelog/sessions/2026-05-08-1100-pe-workflow-v2-end-to-end.md (NEW)
  — full session log với 13 commit timeline + stats + gotchas + pending

Memory:
- project_solution_erp.md — entry Session 17 wrap-up đầy đủ (KHÔNG tạo
  file feedback mới — decisions specific cho project, không reusable
  cross-project per §9.5 anti-pattern)

Verify:
- 81 test pass (58 Domain + 23 Infra) — không thay đổi sau wrap-up
- 0 BE error
- 2 FE builds OK (đã verify ở các commit trước)
- Quy tắc consolidate §6.5: KHÔNG cắt narrative, chỉ phân tầng + remove
  duplicate. Session 17 row dài cố ý — cover full 13 commit context cho
  Session 18+ đọc lại.
2026-05-08 16:40:49 +07:00

6.7 KiB
Raw Blame History

2026-05-08 (Session 17 wrap-up) — PE Workflow V2 schema + Service wire end-to-end

13 commit từ c847dc0de0f38d. Resume từ Session 16 (drastic refactor flat Mig 21) — user phát hiện schema flat vẫn không đúng intent → yêu cầu schema riêng + Menu mới.

Spec từ user

Mã Quy trình - Tên Quy trình
  * Bước 1 - Phòng A
    * Cấp 1 - NV X (1 NV cụ thể qua ApproverUserId)
    * Cấp 2 - NV Y
  * Bước 2 - Phòng B
    * Cấp 1 - NV Z

Khác Mig 21: mỗi Cấp = NV CỤ THỂ qua ApproverUserId, KHÔNG group Dept+PositionLevel/Role/User.

State machine 5 trạng thái (Option A user chốt diagram)

Nháp ──Drafter trình──► Đã gửi duyệt ──approve cấp cuối──► Đã duyệt (terminal)
                                     ├─ Trả lại ──────────► Trả lại
                                     └─ Từ chối ──────────► Từ chối (terminal)
Trả lại ──Drafter sửa+gửi lại──► Đã gửi duyệt (chạy LẠI từ Cấp 1 Bước 1)

Trả lại = Phase RIÊNG (TraLai=98), KHÔNG revert DangSoanThao + KHÔNG jump-back. Drafter từ TraLai gửi lại = entry point thứ 2 mirror DangSoanThao → workflow chạy lại từ đầu.

Migration 22-24 (3 mig mới)

Mig Tên Nội dung
22 AddApprovalWorkflowsV2 3 entity: ApprovalWorkflow + Step + Level + ApplicableType enum (DuyetNcc/DuyetNccPhuongAn/Contract). 3 CREATE TABLE + UNIQUE (Code, Version) + FK Cascade Step→Workflow + Level→Step + FK Restrict Department + ApproverUserId. Menu V2 seed
23 AddApprovalWorkflowIdToPurchaseEvaluation PE.ApprovalWorkflowId Guid? FK Restrict — pin V2 lúc create
24 AddCurrentApprovalLevelOrderToPe PE.CurrentApprovalLevelOrder int? — track Cấp đang chờ

13 commit timeline

# Commit Tóm tắt
1 c847dc0 Chunk A — Domain V2 + EF Config + Mig 22 + Menu seed
2 f6047d5 Chunk B — Application CQRS + API ApprovalWorkflowsV2Controller
3 2781c7e Chunk C — FE Designer ~480 LOC ApprovalWorkflowsV2Page.tsx
4 12daa7f Chunk D — Docs Schema mới
5 9712778 Designer iter 1 — lock 3 cấp/bước (sai intent)
6 f3bea3c Designer iter 2 — đúng intent: max 3 cấp × N NV/cấp + sequential gating + filter Phòng + Validator BE strict
7 ff21120 State machine 5 trạng thái — TraLai Phase riêng. Policy + Service Reject branch → TraLai. 4 test mới TraLai entry. FE rename "Bản nháp" → "Nháp"
8 d642fd3 Docs STATUS Session 17 5 trạng thái
9 0a40c65 Mig 23 pin V2 vào PE + Workspace Select V2
10 b41484b Mig 24 + Service V2 wire ApproveV2Async + Synthetic Policy ForV2Schema
11 d814429 UX disable button non-approver + banner "Đến lượt bạn" / "Không phải lượt" + DTO CurrentApproval
12 9e63e2d d250ae4 74745a7 List/Inbox V2-aware + 2 dropdown filter (chỉ ở Duyệt)
13 ac41d5e SQL clean prod + test user nv.test@solutions.com.vn
de0f38d Panel 3 flow render — bỏ phase cards, hiện Bước/Cấp với Status Done/Current/Pending

Service V2 wire — branch theo schema pin

// PurchaseEvaluationWorkflowService.TransitionAsync (Mig 24)
if (evaluation.ApprovalWorkflowId is Guid awId)
    await ApproveV2Async(...)
        // Load AW.Steps + Levels Include 3-level
        // Group Levels by Order = Cấp (OR-of-N approvers cùng cấp)
        // Match actor.Id ∈ ApproverUserId
        // Advance: levelOrder++ trong Step → idx++ + reset levelOrder=1 → DaDuyet
else
    await ApproveV1LegacyAsync(...)  // giữ logic Mig 21

UX V2-aware

  • Banner emerald "✓ Đến lượt bạn duyệt" / amber "⚠ Không phải lượt bạn — chỉ {NV X / Y} duyệt được"
  • Button Duyệt forward disabled khi V2 + actor không trong Cấp + tooltip
  • Trả lại + Từ chối vẫn enabled (BE không gating reject theo cấp)
  • Inbox ResolveV2InboxIdsAsync precompute IDs khớp actor.Id
  • 2 dropdown filter "Quy trình duyệt" + "Trạng thái" (chỉ ở Duyệt — Danh sách giữ 1 dropdown)
  • Panel 3 thay 4 phase cards bằng flow workflow thực tế:
    ✓ Bước 1 — Phòng CCM
       ✓ Cấp 1 (đã duyệt) NV Test
       ● Cấp 2 (đang chờ) Phan Văn Chương   ← highlight brand
       ○ Cấp 3 (chưa)     Nguyễn Văn Trường
    

Test setup prod

  • SQL clean-transactional-uat.sql xóa 9 PE + 11 HĐ + 19 Notif + reset CodeSequences. Giữ master (Users=8, Suppliers=19, Projects=9, Departments=9, V1+V2 Workflows). Run via SSH VPS .\SQLEXPRESS.
  • Test user nv.test@solutions.com.vn / TestUser@123456 (Drafter, CCM, ID 881269c7-dbb5-4aad-a92c-08deace07898) tạo qua API admin POST /api/users.

Stats final Session 17

Trước Sau
Migrations 21 24 (+3)
DB tables 55 58 (+3)
API endpoints ~134 ~140 (+5)
FE pages 32 33 (+1)
Test pass 77 81 (+4 TraLai entry point)
Gotchas 41 43 (+2 dual schema + Step.Order ≠ index)

Gotchas mới (2)

  • #42 Dual schema V1 vs V2 — Service phải branch theo pin field: phiếu pin V2 mà Service đọc WorkflowDefinitionId → match approver schema cũ → Forbidden. Fix: branch if (ApprovalWorkflowId is Guid)ApproveV2Async.
  • #43 Step.Order ≠ index 0-based: EF không thể query Step.Order == idx + 1 thẳng. Cần precompute candidates EF + in-memory sort by Order + array index.

Pending Session 18+

Task Estimate Priority
Contract V2 wire (Mig 25) 4-6h dedicated session High (sau khi PE UAT confirm)
Phân quyền strict V2 2h Medium
Drop legacy V1 + cleanup deprecated columns Mig 26 cleanup, 2h Low (chờ migrate hết phiếu cũ)
Test Domain ApproveV2Async + match logic 3h Medium
Budget V2 wire (Mig 27) 4h dedicated Low
Admin role bypass option C audit log 2h Low

Memory entry — không tạo mới

Session 17 decisions ghi đầy đủ vào memory/project_solution_erp.md. Pattern dual schema reusable nhưng quá specific cho project — không tạo feedback_dual_schema_pattern.md riêng (anti-pattern §9.5 "viết skill chỉ để có thêm" áp dụng cho memory).

Skill update

contract-workflow skill +section "Phase 9+ done (Mig 22-24 — Session 17) — V2 schema riêng + state machine 5 trạng thái" — mention V2 cross-ref + Service branch + match logic V2 vs V1 table + Designer constraints.

KHÔNG tạo skill pe-workflow-v2 mới — overlap với contract-workflow existing skill (cùng pattern state machine + versioned WF, khác schema).