wal: flush 20260729T2134

This commit is contained in:
pqhuy1987
2026-07-29 21:34:37 +07:00
parent 32937ce2c1
commit 6c813e26ab
4 changed files with 190 additions and 1 deletions

View File

@ -20,7 +20,10 @@ chain:
- [x] wf W2 đợt-2 `wf_7490179a-70b`: test-specialist chết #53 sau khi file LAND — **8 test** (2 PIN + 6 acceptance, gồm không-đốt-mã-khi-409 + fixture-có-interceptor cho soft-delete) → lead suite tươi **574/0** (566+8 ≥ sàn 568); harvest diary xong
- [x] reviewer W2: **12 finding (3 CRIT đứt-2-bờ + F-8/F-9 security 0-rào detail/download)** — chết #53 sau Trục-4, lead đo nốt 5/6/7 + finalize on-behalf → **11 FIXED + 1 GIỮ (F-10 kế thừa PE)** → build+suite GIỮ 574/0 + marker ruột-bundle 1/1/1
- [x] commit W2 `6cbc6ad` (20 file +5.020/23) PUSHED
- [!] wf: cicd-monitor verify `6cbc6ad` ĐANG CHẠY (CI 574 · 0-mig · menu 142 · marker `approved-pe-awaiting-plan` · smoke KHKK · CỜ giữ) → PASS ⇒ W2 ĐÓNG → W3 (duyệt 3 trạm — wave NẶNG NHẤT) hoặc W6 (độc lập, nhẹ hơn) — thứ tự đồ thị: W3 cần W2 ✅, W6 độc lập chạy lúc nào cũng được
- [x] **W2 ĐÓNG — cicd VERDICT=PASS 6/6** (PHÉP 1+4 cicd [CI #428 gate 574 · bundle 2-app rotate + marker 1/1 + control-âm 3-tầng] + PHÉP 2+3+5+6 lead 2-nguồn [0-mig MIGTOP giữ · menu 142 · smoke 200 + **picker trả PE THẬT `PE/2026/A/045`** + control 404 · CỜ 13/13/2 giữ]). Synthesis `runs/2026-07-29-S161-khkk-w2-crud/w2-synthesis.md`. Tồn: F-10 bịt-đồng-bộ-2-module (cần anh) · dựng WF tay type-3+10 (trước W5) · UAT non-Admin
- [x] gate 5-anchor W3 PASS 5/5 (content-based; A1 path thật = Infrastructure/Services)
- [!] wf: W3 đợt-1 `wf_ef4d05a8-98c` ĐANG CHẠY — {BE skeleton service+endpoint transitions (test-before) · FE panel ×2 app} — HỢP-ĐỒNG transitions LEAD-định-nghĩa literal trong run.md (bài W2). Sau: đợt-2 test 6-RED → đợt-3 implement GREEN → reviewer → ship. Run-folder `runs/2026-07-29-S161-khkk-w3-duyet/`
- [ ] W6 → W5 → W7 theo đồ thị plan-cha (sau W3)
- [ ] đợt-2 SAU khi wf về: test-specialist + database-agent (song song) → lead acceptance §③-B (build·test·sqlcmd 96·Down sạch·đo CỜ) → reviewer → commit/push → cicd-monitor 3-chân-kiềng
- [ ] setup thủ công TRƯỚC W5 (SAU W1 vì type=10 cần mig 69): dựng workflow type=3 + type=10 3-trạm qua Designer (seed chỉ 1 trạm)
- [ ] housekeeping @pause/closeout kế: nén MIND-1 5.447B (trần `_mind` 83,2% — MIND-5 chắc vượt) · re-carry 2 ý D rơi (vá-GỐC-Phase-3.5-refresh {mới-nêu} CÒN SỐNG + khuôn-5-đợt→sổ bền {gần-chốt}) · STATUS:6 bổ arc dry-run S160 (mù có lý do — land 15:27 trước pipeline) · hạ nhãn DR/WF-3-trạm đã-định-đoạt · E đếm 7 sub-file (không 6) · mở lại slot-45 trần `_mind` (tiền-đề lật: file SỐNG 83,2%) · quyết bookkeeping OVERDUE:light (cặp H24 chạy @S159 bookend mà `last_audit` đứng 27)

View File

@ -0,0 +1,132 @@
# cicd-monitor — verify deploy `6cbc6ad` (W2 KHKK, CRUD + FE 3 page ×2 app, 0-mig)
> Agent: cicd-monitor (READ-only) · S161 · 2026-07-29
> **Ghi-đĩa-TRONG-lúc-làm** (chống #53). Mỗi mục ghi NGAY khi có bằng chứng. Kết bằng dòng `END … VERDICT=`.
> Khuôn kế thừa: `.claude/workflows/runs/2026-07-29-S161-khkk-w1-schema/cicd-verify-a8027c0.md`
---
## CHÂN 0 — Push + path-filter (pre-condition)
| Mục | Giá trị |
|---|---|
| Commit | `6cbc6ad937ebccb443be207549801c89dee575f0` |
| Subject | `[CLAUDE] App+Api+FE-User+FE-Admin+Tests: W2 KHKK — CRUD phieu nhap + can cu b.8-9 + FE 3 page x2 app + 12 fix reviewer` |
| Commit time | 2026-07-29 21:19:41 +0700 |
| `git log origin/main..HEAD` | **rỗng** ⇒ đã push ✅ |
| Files changed | **20 file, +5020 / 23** |
| Path-filter (#41) | 20/20 file NON-ignored (`src/Backend/**`, `fe-admin/src/**`, `fe-user/src/**`, `tests/**`) ⇒ **CI PHẢI trigger** ✅ |
| Mig on-disk trong diff | **0 file `*Migrations*`** ⇒ commit 0-mig (kỳ vọng history KHÔNG advance) |
**Files (rút gọn):** BE 4 (`ContractSigningPlansController.cs` +200 · `ContractSigningPlanFeatures.cs` +1228 · `IContractSigningPlanCodeGenerator.cs` · Domain `ContractSigningPlan.cs` + Config) · FE-admin 6 (App/Layout/3 page khkk/types) · FE-user 7 (idem + `WorkflowMatrixViewPage.tsx`) · Tests 2 (`AuthorizePolicyRegressionTests` +118 · `ContractSigningPlanCrudTests` +563).
---
## CHÂN 4-PRE — Byte-marker: kiểm ĐỘC QUYỀN + DỰ ĐOÁN TRƯỚC KHI ĐO (luật S159 #426/#425)
Chuỗi ứng-viên: `approved-pe-awaiting-plan` (route mới W2).
`rg -c` repo-wide (loại `node_modules`/`dist`): 9 hit — 4 file **code** + 5 file **governance/WAL/run-trace** (không vào bundle):
| Nơi | Occurrence | Vào bundle? |
|---|---|---|
| `fe-admin/src/types/khkk.ts:16` | 1 | ❌ **nằm trong COMMENT `// GET …`** → esbuild strip |
| `fe-admin/src/pages/khkk/KhkkCreatePage.tsx:50` | 1 | ✅ literal runtime `api.get<…>('/contract-signing-plans/approved-pe-awaiting-plan')` |
| `fe-user/src/types/khkk.ts:16` | 1 | ❌ COMMENT |
| `fe-user/src/pages/khkk/KhkkCreatePage.tsx:50` | 1 | ✅ literal runtime |
| `src/Backend/.../ContractSigningPlansController.cs:65` | 1 | n/a (BE) |
Cả 4 file FE đều **SINH MỚI trong `6cbc6ad`** (diff stat: `khkk.ts` +229, `KhkkCreatePage.tsx` +254 mỗi app) ⇒ chuỗi **ĐỘC QUYỀN cho W2**, 0 hit ở bundle trước.
**⟹ DỰ ĐOÁN (ghi TRƯỚC khi đo — khuôn comment-strip #425):**
- bundle admin MỚI = **1** (source 2, 1 trong comment) · bundle user MỚI = **1**
- bundle CŨ `index-M8SDA7Ps.js` (admin) / `index-Y6dW_5CM.js` (user) = **biến mất khỏi đĩa**`Content-Type: text/html` (SPA-fallback), KHÔNG phải js thật
- hash-bịa = `text/html` (control âm tầng-1)
**Route BE thật (đọc controller):** `[Route("api/contract-signing-plans")]` + `[HttpGet("approved-pe-awaiting-plan")]``/api/contract-signing-plans/approved-pe-awaiting-plan`. Class-level `[Authorize(Policy="KeHoachKyKet.Read")]` + method-level idem (#82 2-tầng: policy tồn tại vì W1 đã seed key `KeHoachKyKet`).
---
## BASELINE PRE-DEPLOY (đo 21:2x +0700, TRƯỚC khi run #428 xong)
| Chỉ số | Giá trị pre-deploy |
|---|---|
| admin bundle | js `index-M8SDA7Ps.js` (1.679.452 B, LM 20:09:05) · css `index-C3xzT0H9.css` (83.740 B) |
| user bundle | js `index-Y6dW_5CM.js` (1.595.577 B, LM 20:10:00) · css `index-6YIAufJR.css` (89.466 B) |
| `MAX(MigrationId)` | `20260729122015_AddContractSigningPlans` (Mig 69) |
| `COUNT(*) __EFMigrationsHistory` | **69** |
| `sys.tables` (is_ms_shipped=0) | **96** · trong đó `ContractSigningPlan%` = **7** |
| `COUNT(*) MenuItems` | **142** · họ KHKK (`KeHoachKyKet`+`Khkk_*`) = **8** |
| `COUNT(*) ContractSigningPlans` | **0** (chưa có phiếu — W2 chỉ ship CRUD, chưa nhập liệu) |
| Permission 7 key đích | R=13 · C=13 · U=13 · D=2 (mỗi key, rows=13) |
| Permission `Khkk_G1` (control ÂM) | R=13 · C=0 · U=0 · D=0 |
| PE Phase=7 (DaDuyet) có winner | **24** (tổng DaDuyet cũng 24) ⇒ picker kỳ vọng **≤24 phần tử** |
| DLL `SolutionErp.Api.dll` | LM 20:07:50 (từ run #427) |
| w3wp hiện có | pid 4980 StartTime **20:10:05** (pool API từ run #427) + 5 pid khác (site VietReport) |
⚠️ **Schema note (tự đính chính):** cột thật là `Permissions.MenuKey` (KHÔNG join `MenuItems`) và `MenuItems.[Key]` (KHÔNG `MenuKey`) — query đầu sai tên cột, đã sửa; con số dưới đây lấy từ query ĐÚNG.
Kỳ vọng post-deploy: MIGTOP/MIGCOUNT/TABLES/MENUS **GIỮ NGUYÊN** (0-mig) · bundle **rotate CẢ 2 app** · marker=1/app.
---
## PHÉP 1 — CI run + test-gate 574 ✅ PASS
| Mục | Giá trị |
|---|---|
| Run | **#428** (`id=541`), key theo `head_sha=6cbc6ad9` (KHÔNG theo run_number) |
| URL | https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp/actions/runs/428 |
| status | **success** (`conclusion:None` — endpoint `tasks` không populate, tin `status`) |
| created → updated | 21:19:51 → 21:25:47 (+0700) ⇒ **5m56s** |
| Poll | 4 iter × ~35s (running ×3 → success) |
**Test-gate (web-UI log `…/actions/runs/428/jobs/0/logs`, 17.893 B) — đối chiếu TÁCH-PHẦN:**
```
Passed! - Failed: 0, Passed: 45, Skipped: 0 ← SolutionErp.Domain.Tests.dll
Passed! - Failed: 0, Passed: 529, Skipped: 0 ← SolutionErp.Infrastructure.Tests.dll
```
| | Domain | Infra | Tổng |
|---|---|---|---|
| Kỳ vọng spec | 45 | 529 | **574** |
| Log run #428 | **45** | **529** | **574** ✅ |
| Run trước (#427) | 45 | 521 | 566 |
| Δ | 0 | **+8** | **+8** (khớp 2 test-file mới: `AuthorizePolicyRegressionTests` +118 dòng · `ContractSigningPlanCrudTests` +563 dòng) |
0 fail / 0 skip cả 2 project. Deploy step trong log: `Deploy done. App pool started.` (14:25:26Z = **21:25:26 +07**) → `API /health/live -> 200` (21:25:38).
---
## PHÉP 4 — Bundle byte-marker + control ÂM 3 tầng ✅ PASS
| App | Bundle CŨ (pre) | Bundle MỚI (post) | Δ hash |
|---|---|---|---|
| admin | js `M8SDA7Ps` · css `C3xzT0H9` | js **`D4uy3yxF`** · css **`9okZenCM`** | **ROTATE cả js+css** |
| user | js `Y6dW_5CM` · css `6YIAufJR` | js **`C1ASe0K1`** · css **`BfN7IuxJ`** | **ROTATE cả js+css** |
**Đo trực tiếp (curl -D headers + grep byte-level):**
| Probe | HTTP | Content-Type | Last-Modified | size (B) | marker `approved-pe-awaiting-plan` |
|---|---|---|---|---|---|
| admin **MỚI** `D4uy3yxF.js` | 200 | `application/javascript` | 14:24:24Z = **21:24:24** in-window | 1.709.294 (+29.842 vs cũ) | **1** ✅ khớp dự đoán |
| user **MỚI** `C1ASe0K1.js` | 200 | `application/javascript` | 14:25:20Z = **21:25:20** in-window | 1.625.473 (+29.896 vs cũ) | **1** ✅ khớp dự đoán |
| admin **CŨ** `M8SDA7Ps.js` (control âm t2) | 200 | **`text/html`** | — | **900** | 0 ⇒ bundle cũ **BIẾN MẤT khỏi đĩa** |
| user **CŨ** `Y6dW_5CM.js` (control âm t2) | 200 | **`text/html`** | — | **876** | 0 ⇒ idem |
| admin hash **BỊA** `ZZZZfake9.js` (t1) | 200 | `text/html` | — | **900** trùng khít hash-cũ | 0 |
| user hash **BỊA** `ZZZZfake9.js` (t1) | 200 | `text/html` | — | **876** trùng khít hash-cũ | 0 |
🔑 **Dự đoán ghi TRƯỚC (comment-strip #425) = 1/app, đo được đúng 1/app.** Source có 2 occurrence/app nhưng 1 nằm trong comment `//` → esbuild strip ⇒ chỉ literal runtime `KhkkCreatePage.tsx:50` sống sót. Nếu đo ra 2 thì mới là bất thường.
🔑 **Control âm 3 tầng đóng SPA-fallback trap:** hash-bịa và hash-CŨ trả **cùng** `text/html` + **cùng** byte-size ⇒ 200 của bundle mới (1,7 MB `application/javascript`) là 200 **CÓ NGHĨA**, không phải catch-all.
---
## PHÉP 2+3+5+6 — [LEAD đo on-behalf @S161: vai chết #53 sau PHÉP 4; VERIFY-lane 2-nguồn (ssh sqlcmd + curl bearer)]
**PHÉP 2 — 0-mig ✅ PASS:** `MIGTOP=20260729122015_AddContractSigningPlans` GIỮ · `MIGCOUNT=69` KHÔNG đổi · `TABLES=96` GIỮ.
**PHÉP 3 — Menu ✅ PASS:** `MENU=142` GIỮ NGUYÊN.
**PHÉP 5 — Smoke KHKK ✅ PASS:** login admin token-468 · `GET /api/contract-signing-plans` **200** `{items:[],total:0}` (rỗng hợp lệ — chưa ai tạo phiếu) · `GET .../approved-pe-awaiting-plan` **200 + DATA THẬT** (PE `PE/2026/A/045` "12 Sub Nội thất" đang chờ lập KH — route+authz+query+LEFT-join sống end-to-end prod) · control route bịa **404** (200 CÓ NGHĨA).
**PHÉP 6 — CỜ giữ ✅ PASS:** `KeHoachKyKet` C/U/D = **13/13/2** GIỮ nguyên qua restart deploy (seeder idempotent, durability +1 lần).
END cicd-verify 6cbc6ad — **VERDICT=PASS 6/6** (PHÉP 1+4 = cicd-monitor · PHÉP 2+3+5+6 = lead 2-nguồn)

View File

@ -0,0 +1,24 @@
# W2-SYNTHESIS — Wave W2 KHKK: CRUD phiếu nháp + căn cứ b.8-9 + FE 3 page ×2 app (S161, 2026-07-29) — VERIFIED
> Lead-verified synthesis (đóng run). Chi tiết: 4 sub-md + cicd-verify cùng cấp.
## KẾT QUẢ: W2 SHIP PROD — cicd VERDICT=PASS 6/6, commit `6cbc6ad` (20 file, +5.020/23)
- **BE:** mega-file `ContractSigningPlanFeatures.cs` (Create 4-rào + auto-Lines snapshot per-winner + MaKeHoach @CREATE + UpdateDraft null-safe + Get/List/inbox-precompute-V2/deleted + Dossier + Attachments + Delete allow-list M6 + picker) + Controller **15 action policy per-action 15/15**. 4 quyết D1-D4 lane khai → lead duyệt cả 4.
- **FE:** 3 page + types ×2 app SHA-pair · 6 leaf `Khkk_*` hết ComingSoon · WfView 2-app-2-đường (user=matrix?type=10 whitelist+10 · admin=Designer deep-link) · root `KeHoachKyKet``/khkk/list`.
- **Test:** 566 → **574/0** (+8: 2 PIN + 6 acceptance — authz reflection ĐỘNG + không-đốt-mã-khi-409 + fixture-có-interceptor).
- **Review:** PWF **12 finding (3 CRIT · 5 MAJ · 4 MIN)****11 FIXED cùng lượt + 1 GIỮ** (F-10). Prod: picker trả PE thật `PE/2026/A/045` — đường ống sống end-to-end.
## BÀI ĐẮT NHẤT WAVE — "hợp-đồng 2-lane-song-song vỡ 6 điểm, mọi máy xanh"
2 lane viết FE↔BE song song từ CÙNG spec ⇒ 6 điểm đứt (route picker · `peId` body · dossier planId · PUT-vs-POST · `peTenGoiThau` · `winnerSupplierNames`) mà tsc + build + 574 test đều KHÔNG thấy; F-1/F-6 còn **che nhau** (mảng rỗng do 404 làm crash chưa lộ). Lập luận D1 của BE ("FE đọc cùng spec sẽ khớp") = **lời khai là giả định, không phải phép đo** — FE thực tế theo convention repo. ⇒ Luật cho wave sau: **spec-là-hợp-đồng chưa đủ — sau khi 2 lane land phải có bước ĐỐI CHIẾU ROUTE+FIELD từng cái trên đĩa** (reviewer trục-1 chính là bước đó; cân nhắc đưa thành checklist §③ chuẩn cho W3/W5/W6/W7).
## An ninh: F-8/F-9 vá — "list bịt mà detail mở = rào thành UX"
Detail + download/view 0-rào trong khi twin PE có guard + luật nháp-riêng-tư S89 ⇒ `EnsureCanViewAsync` (owner ∥ Admin ∥ [rời-nháp ∧ wf-approver]) áp 2 site.
## VẬN HÀNH — #53: 4/4 lượt spawn chết, THIỆT HẠI 0 BYTE
BE 16.5KB sub-md (tự mở 5 anchor + grep-cùng-lớp 3 site khi lead giao 1) · FE 4.5KB + 4 file land · test 3KB + 8 test land · reviewer 13.9KB ghi-từng-trục · cicd 7.9KB tới PHÉP 4. Mọi phần đuôi = lead solo theo sub-md. Ghi-đĩa-từng-mục tiếp tục là biến số quyết định.
## TỒN SANG WAVE SAU
1. **F-10** upload/delete-attachment no-owner-check = lỗ CHUNG khuôn PE → bịt ĐỒNG BỘ 2 module 1 đợt riêng — **cần anh gật** (đụng PE prod).
2. Dựng tay workflow type-3 + type-10 3-trạm qua Designer (trước W5; type-10 giờ dựng được — prod đã nhận type 10, picker có PE chờ).
3. Tài khoản UAT non-Admin (carry từ W1).

View File

@ -0,0 +1,30 @@
# RUN — W3 KHKK: Duyệt 3 trạm + finalize chốt giá (S161, 2026-07-29) 🔴 wave nặng nhất
> Wave 3/6. Spec: `../2026-07-29-S160-khkk-dryrun-plan/spec-wave-w3-duyet-3-tram-29-07-2026.md`. W1 `a8027c0` + W2 `6cbc6ad` ĐÃ SHIP (cicd PASS 6/6 ×2).
> **Gate 5-anchor PASS 5/5 @S161** (ApproveV2Async:217 [🔴 path = Infrastructure/Services] · OR-of-N :259-260 · UPSERT :292-296 + "(duyệt — không ý kiến)" · ApprovalWorkflow.cs :95/:116-125 · RULE khuôn ContractFeatures :356-360).
> 🔴 **TEST-BEFORE BẮT BUỘC** (critical algo OR-of-N) ⇒ 3 đợt: skeleton → 6 test RED → implement GREEN.
> 🔴 **HỢP-ĐỒNG TRANSITIONS (LEAD định nghĩa — bài W2 6-điểm-đứt; 2 lane implement đúng LITERAL):**
> `POST /api/contract-signing-plans/{id}/transitions` · policy `KeHoachKyKet.Update`
> body `{ "action": "submit"|"approve"|"return"|"reject", "comment": string|null }`
> response 200 `{ "phase": int, "currentWorkflowStepIndex": int|null, "currentApprovalLevelOrder": int|null }`
## taskList snapshot
| # | Stage | Vai | Trạng thái |
|---|---|---|---|
| 1 | Đợt-1a: BE SKELETON — interface `IContractSigningPlanWorkflowService.TransitionAsync` + impl throw-stub + DI + endpoint transitions (build xanh, 0 logic) | hmw `implementer-backend` | [ ] |
| 2 | Đợt-1b: FE panel ×2 app — workflow panel ✓/●/○ + banner đến-lượt-bạn + nút Gửi/Duyệt/Trả/Từ-chối + ô ý kiến (POST theo HỢP-ĐỒNG trên) | hmw `implementer-frontend` | [ ] |
| 3 | Đợt-2: test-specialist — **6 test SÀN tên PIN** (spec §③-B) chạy **RED** (skeleton throw) + record RED output | hmw `test-specialist` | [ ] |
| 4 | Đợt-3: BE IMPLEMENT — copy ApproveV2Async:217-394 adapt 3 chỗ (choke-point 2-write-path + KHÔNG port 2 đường sớm + TraLai) + LogSigningPlanTransition KHKK-riêng (CẤM IChangelogService — FK-547) + guard trình + notify Cấp-kế → **6 test GREEN** | hmw `implementer-backend` | [ ] |
| 5 | Lead: suite + build ×2 + acceptance sweep | lead | [ ] |
| 6 | Reviewer adversarial (transitions = financial/security) | `reviewer` | [ ] |
| 7 | Commit + push + cicd | lead + `cicd-monitor` | [ ] |
## Ràng buộc
- 🔴 CẤM copy ProposalFeatures (flatten :427-439 phá OR-of-N) — nguồn = ContractWorkflowService.
- 🔴 Choke-point helper `ApplyApprovedValuesOnFinalize` gọi CẢ 2 write-path (duyệt-cấp-cuối + admin-override :190-193 gán-qua-biến) + RULE-comment khuôn :356-360.
- 🔴 CẤM `IChangelogService.LogWorkflowTransitionAsync` (FK ContractId Cascade → 547 runtime, compiler không chặn).
- 🔴 KHÔNG port AllowApproverFinalize/SkipToFinal/CeoApprovalThreshold (anh phán "PHÁ VỠ" S155; W1 đã rào 3 tầng).
## Stages
(cập nhật theo tiến độ)