From 51b50ce646960da264f31ebe7a5b46442856e72c Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Fri, 31 Jul 2026 14:07:34 +0700 Subject: [PATCH] wal: flush 20260731T1407 --- .claude/WAL.md | 6 ++- .../spec-4gd-khkk-tong-quat-31-07-2026.md | 4 +- .../spec-cum3-chi-tiet-31-07-2026.md | 2 +- .../sub-review-fable-b3.md | 44 ++++++++++++++++++- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/.claude/WAL.md b/.claude/WAL.md index 7f11df7..8c55778 100644 --- a/.claude/WAL.md +++ b/.claude/WAL.md @@ -56,8 +56,10 @@ next: 5/6 OG CHỐT (1 schema-GỘP+UI-1-1 · 2 đội-hình-cũ · 7 N-phiếu+ đối chiếu chéo 4 spec → A mâu-thuẫn-liên-spec · B vá-đè-vá · C build-order · E GO/NO-GO · F digest-owner). Về → lead tổng → BẢNG TỔNG trình anh → B4 build K1 (anh pre-authorize "chốt kỹ rồi thì dry-run luôn"; seed-land vẫn chờ OG-6+câu-II · K8 chờ câu-V). - CHỜ ANH: (I) bản-15-trang · (II) B2-14-dòng+"/" · (III) ai-bấm-Đưa-vào-HĐ [default Drafter+Procurement+ - Admin] · (V) PE-thật vs ZZTEST-riêng [nghiêng (b): trước-K2 rào per-PE khóa TOÀN BỘ A/049] · OG-6 soát. + (V) ✅ CHỐT: "phiếu đã duyệt không xóa" = THIẾT KẾ ĐÚNG ERP (owner ratified — CẤM B4 sửa allow-list) + ⇒ K8 dùng PE ZZTEST RIÊNG (phiếu bất tử nằm gói test). +BACKLOG giai-đoạn-sau: phiếu điều-chỉnh/thay-thế + (amendment, áp PE/KHKK/HĐ) + authz-per-nhóm + bung-gộp UI — spec tổng đã ghi 3 mục. + CHỜ ANH: (I) bản-15-trang · (II) B2-14-dòng+"/" · (III) ai-bấm [default Drafter+Procurement+Admin] · OG-6. Sổ lane-chết: fable 3/8 · opus 1/12. verify: diff --git a/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-4gd-khkk-tong-quat-31-07-2026.md b/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-4gd-khkk-tong-quat-31-07-2026.md index a80c099..9980c71 100644 --- a/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-4gd-khkk-tong-quat-31-07-2026.md +++ b/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-4gd-khkk-tong-quat-31-07-2026.md @@ -51,4 +51,6 @@ Chuỗi 4 GĐ per-gói-thầu theo SOL-CCM-SP-002: GĐ1 Duyệt NCC (PE = CHA, > 🔴 **OG-3 NÂNG CẤP @S164 (cùng lời chốt OG-9):** *"vậy bài toán trần budget xem như ĐÓNG. Vì người chốt chặn budget là anh Chương."* ⇒ NĐUQ/ngưỡng tiền = **HUMAN-GATE VĨNH VIỄN** (TP.CCM Phan Văn Chương quyết cái gì cần CEO) — **XÓA ý "enforce máy = wave opt-in sau"** khỏi mọi spec; cột NĐUQ trên danh mục thuần ghi chú. Không còn wave threshold nào trong backlog. -END spec v2 — 8 wave · 8 quyết định · 6 OG · 14 vá B1b áp đủ. +**BACKLOG giai-đoạn-sau (owner @S164, không làm đợt này):** (1) authz-per-nhóm KHKK (OG-8) · (2) **phiếu điều chỉnh/thay thế** cho chứng từ đã duyệt — khuôn amendment ERP, áp PE/KHKK/HĐ (*"Nếu xóa thì có thể làm 1 tính năng điều chỉnh phiếu để cập nhật điều chỉnh/thay thế - ko xóa phiếu đã duyệt. Cái này để giai đoạn sau."*) · (3) bung-gộp UI (OG-1/OG-7 nửa sau — máy đã sẵn). + +END spec v2 — 8 wave · 9 quyết định · OG đủ · backlog 3 mục giai-đoạn-sau. diff --git a/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-cum3-chi-tiet-31-07-2026.md b/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-cum3-chi-tiet-31-07-2026.md index 96c4ade..785a498 100644 --- a/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-cum3-chi-tiet-31-07-2026.md +++ b/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-cum3-chi-tiet-31-07-2026.md @@ -21,7 +21,7 @@ K7 cầu KHKK→HĐ (bridge 8v/8test — đường ống S156 ĐÃ vá @W6-S161, 9. 🔴 **[L2-H5] B0 = FORM NGƯỜI THẬT fail-closed**: bảng 14 dòng {bước · người · email · tài khoản} PHẢI ĐIỀN ĐỦ trước giờ-G (12/14 bước đang trống); nguồn = K3-acceptance LIVE; thiếu 1 dòng = KHÔNG chạy. 10. 🔴 **[L2-H2] Phép đo QĐ9 phải TRƯỢT ĐƯỢC**: sau finalize → **sửa NS/giá nguồn** (PE hoặc catalog) → reload phiếu → số **KHÔNG đổi** = PASS (đổi = FAIL); đo **CẢ 2 nhánh** (a-Chương finalize-CCM VÀ lên-CEO-Trường duyệt) — hiện phép đo 0-bit. 11. 🔴 **[L2-H3] Dấu ZZTEST cho phiếu KHKK**: mã phiếu auto-gen (`KHKK/2026/xxx`) KHÔNG mang ZZTEST — bản ghi sống-vĩnh-viễn lại không dấu. Vá: nhét `ZZTEST` vào field hiển thị được trên list (tên kế hoạch/ghi chú — soi DTO chọn field) + **rollback theo DANH SÁCH ID** ghi lại từng bước, không theo prefix. -12. 🔴 **[L2-H4 ⨯ L1-F5] Câu giờ-G (V) trình anh ĐỦ 2 hệ quả**: (i) phiếu KHKK DaDuyet trên PE thật **không xóa được kể cả Admin** (sqlcmd là lối duy nhất); (ii) 🔴 **TRƯỚC K2 rào là per-PE** ⇒ phiếu ZZTEST khóa **TOÀN BỘ** `PE/2026/A/049` (không phải chỉ nhóm-4) — nghiêng mạnh về **phương án (b) PE ZZTEST riêng**; nếu anh chọn (a) PE thật thì bắt buộc chạy SAU K2. +12. ✅ **[CHỐT @S164 — câu V] "Phiếu đã duyệt không xóa" = THIẾT KẾ ĐÚNG, owner ratified** (verbatim: *"đồng ý luôn, hiện tất cả các phiếu nếu đã duyệt gần như ko xóa đc. Đồng ý cái này đúng với thiết kế ERP."*) ⇒ (i) delete allow-list `{DangSoanThao, TuChoi}` **GIỮ NGUYÊN — CẤM B4 "sửa" nó** (nó không phải bug); (ii) hệ quả vận hành: phiếu test đã duyệt BẤT TỬ ⇒ **K8 CHỐT dùng bộ PE ZZTEST RIÊNG** (để phiếu bất tử nằm trên gói test, không phải gói thật `A/049` — trước K2 rào per-PE còn khóa nguyên gói); (iii) 🆕 **BACKLOG giai-đoạn-sau (lời anh):** tính năng **"phiếu điều chỉnh/thay thế"** — cập nhật chứng từ đã duyệt bằng chứng từ điều chỉnh, KHÔNG xóa gốc (khuôn amendment ERP; áp được cả PE/KHKK/HĐ) — ghi nhận, KHÔNG làm đợt này. 13. **[L3-H4] B16 rollback HĐ = NO-OP hiện tại** (numeric guard chặn xóa cả khi TuChoi) — rollback plan ghi rõ: HĐ test dọn bằng **sqlcmd soft-delete** (lệnh cụ thể per bảng: Contracts + ContractApprovals + Changelogs + Line.ContractId=NULL + pe.ContractId=NULL), thứ tự ngược. 14. **[L2-M10] Câu III treo → acceptance "ai bấm" để [CHỜ-ANH]** — không chốt trong DoD tới khi anh trả; default dialog + người-có-quyền. 15. **[L2-M12] DoD cardinality đo được**: sau bridge UI-1-1 — đếm `SELECT COUNT(DISTINCT ContractId) FROM Lines WHERE PlanId=X AND ContractId IS NOT NULL` == số lần bấm; gộp (sau này) = N line 1 ContractId. diff --git a/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-review-fable-b3.md b/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-review-fable-b3.md index c16d175..7ee5a4c 100644 --- a/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-review-fable-b3.md +++ b/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-review-fable-b3.md @@ -4,10 +4,50 @@ > Luật đan xen: đọc 1 spec → ghi section NGAY. ## A. Mâu thuẫn LIÊN-SPEC -(ĐANG LÀM) +(ĐANG LÀM — nháp sau spec tổng, chờ đối chiếu 3 cụm) + +### A-0. Nội-bộ spec tổng (phát hiện khi đọc lượt 1) +- **[A-0a] QĐ5 vs OG-3-nâng-cấp TỰ MÂU THUẪN trong CÙNG file:** `spec-4gd-khkk-tong-quat:15` QĐ5 còn nguyên *"enforce (`CeoApprovalThreshold`) = wave opt-in sau"* trong khi `:52` ra lệnh *"**XÓA ý 'enforce máy = wave opt-in sau' khỏi mọi spec**"*. Spec tổng tự vi phạm lệnh của chính nó → phải sweep cụm 1-3 xem câu này còn rớt ở đâu. +- **[A-0b] Đếm sai nội bộ:** header ② ghi "8 quyết định (v2)" nhưng liệt 9 items (:11-19, QĐ9 budget-freeze mới @S164); END `:54` ghi "6 OG" nhưng bảng ④ có 8 hàng (OG-1/2/3/5/6/7/8/9). Con số header/footer chưa sync sau khi chèn QĐ9 + OG-8/9. +- **[A-0c] QĐ9 mang cờ "⚠️ MERGE-PENDING: B2-cụm-1 lane phóng TRƯỚC lời này — lead merge vào spec chi tiết khi lane về" (`:19`) → kiểm tra cụm-1/cụm-3 đã nhận merge chưa (schema snapshot → K2, hook finalize → K3). + +### A-1. Drift số menu/policy — **MÂU THUẪN THẬT, cụm-1 CHƯA nhất quán với cụm-2** 🔴 +- `spec-cum1:8` vá-1 neo **TUYỆT ĐỐI**: *"Menu keys 55→64 · Policies 220→256 — khai 2 row STATUS cùng lúc"* ⟂ `spec-cum2:9` vá-2 **CẤM đúng kiểu neo đó**: *"Drift khai DELTA (+49/+196), CẤM neo 2 mốc tuyệt đối (64→113 chỉ đúng nếu cụm-1 land trước — thứ tự ship đang cho song song)"*. Cụm-2 BIẾT về mốc 64 của cụm-1 và phòng hộ cho mình, nhưng **cụm-1 không được sửa ngược** → 2 spec dạy builder 2 luật ngược nhau về CÙNG 2 row STATUS. +- Thêm: 9 key của cụm-1 trải 2 wave (`ContractCatalog` = K1 +1 · 8 `AwV2_KhkkN*` = K3 +8) ⇒ "55→64" chỉ đúng tại K3-land; khai trọn ở K1 = STATUS nói dối suốt cửa sổ K1→K3. +- Số học nội bộ tự khớp (9×4=36: 220→256 ✓ · 49×4=196: 256→452 ✓) — lỗi KHÔNG nằm ở arithmetic mà ở **kiểu neo**. +- **Fix 1 dòng (trước B4):** sửa cụm-1 vá-1 thành DELTA per-wave (+1 @K1 · +8 @K3) + mọi commit khai drift kèm lệnh đo lại `MenuKeys.All` thực tế (mượn nguyên câu cụm-2 vá-2). Verdict: **MÂU THUẪN #1 — phải vá spec trước build.** + +### A-2. 3-site grant cụm-2 ⟂ 9-key cụm-1 — NHẤT QUÁN về máy, THIẾU 1 câu ranh giới +- Cụm-2 3-site (`spec-cum2:25` — seed `:1780` · `SeedKeHoachKyKetAccessAsync:2415` · `KhkkKeys():2185`) áp cho **49 row KHKK user-facing**. Cụm-1 vá-1 (`spec-cum1:8`) chỉ đưa 9 key **VÀO All** — KHÔNG nói vào `KhkkKeys()`. Đọc máy: đúng như vậy là CHUẨN — + - 8 `AwV2_KhkkN*` = menu-con dưới `ApprovalWorkflowsV2` (System subtree, admin-only theo QĐ7 tổng `:17` CHỪA System + AwV2); grant qua **All-loop-Admin `DbInitializer.cs:2058`** là đủ. Đưa vào `KhkkKeys()` ⇒ 13 vai thường được CanRead menu designer = quyền-lệch (fe-user không có route → #50 drop im lặng, không vỡ UI nhưng bẩn grant + họ #85 menu-rộng-hơn-API). + - `ContractCatalog` = leaf nhánh Catalogs/Master, KHÔNG thuộc cây `KeHoachKyKet` → không có lý do vào `KhkkKeys()`. Acceptance cụm-1 chỉ đo "login **Admin** thấy leaf ×2 app" — tức đợt này user thường KHÔNG thấy danh mục (chưa grant role thường). Chấp nhận được (danh mục = master admin nhập) nhưng nên khai 1 câu để owner biết. +- **Rủi ro thật:** comment `:2204` *"quên 1 bên = quyền lệch"* + cụm-2 vá-15 dạy khuôn TRONG-All có thể xúi builder "cho đủ bộ" nhét cả 9 key vào `KhkkKeys()`. **Fix 1 dòng:** thêm vào cụm-1 vá-1: *"9 key này KHÔNG vào `KhkkKeys()`/site-2/3 — chỉ All (+Admin-loop)"*. Verdict: KHÔNG mâu thuẫn, cần 1 câu chốt ranh. +- Designer fe-user: KHÔNG thấy và KHÔNG NÊN — fe-user không route System subtree; đường thấy duy nhất = fe-admin (K6 CHỪA `ApprovalWorkflowsV2 :1801`). + +### A-3. Chuỗi ApprovalGroup K2→K4b→K5 — (nháp sau cụm-2, chờ cụm-3 vá-5 T2) +- K2 CHỦ (cột + backfill=1 + param `group` + DTO `:34` + picker create cụm-1 vá-4) → K4b tiêu thụ (queryKey += group `spec-cum2:10` vá-3 · phase+group từ searchParams vá-5 · preset `?group=` vá-6) → K5 group-by `approvalGroup` + hiện đủ 8 + fallback NULL-group (vá-9). Chuỗi schema→API→list→tree ĐỦ 1 đường tính đến cụm-2. Chờ soi cụm-3 vá-5 "T2-sau-K2" rồi chốt. + +### A-4. Freeze QĐ9 — nháp sau cụm-1 (chờ cụm-3 vá-10) +- Cột runtime `EndedByLevelFinalize`: tổng `:46` OG-3-SỬA "(b) forward-provision vào Mig 71 ⇒ K3 0-mig" **KHỚP** `spec-cum1:14` vá-7 (Mig 71 item 6 + tên mig `AddKhkkApprovalGroupCatalogAndFinalizeRuntime` + khai ghost-window K2→K3). ✅ cùng 1 cột. +- ⚠️ **Snapshot budget (QĐ9 "phiếu DaDuyet đọc SNAPSHOT, mirror Mig 67 11-cột") KHÔNG THẤY trong cụm-1**: Mig 71 chỉ 6 item (1-5 nền + EndedByLevelFinalize), KHÔNG có cột snapshot; freeze cụm-1 = tổ hợp {vá-2 test-khóa :342-unreachable (`WorkflowService.cs`) + vá-6 phase-guard line-edit kéo về K2 + vá-8 "list thêm Σ Approved sau freeze"} ⇒ thiết kế freeze = **immutability-live** chứ KHÔNG snapshot-read. MERGE-PENDING `:19` của tổng **CHƯA merge** vào cụm-1 final. Chờ cụm-3 vá-10 rồi phán. +- 🪤 Bẫy **":342 hai file khác nhau"**: tổng QĐ2 dùng `:342-347` = `ContractSigningPlanFeatures.cs` (rào 1-PE-1-phiếu, K2 ĐỔI); cụm-1 vá-2 dùng `:342` = `WorkflowService.cs` (`ReturnOrRejectAsync`, CẤM sửa — DaDuyet unreachable). Builder đọc lướt sẽ sửa nhầm site. Cần 1 câu định-danh-file trong spec build. + +### A-x. Drift consumer-count tổng ⟂ cụm-1 +- Tổng `:12` QĐ2: *"acceptance rà **16 consumer** (10 BE + 6 FE — l3-F18)"* ⟂ `spec-cum1:23` checklist K2: *"bảng **18 consumer** (17 nền + :712-713)"*. Cụm-1 THẮNG theo luật vá (nền 17 + vá-8 thêm 1 = 18) nhưng tổng chưa sửa số ⇒ builder đọc tổng trước sẽ rà thiếu 2. Fix 1 dòng ở tổng khi ship. + +### A-6. OG-7 UI-hướng-1 — 2 cửa tạo phiếu nhóm 2 KHÔNG chỏi, nhưng NÚT PHỤ chưa có chủ (nháp sau cụm-2) +- Cửa 1: KhkkCreatePage + picker nhóm (cụm-1 vá-4, thuộc K2). Cửa 2: leaf "Thao tác" preset `?group=` (cụm-2 vá-6, K4b — 0 phụ thuộc K3, chỉ cần picker vá-4). 2 cửa cùng đổ về 1 form — KHÔNG trùng/chỏi. +- ⚠️ Nhưng OG-7 tổng `:45` hứa UX cụ thể: *"PE có phiếu rồi → hiện phiếu + **nút phụ 'Tạo thêm cho nhóm khác'** (thay 409 chặn hẳn)"* — grep cả cụm-1 lẫn cụm-2: KHÔNG vá nào nhận việc "nút phụ" này (cụm-1 vá-4 = picker nhóm; K2 đổi picker PE `:1201-1202` = gỡ filter PE-đã-có-phiếu; cụm-2 vá-6 = preset group). Acceptance cụm-1 "tạo phiếu nhóm 2 TỪ UI ×2 app" đo được OUTCOME nhưng không ép UX hướng-1. → LỖ CHỦ-VIỆC nhỏ: cần 1 dòng gán "nút phụ + hiện-phiếu-thay-chặn" về K2 (cùng site picker) hoặc tuyên bố 2-cửa-là-đủ-default và hạ câu OG-7 xuống mô tả hành vi picker. Chờ cụm-3 xem có ai nhận không. ## B. Vá-đè-vá (vá cụm sau có phá vá cụm trước?) -(ĐANG LÀM) +(ĐANG LÀM — cặp nghi tính đến cụm-2; chờ cụm-3 để chốt 43 vá) + +| # | Cặp | Verdict nháp | +|---|---|---| +| B-1 | cụm-1 vá-6 (kéo phase-guard line-edit K4b→K2) ⟂ cụm-2 K4b checklist | ✅ SẠCH — cụm-2 final K4b (`spec-cum2:26`) KHÔNG còn nhắc phase-guard ⇒ move đã được cụm-2 tôn trọng, không mồ côi không trùng | +| B-2 | cụm-2 vá-6 (Thao tác preset VỀ K4b) ⟂ tổng K4b "chờ K2 param" | ✅ SẠCH — dependency K2 giữ nguyên, chỉ gỡ phụ thuộc K3 giả | +| B-3 | tổng K3 "mở resolvePath **fe-admin** `Layout.tsx:166-172` nhận code mới" ⟂ cụm-2 vá-8 "**KHÔNG nới regex fe-admin** đợt này" | ⚠️ KHÔNG phá nhau NHƯNG dễ đọc nhầm thành phá: 2 câu nói về 2 HỌ key khác nhau trên CÙNG file/hàm — K3 nới cho `AwV2_KhkkN*` (designer, System subtree, vẫn hiện sau K6) · vá-8 cấm nới cho `Khkk_*` 48-leaf (KeHoachKyKet bị ẩn admin + fe-admin THIẾU `WorkflowMatrixViewPage`). Cần 1 câu ranh trong spec build: "fe-admin resolvePath: THÊM pattern AwV2_KhkkN* — CẤM thêm pattern Khkk_*" kẻo builder K3 tiện tay nới cả hai | +| B-4 | cụm-1 vá-2 (CẤM sửa `WorkflowService.cs:342`) ⟂ tổng QĐ2 "đổi rào :342-347" | ✅ KHÔNG đụng nhau về máy — 2 file khác nhau trùng số dòng (`Features.cs:342-347` rào 1-PE-1-phiếu PHẢI đổi · `WorkflowService.cs:342` unreachable CẤM đụng); nhưng là bẫy-đọc-lướt đã ghi ở A-4, spec build phải ghi TÊN FILE cạnh mọi ":342" | ## C. Build-order cuối + gate (ĐANG LÀM)