wal: flush 20260727T1250
This commit is contained in:
@ -18,6 +18,172 @@
|
||||
|
||||
---
|
||||
|
||||
## 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)
|
||||
|
||||
_(pending)_
|
||||
- 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:18–12: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 -->
|
||||
|
||||
|
||||
Reference in New Issue
Block a user