Files
solution-erp/.claude/workflows/runs/2026-07-27-S156-bch-post-ceo-flow/sub-invest-bch-1.md
2026-07-27 16:44:36 +07:00

22 KiB
Raw Blame History

sub-invest-bch-1 — Quy trình bước 7→21 (lane PROJECT/BCH) + wire + checklist

Run: 2026-07-27-S156-bch-post-ceo-flow · agent: investigator-codebase (/fable-real, effort max) Trạng thái file: GHI TRONG LÚC LÀM — mục nào chưa có ghi [PENDING]. File này = sản phẩm chính (#53 mitigation). Nguồn sự-thật sơ đồ: bảng 21 bước trong run.md cùng thư mục. KHÔNG bịa bước ngoài bảng.


0. Verify grounding lead (4 phép — làm lại từ đĩa, không tin suông)

Phép Lệnh em chạy Kết quả Khớp lead?
shopdrawing/TVGS/duyệt mẫu grep -rli "shopdrawing|TVGS|duyet mau|duyệt mẫu" trên src/Backend + fe-admin/src + fe-user/src 0 hit khớp — bước 8-9 đất trắng
ContractPhase LEGACY Read src/Backend/SolutionErp.Domain/Contracts/ContractPhase.cs 12 giá trị enum, 7 dòng [LEGACY] comment (DangChon/DangGopY/DangDamPhan/DangInKy/DangKiemTraCCM/DangTrinhKy/DangDongDau); sống = DangSoanThao=2, DaPhatHanh=9, ChoDuyet=10, TraLai=98, TuChoi=99 khớp (lead nói "6 LEGACY" — đếm lại là 7 kể cả DangChon=1; sai số nhỏ không đổi kết luận)
Cầu PE→HĐ Read CreateContractFromEvaluationFeatures.cs (204 dòng) CÓ THẬT, guard Phase==DaDuyet + IsWinner≥1 + ContractId==null, multi-winner → N HĐ draft khớp
PurchaseEvaluationPhase.DaDuyet=7 (đã biết từ S133/S155 + ListApprovedPurchaseEvaluationsQuery:173 filter Phase == DaDuyet) terminal thành công khớp

VÌ SAO LEGACY (quyết định câu ranh giới): ContractPhase.cs:3-13 ghi thẳng — post-Mig 21 (S16)

  • Session 17 spec 5-trạng-thái, 7 phase VẬT-LÝ trung gian (góp ý/đàm phán/in ký/CCM/trình ký/đóng dấu) bị CỐ Ý bỏ, thay bằng ChoDuyet=10 đơn nhất + con trỏ CurrentWorkflowStepIndex/CurrentApprovalLevelOrder chạy trên workflow V2 admin-config (ApprovalWorkflows Steps=Phòng > Levels=Cấp OR-of-N). ⇒ Các "trạm vật-lý" của bước 13→21 sơ đồ (đàm phán, ký nháy, CCM kiểm tra, CEO ký, HR đóng dấu) chính là những phase đã bị gỡ — công ty đã từng mô hình hoá đúng dải này bằng enum cứng và ĐÃ THAY bằng mô hình phẳng cấu hình được. Hồi sinh enum = đi ngược quyết định kiến trúc S16-S17.

1. VERDICT RANH GIỚI (deliverable B câu hỏi bắt buộc)

LAI — tách làm 2 khúc:

  • Bước 13→21 = TÁI DÙNG module Contract hiện có (không dựng mới, không hồi sinh LEGACY enum). Chứng:
    1. Cầu PE→HĐ có sẵn (CreateContractFromEvaluationFeatures.cs:92-115 tạo draft DangSoanThao + gen mã ngay + GiaTri = SUM quote IsSelected per winner).
    2. Contract V2 approve = cookie-cutter PE (ContractWorkflowService.cs:217-394 ApproveV2Async: OR-of-N match :259-260, UPSERT ContractLevelOpinions :292-316, skipToFinal :320-352, terminal gen mã + DaPhatHanh :366-385). Trạm 17→18→19 map thành Steps của 1 workflow ApplicableType.Contract=3 (ApprovalWorkflow.cs:57 — CÓ SẴN).
    3. Bước 15-16 (đàm phán giấy + ký nháy với thầu phụ NGOÀI hệ thống) = upload attachment AttachmentPurpose.ScannedSigned=2 (ContractAttachment.cs:8) + comment/changelog — mô hình phẳng hấp thụ trạm offline bằng chứng-từ đính kèm, đúng cách 7 phase cũ bị gỡ.
    4. Bước 19-20 (đóng dấu + scan lưu trữ) = SealedCopy=3 (ContractAttachment.cs:9) có sẵn.
  • Bước 7→12 = DỰNG MỚI (đất trắng có chứng 0-hit) — nhưng dựng theo khuôn cookie-cutter V2 có sẵn (12-bis đã lặp 12×: PE → Contract → Proposal → 4 WorkflowApps), KHÔNG phát minh pattern mới. Lý do không nhét vào PE: PE.Phase đã terminal DaDuyet, gắn thêm chuỗi duyệt thứ 2 lên cùng entity = 2 con trỏ workflow trên 1 record (mâu thuẫn ApprovalWorkflowId 1-cột). Lý do không nhét vào Contract: bước 8-12 xảy ra TRƯỚC khi có HĐ draft (bước 13 mới sinh draft); và giá trị ký HĐ được chốt ở bước 12 là INPUT cho draft.

Điểm LAI thứ 3 (phát hiện ngoài câu hỏi): cầu PE→HĐ hiện pin V1 WorkflowDefinitionId (CreateContractFromEvaluationFeatures.cs:68-71,108) và KHÔNG có tham số ApprovalWorkflowId V2, trong khi create-HĐ thường (ContractFeatures.cs:37,79,109) ĐÃ nhận pin V2 từ S29. HĐ sinh từ phiếu sẽ rơi nhánh V1 legacy (hardcoded policy fallback nếu V1 không có active def) — đúng lớp lỗi "cơ-chế đúng, thứ đi qua nó KHÔNG có". Muốn bước 13→21 chạy trạm V2 thì cầu PHẢI nhận + pin V2. [ĐÃ VERIFY — xem §2 mục B-1]


2. Chứng cứ nền đã thu (ghi dần)

  • ContractPhase.cs:14-28 — enum 12 giá trị, sống 5.
  • CreateContractFromEvaluationFeatures.cs:53-60 guard DaDuyet/winner/idempotent; :88-90 GiaTri per winner = SUM Quote.IsSelected của NCC đó; :104 carry PaymentTerms → DraftData; :106-107 carry NS kỳ này → BudgetManual*; :113 gen MaHopDong NGAY lúc tạo từ phiếu (khác luồng thường: gen ở terminal DaPhatHanh ContractWorkflowService.cs:371-377 — HĐ từ phiếu có mã trước khi duyệt).
  • ApprovalWorkflow.cs:53-67ApplicableType 9 giá trị (1-9), append-only (tiền lệ Mig 37 extend enum KHÔNG cần migration bảng). Slot 10 trống cho module mới.
  • ApprovalWorkflow.cs:43 CeoApprovalThreshold — grep toàn src/Backend: consumer CHỈ PE (PurchaseEvaluationWorkflowService.cs + PE features/DTOs + admin features). 0 hit trong ContractWorkflowService.cs ⇒ bước 18 "CEO ký nếu >5 tỷ" hiện KHÔNG có cơ chế phía HĐ (cột DB dùng chung có sẵn, service HĐ không đọc — admin set vào workflow Contract-type sẽ bị NGÓ LƠ im lặng).
  • ApprovalWorkflowLevel.cs:156-169Mig 68 AddPeAllowApproverDelete ĐÃ LAND (file mig 20260727033522_* tồn tại) ⇒ mọi migration mới của run này đánh số từ 69.
  • ContractAttachment.cs:5-11 — Purpose: DraftExport=1 / ScannedSigned=2 / SealedCopy=3 / Other=99. KHÔNG phân biệt ký-nháy (initial) vs ký-chính — bước 16 vs 17 cần thêm giá trị enum (int column, tiền lệ PE ComparisonTable=4 thêm enum không cần migration).
  • ContractsController.cs:12-13 — class-level [Authorize] TRẦN, 0 per-action policy (mirror PE S147/S155). 29 endpoint sống: CRUD + transitions + comments + attachments + 7×2 details + changelogs
    • department-approvals.
  • ContractWorkflowService.cs:341,358,390 — SLA V2 advance = hardcode AddDays(7); ApprovalWorkflowStep KHÔNG có cột SlaDays ⇒ SLA "3 ngày BCH bổ sung" (ghi chú sơ đồ) không config được per-step trong V2 hiện tại.

2-bis. Chứng cứ bổ sung (đo sau lần flush đầu — §3 trích dẫn các mục này)

  • ContractFeatures.cs:334-351 GetEligiblePhases — IDOR view-guard list/detail xây toàn bằng phase LEGACY: không role nào map ChoDuyet/DaPhatHanh/TraLai/TuChoi. Non-admin không-phải-drafter (CCM/CEO/HR/BCH) bị chặn xem HĐ đang ChoDuyet — kể cả HĐ chờ chính mình duyệt (:423-432 detail guard = isDrafter ∥ isEligibleByRole). BCH (thường ProjectManager) không thấy cả DangSoanThao (chỉ Drafter/DeptManager, :342-343).
  • ContractFeatures.cs:363-372 inbox PhaseActorRoles — cũng 100% legacy-map, không có entry ChoDuyet ⇒ HĐ V2 đang chờ duyệt KHÔNG vào inbox của ai (PE có ResolveV2InboxIdsAsync, HĐ chưa từng được mirror).
  • ContractWorkflowService.cs:407-427 notify khi transition → chỉ Drafter; không báo approver kế / BCH. ContractWorkflowService.cs:49-66 nhánh Reject: không guard theo cấp, TraLai clear pointer — trình lại chạy từ Bước 1 Cấp 1 (không có 4 return-mode như PE).
  • ContractFeatures.cs:151-157 UpdateContractDraft — guard duy nhất Phase==DangSoanThao, không check drafter ⇒ BCH sửa draft được về mặt cơ chế (nếu qua được view-guard); nhưng command không có ApprovalWorkflowId ⇒ không có đường re-pin V2 sau khi tạo.
  • fe-user/src/pages/contracts/ContractDetailPage.tsx:1-36 — wrapper mỏng; UI thật ở components/contracts/ContractDetailContent + WorkflowHistoryPanel (2 app mirror).
  • CreateContractFromEvaluationFeatures.cs:113 + ContractFeatures.cs:113-118 — HĐ (cả 2 đường tạo) gen MaHopDong NGAY lúc create, không đợi terminal (khác skill-doc cũ "gen ở DangDongDau").

3. QUY TRÌNH CHI TIẾT — bước 7→21 dịch sang ngôn ngữ hệ thống (deliverable A)

Bước 1-6 = module PE hiện tại, kết ở PE.DaDuyet=7 — KHÔNG đụng. ❓Q<n> = mơ hồ/thiếu/mâu thuẫn, chi tiết ở §6. "PMH" = Phòng Mua hàng/Cung ứng (Procurement). "TP" = thầu phụ. Cột SLA = đúng những gì sơ đồ ghi (3 mốc), "—" = sơ đồ không ghi.

# Lane Actor Trigger Input Output Điều kiện chuyển Nhánh lỗi SLA
7 Procurement PMH PE chạm DaDuyet=7 Phiếu PE (winners IsWinner, giá SUM Quote.IsSelected, HoSoLink NAS) Mail thông tin cho BCH/NTP/NCC phối hợp bước tiếp Gửi xong → 8 NTP/NCC = bên NGOÀI, email external chưa có (SMTP TODO) Q8 · "BCH dự án X" chưa có định danh trong hệ thống Q1
8 PROJECT BCH + TVGS (TVGS = tư vấn giám sát NGOÀI hệ thống Q7) Nhận thông tin b.7 Mẫu vật liệu + shopdrawing từ TP/NCC Mẫu ĐƯỢC DUYỆT + shopdrawing ĐƯỢC DUYỆT (TVGS xác nhận) Đủ bộ được duyệt → 9 TVGS bác mẫu → TP/NCC nộp lại — sơ đồ KHÔNG vẽ vòng lặp; hệ thống = trạng thái per-item (nộp/duyệt/bác)
9 PROJECT BCH Bộ b.8 đủ Hồ sơ mẫu+shopdrawing đã duyệt + báo giá từ PE Hồ sơ SO SÁNH GIÁ + ĐỀ XUẤT giá trị ký HĐ Gửi PMH → 10 Ghi chú sơ đồ: "hồ sơ sai sót thiếu khối lượng, sai spec, thiếu phạm vi → gửi mail làm rõ xác nhận"
10 Procurement PMH Nhận đề xuất BCH Hồ sơ so sánh giá + giá đề xuất Giá trị HĐ TP xác nhận lại, chuyển CCM OK → 11 Không OK → trả BCH (sơ đồ không vẽ nhánh trả)
11 CCM CCM Nhận từ 10 Hồ sơ + giá đã xác nhận Kết quả CCM kiểm tra Pass → 12 Fail → ? sơ đồ không vẽ (map hệ thống = Trả lại)
12 CEO CEO hoặc CCM Nhận từ 11 Hồ sơ giá trị ký HĐ GIÁ TRỊ KÝ HĐ ĐƯỢC CHỐT (CEO ký / CCM đóng dấu approval) Chốt → 13 Điều kiện rẽ CEO-vs-CCM sơ đồ KHÔNG ghi Q3 — khuôn gần nhất = CeoApprovalThreshold (PE-only)
13 Procurement PMH (= Drafter HĐ) Giá chốt b.12 Phiếu PE + giá chốt Q6 + full bản vẽ/khối lượng/tính toán BCH gửi (ghi chú PHỐI HỢP) HĐ DRAFT — hệ thống ĐÃ có cầu POST /purchase-evaluations/{id}/create-contract (DangSoanThao, gen mã ngay, N HĐ nếu multi-winner) — gửi BCH kiểm tra Draft tới tay BCH → 14 "Gửi BCH" hiện KHÔNG có kênh: notify chỉ Drafter + inbox HĐ legacy-map (§2-bis) · cầu pin V1 không nhận V2 (§1) BCH gửi info trong 3 ngày · khúc 13→18 = 7-10 ngày
14 PROJECT BCH Nhận draft HĐ draft + scope/tiến độ thực tế Draft ĐÃ bổ sung thông tin, gửi lại PMH xác nhận trước khi gửi TP PMH xác nhận → 15 Thiếu info → lặp 13↔14 (sơ đồ ghi PHỐI HỢP) · hệ thống: BCH bị IDOR-guard chặn XEM draft (role thường không map DangSoanThao §2-bis) Q1 — sửa được thì cơ chế edit đã mở (update không check drafter) 3 ngày
15 Procurement PMH ↔ TP (ngoài hệ thống) Draft đã xác nhận HĐ bản gửi TP TP kiểm tra + đàm phán; TP chuyển bản về BCH ký nháy TP đồng ý + ký nháy → 16 Đàm phán đổi giá/điều khoản → quay về đâu (13 sửa draft? hủy?) — sơ đồ không vẽ Q13 trong khúc 7-10d
16 PROJECT BCH Nhận bản TP đã ký nháy HĐ giấy ký nháy Chuyển bản ký nháy về PMH — hệ thống = upload scan (attachment không phase-guard, up được mọi phase) PMH nhận → 17 AttachmentPurpose chưa có loại "ký nháy" (chỉ ScannedSigned/SealedCopy) Q12 trong khúc 7-10d
17 Procurement + CCM PMH trình; CCM duyệt Nhận HĐ ký nháy HĐ + hồ sơ PMH "chuyển sang trình ký (ký nháy hoặc ký chính Q12)" — hệ thống = trình DangSoanThao→ChoDuyet, CCM = Step V2 đầu, CCM kiểm tra + KÝ NHÁY CCM duyệt → 18 CCM trả lại → TraLai reset TOÀN BỘ chuỗi (không có return-1-cấp như PE) Q9 trong khúc 7-10d
18 CEO CEO CCM xong b.17 HĐ + giá trị CEO ký HĐ nếu GiaTri > 5 tỷ Ký (hoặc ≤5 tỷ: skip — AI ký chính? Q4) → 19 CEO từ chối → TuChoi/TraLai · cơ chế ngưỡng phía HĐ CHƯA TỒN TẠI (CeoApprovalThreshold 0-consumer HĐ §2) Q5 · multi-winner: ngưỡng per-HĐ hay per-GÓI Q4 kết khúc 7-10d
19 Procurement PMH → HR HĐ ký xong HĐ ký chính HR đóng dấu — hệ thống: HR = Step V2 cuối; sau đó terminal DaPhatHanh (mã HĐ đã gen từ create) Đóng dấu → 20
20 CCM CCM HĐ đã đóng dấu HĐ hoàn chỉnh Scan lưu trữ — AttachmentPurpose.SealedCopy=3 CÓ SẴN, up được ở DaPhatHanh Upload → 21
21 Procurement PMH Bản lưu xong HĐ giấy Chuyển phát nhanh về TP XONG (hệ thống: HĐ đứng DaPhatHanh terminal) Theo dõi vận đơn ngoài hệ thống Q14

Đọc bảng theo hệ thống — 4 khúc:

  1. 7-12 = ĐẤT TRẮNG (0-hit §0) — chuỗi: BCH làm hồ sơ (8-9) → duyệt 3 trạm PMH→CCM→CEO/CCM (10-12). Cấu trúc 10-12 giống hệt 1 workflow V2 3-Step. Kiến trúc chọn ở Q2.
  2. 13-14 = DangSoanThao (draft cộng tác PMH↔BCH — cơ chế edit mở sẵn, cơ chế XEM đang chặn BCH).
  3. 15-16 = offline/giấy — hệ thống ghi vết bằng attachment + comment, không phase riêng (đúng triết lý Mig 21 đã gỡ DangDamPhan/DangInKy).
  4. 17-19 = ChoDuyet chạy Steps V2 (CCM → CEO-theo-ngưỡng → HR) → 20-21 = DaPhatHanh + attachment. Lane ⑥ ghi chú NCC "phải duyệt mẫu/shopdrawing MỚI ký HĐ" = GATE giữa khúc 1 và khúc 4 Q11.

4. [PENDING] Wire chi tiết B

5. [PENDING] Checklist C

6. CÂU HỎI CHO OWNER (14 câu — Q1-Q6 CHẶN THIẾT KẾ, trả lời khác ⇒ wire khác)

Q1 🔴 CHẶN — "BCH Công trường của dự án X" là AI trong hệ thống? Vì sao hỏi: không tồn tại model nào — Department.ManagerUserId 0/10 row Dev + FE hardcode null (S155), User.PositionLevel 33/33 NULL, Project không có field team/BCH; đồng thời IDOR-guard hiện chặn BCH xem HĐ (§2-bis). Phương án: (a) thêm Project.BchDepartmentId/bảng ProjectMembers → model đúng nhưng +migration +màn admin gán; (b) role mới SiteCommand + so DepartmentId → rẻ hơn nhưng không phân biệt được BCH dự án A vs B; (c) làm như PE: chỉ đích danh user trong Level của workflow V2 (không cần model BCH) → 0 migration, nhưng "BCH" chỉ tồn tại trong từng quy trình, đổi người = sửa quy trình (mà V2 KHÔNG có lệnh Update — S155). Chọn phương án nào?

Q2 🔴 CHẶN — Khúc 8-12 dựng thành module MỚI hay Contract-sớm? Vì sao hỏi: sơ đồ chỉ sinh HĐ draft ở b.13, nhưng 10-12 lại là chuỗi duyệt giống hệt V2. Phương án: (a) module mới "Hồ sơ sau trúng thầu" (PostAward) FK→PE, có Phase + ApprovalWorkflowId riêng (ApplicableType=10 append-only theo tiền lệ Mig 37), duyệt xong mới cho tạo HĐ → tách bạch, mirror khuôn 12-bis (PE/Proposal/WorkflowApps), nhưng +N bảng +menu +2 FE; (b) tạo Contract NGAY sau b.7 và cho HĐ trình 2 VÒNG (vòng giá 10-12, vòng ký 17-19) → ít bảng mới nhưng phá state machine 5-trạng-thái hiện tại (1 HĐ 2 lần ChoDuyet = đổi service + FE lớn, rủi ro cao); (c) tối giản: 8-9 chỉ là attachment + checklist trên PE (không workflow 10-12 trong hệ thống, PMH/CCM/CEO xác nhận ngoài) → gần như 0 công BE, nhưng mất vết duyệt 10-12. Em nghiêng (a) hoặc (c) — (b) khuyên tránh; anh chốt?

Q3 🔴 CHẶN — Bước 12: điều kiện nào rẽ "CEO ký" vs "CCM đóng dấu approval"? Vì sao hỏi: sơ đồ ghi "hoặc" không ghi điều kiện. Cùng ngưỡng 5 tỷ như b.18? Hay CCM luôn đóng dấu và CEO chỉ ký gói lớn? Ảnh hưởng: cấu hình workflow khúc 10-12 (nếu Q2=a) — có Step CEO điều kiện hay không.

Q4 🔴 CHẶN — Bước 18: HĐ ≤ 5 tỷ thì AI ký chính? Và 5 tỷ tính trên gì khi multi-winner? Vì sao hỏi: (i) sơ đồ chỉ nói CEO ký >5 tỷ, không nói nhánh còn lại (role AuthorizedSigner có sẵn trong hệ thống — dùng?); (ii) 1 phiếu PE liên-danh sinh N HĐ, MỖI HĐ 1 GiaTri riêng (CreateContractFromEvaluationFeatures.cs:88-90) — gói 6 tỷ chia 3 HĐ × 2 tỷ sẽ TRƯỢT ngưỡng nếu tính per-HĐ. Per-HĐ hay per-gói (SUM các HĐ cùng phiếu)?

Q5 🔴 CHẶN — Cơ chế ngưỡng b.18 phía HĐ wire kiểu nào? (phụ thuộc Q4) Vì sao hỏi: CeoApprovalThreshold là cột CHUNG bảng ApprovalWorkflows nhưng chỉ PE service đọc — admin set vào workflow Contract-type sẽ bị ngó lơ im lặng (§2). Phương án: (a) port logic threshold vào ContractWorkflowService.ApproveV2Async (mirror PE, 0 migration, cột sẵn) — CCM finalize khi GiaTri < ngưỡng; (b) 2 workflow Contract-type (có/không Step CEO), PMH chọn theo giá trị lúc trình — 0 code BE nhưng dựa kỷ luật người dùng, sai chọn = sai luồng; (c) port AllowApproverFinalize per-slot (cũng đang PE-only). (a) đúng tinh thần "5 tỷ" tự động nhất.

Q6 🔴 CHẶN — Giá trị nào ghi vào HĐ: giá CHỐT bước 12 hay SUM báo giá PE? Vì sao hỏi: cầu hiện lấy SUM Quote.IsSelected từ PE; nhưng b.9-12 tồn tại chính vì khối lượng/giá sau duyệt mẫu + shopdrawing có thể LỆCH con số PE. Nếu giá-12 thắng: cần chỗ lưu giá chốt (PostAward nếu Q2=a) + cầu đọc từ đó + audit lệch PE-vs-chốt. Nếu PE thắng: b.10-12 chỉ là xác nhận, lệch xử lý bằng sửa tay draft (đã cho phép sửa GiaTri ở DangSoanThao).

Q7 — TVGS là user đăng nhập hay chỉ được ghi vết? Vì sao hỏi: TVGS = tư vấn giám sát phía chủ đầu tư, NGOÀI công ty. Phương án: (a) BCH nhập hộ kết quả (tên TVGS + ngày + scan chữ ký) → 0 user mới, khuyến nghị; (b) cấp account TVGS → thêm role + permission + rủi ro lộ dữ liệu nội bộ. Sơ đồ không đòi (b) — xác nhận (a)?

Q8 — Email ra NGOÀI (b.7 NTP/NCC, b.15 gửi TP, b.21 báo chuyển phát) có trong scope hệ thống không? Vì sao hỏi: SMTP outbox = TODO toàn hệ thống (CLAUDE.md); notification hiện in-app + SignalR nội bộ. Nếu trong scope → mở công trình email riêng (MailKit + template + địa chỉ NCC từ Supplier 30-field). Nếu ngoài (PMH gửi Outlook tay) → hệ thống chỉ cần nút "đánh dấu đã gửi" + changelog.

Q9 — Trả lại giữa khúc 17-19 chấp nhận reset-về-đầu không? Vì sao hỏi: HĐ V2 chỉ có TraLai toàn-phần (ContractWorkflowService.cs:57-61 — trình lại chạy từ Bước 1 Cấp 1); PE có 4 return-mode (1-cấp/1-bước/assignee/drafter) nhưng HĐ chưa từng port. CEO trả 1 câu chữ → đi lại từ CCM. Chấp nhận (0 công) hay port return-mode (công vừa, mirror PE)?

Q10 — SLA "3 ngày" (13-14) và "7-10 ngày" (13→18) có cần hệ thống ENFORCE không? Vì sao hỏi: V2 không có per-step SLA — service hardcode AddDays(7) mọi bước (§2), muốn đúng 3 ngày phải thêm cột SlaDays vào ApprovalWorkflowSteps (+migration +Designer +service đọc). Hay chỉ cần hiển thị deadline tham khảo (0 công, dùng 7d mặc định)?

Q11 — Gate lane ⑥: "NCC phải duyệt mẫu/shopdrawing MỚI ký HĐ" — chặn CỨNG hay cảnh báo MỀM? Vì sao hỏi: quyết định guard ở đâu: (cứng) chặn trình-ký/tạo-HĐ khi package 8-9 chưa đủ — cần Q2=a để có trạng thái machine-checkable; (mềm) banner cảnh báo — rẻ, giữ linh hoạt (khuôn "vượt ngân sách = cảnh báo mềm" S62 đã có tiền lệ). Và gate áp cho cả THẦU PHỤ không (sơ đồ chỉ ghi cho NCC; TP ký "song song HĐ chủ đầu tư")?

Q12 — Phân biệt ký NHÁY vs ký CHÍNH bằng gì? Vì sao hỏi: AttachmentPurpose chỉ có ScannedSigned/SealedCopy — b.16 (TP ký nháy), b.17 (CCM ký nháy), b.18 (ký chính) hiện không phân biệt được. Phương án: thêm enum InitialSigned=4 (int column, KHÔNG cần migration — tiền lệ PE ComparisonTable=4) — đủ chưa, hay owner muốn trạng thái ký riêng trên HĐ?

Q13 — Bước 15 đàm phán làm ĐỔI nội dung/giá thì quay về đâu? Vì sao hỏi: sơ đồ không vẽ nhánh lùi 15→13. HĐ đang DangSoanThao thì sửa thoải mái (cơ chế mở); nhưng nếu lúc đó đã trình (ChoDuyet) thì phải TraLai. Quy ước vận hành: CHỈ trình sau khi TP chốt xong (16)? — nếu vậy b.17 "trình ký" là điểm trình DUY NHẤT, khớp mapping §3 khúc 4.

Q14 — Bước 21 có cần lưu mã vận đơn chuyển phát không? (phụ, không chặn) Nếu cần: +1 field/ghi chú attachment; nếu không: comment đủ.