From 32ef4bcb77e86f809c8c29dd2ebb992862dd22fa Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Wed, 29 Jul 2026 15:51:33 +0700 Subject: [PATCH] wal: flush 20260729T1551 --- .../2026-07-29-S160-khkk-dryrun-plan/run.md | 1 + .../sub-investigator-codebase-1.md | 187 +++++++++++++++++- .../sub-investigator-codebase-2.md | 60 ++++++ 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 .claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-2.md diff --git a/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/run.md b/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/run.md index 4ee8a1e..b2e4f51 100644 --- a/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/run.md +++ b/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/run.md @@ -51,3 +51,4 @@ - [x] 1. scaffold + extract (15:45-15:50) - [!] 2+3. 2 lane `/fable-real investigator-codebase` model=fable PHÓNG SONG SONG ~15:55 (lane-1 nguồn GĐ3-GĐ4 → `sub-investigator-codebase-1.md` · lane-2 codebase map → `sub-investigator-codebase-2.md` — cả 2 ghi-đĩa-trong-lúc-làm, kết bằng END+TOTAL line) + - lane-2 lượt-1 ~16:03: **#53 garble** (return = mẩu "## Q2 — Bridge…"); đĩa cứu §0-§2 (Q1-Q2, 11.039B ruột thật — Q1 có RE-VERIFY line-trôi vs S156 do arc-2 thêm ListDeleted); **SendMessage-resume** làm nốt Q3-Q7 append cùng file diff --git a/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-1.md b/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-1.md index 79aa216..87da56d 100644 --- a/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-1.md +++ b/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-1.md @@ -27,4 +27,189 @@ TABLE 1 hàng theo thứ tự (cột Trách nhiệm + Thời gian — tên bư | :54 | HRA | (không ghi) | Đóng dấu | | :55 | PB/BCH CT/CCM | (không ghi) | Phát hành + Lưu trữ | -(tiếp tục append bên dưới) +### F-04. FO-002.01 đọc xong (40r×13c, 1 table) + +Cấu trúc form: header thông-tin HĐ (`:8-11` Phòng ban/Dự án · Loại HĐ tick-box · Tên đối tác · Nội dung) + 4 KHỐI KÝ per-phòng (`:15-45`) + LƯU Ý 3 luật (`:46`). + +**4 khối ký + mục tick từng khối** (mỗi khối có Họ tên + Ngày): +1. PHÒNG BAN/DỰ ÁN — ĐỀ XUẤT (`:15-20`): tick ①Soạn thảo ②Nội dung HĐ +2. PHÒNG CUNG ỨNG — PRO (`:21-30`): tick ①Điều khoản HĐ ②Điều khoản t/toán ③Rủi ro pháp lý HĐ +3. PHÒNG CCM (`:31-40`): tick ①G/trị HĐ so với NS ②Rủi ro pháp lý HĐ +4. GIÁM ĐỐC / NĐUQ (`:41-45`): "Ký kết, phát hành" (1 mục) + +**LƯU Ý (`:46`) — 3 luật nghiệp vụ:** +- (a) HĐ **Chủ đầu tư**: đơn vị đề xuất chuyển TRỰC TIẾP Giám đốc (bỏ PRO+CCM). Mọi loại còn lại PHẢI qua PRO và CCM trước. → khớp cờ `BypassProcurementAndCCM` đã có trong code (lane-2 verify). +- (b) Mỗi bộ phận CHỈ 01 NGÀY xử lý; quá 01 ngày chưa xong = **XEM NHƯ ĐÃ THÔNG QUA** (auto-pass). Kéo dài phải báo bộ phận soạn thảo + ghi chú vào "Ý kiến". → mâu thuẫn V2 no-auto-approve (đã biết S157, owner O-2: SLA=tham khảo). +- (c) Bảng kiểm tra PHẢI lưu kèm bộ hồ sơ gốc → FO-002.01 là ARTIFACT của bộ HĐ cứng, không chỉ màn hình. + +**Tick-box Loại HĐ trên form (`:9`): 6 lựa chọn** = Chủ đầu tư / Nhà cung cấp / Thầu phụ / Tổ đội / Thiết bị thuê / Khác — KHÔNG 1:1 với 7 ContractType repo (không có Mua bán/Dịch vụ/Nguyên tắc riêng; có "Thiết bị thuê" + "Khác" mà repo không có). Ghi nhận diff phân loại, form-render cần map. + +**Chuỗi ký FO-002.01 = ĐỀ XUẤT → PRO → CCM → GIÁM ĐỐC.** QT TABLE 2 chỉ nêu cover được ký ở b.17 (PD/PM/TPB), b.18 (CCM), b.19 (BOD) — **PRO không có trạm riêng trong lưu đồ QT** nhưng có khối ký trên cover + LƯU Ý (a) buộc "qua PRO và CCM". → QT mơ hồ chỗ này; đề xuất: PRO ký cover trong khoảng b.17→b.18 (sau ký nháy nội bộ, trước CCM). + +### F-05. RG-001 v02 đọc xong (2.907B) + +**Mã HĐ `A/B/SOL&C/D`** (`:7`): A=Code dự án HOẶC Năm (HĐ dịch vụ/nguyên tắc) · B=viết tắt loại HĐ · C=viết tắt TP/NCC/TĐ/NC/ĐVDV · D=STT từ 01. + +**Bộ viết tắt loại HĐ v02 CHỈ CÓ 4** (`:12-16`): HĐTP · HĐGK (Giao khoán/Đội thi công/Nhân công cơ hữu) · NCC · HĐDV. **KHÔNG có "MB" (Mua bán)** — trong khi repo codegen có 7 type gồm `HopDongMuaBan → {Project}/MB/SOL&{Sup}/{Seq}`. + +**6 ví dụ mã HĐ** (`:46-51`): FLOCK 01/HĐTP/SOL&HD/01 · FLOCK 01/HĐGK/SOL&PVL/01 · FLOCK 01/NCC/SOL&CC1/01 · 2026/NCC/SOL&AKATI/01 (nguyên tắc=Năm) · FLOCK 01/HĐDV/SOL&KG/01 · 2026/HĐDV/SOL&TTL/01. + +**2 dạng PO:** +- PO THEO HĐ nguyên tắc (`:25`, ví dụ `:54`): `X/Y/PO Z` = `{ProjectCode}/{NCC-abbr}/PO {Seq}` — ví dụ `FLOCK 01/TRUNGDUNG/PO 01`. KHÔNG có `SOL&`, KHÔNG có token loại HĐ, "PO" đứng TRƯỚC seq có DẤU CÁCH. +- PO KHÔNG theo HĐ nguyên tắc (`:36`, ví dụ `:57`): `A/PO/SOL&C/D` — ví dụ `FLOCK 01/PO/SOL&PVL/01`. "PO" chiếm vị trí loại-HĐ, có `SOL&`. + +**Mã cho PHIẾU KHKK: RG-001 v02 KHÔNG quy định** — văn bản chỉ cover mã HĐ + mã PO. (Đề xuất ở §3.) + +## §3 — Câu 3: DIFF RG-001 v02 vs bản repo (forms-spec.md) + +### F-06. Kết luận DIFF: forms-spec.md = parse của CHÍNH file v02 → 0 lệch trên format + +Folder FORM chỉ có 1 file RG-001 = `SOL-CCM-RG-001.v02 QD ma so hop dong.docx` (46.147B, mtime 2026-03-19) — tức Phase 0 đã parse đúng bản v02, không có v01 nào khác trên đĩa. Đối chiếu TỪNG dòng: + +| Điểm | RG-001 v02 (src :dòng) | forms-spec.md (:dòng) | Verdict | +|---|---|---|---| +| Format HĐ `A/B/SOL&C/D` | `:7` | `:82-87` 6 row | KHỚP 6/6 ví dụ nguyên văn (kể cả `FLOCK 01` có DẤU CÁCH) | +| 4 viết tắt HĐTP/HĐGK/NCC/HĐDV | `:12-16` | `:82-87` cột Loại | KHỚP (HĐGK gồm Tổ đội/NC cơ hữu ✓) | +| Nguyên tắc → Năm thay ProjectCode | `:8-9` + ví dụ `:49,:51` | `:85,:87` | KHỚP | +| PO theo HĐNT `X/Y/PO Z` (không SOL&, "PO␣01") | `:25,:54` | `:93` | KHỚP | +| PO không theo HĐNT `A/PO/SOL&C/D` | `:36,:57` | `:94` | KHỚP | + +**3 điểm KHÔNG-khớp-hoàn-toàn (đắt cho lane-2):** +1. 🔴 **"MB" (Mua bán) KHÔNG TỒN TẠI trong RG-001 v02** — v02 chỉ định nghĩa 4 viết tắt (`:12-16`), KHÔNG có MB; forms-spec cũng không có row MB. NHƯNG codegen repo (skill contract-workflow, bảng Mã HĐ gen) có `HopDongMuaBan → {Project}/MB/SOL&{Sup}/{Seq}` — tức "MB" là SÁNG TÁC của repo, không có gốc quy định. HĐ Mua bán (template FO-002.06 có thật) dùng mã gì theo v02? **Nguồn CÂM.** Đề xuất default dry-run: GIỮ "MB" hiện trạng (đổi codegen giữa dry-run = rủi ro), flag chờ anh ratify (option: map Mua bán→NCC hoặc →PO). Lane-2 check consumer. +2. **Scope reset Seq: v02 CÂM** — chỉ ghi "đánh số tăng dần bắt đầu từ 01" (`:19-20`), KHÔNG nói seq reset theo gì. forms-spec `:96` diễn giải "theo dự án + loại HĐ + đối tác" = interpretation hợp lý (codegen per-prefix khớp), nhưng cần biết đây là suy, không phải quy định. +3. **Chữ "dịch vụ/nguyên tắc" mơ hồ ở `:8`** ("Năm đối với HĐ dịch vụ/nguyên tắc") — nếu đọc chữ, HĐDV cấp-riêng cũng dùng Năm; nhưng ví dụ `:50` = `FLOCK 01/HĐDV/...` (ProjectCode) → ví dụ THẮNG chữ: Năm CHỈ cho nguyên tắc. forms-spec đã resolve đúng theo ví dụ. + +### F-07. Mã cho PHIẾU KHKK: RG-001 v02 KHÔNG quy định + +v02 chỉ cover mã HĐ + mã PO (2 loại). Không có mã phiếu trình/kế hoạch nào. → khai "nguồn không nói". Đề xuất default (mirror tiền lệ PE `PE/{YYYY}/{A|B}/{Seq:D3}` là mã tự đặt của hệ thống, không từ QĐ nào): **`KHKK/{YYYY}/{Seq:D3}`** atomic sequence, hiển thị trên phiếu + list; chờ anh ratify (spec cũ đã đề gì → xem §F-08 sau khi đọc spec). + +## §2-pre — Câu 2 chất liệu: folder FORM + "hợp đồng cứng" vật lý + +### F-08. Danh mục FORM folder (8 file, ls 2026-07-29 — khớp forms-spec 8 form, KHÔNG file mới) + +| File (bytes, mtime) | Loại | Nhận diện | +|---|---|---| +| FO-002.01.v01 Bảng kiểm tra (113.214B docx) | Cover/checklist | ĐÃ extract S157 | +| FO-002.02.v01 Trọn gói NC+VT (516.608B .doc) | Template HĐ cứng | thầu phụ trọn gói | +| FO-002.03.v01 Trọn gói NC+TB (591.360B .doc) | Template HĐ cứng | thầu phụ trọn gói TB | +| FO-002.04.v01 Điều kiện chung (192.608B docx) | Appendix cố định | đính kèm HĐ trọn gói | +| FO-002.05.v01 HĐ Giao khoán (459.676B docx) | Template HĐ cứng | 10 table | +| FO-002.06.v01 HĐ mua bán (356.864B .doc) | Template HĐ cứng | NCC vật tư/TB | +| FO-002.07.V01 Đơn đặt hàng (1.032.615B xlsx) | Template PO | 3 sheet (SS GIA/PO/Po01 NLT) | +| RG-001.v02 QĐ mã số (46.147B docx) | Quy định | extract @S160 | + +→ "6 template còn lại" = 002.02→.07. 3 file `.doc` (02/03/06) vẫn chưa convert (forms-spec TODO Phase 2 còn treo). mtime mới nhất 2026-03-19 = KHÔNG có bản mới sau Phase 0 parse → catalog forms-spec vẫn đúng hiện trạng đĩa. + +## §1 (tiếp) — Câu 1: bảng b.13→21 + ranh GĐ3/GĐ4 + +### F-09. 🔴 RANH GĐ3/GĐ4 KHÔNG cần suy từ QT — OWNER ĐÃ CHỐT @S159 + +Spec cũ `:27` (verbatim owner ratification): **"ranh GĐ2 = b.7→12 (b.12 chốt con số ∈ GĐ2) · GĐ3 = b.13→18 tận dụng Contract V2 · GĐ4 = b.19→21 + ký cứng upload-only"**. QT tự nó KHÔNG chia giai đoạn (1 quy trình 9 bước liền); ranh là quy ước dự án đã ratify. +⚠️ **DRIFT trong run.md `:17`**: lead viết "GĐ3 Duyệt hợp đồng (b.13→21…)" — đọc đúng phải là *khúc 13→21 = verdict LAI (toàn bộ tái dùng Contract)*, còn RANH GĐ3/GĐ4 = 13→18 / 19→21 theo owner @S159. Plan cha PHẢI dùng ranh @S159, đừng chép "b.13→21" thành span GĐ3. + +### F-10. Bảng b.13→21 chi tiết (khuôn spec cũ §1.5; nguồn = QT TABLE 2 `:60-68` + SLA TABLE 1 `:47-55` + FO-002.01) + +Căn số: toàn trình b.1-6=PE(GĐ1) · b.7-12=KHKK(GĐ2) · **b.13-21 ↔ 9 bước ISO 1:1** (spec cũ §1.3(A) `:35-38`, lens-fidelity xác nhận 9/9 `:459-461`). + +| b | GĐ | Việc | Ai (QT) | Đầu vào | Đầu ra/artifact | Chuyển bước | SLA QT | +|---|---|---|---|---|---|---|---| +| 13 | GĐ3 | Lựa chọn NTP/NCC | PB/BCH CT (`:60`) | QĐ theo SOL-PRO-SP-001 (`:47`,`:60` — **nguồn thứ 4 NGOÀI pin, chưa ai đọc**, spec cũ `:483-485`) | NTP/NCC được chọn | → b.14 | không ghi | +| 14 | GĐ3 | Soạn thảo HĐ | QS/NV.PB soạn; TBP/TPB kiểm khớp gói thầu + biểu mẫu (`:61`) | Winner + giá chốt GĐ2 + template FO-002.02→06 | Dự thảo HĐ, gửi các PB **qua email** lấy ý kiến | → b.15 | 07 ngày (`:48`) | +| 15 | GĐ3 | Góp ý nội dung | PD/PM (phạm vi CV/tiến độ/chất lượng/biện pháp — HĐ BCH CT) · EQU (thuê/mua TB) · PRO (vật tư/TP trọn gói) · CCM (điều khoản chi phí) · ACT/FIN (thanh toán/bảo lãnh/bảo hành) (`:62`) | Dự thảo | Ý kiến per-phòng | → b.16 | 07 ngày (`:49`) | +| 16 | GĐ3 | Đàm phán thương thảo | QS/NV.PB/TBP/TPB/PD/PM; PB/BCH CT đàm phán chất lượng/giao hàng/giá trị/thanh toán/tạm ứng; phòng chức năng tham gia nếu yêu cầu (`:63`) | Dự thảo + ý kiến | Điều khoản chốt với NTP | → b.17 | 07 ngày (`:50`) | +| 17 | GĐ3 | In HĐ | ⚠️ 2 nguồn trong CÙNG doc lệch nhẹ: T1 `:51` ghi trách nhiệm **NTP/NCC/TĐ**, T2 `:64` ghi **QS/NV.PB** (chủ trì) — thực chất chuỗi: NTP in 2 mặt + **KÝ + ĐÓNG DẤU TRƯỚC** gửi về PB/BCH CT → **cập nhật SỐ HĐ theo quy định** (RG-001) → PD/PM/TPB **ký nháy từng HĐ đúng vị trí** → PD/PM/TPB/TBP ký duyệt + ý kiến lên **cover FO-002.01** → QS/NV.PB chuyển CCM | Điều khoản chốt | **BẢN CỨNG ra đời tại đây** + số HĐ + ký nháy + cover khối ĐỀ XUẤT | → b.18 | 07 ngày (`:51`) | +| 18 | GĐ3 | Kiểm tra | CCM; **TP.CCM ký nháy từng HĐ** + ký duyệt + ý kiến lên cover FO-002.01 (`:65`) | Bộ cứng + cover | Cover khối CCM đã ký | → b.19 | 03 ngày (`:52`) | +| 19 | **GĐ4** | Duyệt | BOD/**NĐUQ** xem xét + **ký duyệt HĐ** (`:66`) | Bộ cứng đã qua CCM | Chữ ký GĐ trên HĐ + cover khối GĐ "Ký kết, phát hành" | → b.20 | 01 ngày (`:53`) | +| 20 | GĐ4 | Đóng dấu | **HRA/ISO** (T2 `:67` có ISO; T1 `:54` chỉ HRA); PB/BCH CT chuyển HĐ đã ký đến HRA/ISO đóng dấu theo quy định | HĐ đã ký GĐ | HĐ đóng dấu SOL | → b.21 | không ghi | +| 21 | GĐ4 | Phát hành + Lưu trữ | PB/BCH CT + CCM (`:68`) | HĐ hoàn chỉnh | **scan + gửi 01 BẢN GỐC cho CCM** · thông báo + chuyển bản gốc "theo đúng số lượng" đến NTP/NCC · lưu bản gốc · **lưu Server theo Filing System (bản CỨNG chính + bản SCAN)** | terminal | không ghi | + +**Nhánh lỗi/vòng lặp: QT KHÔNG VẼ** nhánh trả-lại nào cho b.13→21 (spec cũ bảng mâu-thuẫn #5 `:88` cùng nhận định) → hệ thống dùng TraLai/TuChoi sẵn có của V2, khai là default. + +### F-11. Nuance ranh: bản cứng SINH ở b.17 (GĐ3) nhưng MODULE cứng (GĐ4) mở từ b.19 + +Owner chốt GĐ4=b.19→21, nhưng theo QT thì vật-lý giấy + ký NTP + ký nháy + số HĐ đều sinh ở b.17-18 (∈GĐ3). ⇒ Trang `Hdc_*` phải HIỂN THỊ readonly metadata sinh từ b.17-18 (NTP đã ký/đóng dấu, ký nháy, cover 2 khối đầu), còn THAO TÁC của nó chỉ là 3 trạm b.19/20/21. Khai rõ để lane-2/lead không dựng trùng trạm. + +### F-12. Điều kiện ">5 tỷ" quanh b.18→19: NGOÀI nguồn pin + +Sổ S156 ghi "bước-18 '>5 tỷ' chưa có máy" (nguồn = sơ đồ PDF S156, KHÔNG nằm trong 6 nguồn pin lượt này). QT + FO-002.01 + RG-001 đều IM LẶNG về ngưỡng giá trị. → uncertain: KHÔNG đưa ngưỡng vào bảng bước; lead muốn dùng phải re-check PDF S156 + hỏi anh (twin câu Q3 GĐ2 đang treo). + +## §2 — Câu 2: GĐ4 "Hợp đồng cứng" cụ thể là gì + đề xuất 6 leaf `Hdc_*` + +### F-13. GĐ4 theo nguồn — cái BIẾT và cái NGUỒN CÂM + +**Nguồn NÓI (QT `:64-68` + FO-002.01 `:46`):** +- Ký: NTP ký+đóng dấu TRƯỚC (b.17) → ký nháy nội bộ PD/PM/TPB đúng vị trí (b.17) → TP.CCM ký nháy (b.18) → **BOD/NĐUQ ký duyệt (b.19)**. Đóng dấu SOL: HRA/ISO (b.20). +- Lưu: 01 bản gốc → CCM · bản gốc theo số lượng → NTP/NCC · PB/BCH CT lưu bản gốc · Server Filing System giữ CẢ bản-cứng-chính lẫn bản-scan (b.21). +- Scan/số hoá: CÓ — scan là nghĩa vụ b.21; cover FO-002.01 PHẢI lưu kèm bộ hồ sơ gốc (luật (c) `:46`). +**Nguồn CÂM (khai + đề xuất default, đảo được):** +- **Tổng số bộ in**: QT không quy định (chỉ "01 bản cho CCM" + "theo đúng số lượng" cho NTP) → default: field `SoBoGoc` nhập tay khi tiếp nhận, tối thiểu 2; cần anh ratify. +- **Nơi lưu vật lý cụ thể** (tủ/phòng/mã hồ sơ): không nói → default: field text `ViTriLuuTru` + `FilingPath` (link server), nhập ở b.21. +- **Ai bấm gì trên hệ thống**: QT là quy trình giấy; owner @S159 đã chốt cơ chế hệ thống = **"ký cứng upload-only"** → mỗi trạm b.19/20/21 = 1 action xác nhận + upload scan bằng chứng, KHÔNG e-signature. + +### F-14. Artifact GĐ4 cần track (đề xuất, suy trực tiếp từ b.17-21) + +1. Số HĐ (RG-001) — sinh trước GĐ4 (xem F-16 lệch thời điểm). 2. `SoBoGoc` (default, nguồn câm). 3. Trạng thái cứng: đề xuất 4 mốc `ChoKyGD → DaKyGD → DaDongDau → DaPhatHanh` (map 1:1 b.19/20/21+terminal). 4. Scan bộ HĐ đã ký+đóng dấu (b.21). 5. Scan cover FO-002.01 (luật (c)). 6. Tick + ngày "01 bản gốc đã giao CCM". 7. Số bộ + ngày giao NTP/NCC. 8. `ViTriLuuTru` + `FilingPath`. 9. Ngày ký GĐ / ngày đóng dấu / ngày phát hành + người thao tác (audit). 10. Readonly từ GĐ3: NTP đã ký (b.17), ký nháy PD/PM/TPB + TP.CCM (b.17-18). + +### F-15. Đề xuất nội dung 6 leaf `Hdc_*` (nhãn "- Bảng cứng", skeleton prod sẵn — run.md `:47`) + +| Leaf | Dry-run cần hiển thị/thao tác | +|---|---| +| `Hdc_WfView` | Sơ đồ 3 trạm b.19→21 (Ký GĐ → Đóng dấu → Phát hành/Lưu) + đếm HĐ đang đứng mỗi trạm — mirror trang "Tổng quan quy trình" arc-2 | +| `Hdc_List` | Mọi HĐ đã vào GĐ4 (tức GĐ3 xong): mã HĐ, NCC, dự án, giá trị, trạng thái cứng 4-mốc, số bộ, cột thiếu-scan | +| `Hdc_Create` | ⚠️ **Nguồn không nói** — GĐ4 không "tạo mới từ trắng". Default: form "Tiếp nhận bản cứng" pick HĐ GĐ3-xong + nhập `SoBoGoc`/ghi chú; cần anh ratify (option B: leaf này giữ ComingSoon, tiếp nhận tự động khi GĐ3 terminal) | +| `Hdc_Pending` | Inbox theo vai: BOD/NĐUQ thấy ChoKyGD · HRA thấy DaKyGD (chờ đóng dấu) · PB/BCH+CCM thấy DaDongDau (chờ phát hành/scan/giao) | +| `Hdc_Approved` | HĐ DaPhatHanh: đủ scan + đã giao CCM/NTP + nơi lưu | +| `Hdc_Deleted` | Soft-deleted records (khuôn 6-leaf y-chang Duyệt NCC, commit `ea962b1`) | +Mỗi transition = nút xác nhận + upload scan + note (upload-only @S159). + +### F-16. Lệch thời điểm GÁN MÃ HĐ: QT b.17 vs máy gen ở terminal — input cho lane-2 + +QT `:64`: "Cập nhật số Hợp đồng theo quy định" nằm TRONG b.17 In HĐ (mã phải có trên bản in). Code hiện gen mã lúc khác (skill: transition DangDongDau; sổ S156: V2 terminal gen-mã+DaPhatHanh — **lane-2 verify site thật**). Dry-run default: GIỮ máy hiện trạng (mã sinh ở terminal GĐ3 = sau b.18, vẫn TRƯỚC khi GĐ4 thao tác) + ghi nhận lệch so QT-b.17; user viết tay mã lên bản in nếu in trước. Cần anh ratify nếu muốn dời sớm thời điểm gen. + +## §4 — Câu 4: FO-002.01 → gate/checklist per-phòng + +### F-17. Map 4 khối ký ↔ bước + +| Khối FO-002.01 | Mục tick | Bước | Căn cứ | +|---|---|---|---| +| PHÒNG BAN/DỰ ÁN (ĐỀ XUẤT) | Soạn thảo · Nội dung HĐ | ký ở **b.17** (nội dung làm từ b.14) | QT `:64` "ký duyệt + ý kiến lên tờ cover" | +| PHÒNG CUNG ỨNG (PRO) | Điều khoản HĐ · Điều khoản t/toán · Rủi ro pháp lý | **b.17→18 handover** — QT KHÔNG có trạm PRO riêng trong lưu đồ; LƯU Ý (a) buộc "qua PRO và CCM trước" → khai mơ hồ, default đặt PRO ký NGAY TRƯỚC CCM | FO `:21-30` + `:46`(a) | +| PHÒNG CCM | G/trị HĐ so với NS · Rủi ro pháp lý | **b.18** | QT `:65` | +| GIÁM ĐỐC/NĐUQ | Ký kết, phát hành | **b.19** | QT `:66` | + +Spec cũ đã dùng chuỗi này làm đối-chứng-GIẤY cho O-1 (bảng `:92` — cùng HÌNH b.9→12 GĐ2). Hai giai đoạn dùng CÙNG khuôn 4-trạm là feature, không phải trùng lặp. + +### F-18. Default dry-run cho 3 luật LƯU Ý + checklist (O-Q1/O-Q2 CHƯA trả lời — default phải đảo được) + +1. **Checklist per-phòng (O-Q2 treo):** dry-run chạy bằng **comment tự do LevelOpinions như hiện trạng V2 = 0 dev mới**; số hoá checkbox (ĐỀ XUẤT 2 mục · PRO 3 · CCM 2 · GĐ 1) dời sang wave-gate sau khi anh trả lời. Đảo: bật checkbox per-Level, map đúng bảng F-17. +2. **Auto-pass 01-ngày (luật (b)):** KHÔNG máy hoá (mâu thuẫn duyệt-chặn V2; O-2 SLA=tham khảo — spec cũ `:412` cùng kết luận). Default: hiển thị số-ngày-đang-chờ trên phiếu, không auto-approve. Đảo: cần SLA-engine (đã bị loại khỏi mọi wave GĐ2 — nếu anh muốn thì là wave riêng). +3. **Bypass Chủ đầu tư (luật (a)):** ngoài scope dry-run NTP/NCC (QT scope = TP/NCC/TĐ); cờ `BypassProcurementAndCCM` đã tồn tại, không kích hoạt. +4. **Cover lưu kèm bộ gốc (luật (c)):** thành acceptance GĐ4: HĐ DaPhatHanh PHẢI có scan cover đính kèm (attachment purpose riêng — lane-2 check enum `AttachmentPurpose` thiếu ký-nháy/cover, sổ S156 đã flag). + +## §5 — Câu 5: wave-structure NGHIỆP VỤ GĐ3+GĐ4 (nối W1-W5 spec cũ) + +### F-19. Nguyên tắc kế thừa + đề xuất W6→W9 + +Nguyên tắc spec cũ §③ `:253-254`: mỗi wave deploy riêng phải trả lời "người dùng thấy gì"; NOTE @S160: menu đã public toàn bộ (skeleton), dark-launch = lớp TRANG/DATA. + +| Wave | Tên (nghiệp vụ) | Người dùng thấy gì khi đẩy riêng | Chặn bởi | Bắt buộc cho dry-run E2E? | +|---|---|---|---|---| +| **W6** | GĐ3 sống: HĐ từ KHKK → duyệt V2 → DaDuyet | Tạo HĐ từ phiếu KHKK DaDuyet (giá = ApprovedAmount), trình, 3 trạm PRO→CCM→CEO duyệt web (default mirror chuỗi FO-002.01, admin-config được), approver MỞ ĐƯỢC phiếu chờ mình | Q6/Q11 (cầu W5 — anh ĐÃ MỞ gate chạm HĐ @S160 run.md `:17`④); 🔴 authz S156 phải khoanh vùng per-action TRONG wave này vì dry-run mở menu mọi người | ✅ | +| **W7** | GĐ4 lõi: Hdc 6 leaf trang thật, 3 trạm cứng b.19/20/21 | Theo dõi bản cứng: tiếp nhận → ký GĐ (upload) → đóng dấu → phát hành (scan+số bộ+giao CCM/NTP+nơi lưu) | `Hdc_Create` semantics cần anh ratify (F-15); còn lại default đủ chạy | ✅ | +| **W8** | Gate + checklist FO-002.01 số hoá | Checkbox per-phòng trên phiếu + gate trình/duyệt siết dần | ✅ **O-Q1 + O-Q2** (twin W4 GĐ2) | ❌ hoãn — nguồn: O-2 tham khảo + 2 câu owner treo | +| **W9** | Hồ sơ hoàn tất + nhắc thiếu scan + thống kê lưu trữ | Filing view, cảnh báo HĐ phát hành thiếu scan/cover | không | ❌ hoãn — không chặn vòng chạy | + +**Bắt buộc E2E đến "Hợp đồng cứng": W5(cầu, spec cũ) + W6 + W7.** b.14-16 (soạn/góp ý/đàm phán) dry-run bằng trạng thái Nháp + comment thread + update draft (default khai rõ: ISO có trạm "Góp ý 6 phòng" nhưng V2 5-state không có phase góp-ý riêng — nếu anh muốn trạm thật thì thêm Bước trong workflow admin-config, 0 code). + +### F-07-BỔ-SUNG. Mã phiếu KHKK: spec cũ ĐÃ đề `KHKK/{YYYY}/{Seq:D3}` (`:128` tái dùng `WorkflowAppCodeSequence` prefix namespaced + `:307` "owner nên liếc format trước W1") — F-07 giữ nguyên kết luận "RG-001 câm", đề xuất KHỚP spec cũ, vẫn CHỜ anh ratify format. + +## §6 — Surprises ngoài 5 câu hỏi + +- F-20. **run.md `:17` drift ranh GĐ3** (chi tiết F-09) — Plan cha phải theo owner @S159: GĐ3=13→18, GĐ4=19→21. +- F-21. **"MB" codegen không có gốc quy định** (F-06.1) — dry-run HĐ Mua bán sẽ đẻ mã ngoài RG-001 v02; forms-spec.md cũng KHÔNG có row MB → repo tự thêm ở tầng codegen, cần owner ratify hoặc loại type MuaBan khỏi dry-run. +- F-22. **forms-spec TODO Phase 2 còn treo**: 3 file `.doc` (002.02/.03/.06) chưa convert → template render HĐ trọn gói/mua bán chưa chắc chạy được trong dry-run — lane-2 check form-engine coverage thật; nghiệp vụ fallback: đính file mẫu tĩnh. +- F-23. **FO-002.01 tick-box 6 loại HĐ ≠ 7 ContractType repo** (F-04) — màn render cover cần bảng map, "Thiết bị thuê"/"Khác" không có ContractType tương ứng. +- F-24. **SLA QT b.14-17 = 07 ngày** khớp fallback code (7d) nhưng b.17 In-HĐ QT=07d ≠ skill DangInKy=1d — O-2 nói tham khảo nên không chặn, ghi để bảng SLA hiển thị đúng NGUỒN thay vì đúng code. + + + diff --git a/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-2.md b/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-2.md new file mode 100644 index 0000000..ec0a732 --- /dev/null +++ b/.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/sub-investigator-codebase-2.md @@ -0,0 +1,60 @@ +# sub-investigator-codebase-2 — LANE-2 CODEBASE DRY-RUN MAP (S160, /fable-real) + +> Vai: investigator-codebase · engine-đắt REAL · ghi-đĩa-trong-lúc-làm (chống #53). +> Trục: CODE THẬT trên repo. Lane-1 (song song) lo nghiệp vụ từ QT/FORM. +> Spec KHKK cũ (GĐ2 b.7→12, W1-W5, 7 bảng, Mig 69, type=10) = RATIFIED — chỉ BỔ SUNG GĐ3+GĐ4. +> Ranh giai đoạn (owner chốt @S159, spec §1.2): GĐ2=b.7→12 · GĐ3=b.13→18 (tận dụng Contract V2) · GĐ4=b.19→21 + ký cứng upload-only. + +## §0 — Nguồn đã đọc + tiền đề + +- `run.md` S160 (lệnh anh verbatim + ràng buộc 5-anchor + authz S156 + gotcha #84 no-SQL-tay). +- Spec S157 497 dòng ĐỌC TRỌN (①②③④⑤): 7 bảng `ContractSigningPlan*`, Mig 69, `ApplicableType=10`, W1-W5, NOTE W1 @S160 (Khkk_* skeleton ĐÃ prod, dark-launch ĐẢO — menu public, ComingSoon→trang thật mới là "bật"). +- `src-QT-TRINH-KY-HD.txt`: bảng 2 = 9 bước ISO (Lựa chọn→Soạn thảo→Góp ý→Đàm phán→In HĐ→CCM→BOD→Đóng dấu→Phát hành/Lưu trữ) ↔ `ContractPhase` 1-9 khớp 1:1 (xác nhận S157 lens-fidelity). +- `src-RG-001-v02-ma-so-hd.txt` (2.907B): format `A/B/SOL&C/D` + 6 ví dụ HĐ + 2 dạng PO (`X/Y/PO Z` theo nguyên tắc · `A/PO/SOL&C/D` không nguyên tắc). + +(mục chi tiết append dần bên dưới — mỗi §=1 câu hỏi) + +--- + +## §1 — Q1: MAP TÁI DÙNG b.13→21 → Contract V2 (mọi dòng RE-VERIFY trên đĩa 07-29, KHÔNG chép mù S156 — line đã TRÔI vì arc-2 thêm `ListDeleted`) + +**Khung đọc:** GĐ3 = b.13→18 (owner @S159) chạy trên state machine 5-trạng-thái `ContractPhase.cs:14-28` (sống: DangSoanThao=2 · ChoDuyet=10 · DaPhatHanh=9 · TraLai=98 · TuChoi=99; 7 phase `[LEGACY]` = chính các trạm 13-21 đã gỡ CỐ Ý Mig 21). GĐ4 = b.19→21. Duyệt V2 = `ContractWorkflowService.ApproveV2Async` (`ContractWorkflowService.cs:217-394`) cookie-cutter PE: OR-of-N `:259-260` · UPSERT `ContractLevelOpinions` `:292-316` · skipToFinal `:320-352` · terminal gen-mã+DaPhatHanh `:366-385`. + +| b | Việc (theo QT/PDF) | Phase/feature hiện có | Trạng thái | Chứng (file:line, đo 07-29) | +|---|---|---|---|---| +| 13 | PMH soạn draft HĐ từ giá chốt KHKK | `DangSoanThao`; 2 đường tạo: bridge PE→HĐ + create thường (create thường ĐÃ nhận pin V2 `ContractFeatures.cs:109`; gen `MaHopDong` NGAY tại create `:113-118` — RG-001 có mã từ nháp, KHÔNG đợi terminal) | **PARTIAL** | Bridge pin V1-only `CreateContractFromEvaluationFeatures.cs:68-71,108` + KHÔNG đọc giá KHKK (`giaTri=SUM Quote.IsSelected` `:88-90`) → chi tiết §2 | +| 14 | BCH bổ sung/hoàn thiện draft | `UpdateContractDraftCommand` guard duy nhất `Phase==DangSoanThao` (`ContractFeatures.cs:156-157`), KHÔNG check drafter ⇒ BCH SỬA được về cơ chế | **PARTIAL** | Nhưng BCH KHÔNG XEM được: view-guard `GetEligiblePhases` (`:334-351`) map `DangSoanThao` chỉ cho `Drafter/DeptManager` (`:342-343`); role ProjectManager chỉ được `DangGopY` legacy. Command cũng KHÔNG có `ApprovalWorkflowId` (`:136-145`) ⇒ 0 đường re-pin V2 sau tạo | +| 15 | Đàm phán với TP (ngoài hệ thống) | Không phase riêng (DangDamPhan=LEGACY đã gỡ) — ghi vết = comment + attachment | **SẴN** (triết lý Mig 21: trạm offline = chứng từ đính kèm) | `ContractPhase.cs:19` LEGACY; attachment upload KHÔNG phase-guard (`ContractAttachmentFeatures.cs` 0 hit guard `Phase` — chỉ changelog `:84,:144`) | +| 16 | TP ký nháy → BCH chuyển PMH (scan) | Upload attachment mọi phase | **GAP nhỏ** | `AttachmentPurpose` (`ContractAttachment.cs:5-11`) = DraftExport/ScannedSigned/SealedCopy/Other — KHÔNG có "ký nháy" (InitialSigned). Enum-extend int-column 0-migration (tiền lệ PE `ComparisonTable=4`) | +| 17 | PMH trình ký; CCM kiểm tra + ký nháy | Trình `DangSoanThao→ChoDuyet` (`ContractWorkflowService.cs:70-88`, init con-trỏ đôi `:81-84`); CCM = Step 1 của workflow V2 `ApplicableType.Contract=3` — duyệt qua `ApproveV2Async` | **PARTIAL** | 🔴 3 lỗ: (i) guard trình đòi role `Drafter∨DeptManager` (`:73-78`) — PMH mang `Procurement` bị 403 (lớp "vai đi qua không có"); (ii) approver KHÔNG XEM được HĐ ChoDuyet — `GetEligiblePhases` 0 entry ChoDuyet; (iii) KHÔNG vào inbox — `PhaseActorRoles` (`:421-430`) 100% legacy, 0 entry ChoDuyet | +| 18 | CEO ký nếu >5 tỷ | Step CEO trong workflow V2 (Level đích danh Director) — chạy được nếu CEO ký MỌI HĐ | **GAP** (phần ngưỡng) | `CeoApprovalThreshold` = cột chung `ApprovalWorkflow.cs:43` nhưng grep `ContractWorkflowService.cs` = **0 hit** (đọc trọn 443 dòng 07-29) — admin set vào workflow Contract-type bị NGÓ LƠ im lặng. `AllowApproverFinalize` cũng PE-only. Đường có sẵn 0-code: 2 workflow (có/không Step CEO) + user chọn lúc tạo | +| — | (kết GĐ3) | Duyệt cấp cuối → `DaPhatHanh` terminal + gen mã nếu chưa có (`:366-385`) | **SẴN** | Terminal của V2 = "Đã phát hành" — nghĩa là b.19-21 GĐ4 xảy ra SAU terminal về mặt hệ thống | +| 19 | HR đóng dấu | 2 lựa chọn: (a) HR = Step cuối workflow V2 (SẴN, chỉ cấu hình — terminal dời về sau HR); (b) tracking riêng trên vật thể "bản cứng" GĐ4 | **SẴN-config / GAP-nếu-tracking-riêng** | `DangDongDau=8` LEGACY (`ContractPhase.cs:23`) — KHÔNG hồi sinh. §3 đề xuất | +| 20 | CCM scan bản cứng, lưu trữ | `AttachmentPurpose.SealedCopy=3` upload ở DaPhatHanh | **SẴN** | `ContractAttachment.cs:9`; upload không phase-guard ⇒ up được sau terminal | +| 21 | Chuyển phát nhanh bản gốc về TP + lưu | Không field nào (mã vận đơn/số bản gốc/vị trí lưu) | **GAP** (nhỏ — comment đủ nếu owner không đòi field) | `Contract.cs:8-70` đọc trọn: 0 field bản-cứng (không seal-date, không courier, không số-bản-gốc, không vị-trí-lưu-file-cứng) | + +**Kết Q1:** cơ chế duyệt (17-18) + terminal + attachment (15,16,20) = TÁI DÙNG được ngay sau khi vá 3 lỗ "đường ống" (view/inbox/vai-trình) — đúng verdict LAI S156, hôm nay re-verify còn nguyên. GĐ4 (19-21) KHÔNG có vật mang trong Contract entity — cần quyết định §3 (field-on-Contract vs entity mới). + +**Đếm endpoint (đo 07-29):** `ContractsController.cs` = **30 endpoint** (8 đọc + **22 ghi**), class `[Authorize]` trần `:13`; ngoại lệ DUY NHẤT có policy: `GET /deleted` `[Authorize(Policy="Contracts.Read")]` `:28-29` (arc-2 S159) — khuôn per-action ĐÃ CÓ TIỀN LỆ ngay trong file này. + +--- + +## §2 — Q2: BRIDGE KHKK chen giữa PE và Contract + +**Hiện trạng bridge (đo 07-29):** `POST /api/purchase-evaluations/{id}/create-contract` (`PurchaseEvaluationsController.cs:339-346`, body `{ContractType, TenHopDong, Bypass}` `:379-382` — KHÔNG có `ApprovalWorkflowId`) → handler `CreateContractFromEvaluationFeatures.cs`: guard `Phase==DaDuyet` + `winners.Count>0` + `pe.ContractId==null` (`:53-60`); per-winner `giaTri = SUM Quote.IsSelected` (`:88-90`); pin **V1-only** `WorkflowDefinitionId=activeWfId` (`:68-71,:108`); gen mã atomic self-committing codegen (`:78-115`); idempotency `pe.ContractId = contracts[0].Id` (`:145`). Picker: `GET /purchase-evaluations/approved-pending-contract` (`:335-337`) → `ListApprovedPurchaseEvaluationsQuery` filter `Phase==DaDuyet && ContractId==null` (`CreateContractFromEvaluationFeatures.cs:173`). + +**(a) KHKK kế thừa từ PE** (đã RATIFIED spec S157 §2.3 — chỉ tóm + anchor sống): header `PurchaseEvaluationId` loose-Guid + `ProjectId` denorm + `DepartmentId` (C5) + snapshot `HoSoLink`; **Lines auto-sinh từ winners** `pe.Suppliers.Where(IsWinner)` với `PeReferenceAmount = SUM Quote.IsSelected` per-winner **snapshot 1 lần** — copy đúng phép tính bridge cũ `:88-90` + guard `:53-60`. Khuôn nguyên con nằm sẵn trong file bridge. + +**(b) Contract tạo từ KHKK kế thừa gì** (spec §2.5 RATIFIED, W5): (i) `giaTri = line.ApprovedAmount` khớp `w.SupplierId` **thay** `SUM :88-90` khi PE có plan `DaDuyet` + ContextNote lệch *"giá KH x vs SUM-PE y"* vào changelog (khuôn `:121-140`); (ii) **+param `ApprovalWorkflowId` pin V2** — thiếu nó HĐ từ phiếu rơi nhánh V1: nếu 0 active `WorkflowDefinition` cho type đó → **KẸT CỨNG** `ConflictException` `ContractWorkflowService.cs:115-116` (re-verify 07-29: đúng dòng `def == null || def.Steps.Count == 0`); (iii) phần còn lại giữ nguyên từ PE (TenHopDong/PaymentTerms→DraftData/BudgetManual* `:101-107`); (iv) 🆕 ghi ngược `Line.ContractId = contract.Id` per-winner (cột C6 spec đã có chỗ) — vòng lặp `:82-115` đã per-winner nên chỗ ghi tự nhiên. + +**(c) Sửa bridge cũ hay thêm bridge mới → SỬA BRIDGE CŨ (1 file), KHÔNG đẻ bridge thứ 2** — đây là hướng spec W5 đã ratify; lý do kỹ thuật đứng vững hôm nay: entry-point PE giữ idempotency `pe.ContractId` (`:59-60,:145`) + FE nút tạo HĐ đã tồn tại màn PE; bridge mới từ KHKK = endpoint thứ 2 cùng nghĩa (2 chỗ sửa về sau — lớp lỗi 2-site S155). Bổ sung DUY NHẤT cho dry-run: màn KHKK detail (DaDuyet) thêm **nút deep-link** gọi CÙNG endpoint cũ — 0 endpoint mới, 0 handler mới. *(Phương án B ghi để review chốt: `POST /contract-signing-plans/{id}/create-contracts` riêng — chỉ đáng nếu owner muốn 1 KHKK chia nhiều đợt HĐ; hiện 0 yêu cầu.)* + +**(d) Cardinality chuỗi PE↔KHKK↔Contract:** +| Cặp | Ràng buộc | Cơ chế enforce | +|---|---|---| +| PE → KHKK | 1 PE — **≤1 plan SỐNG** (1-N lịch sử, tạo lại được sau TuChoi) | app-level `AnyAsync(p.PeId==x && p.Phase!=TuChoi)` → 409 (spec §2.3; KHÔNG đặt được UNIQUE-filtered theo Phase động — đúng lựa chọn app-level) | +| PE → Contract | 1 PE — N HĐ (multi-winner Mig 58) | `pe.ContractId = contracts[0].Id` `:145` + guard `:59-60` "đã tạo HĐ rồi" | +| KHKK → Contract | 1 plan — N Lines (UNIQUE filtered `PlanId+SupplierId`) — mỗi Line ↔ ≤1 HĐ | `Line.ContractId Guid?` (C6) ghi tại bridge; truy ngược HĐ→plan qua Line | +| ⚠️ đường tắt | PE → Contract KHÔNG QUA KHKK vẫn sống (Q11 mặc định = cảnh báo mềm) | dry-run phải chấp nhận 2 đường song song cho tới khi owner nâng cứng Q11 | + +**Pattern tái dùng cite được:** (1) pull-model picker `ListApprovedPurchaseEvaluationsQuery:173` — nhân bản đổi vị ngữ `&& chưa-có-plan-sống` cho màn "PE chờ lập KH" (W2 spec cũ); picker tạo-HĐ đổi nguồn thành plan `DaDuyet` (hoặc giữ PE + banner có/không plan — Q11). (2) Multi-entity create + self-committing codegen atomic `:78-82` comment + loop. (3) Auto-Lines từ winners `:56-62,:82-91`.