9.7 KiB
CI/CD verify — df52fa0 (W3 KHKK — duyệt 3 trạm, 0 migration)
Ghi TỪNG MỤC ngay khi có bằng chứng (đối-sách #53: file = sản phẩm chính, return chỉ là tóm tắt). Agent: cicd-monitor · Session S161 W3 · Ngày 2026-07-29
§0. Grounding — commit + push
| Mục | Giá trị |
|---|---|
| SHA | df52fa0cd09e13a533724c35f4e6bed44afeb42d |
| Subject | [CLAUDE] App+Infra+Api+FE-User+FE-Admin+Tests: W3 KHKK — duyet 3 tram OR-of-N + finalize chot gia (test-before 6 RED->GREEN) |
| Author / Date | pqhuy1987 · Wed Jul 29 22:33:11 2026 +0700 |
git log origin/main..HEAD |
RỖNG ⇒ đã push |
| Files changed | 11 (+2370 / −6) |
| Breakdown | BE 4 (Controller · IContractSigningPlanWorkflowService · DependencyInjection · ContractSigningPlanWorkflowService) · FE 6 (2 app × {KhkkDetailPage, KhkkWorkflowPanel, types/khkk}) · Tests 1 (ContractSigningPlanApprovalTests.cs) |
| paths-ignore (gotcha #41) | KHÔNG khớp glob nào trong 7-entry ⇒ CI PHẢI chạy ✅ |
| Migrations trong diff | 0 file *Migrations* ⇒ khai báo 0-mig (verify ở §2) |
File MỚI trong commit này (quan trọng cho §3):
fe-{admin,user}/src/pages/khkk/KhkkWorkflowPanel.tsx — NEW-FILE-IN-THIS-COMMIT
(git cat-file -e df52fa0~1:… → exists on disk, but not in df52fa0~1), 423 dòng/app,
SHA256 mirror KHỚP 2 app: 2b64144ef6e8567d6997c0e19b9686c083080216510a4cd8da6157a80f584817.
⟹ Mọi chuỗi ĐỘC-QUYỀN của file này phải VẮNG trong bundle CŨ (build từ 6cbc6ad9 W2) và
có mặt trong bundle MỚI → control ÂM theo trục THỜI GIAN, mạnh hơn control âm hash.
§1. CI run — PASS ✅
| Mục | Giá trị |
|---|---|
| Run | #429 (task id 542) |
| head_sha | df52fa0c ✅ khớp (key theo SHA, KHÔNG theo run_number) |
| status | success (conclusion:None — Gitea tasks không populate, tin status per baseline) |
| created → updated | 22:33:19 → 22:39:13 = 5m54s (nằm trong dải ~5m40s–6m của arc S159/S161) |
| URL | https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp/actions/runs/429 |
Test gate (đọc web-UI log …/runs/429/jobs/0/logs, 17.900 B) — đối chiếu TÁCH-PHẦN:
:29 Passed! - Failed: 0, Passed: 45, Skipped: 0, Total: 45, Duration: 147 ms - SolutionErp.Domain.Tests.dll
:47 Passed! - Failed: 0, Passed: 535, Skipped: 0, Total: 535, Duration: 1 m 36 s - SolutionErp.Infrastructure.Tests.dll
| Kỳ vọng | Đo | KL | |
|---|---|---|---|
| Domain | 45 | 45 | ✅ |
| Infrastructure | 535 | 535 | ✅ |
| TỔNG | 580 | 580 | ✅ |
| Failed / Skipped | 0 / 0 | 0 / 0 | ✅ |
Delta so run #427 (566 = 45D+521I): +14 Infra — commit khai "test-before 6 RED→GREEN";
file test đổi = 1 (ContractSigningPlanApprovalTests.cs). 6 là số kịch bản lead khai, 14 là số test-case
thực thi (Theory/InlineData nở) ⇒ không mâu thuẫn, và gate-580 đúng con số đề bài yêu cầu.
§2. 0-migration invariant
(đang cập nhật)
§3. Bundle marker
§3.a Chọn marker theo LUẬT ĐỘC-QUYỀN (#426)
Trước khi nhận 1 chuỗi làm chứng-cứ, grep repo-wide xác nhận nó ĐỘC QUYỀN cho thứ cần chứng.
Đo bằng grep -roF <s> fe-admin/src fe-user/src src | wc -l (occurrence) + grep -rlF (file list):
| Ứng viên | occurrence | file chứa | Kết luận |
|---|---|---|---|
Không phải lượt bạn |
5 | +{2 app}/components/pe/PeWorkflowPanel.tsx +PurchaseEvaluationWorkflowService.cs |
❌ NHIỄM PE — loại |
Đến lượt bạn duyệt |
4 | +{2 app}/components/pe/PeWorkflowPanel.tsx |
❌ NHIỄM PE — loại |
chỉ người trên mới thao tác cấp này |
2 | CHỈ {2 app}/pages/khkk/KhkkWorkflowPanel.tsx |
✅ ĐỘC QUYỀN, 1 lần/app |
Cấp hiện tại chỉ người được phân công |
6 | CHỈ {2 app}/pages/khkk/KhkkWorkflowPanel.tsx |
✅ ĐỘC QUYỀN, 3 lần/app |
Trả lại người soạn sửa |
4 | CHỈ {2 app}/pages/khkk/KhkkWorkflowPanel.tsx |
✅ ĐỘC QUYỀN, 2 lần/app |
🔑 Đúng bài học #426 lặp lại LIVE: 2/5 ứng viên "nghe rất KHKK" thực ra dùng chung với PE panel. Nếu áp máy móc
Đến lượt bạn duyệtthì bundle CŨ đã có sẵn ⇒ PASS GIẢ.
Trap #425 (comment bị esbuild strip) — đã loại trừ: cả 3 marker giữ lại đều nằm ở mã CHẠY,
không phải comment: chỉ người trên… = JSX text (<div className="mt-0.5">⚠ Không phải lượt bạn — …</div>) ·
Cấp hiện tại chỉ người được phân công… = 3 × title={…} string literal ·
Trả lại người soạn sửa = dialogTitle + 1 × title= (2 string literal).
§3.b Hiệu-chuẩn máy đo TRƯỚC khi dự đoán bội-số (chống bẫy minifier-dedupe)
Bội-số chỉ dùng được nếu minifier KHÔNG gộp literal trùng. Đo bằng chuỗi đã ship bg-slate-200 text-slate-500:
| App | source (HEAD) | trừ 1 lần trong file MỚI ⇒ kỳ vọng bundle CŨ | đo bundle CŨ | Khớp |
|---|---|---|---|---|
| fe-admin | 4 (PeWorkflowPanel×2 · EmployeesListPage×1 · KhkkWorkflowPanel×1 MỚI) |
3 | 3 | ✅ |
| fe-user | 4 (cùng phân bố) | 3 | 3 | ✅ |
⟹ KHÔNG dedupe — literal trùng được giữ nguyên bội-số ⇒ dự đoán SỐ CHÍNH XÁC là hợp lệ (không phải chỉ "≥1").
§3.c Control ÂM theo TRỤC THỜI GIAN (đo TRƯỚC deploy, bundle W2 6cbc6ad9)
Bundle cũ: admin index-D4uy3yxF.js (1.709.294 B) · user index-C1ASe0K1.js (1.625.473 B), cả 2 ct=application/javascript.
| Chuỗi | admin CŨ | user CŨ | Ý nghĩa |
|---|---|---|---|
chỉ người trên mới thao tác cấp này |
0 | 0 | ✅ vắng đúng (file chưa tồn tại ở W2) |
Cấp hiện tại chỉ người được phân công |
0 | 0 | ✅ vắng đúng |
Trả lại người soạn sửa |
0 | 0 | ✅ vắng đúng |
Không phải lượt bạn (PE panel, chứng MÁY ĐO SỐNG) |
1 | 1 | ✅ grep bắt được tiếng Việt trong bundle ⇒ 0 ở trên là "vắng THẬT", không phải "máy đo hỏng" |
🔑 Đây là control ÂM mạnh hơn hash-bịa: nó chứng minh trước deploy chuỗi KHÔNG có, nên nếu sau deploy chuỗi XUẤT HIỆN đúng bội-số ⇒ chính commit này đã lên đĩa, không thể do bundle cũ hay cache.
§3.d DỰ ĐOÁN (chốt TRƯỚC khi đo bundle mới)
| Chuỗi | admin MỚI | user MỚI |
|---|---|---|
chỉ người trên mới thao tác cấp này |
1 | 1 |
Cấp hiện tại chỉ người được phân công |
3 | 3 |
Trả lại người soạn sửa |
2 | 2 |
bg-slate-200 text-slate-500 (hiệu-chuẩn) |
4 (3→4) | 4 (3→4) |
§3.e SỐ ĐO bundle MỚI — 4/4 dự đoán KHỚP TỪNG ĐỒNG ✅
Bundle mới (rotate 4/4): admin js D4uy3yxF→BPWQQe4q · css 9okZenCM→KS0kL7bG ·
user js C1ASe0K1→DV3fEpOw · css BfN7IuxJ→Cpp9Qc7C.
Size: admin 1.709.294 → 1.720.297 (+11.003 B) · user 1.625.473 → 1.636.476 (+11.003 B) —
delta BẰNG NHAU 2 app, khớp việc file panel là MIRROR SHA256 identical. Cả 2 ct=application/javascript.
| Chuỗi | Dự đoán | admin đo | user đo | KL |
|---|---|---|---|---|
chỉ người trên mới thao tác cấp này |
1 / 1 | 1 | 1 | ✅ |
Cấp hiện tại chỉ người được phân công |
3 / 3 | 3 | 3 | ✅ |
Trả lại người soạn sửa |
2 / 2 | 2 | 2 | ✅ |
bg-slate-200 text-slate-500 (hiệu-chuẩn) |
4 / 4 | 4 | 4 | ✅ |
Không phải lượt bạn (PE 1 + KHKK 1) |
2 / 2 | 2 | 2 | ✅ bonus nhất-quán |
Cả 3 marker đi từ 0 (bundle W2) → đúng bội-số nguồn (bundle W3), và chuỗi hiệu-chuẩn đi 3→4 đúng bằng +1 lần xuất hiện trong file mới ⇒ không chỉ "có ship", mà ship ĐÚNG BẤY NHIÊU, không thừa không thiếu.
§3.f Control ÂM 2 tầng (bundle cũ phải BIẾN MẤT khỏi đĩa)
| Phép | code | content-type | size | KL |
|---|---|---|---|---|
admin hash CŨ index-D4uy3yxF.js |
200 | text/html |
900 | ✅ đã bị ghi đè |
user hash CŨ index-C1ASe0K1.js |
200 | text/html |
876 | ✅ đã bị ghi đè |
admin hash BỊA index-ZZZZ9999.js |
200 | text/html |
900 | ✅ trùng khít hash cũ |
user hash BỊA index-ZZZZ9999.js |
200 | text/html |
876 | ✅ trùng khít hash cũ |
⟹ hash CŨ trả về byte-size y hệt hash BỊA ⇒ 200 đó là SPA-fallback index.html, không phải file thật
(bẫy #69/SPA-fallback). Bundle W2 đã bị xoá khỏi đĩa ⇒ deploy ghi đè THẬT.
PHÉP 3 = PASS.
§4. Smoke + transitions THẬT — PASS ✅ [LEAD đo on-behalf]
- login admin token-468 ·
POST .../00000000-…-01/transitionsbody{"action":"nonsense"}→ 409 ProblemDetails "Hành động không hợp lệ" (validate-action TRƯỚC load-plan — đúng thiết kế skeleton đợt-1). - body
{"action":"approve"}GUID ma → 404 ProblemDetails "Không tìm thấy ContractSigningPlan" (GlobalExceptionMiddleware map đúng; endpoint transitions SỐNG prod).
§5. Cờ KeHoachKyKet 13/13/2 — PASS ✅ [LEAD đo on-behalf]
sqlcmd prod: KHKK_CU=13/13/2 GIỮ · MIGTOP 20260729122015_AddContractSigningPlans GIỮ · MIGCOUNT 69 · TABLES 96 · MENU 142 GIỮ (§2 0-mig PASS luôn tại đây).
END cicd-verify df52fa0 — VERDICT=PASS 5/5 (§1+§3 cicd-monitor · §2+§4+§5 lead 2-nguồn)