Files
solution-erp/.claude/workflows/runs/2026-07-27-S155-pe-delete-approver/cicd-verify-dot1.md
2026-07-27 12:50:05 +07:00

9.8 KiB
Raw Blame History

CICD verify — dot 1 — commit b1bae77

Ghi-đĩa TRONG lúc làm (7 sub mất return trong run này). Mỗi mục ghi ngay khi có kết quả. Bắt đầu: 2026-07-27, agent cicd-monitor.

Stage 1 — Push + path-filter (DONE)

  • Commit: b1bae77c9c9863b846be418c7e8c1c695b11656a
  • Subject: [CLAUDE] Workflow: sua quy trinh duyet TAI CHO + co F6 AllowApproverDelete (dot 1)
  • Commit date: 2026-07-27 12:36:59 +0700
  • git log origin/main..HEAD = EMPTY → push đã lên remote OK
  • Files changed = 13, breakdown:
    • FE: 3 (fe-admin/src/pages/system/ApprovalWorkflowsV2Page.tsx, fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx, fe-user/src/types/approvalWorkflowV2.ts)
    • BE: 5 (Api Controller ApprovalWorkflowsV2Controller.cs, App ApprovalWorkflowV2AdminFeatures.cs, Domain ApprovalWorkflow.cs, Infra ApprovalWorkflowConfiguration.cs, Infra PurchaseEvaluationWorkflowService.cs)
    • Mig: 3-file rule ĐỦ20260727033522_AddPeAllowApproverDelete.cs + .Designer.cs + ApplicationDbContextModelSnapshot.cs
    • Tests: 2 (AuthorizePolicyRegressionTests.cs, UpdateAwDefinitionTests.cs)
  • Path-filter (7-glob paths-ignore): KHÔNG file nào khớp → CI PHẢI trigger (không skip)

Migration nội dung (đọc từ đĩa, file có trong commit)

20260727033522_AddPeAllowApproverDelete.cs Up():

migrationBuilder.AddColumn<bool>(
    name: "AllowApproverDelete", table: "ApprovalWorkflowLevels",
    type: "bit", nullable: false, defaultValue: false);

→ AddColumn-only, no new table (kỳ vọng sys.tables giữ 89). Down = DropColumn (reversible).

Pre-deploy bundle snapshot (chụp LÚC run đang chạy, 12:38)

App JS CSS
admin index-hHISK1Ig.js index-CBzUlgOA.css
eoffice index-CJeXZso2.js index-BHsBUA8e.css

Stage 2 — Gitea Actions run (IN PROGRESS)

  • Run id=529 · run_number=#416 · head_sha b1bae77c — MATCH commit
  • created_at 2026-07-27T12:37:18+07:00 · status lúc đo đầu = running
  • Run URL: https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp/actions/runs/416
  • TERMINAL: status=success · updated 2026-07-27T12:42:49+07:00 · duration 5m31s (12:37:18→12:42:49) — trong dải bình thường (~5m30 các run gần đây)
  • ⚠️ conclusion=None là bình-thường ở Gitea tasks API (đã tái-xác-nhận nhiều lần) → tin status.

Test gate — CÓ CHẠY và PASS

Log web-UI runs/416/jobs/0/logs (17.856 B tải về), trích nguyên văn:

Passed!  - Failed:     0, Passed:    45, Skipped:     0
Passed!  - Failed:     0, Passed:   506, Skipped:     0

