wal: flush 20260727T1551

This commit is contained in:
pqhuy1987
2026-07-27 15:51:05 +07:00
parent 054ba022e4
commit cc5a6e3d85
5 changed files with 139 additions and 15 deletions

View File

@ -118,18 +118,130 @@ Tổng: `Permissions` 718 hàng / **68 MenuKey distinct** · `MenuItems` 105 hà
vẫn `20260727033522_AddPeAllowApproverDelete` (Mig 68) · `sys.tables`(is_ms_shipped=0) = **89**.
Đúng kỳ vọng "đợt 2 không có migration".
## 4. Endpoint mới — ĐANG ĐO
---
(chưa có)
> 🔻 **Mục 4-7 đo ở `/tiep` @S156 (2026-07-27 ~15:35), do LEAD tự đo bằng curl/sqlcmd** — không giao lại
> `cicd-monitor` vì chính vai đó đã dừng giữa chừng ở file này lúc 14:14 (VERIFY-lane, khuôn `#53`).
> 🔴 **Đổi ngữ cảnh so mục 0-3:** sau `4464a46` còn một deploy nữa — **`f4494cf`** (fix menu sáng nhầm),
> run **531** `14:36:54 → 14:42:35 = 5m41s status=success`. Nên **bundle hiện tại là của `f4494cf`**,
> đã ĐÈ bundle của `4464a46`. Xem caveat B ở mục 7.
## 5. Smoke chống hồi quy — ĐANG ĐO
## 4. Endpoint mới — ✅ PASS (401, KHÔNG phải 404)
(chưa có)
Route thật (`PurchaseEvaluationsController.cs:177,187`): `DELETE {id:guid}/by-approver` · `GET deleted`.
## 6. Bundle FE ×2 — ĐANG ĐO
```
DELETE /api/purchase-evaluations/{guid}/by-approver -> 401 ← endpoint MỚI #1
GET /api/purchase-evaluations/deleted -> 401 ← endpoint MỚI #2
DELETE /api/purchase-evaluations/{guid} -> 401 (control: xóa nháp, có từ trước)
--- control: route chắc chắn KHÔNG tồn tại ---
DELETE /api/purchase-evaluations/{guid}/by-approver-nonexistent -> 404
GET /api/purchase-evaluations/deleted-nonexistent -> 404
```
(chưa có)
→ 2 route mới **401** = đã lên prod + `[Authorize]` chặn đúng. 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.
## 7. Verdict — ĐANG ĐO
## 5. Smoke chống hồi quy — ✅ PASS 8/8 + D3 anti-regression PASS
Bearer admin (`POST /api/auth/login` → 200, `accessToken` 468 ký 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=41230 InvalidCol=False
```
**8/8 HTTP 200, 0/8 có `Invalid column name`**. (Caveat giữ nguyên như đợt 1: 6 module Văn-phòng-số trả
91 B = envelope rỗng ⇒ chỉ chứng minh query **không ném**, chưa chứng minh join sâu.)
**Model ⟷ DB đồng bộ:** `AwV2` materialize `allowApproverDelete` = **54** · `allowApproverFinalize` = **54**
(khớp đúng số đợt 1) ⇒ cột mới round-trip qua EF từ DB thật.
### 🔑 D3 anti-regression — phiếu xóa mềm KHÔNG rò rỉ sang list sống
🔴 **2 phép đo ĐẦU TIÊN của lead là RỖNG NGHĨA, phải vứt** — đo `item.isDeleted` trên cả 2 endpoint,
ra "0 rò rỉ" + "9 item không-deleted lọt vào". **Cả hai vô nghĩa**: `isDeleted` **KHÔNG có trong DTO**
(đã kiểm: key-set 29 field, `'isDeleted' in item` = `False` ở CẢ HAI). Một cái trông như PASS, một cái
trông như FAIL — **đều là hư không**. Đúng lớp lỗi *phép-đo-rỗng-nghĩa* mà chính phiên này vừa ghi bài học.
Phép ĐÚNG = **giao tập ID**, độc lập hoàn toàn với field DTO:
```
list thường = 37 phiếu (totalCount=37)
/deleted = 9 phiếu (totalCount=9)
GIAO TẬP = 0 ← phiếu đã xóa KHÔNG hiện ở list sống
```
**8a PASS** (`IgnoreQueryFilters()` có kèm `.Where(x => x.IsDeleted)`, không "gỡ filter rồi liệt kê tất").
**8c(a) PASS** (list "Đã xóa" không chứa phiếu sống). Hai tập phân hoạch sạch.
**KHÔNG phải lỗi (đã soi, kết luận là cố ý):** `/deleted` dùng **CHUNG DTO** với list sống ⇒ không có
`deletedAt`/`deletedBy`. FE khai thẳng ở `PurchaseEvaluationsListPage.tsx:557-561` và hiển thị `updatedAt`
với nhãn **`🗑 xóa ≈`**, **cố ý bỏ trống tên người xóa thay vì đoán**. Spec mục 6 chỉ đòi "CHỈ XEM",
không đòi cột ai/khi-nào ⇒ **không phải lớp "DTO thiếu field FE đang đọc"** (H1 đợt 2), vì FE biết và đã
xử lý trung thực. Ghi lại để lần sau khỏi báo động nhầm.
## 6. Bundle FE ×2 — ✅ PASS
```
== admin ==
JS pre(14:07)=CiUBEEJr now=BK8w3QxU ROTATED
CSS pre(14:07)=DX5ew0wg now=DiNJjaoo ROTATED
real-js index-BK8w3QxU.js HTTP 200 size=1674598 ct=application/javascript LM=Mon, 27 Jul 2026 07:41:15 GMT
FAKE-ctl HTTP 200 size=900 ct=text/html
== eoffice ==
JS pre(14:07)=DFh7GK0t now=DYnxSI0T ROTATED
CSS pre(14:07)=BHsBUA8e now=BRCvEHvC ROTATED
real-js index-DYnxSI0T.js HTTP 200 size=1574829 ct=application/javascript LM=Mon, 27 Jul 2026 07:42:10 GMT
FAKE-ctl HTTP 200 size=876 ct=text/html
```
- **JS + CSS ROTATE cả 2 app** so baseline pre-đợt-2 (14:07:54).
- `Last-Modified` **07:41:15 / 07:42:10 GMT = 14:41:15 / 14:42:10 +07** → nằm **TRONG cửa-sổ deploy run 531
(`f4494cf`, 14:36:5414:42:35)** ⇒ ship-proof thật, không phải hash-delta suông.
- Bẫy SPA-fallback loại sạch: hash bịa cũng trả 200 nhưng **`text/html` + 900/876 B** ⟹ file thật là JS thật.
### Byte-verify #77 — mã tính-năng CÓ THẬT trong bundle prod (cộng dồn 3 commit)
| chuỗi | nguồn | admin | eoffice |
|---|---|---|---|
| `allowApproverDelete` | `b1bae77` đợt 1 (cờ F6) | 8 | 2 |
| `by-approver` | `4464a46` đợt 2 (endpoint xóa) | 1 | 1 |
| `deleted=1` | `4464a46` đợt 2 (màn "Đã xóa") | 1 | 1 |
| `view=approved` | `f4494cf` (fix menu sáng nhầm) | 1 | 1 |
**4/4 marker có mặt trong CẢ HAI bundle** ⟹ mã của **cả ba** commit đang sống trên prod.
## 7. Verdict — ✅ **CICD PASS 6/6**
| # | Hạng mục | Kết quả |
|---|---|---|
| 1 | Gitea run + test gate | ✅ run 530 `4464a46` success 5m47s · **562 PASS/0 FAIL** trích từ log CI |
| 2 | Menu prod (trọng-tâm) | ✅ 4 key mới + `Pending` "Duyệt"→"Đang duyệt" 2/2, có mốc pre-deploy làm chứng |
| 3 | Permission seed | ✅ 4 key mới × 13/13 role, cả 2 danh sách seed đều ăn · NO-MIG confirm |
| 4 | Endpoint mới | ✅ 2/2 route → 401; control bịa → 404 |
| 5 | Smoke + D3 anti-regression | ✅ 8/8 · giao tập ID = 0 · AwV2 cột mới ×54 |
| 6 | Bundle FE ×2 | ✅ rotate ×2 app, LM trong cửa-sổ deploy, 4/4 byte-marker |
**Kèm: cicd cho `f4494cf` cũng ĐẠT** — run 531 success 5m41s; bundle hiện tại chính là của commit này
(LM 14:4114:42) và chứa `view=approved`. Hai mục nợ trong WAL (`[!]` đợt 2 + `[ ]` `f4494cf`) đóng **cùng
một lượt đo** vì dùng chung phép bundle.
### ⚠️ 3 caveat khai thẳng (đừng đọc thành "đã kín")
- **A. 6 module Văn-phòng-số trả envelope rỗng 91 B** ⇒ chỉ chứng minh query không ném, **chưa** chứng minh
join sâu. Hai phép mạnh thật là PE (5.103 B có dữ-liệu) và AwV2 (41.230 B).
- **B. 🔴 Không thể chứng minh HỒI-TỐ rằng bundle của riêng `4464a46` đã rotate lúc 14:12** — không ai chụp
snapshot tại thời điểm đó, và `f4494cf` đã đè lên 30 phút sau. Cái **chứng minh được** là: mã FE của đợt 2
(`by-approver`, `deleted=1`) **đang sống trong bundle prod hiện tại**. Về vận-hành đó mới là điều cần biết,
nhưng phát biểu phải đúng phạm vi — không được nói "bundle đợt 2 đã verify rotate".
- **C. Lead tự bắt 2 lỗi đo của chính mình trong lượt này**: (i) `item.isDeleted` — field không tồn tại,
cả PASS-giả lẫn FAIL-giả; (ii) `item.code` — tên thật là `maPhieu`, nên `/deleted` trông như trả rỗng.
Cả hai lộ ra vì **hỏi lại "phép đo này có đo gì không"** trước khi tin con số.
<!-- END · TOTAL=6 HANG-MUC · VERDICT=PASS -->
(chưa có)

View File

@ -166,6 +166,9 @@ Mọi tên dưới đây là **CANONICAL**. BE phải hiện thực ĐÚNG tên
- **19**: `PeWorkflowPanel.tsx` phải giữ **md5 giống nhau ×2 app** sau khi sửa
- Nhân bản: menu sinh trong `foreach PurchaseEvaluationTypeCodes` ⇒ mỗi mục mới **× số loại phiếu**
- [ ] Đ2-W1 — BE (xóa-by-approver + list deleted + menu seed + changelog)
- [ ] Đ2-W2 — FE (nút xóa + 3 mục menu + màn Đã xóa)
- [ ] Đ2-W3 — test + reviewer → deploy
- [x] Đ2-W1 — BE (xóa-by-approver + list deleted + menu seed + changelog)
- [x] Đ2-W2 — FE (nút xóa + 3 mục menu + màn Đã xóa)
- [x] Đ2-W3 — test + reviewer → deploy`reviewer-diff-dot2.md` FAIL 12 FLAG (H1 DTO thiếu field) → lead vá → deploy `4464a46`
> 🔧 Sau đợt 2, một fix-nhanh UAT nữa đã đẩy: **`f4494cf`** — click "Danh sách" lại highlight "Đã duyệt" (`phase` vừa là bộ-lọc vừa là danh-tính điều-hướng ⇒ `queryMatches` strip cả 2 vế). Vá 2 chỗ ×2 app. **cicd verify cho commit này CHƯA chạy.**
> 🔧 Ledger này tụt hậu so WAL tới `/tiep` @S156 mới đối-chứng ra (`ctx-verifier` 🚩3) — 3 dòng trên đã `[x]` từ lúc `4464a46` lên prod.