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

223 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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-67``ApplicableType` 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-169`**Mig 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 (/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?**
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 khối lượng/giá
sau duyệt mẫu + shopdrawing 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ỉ xác nhận, lệch xử
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?**
sao hỏi: TVGS = vấn giám sát phía chủ đầu , NGOÀI công ty. Phương án: (a) BCH nhập hộ kết quả
(tên TVGS + ngày + scan chữ ) 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ộ. đồ 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?**
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?**
sao hỏi: V2 chỉ TraLai toàn-phần (`ContractWorkflowService.cs:57-61` trình lại chạy từ Bước 1
Cấp 1); PE 4 return-mode (1-cấp/1-bước/assignee/drafter) nhưng 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?**
sao hỏi: V2 không 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?**
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 để
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 đã tiền lệ). gate áp cho cả THẦU PHỤ không ( đồ chỉ ghi cho NCC; TP
"song song chủ đầu ")?
**Q12 — Phân biệt ký NHÁY vs ký CHÍNH bằng gì?**
sao hỏi: `AttachmentPurpose` chỉ ScannedSigned/SealedCopy b.16 (TP nháy), b.17 (CCM nháy),
b.18 ( 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 riêng trên ?
**Q13 — Bước 15 đàm phán làm ĐỔI nội dung/giá thì quay về đâu?**
sao hỏi: đồ không vẽ nhánh lùi 1513. đang DangSoanThao thì sửa thoải mái ( 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 " đ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 đủ.