45 Domain + 506 Infra = 551 PASS / 0 FAIL / 0 SKIP. KHỚP CHÍNH XÁC số local lead đo (551 = 45+506) Baseline dịch: 532 (run #407) → 551 (+19 Infra). Test gate chạy TRƯỚC build/deploy ⟹ status=success ⟹ gate đã qua.


🔴 Stage 3 — MIGRATION TRÊN DB PROD (kiểm quan trọng nhất) — PASS

sqlcmd qua ssh vietreport-vps, DB SolutionErp, user vrapp. Output NGUYÊN VĂN:

=== TOP3 HISTORY ===
20260727033522_AddPeAllowApproverDelete
20260717032812_AddPeApprovedBudgetSnapshot
20260714035636_AddPeApprovedPriceRange
=== TARGET MIG ROW ===
20260727033522_AddPeAllowApproverDelete
=== COLUMN ===
ApprovalWorkflowLevels|AllowApproverDelete|bit|nullable=NO
=== SYSTABLES ===
89
=== DEFAULT ===
(CONVERT([bit],(0)))

Đối chiếu (đây là điểm F8):

Kiểm Kỳ vọng Thực tế KQ
Row 20260727033522_... trong __EFMigrationsHistory có + ở TOP có, ở TOP
Cột AllowApproverDelete trên ApprovalWorkflowLevels tồn tại, bit, NOT NULL tồn tại, bit, nullable=NO
Default constraint 0 (CONVERT([bit],(0)))
sys.tables (is_ms_shipped=0) 89 (AddColumn no-new-table) 89
Nhất quán history ⟷ cột cả 2 cùng có cả 2 cùng có KHÔNG lệch

🟢 Kịch bản F8 (model có cột / DB không có ⟹ Invalid column name hạ 7 module) KHÔNG xảy ra. Baseline TRƯỚC deploy (đo lúc 12:38, run còn chạy): history top = 20260717032812_AddPeApprovedBudgetSnapshot, chưa có mig mới → chứng minh mig được áp trong cửa-sổ deploy này, không phải sẵn có từ trước.

Mig repo mới nhất giờ = Mig 68 AddPeAllowApproverDelete (trước là Mig 67).


Stage 4 — Smoke 7 module V2 — PASS 8/8

Bearer admin (POST /api/auth/login → HTTP 200, token 468 ký tự). Output thật:

PE          /api/purchase-evaluations?page=1&pageSize=5    HTTP 200  bytes=5103    InvalidCol=False
HopDong     /api/contracts?page=1&pageSize=5               HTTP 200  bytes=91      InvalidCol=False
DeXuat      /api/proposals?page=1&pageSize=5               HTTP 200  bytes=91      InvalidCol=False
NghiPhep    /api/leave-requests?page=1&pageSize=5          HTTP 200  bytes=91      InvalidCol=False
TangCa      /api/ot-requests?page=1&pageSize=5             HTTP 200  bytes=91      InvalidCol=False
CongTac     /api/travel-requests?page=1&pageSize=5         HTTP 200  bytes=91      InvalidCol=False
DatXe       /api/vehicle-bookings?page=1&pageSize=5        HTTP 200  bytes=91      InvalidCol=False
AwV2-list   /api/approval-workflows-v2                     HTTP 200  bytes=41234   InvalidCol=False

0/8 có chuỗi Invalid column name, 8/8 HTTP 200. Kịch bản F8 không tái hiện được. ⚠️ Trung thực về độ mạnh: 6 module Văn-phòng-số trả 91 B (envelope rỗng, chưa có dữ-liệu) nên chỉ chứng minh query chạy không ném, chưa chứng minh join sâu vào Levels. Hai phép mạnh thật nằm ở PE (5.103 B có dữ-liệu) và AwV2 (41.234 B) dưới đây.

🔑 Phép thử TRỰC TIẾP nhất cho F8 — cột round-trip qua EF

GET /api/approval-workflows-v2 (endpoint đọc THẲNG bảng ApprovalWorkflowLevels):

bytes 41234
count allowApproverDelete   = 54
count allowApproverFinalize = 54
LEVEL sample: allowApproverDelete= False | order= 1 | keys# 17

→ Cột MỚI được EF materialize 54 lần từ DB thật ra JSON, giá-trị False đúng default 0. Nếu DB thiếu cột thì chính truy-vấn này đã ném Invalid column nameđây là bằng-chứng khép kín model ⟷ DB đồng bộ.

Stage 5 — Endpoint MỚI PUT /api/approval-workflows-v2/{id}PASS (401, không phải 404)

PUT /api/approval-workflows-v2/1111...1111 (KHÔNG token, có body) -> 401
GET /api/approval-workflows-v2/1111...1111 (KHÔNG token, có body) -> 405
--- control: route chắc chắn KHÔNG tồn tại ---
PUT /api/approval-workflows-v2-nonexistent/{id}                   -> 404

→ Route 401 = đã lên + [Authorize] chặn đúng. Control route bịa trả 404 ⟹ 404 đúng là tín-hiệu "route chưa lên", nên 401 ở route thật là có nghĩa (discriminator sạch, không phải may). (405 ở GET chỉ nói GET {id} không được map — không liên quan.)

Stage 6 — Bundle FE — PASS (deploy thay file thật, không phải cache)

== admin ==
  JS  pre=index-hHISK1Ig.js   post=index-CiUBEEJr.js   ROTATED
  CSS pre=index-CBzUlgOA.css  post=index-DX5ew0wg.css  ROTATED
  real-js  index-CiUBEEJr.js   HTTP 200 size=1670035 ct=application/javascript LM=Mon, 27 Jul 2026 05:41:28 GMT
  FAKE-ctl index-ZZfakehash0.js HTTP 200 size=900    ct=text/html
== eoffice ==
  JS  pre=index-CJeXZso2.js   post=index-DFh7GK0t.js   ROTATED
  CSS pre=index-BHsBUA8e.css  post=index-BHsBUA8e.css  FROZEN
  real-js  index-DFh7GK0t.js   HTTP 200 size=1570257 ct=application/javascript LM=Mon, 27 Jul 2026 05:42:22 GMT
  FAKE-ctl index-ZZfakehash0.js HTTP 200 size=876    ct=text/html
  • JS ROTATE cả 2 app — khớp commit có sửa src cả fe-admin (1 file) lẫn fe-user (2 file).
  • Last-Modified 05:41:28 / 05:42:22 GMT = 12:41:28 / 12:42:22 +07NẰM TRONG cửa-sổ deploy 12:37:1812:42:49 (đây mới là ship-proof chính, không phải hash-delta).
  • real-size 1.670.035 / 1.570.257 B; bẫy SPA-fallback: hash bịa cũng trả 200 nhưng ct=text/html + 900/876 B ⟹ discriminator sạch, file thật là JS thật.
  • eoffice CSS FROZEN = lành tính (#69-REFINE): 2 file fe-user sửa là logic/type, không thêm utility-class Tailwind mới ⟹ CSS byte-identical ⟹ cùng content-hash. Admin CSS rotate vì thêm ô chọn F6 (class mới).

Byte-verify #77 — mã tính-năng CÓ THẬT trong bundle prod

admin    size=1670035  allowApproverDelete=7  allowApproverFinalize=11
eoffice  size=1570257  allowApproverDelete=1  allowApproverFinalize=5

→ chuỗi allowApproverDelete hiện diện trong CẢ HAI bundle đã ship ⟹ không chỉ "file mới" mà đúng mã F6 đã lên.

Health

/health/live  -> 200 b'Healthy'
/health/ready -> 200 b'Healthy'

KẾT LUẬN

CICD: PASS — 6/6 hạng mục bắt buộc đạt, rủi ro F8 đã loại trừ bằng bằng-chứng trực tiếp trên DB prod.

# Hạng mục KQ
1 Gitea run b1bae77 + test gate #416 success 5m31s · 551 PASS (45+506) 0 fail
2 🔴 Mig áp trên DB prod 20260727033522_AddPeAllowApproverDelete ở TOP history
3 🔴 Cột có thật bit NOT NULL default 0 — khớp history, không lệch
4 Smoke 7 module 8/8 HTTP 200, 0 Invalid column name
5 Endpoint mới PUT 401 (control route bịa = 404)
6 Bundle FE 2 app JS rotate ×2, LM trong cửa-sổ, marker F6 có trong bundle

Không có mục nào "không truy được". Không có cảnh-báo cần leo thang. Baseline cập nhật: test 532 → 551; mig mới nhất Mig 67 → Mig 68; sys.tables giữ 89.