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

190 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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():
```csharp
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 +07****NẰ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**.
<!-- END cicd-verify-dot1 -->