8.6 KiB
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)