9.3 KiB
CICD-K1: PASS — 6/6 mục
cicd-monitor — verify deploy K1 SP-002 (50e6d8c)
Artifact chống #53: ghi TỪNG mục NGAY khi đo xong. Kết bằng dòng
END … VERDICT=. Spawn 2026-07-31 · commit50e6d8c38283a9dd45da2001bd2fc6596595558f· READ-only (0 ghi prod)
Stage 1 — Push + path-filter (PRE-điều-kiện)
git log -1→50e6d8c38283a9dd45da2001bd2fc6596595558f|[CLAUDE] Contract: K1 SP-002 danh muc loai HD - ContractCatalogEntries (Mig 70) + seed 86 + CQRS + FE kind-5 x2 app + 8 test|2026-07-31 15:45:50 +0700git log origin/main..HEAD→ RỖNG (đã push hết)git diff --name-only 50e6d8c^ 50e6d8c→ 20 file (neo bằngX^..Xtheo LUẬT S162 CẤM-HEAD~1, vì phiên có Stop-hook WAL auto-commit): BE 11 · FE 6 · Test 1 · Docs 2- vs
paths-ignore7-glob: 18/20 file KHÔNG bị ignore ⇒ CI PHẢI chạy. ✅
Stage 1b — DỰ ĐOÁN TRƯỚC KHI ĐO (chống xác-nhận-ngược)
Đọc DbInitializer.SeedContractCatalogAsync (dòng 3163-3325) trước khi chạm prod:
- Parse lần 1 (regex line-anchored) → 78 ⇒ SAI (tuple xuống dòng). Vứt, KHÔNG báo cáo số này.
- Parse lần 2 (multiline) → 86; cross-check độc-lập
raw code-literal= 86, distinct = 86, dup = []. - Dự đoán
GROUP BY ApprovalGroup: 1:5 · 2:10 · 3:5 · 4:23 · 5:14 · 6:15 · 7:13 · 8:1 - Dự đoán
GROUP BY GroupCode: 11 nhóm — A1:5 A2:1 A3:9 A4:5 B1:23 B2:14 B3:15 C1:6 C2:3 C3:4 CEO:1 - Seeder idempotent (
existingCodes.Contains(code) continue+IgnoreQueryFiltersné #75/#76) ⇒ deploy đầuadded=86. - Serilog dự kiến:
Seeded 86 contract catalog entries (S164 SP-002)(chỉ ghi khiadded>0).
Bundle PRE-deploy (đo LIVE lúc run đang chạy, 15:47)
| App | js | css |
|---|---|---|
| admin | index-B43R6Y17.js |
index-BZ5F-g1w.css |
| eoffice | index-NLI5umBg.js |
index-yNZDmVNz.css |
Khớp nguyên văn hash đề-bài (B43R6Y17 / NLI5umBg) ⇒ mốc "TRƯỚC" hợp lệ.
✅ Mục 1 — Gitea Actions run
- Run id=547 · run_number=#434 · head_sha
50e6d8c3· jobbuild-deploy· runnervps-vietreport-runner v0.2.13 - created
2026-07-31T15:46:06+07:00(push 15:45:50 → pick sau 16s) - Poll 7 iter × ~40s → iter7
status=success, updated2026-07-31T15:52:37+07:00 - Duration ≈ 6m31s ·
conclusion=None(tasks API không populate — tinstatus, đúng khuôn đã biết) - URL: https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp/actions/runs/434
- PASS
✅ Mục 2 — Test gate 598
Nguyên văn từ web-UI log (/actions/runs/434/jobs/0/logs, 18.698 B):
2026-07-31T08:46:34.2961110Z Passed! - Failed: 0, Passed: 45, Skipped: 0, Total: 45, Duration: 196 ms - SolutionErp.Domain.Tes…
2026-07-31T08:49:26.8226799Z Passed! - Failed: 0, Passed: 553, Skipped: 0, Total: 553, Duration: 1 m 44 s - SolutionErp.Infrastr…
- Domain 45 + Infra 553 = 598 — khớp baseline MỚI đề bài (590+8). Đối chiếu TÁCH-PHẦN: Domain 45 GIỮ NGUYÊN, Infra 545→553 = +8 ⇒ đúng "7 lane K1 + T5b gate-fix" (delta rơi trọn vào Infra, đúng nơi file test mới nằm).
- 0 fail / 0 skip cả 2 project.
Failed!/error CSxxxx= 0 hit. - ⚠️ Ghi chú phương-pháp: grep đầu tiên 0 hit do format nhiều-khoảng-trắng (
Passed! - Failed: 0); đã soi lại format thật rồi mới trích — KHÔNG báo "không thấy dòng test". - PASS
✅ Mục 3 — EF migration prod
20260731072441_AddContractCatalogEntries ← TOP
20260729122015_AddContractSigningPlans
20260727033522_AddPeAllowApproverDelete
20260717032812_AddPeApprovedBudgetSnapshot
__EFMigrationsHistoryTOP == repo HEAD mig ⇒ Mig 70 applied prod.- Chân-kiềng (i) chứng-minh-restart-thật:
w3wpPID 2644 StartTime 7/31/2026 3:52:13 PM (trong cửa-sổ deploy 15:46:06→15:52:37) + dòng ĐẦU Serilog2026-07-31 15:52:19.770 +07:00 [INF] Applying migrations...⇒ mọi số DB dưới đây đo SAU recycle (né đúng lỗi #423). - PASS
✅ Mục 4 — Seed prod 86 + phân bố 8 nhóm
sqlcmd (SQL-auth vrapp, sau recycle):
| Đo | Kết quả |
|---|---|
COUNT(*) FROM ContractCatalogEntries |
86 |
GROUP BY ApprovalGroup |
1:5 · 2:10 · 3:5 · 4:23 · 5:14 · 6:15 · 7:13 · 8:1 |
COUNT(DISTINCT Code) |
86 (0 trùng) |
IsActive=1 |
86 · IsDeleted=1 = 0 |
COUNT(DISTINCT GroupCode) |
11 |
Serilog (solution-erp-20260731.log) nguyên văn:
2026-07-31 15:52:27.074 +07:00 [INF] Seeded 86 contract catalog entries (S164 SP-002)
2026-07-31 15:52:25.867 +07:00 [INF] Seeded 1 menu items
2026-07-31 15:52:26.030 +07:00 [INF] Seeded 1 admin permissions
- Control ÂM:
findstr "contract catalog KHONGTONTAI"→ 0 hit ⇒ findstr có răng, không phải khớp bừa. - Đối chứng: 2 dòng
Seeded 1 menu items/Seeded 1 admin permissions= menu-rowContractCatalog+ permission cũng vào (leafCatalogsthứ 5). - 🔑 TAM-GIÁC 3 NGUỒN ĐỘC-LẬP khớp từng đồng: source-parse (86 / 8 nhóm) == sqlcmd prod (86 / 8 nhóm) == API materialize qua EF (86 / 8 nhóm, xem Mục 6). Không nguồn nào suy ra nguồn kia.
- PASS
✅ Mục 5 — Bundle đổi ×2 app (#77 byte-level)
Vế DƯƠNG — hash MỚI là asset THẬT:
| URL | code | content-type | size |
|---|---|---|---|
admin /assets/index-CKgq0YlH.js |
200 | application/javascript |
1.751.576 |
admin /assets/index-DD3xQhNt.css |
200 | text/css |
86.298 |
eoffice /assets/index-CHMCU35C.js |
200 | application/javascript |
1.667.782 |
eoffice /assets/index-CdXRNT7E.css |
200 | text/css |
92.092 |
Vế ÂM — hash CŨ phải BIẾN MẤT khỏi đĩa (né SPA-fallback-200-trap S72, discriminator = Content-Type không phải status):
| URL cũ | code | content-type | size |
|---|---|---|---|
admin index-B43R6Y17.js |
200 | text/html |
900 |
admin index-BZ5F-g1w.css |
200 | text/html |
900 |
eoffice index-NLI5umBg.js |
200 | text/html |
876 |
eoffice index-yNZDmVNz.css |
200 | text/html |
876 |
⇒ cả 4 rơi về SPA-shell 876/900 B (trùng khít size index.html) = file cũ đã bị ghi đè thật, KHÔNG phải cache.
Ship-proof Last-Modified in-window (#69 TWO-MODE — hash-delta một mình không đủ):
- admin
/→Last-Modified: Fri, 31 Jul 2026 08:51:06 GMT= 15:51:06 +07 ✔ in-window ·Cache-Control: no-cache - eoffice
/→Last-Modified: Fri, 31 Jul 2026 08:52:07 GMT= 15:52:07 +07 ✔ in-window ·Cache-Control: no-cache
4/4 hash ROTATE + 4/4 hash cũ chết + LM in-window. PASS
✅ Mục 6 — Smoke
| Check | Kỳ vọng | Đo được | KL |
|---|---|---|---|
GET /health |
(bare) | 404 | control — route bare không tồn tại |
GET /health/ready |
200 | 200 | ✅ |
GET /health/live |
200 | 200 | ✅ |
GET /api/catalogs/contract-catalog KHÔNG token |
401 | 401 | ✅ authz sống |
CONTROL …/contract-catalog-KHONGTONTAI |
404 | 404 | ✅ 401 CÓ NGHĨA |
CONTROL …/bia-dat-hoan-toan |
404 | 404 | ✅ (route bịa ⇒ 401 ở trên không phải blanket) |
https://admin.solutions.com.vn/ |
200 | 200 | ✅ |
https://eoffice.solutions.com.vn/ |
200 | 200 | ✅ |
CÓ token admin GET …/contract-catalog |
200 + 86 row | 200, 25.374 B, 86 row | ✅ |
Cross-check EF-materialize (mạnh hơn sqlcmd vì đi qua Domain→Infra→Api thật):
rows materialized via EF = 86
by approvalGroup: 1:5 . 2:10 . 3:5 . 4:23 . 5:14 . 6:15 . 7:13 . 8:1
distinct codes = 86
sample row: code=A1-01 group=1 signer=TP.CCM
Class-level [Authorize] + ghi [Authorize(Roles="Admin")] (đọc ContractCatalogController.cs:21-22,39-56) ⇒ 401-không-token đúng thiết-kế, không phải #44 silent-403.
- PASS
Ghi chú lệch / quan sát (KHÔNG phải FAIL)
- Hash CI ≠ hash local build. Đề bài dự-báo local ra admin
BE7zE81C/userDSXJJbJq; CI raCKgq0YlH/CHMCU35C. Tiêu chí đề bài (ĐỔI so với trước + curl 200) thoả. Nghĩa: artifact CI khác byte với artifact local (thường do Node minor / cây npm resolve khác) — bình thường, nhưng ⇒ đừng bao giờ dùng hash local làm mốc kỳ vọng cho prod, luôn re-snapshot LIVE. - Duration 6m31s — dài nhất 4 run gần đây (#432 5m50s · #433 5m55s · #431 5m50s). Chưa tới ngưỡng escalate; hợp lý vì run này có thêm Mig 70 + seed 86 row + 8 test mới. Theo dõi tiếp, chưa cần hành động.
Passed!grep 2-khoảng-trắng — lần grep đầu 0-hit là DƯƠNG-GIẢ do format; đã soi format rồi mới kết luận (bài học: 0-hit phải kèm control-dương trước khi báo).[WRN]global-query-filter (ContractSigningPlan/Contract ↔ Approval/Changelog/LevelOpinion) là warning EF có sẵn từ trước (Mig 69 S161), không do commit này sinh ra.
Kết luận
Không có critical issue. Không đề xuất rollback. 0 thao tác ghi lên prod.
END sub-cicd-verify-k1 — VERDICT=PASS 6/6 (run #434 id=547 success 6m31s · gate 598=45D+553I · Mig 70 top prod · seed 86/8-nhóm khớp 3 nguồn · bundle 4/4 rotate + 4/4 hash cũ chết · smoke 8/8 + 401 có-nghĩa)