wal: pause
This commit is contained in:
@ -26,5 +26,5 @@
|
||||
- **Đợt-1** (2 lane song song, file-disjoint): [x] BE CLEAN 5/5 — 3 file +31/−4, bắt lỗi memory-pack lead (`IsDeleted` không tồn tại trên `ContractAttachment` BaseEntity) · [x] FE #53 KHÔNG để lại sub-md nhưng mọi thứ LAND (SHA-pair, build ×2, coming-soon 0/0) — review đo thẳng đĩa bù.
|
||||
- **Đợt-2 test**: [x] CLEAN — `sub-test-specialist-0.md` (17.5K, 12 mục): 587→**590/0**, 3 PIN khớp spec §③-B từng chữ, probe vi-phân `_TempMutationProbe.cs` tạm 5/5 phân biệt bản-hỏng rồi XOÁ (verify 2 chiều: git sạch + Infra 545≠548); vai tự bắt claim-trước-đo của mình → truncate → đo lại.
|
||||
- **Reviewer**: [x] PASS-có-điều-kiện — `sub-reviewer-3.md` §1-§4 đủ evidence (hợp-đồng 4/4 + tsc ×2 · boundary O-A 4/4 · map 7 loại 3 nguồn), §5 VERDICT lead finalize on-behalf (return #53 stale hơn đĩa). FLAG-1 untracked → gate F-0 ĐÃ XỬ · FLAG-2/3 comment ĐÃ VÁ (SHA-pair `C7DCC20B` giữ) · +31/−4 errata ghi vào sub-md BE · §3.1 an-ninh (attachment 0-rào hiện-trạng O-A) chuyển hồ sơ W8-authz.
|
||||
- **Ship**: [!] commit `3119cb9` pushed (12 file +1358/−18) — cicd đang đo 3 chân (CI 590 · sqlcmd menu 142 + mig 69 · bundle marker `hasSealedCopy`/`hard-copies` + smoke `?type` + control âm `type=999`→400).
|
||||
- **Ship**: [x] commit `3119cb9` — cicd **PASS 3/3** (CI #431 590/590 · sqlcmd 142+69 GIỮ + pool-recycle-proof · bundle rotate 4/4 marker khớp-từng-đồng + smoke 200/200/400/404). 1 treo có-chủ-đích: `hasSealedCopy` per-item UNVERIFIED-LIVE (prod 0 HĐ, N=0) → tự đóng ở E2E. Tổng hợp: `ship-synthesis.md`. **W7 ĐÓNG.**
|
||||
- **Bài học lượt này**: (i) PS 5.1 `git commit -m @'…'@` chứa `"` lồng → native-arg VỠ ("error: pathspec") NHƯNG lệnh sau `;` vẫn chạy — push đẩy wal-commit trong khi code-commit chưa tồn tại ⇒ message có quote = `git commit -F <file>`, và ĐỪNG chuỗi `commit; push` một lệnh; (ii) memory-pack slice lead soạn cũng là giả-định — lane BE đo và bác đúng.
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
# ship-synthesis — W7 KHKK GĐ4 "Hợp đồng cứng" 1-MỐC (VERIFIED, lead tổng hợp @S162 2026-07-30)
|
||||
|
||||
> Wave build 5/5 (W1→W2→W3→W6→W7) của dry-run KHKK. Commit **`3119cb9`** (12 file, +1358/−18) — cicd **PASS 3/3 chân**.
|
||||
|
||||
## Giao được gì (đúng chốt @S161 "Upload file cứng lên → Là xem như xong")
|
||||
|
||||
- **BE** (+31/−4, đo 2 phương pháp — errata BE tự-khai +35): `ListContractsQuery` +`ContractType? type` filter server-side (F-C1/F-05) + DTO `HasSealedCopy` derive `Attachments.Any(purpose=SealedCopy=3)` append-cuối default false. 0 policy mới · 0 migration · attachment endpoints 0-diff (O-A giữ).
|
||||
- **FE ×2 SHA-PAIR** (`C7DCC20B…`): trang `/hard-copies` — list phase=9 hardcode phía gọi + badge bản-cứng + panel upload multipart (`file`+`purpose=3`+`note`) khớp endpoint Contract có sẵn + Ý kiến cấp duyệt readonly + hộp amber "ký/đóng dấu NGOÀI hệ thống". 7 leaf `Hdc_*` re-point `?type=1..7`, coming-soon co-occurrence 0/0.
|
||||
- **Tests**: `ContractHardCopyTests` 3 PIN — suite **587→590/0**; probe vi-phân `_TempMutationProbe.cs` (tạm, đã xoá + verify 2 chiều) 5/5 phân biệt bản-hỏng (`>=DangDongDau`, `>=DaPhatHanh`, bỏ-type, `>=ScannedSigned`, `Any()`); 2 invariant ghim: cờ-không-xét-phase (FE chặn ở phía gọi) + cờ-chết-2-màn (Đã xóa/Hộp thư default false — 3 căn cứ giữ nguyên).
|
||||
|
||||
## Chuỗi verify
|
||||
|
||||
| Cổng | Kết quả |
|
||||
|---|---|
|
||||
| Gate 5-anchor | 5/5 |
|
||||
| Review adversarial | PASS-có-điều-kiện → điều kiện ĐÃ XỬ (FLAG-1 untracked→F-0 gate; FLAG-2/3 comment vá giữ SHA-pair; FLAG-4 UX backlog) |
|
||||
| CI #431 | success ~5m50s · gate **590/590** tách-phần 45+545, delta +3 Infra khớp đúng 3 PIN |
|
||||
| sqlcmd prod | MenuItems **142 GIỮ** · `__EFMigrationsHistory` **69 GIỮ** · tables 96 · pool recycle PID `5576` StartTime 00:23:20 > DLL mtime 00:21:02 |
|
||||
| Bundle ×2 | rotate 4/4 · marker khớp dự-đoán-chốt-trước từng đồng: `hasSealedCopy`=1 · `hard-copies`=10 · DƯƠNG 7 (distinct 1..7) / ÂM 0 · control 3-tầng old-hash+fake-hash→text/html |
|
||||
| Smoke | `?phase=9` 200 · `?phase=9&type=1` 200 · âm `?type=999` **400** ValidationProblemDetails thật · route bịa 404 |
|
||||
|
||||
## Treo có chủ đích (KHÔNG phải lỗi)
|
||||
|
||||
1. **`hasSealedCopy` per-item UNVERIFIED-LIVE** — prod 0 hợp đồng (sqlcmd CONTRACTS_TOTAL=0) ⇒ `all()` trên N=0 không tính. Tự đóng khi E2E (sau W5) tạo HĐ đầu tiên → re-curl `?phase=9` 1 lần.
|
||||
2. **§3.1 an-ninh hồ sơ W8**: upload/download attachment Contract 0-rào (hiện trạng O-A anh chốt để mở; W7 thêm lối vào nổi bật nhưng không mở rộng bề mặt lộ).
|
||||
3. **FLAG-4 UX backlog**: multi-file upload dùng chung 1 `note` + `isPending` chỉ phản ánh mutation cuối.
|
||||
|
||||
## Bài học wave (đã ghi run.md + diaries)
|
||||
|
||||
- Memory-pack slice lead soạn cũng là giả-định — lane BE đo và bác (`IsDeleted` không tồn tại trên `ContractAttachment`).
|
||||
- "Số đoán trúng ≠ số đo được" — test lane tự cắt §5-§8 viết-trước-đo rồi đo lại.
|
||||
- Control ÂM chỉ có nghĩa khi vế DƯƠNG cùng hình-dạng regex trả >0 (regex nháy-kép chết trên bundle backtick — suýt FALSE-CLEAN).
|
||||
- PS5.1 `commit -m @'…"…'@` vỡ native-arg mà `; push` vẫn chạy ⇒ message-có-quote dùng `-F <file>` + tách commit/push.
|
||||
- #53 ×3 wave này (FE lane, reviewer, cicd) — 0 byte mất nhờ sub-md ghi-từng-mục; cicd còn 2 chân đo-xong-trước-garble, resume nối đúng chỗ.
|
||||
|
||||
**W7 ĐÓNG ⇒ HẾT wave build được. Còn lại: W5 (cầu KHKK→HĐ) + E2E — BLOCKED chờ anh chốt NGƯỜI DUYỆT 3 trạm (PRO/CCM/CEO trong 18 user prod).**
|
||||
@ -113,3 +113,95 @@ Brief ghi "`Hdc_` không còn đi kèm `coming-soon` (0 hit)". Grep repo-wide TR
|
||||
Đo thật: bare `coming-soon` = **1 (admin) / 2 (eoffice)** — ĐÚNG như kỳ vọng, không phải lỗi.
|
||||
⇒ Chuỗi dùng-chung chỉ làm marker DƯƠNG; muốn chứng VẮNG phải dùng **cặp co-occurrence độc quyền** `Hdc_<X>:<route>` như trên.
|
||||
|
||||
### Control ÂM 2 tầng (chứng bundle CŨ đã bị ghi đè)
|
||||
|
||||
| Probe | http | Content-Type | size |
|
||||
|---|---|---|---|
|
||||
| admin hash **CŨ** `index-BPWQQe4q.js` | 200 | `text/html` | 900 |
|
||||
| admin hash **BỊA** `index-ZZfakeZZ.js` | 200 | `text/html` | 900 |
|
||||
| user hash **CŨ** `index-DV3fEpOw.js` | 200 | `text/html` | 876 |
|
||||
| user hash **BỊA** `index-ZZfakeZZ.js` | 200 | `text/html` | 876 |
|
||||
|
||||
Hash CŨ trả về **trùng khít** hash BỊA ⇒ file cũ **không còn trên đĩa** = đã bị ghi đè thật.
|
||||
Đồng thời chứng **200 trần VÔ NGHĨA** (SPA-fallback rewrite `/*`→index.html) — discriminator sạch là `Content-Type`, không phải mã 200.
|
||||
Đối chứng từ phía đĩa (ssh): `index-BPWQQe4q.js` → **OLD-adminjs-GONE**. Hai nguồn độc lập khớp.
|
||||
|
||||
## CHÂN-2 — sqlcmd prod — ✅ PASS
|
||||
|
||||
`ssh vietreport-vps` + `sqlcmd -E -S .\\SQLEXPRESS` (4-backslash qua ssh), đo **SAU** khi run #431 `success` (không đo lúc `running` — bẫy S159 đợt-2).
|
||||
|
||||
| Chỉ số | Kỳ vọng | Đo được | KQ |
|
||||
|---|---|---|---|
|
||||
| `COUNT(*) MenuItems` | **142 GIỮ** | **142** | ✅ |
|
||||
| `COUNT(*) __EFMigrationsHistory` | **69 GIỮ** | **69** | ✅ |
|
||||
| `MAX(MigrationId)` | không đổi | `20260729122015_AddContractSigningPlans` (Mig 69, từ W1 #427) | ✅ |
|
||||
| `sys.tables` (is_ms_shipped=0) | 96 GIỮ | **96** | ✅ |
|
||||
|
||||
**NO-Mig proof đủ 2 vế:** vế 1 = `git diff … -- '*Migrations*'` **0 file** (CHÂN-0) · vế 2 = history **69 KHÔNG nhích** + MIGTOP y nguyên. ✅
|
||||
**MenuItems 142 GIỮ** đúng bản chất W7: chỉ **re-point `staticMap` phía FE**, không đụng seeder menu (7 leaf `Hdc_*` đã tồn tại sẵn từ đợt trước, W7 chỉ đổi ĐÍCH của chúng).
|
||||
|
||||
### Chứng minh app pool ĐÃ recycle (điều kiện để 3 số trên có nghĩa)
|
||||
|
||||
`appcmd list wp` → map pid→pool (không đoán "một w3wp nào đó"):
|
||||
`WP "5576" (applicationPool:SolutionErp-Api)` ← đúng pool cần
|
||||
|
||||
| Mốc | Giờ | Trong cửa-sổ deploy 00:17:57→00:23:47? |
|
||||
|---|---|---|
|
||||
| API DLL `SolutionErp.Api.dll` mtime | **00:21:02** | ✅ |
|
||||
| **w3wp pid=5576 (SolutionErp-Api) StartTime** | **00:23:20** | ✅ (và **SAU** mtime DLL 00:21:02 ⇒ nạp DLL MỚI) |
|
||||
| admin `index-BBQKvUMa.js` LM | **00:22:18** size 1.734.048 | ✅ (size khớp CHÍNH XÁC bản curl về) |
|
||||
| user `index-BV5--mPf.js` LM | **00:23:14** size 1.650.214 | ✅ (khớp chính xác) |
|
||||
|
||||
## CHÂN-3b — Smoke API prod
|
||||
|
||||
Login `admin@solutions.com.vn` → `accessToken` (len 468) ✅ 200.
|
||||
|
||||
| # | Call | Kỳ vọng | Đo | KQ |
|
||||
|---|---|---|---|---|
|
||||
| a | `GET /api/contracts?phase=9&pageSize=5` | 200 | **200** (`total=0, items=0`) | ✅ mã · ⚠️ field xem dưới |
|
||||
| b | `GET /api/contracts?phase=9&type=1` | 200 | **200** | ✅ |
|
||||
| c | `GET /api/contracts?type=999` | **400** KHÔNG 500 | **400** | ✅ |
|
||||
| d | control route BỊA `/api/contracts-khong-ton-tai` | 404 | **404** | ✅ |
|
||||
|
||||
**(c) body 400 là ValidationProblemDetails THẬT, không phải lỗi chung chung:**
|
||||
`{"title":"One or more validation errors occurred.","status":400,"errors":{"type":["The value '999' is invalid."]}}`
|
||||
→ tên field `type` đích danh ⇒ chặn đúng ở tầng model-binding enum, không phải 500 rơi từ handler. ✅
|
||||
|
||||
**(d)** route bịa trả 404 ⇒ 200 ở (a)/(b) **CÓ NGHĨA**, không phải catch-all nuốt mọi thứ.
|
||||
|
||||
### ⚠️ `hasSealedCopy` per-item = **KHÔNG KIỂM CHỨNG ĐƯỢC LIVE** (không phải PASS, không phải FAIL)
|
||||
|
||||
Phép `all('hasSealedCopy' in i for i in items)` trả **True** — nhưng **N=0** ⇒ `all()` trên tập RỖNG luôn True. **Đây là phép trích RỖNG đọc nhầm thành sạch**, y hệt bẫy đã ghi trong memory. Không được tính là ✅.
|
||||
|
||||
Truy nguyên nhân bằng ĐO, không suy đoán — sqlcmd prod:
|
||||
`CONTRACTS_TOTAL=0` · `CONTRACTS_NOTDELETED=0` · `PHASE9=0`
|
||||
⇒ **Prod chưa có hợp đồng nào.** `total=0` là API trả ĐÚNG trên bảng rỗng — **không phải** IDOR-scope lọc mất, không phải regression của W7. Đã loại trừ khả năng "bug nuốt data" (đó mới là điều đáng sợ nếu bỏ qua).
|
||||
|
||||
⇒ Field `hasSealedCopy` hiện được bảo chứng bằng 3 nguồn KHÁC (không phải bằng payload live):
|
||||
1. **Bundle prod** có `hasSealedCopy` (đo được, CHÂN-3a) — FE đã ship code đọc field.
|
||||
2. **Gate CI 590/590** gồm 3 test PIN mới `ContractHardCopyTests` — có ca **LẬT-1-BIẾN** (thêm đúng 1 đính kèm `purpose=SealedCopy` ⇒ cờ false→true) nên không phải test "xanh vì cờ chết cứng".
|
||||
3. Đây là **giới hạn của môi trường**, sẽ tự đóng khi prod có HĐ đầu tiên ở phase 9.
|
||||
|
||||
**Khuyến nghị (không tự làm — READ-only):** khi UAT tạo HĐ thật đầu tiên, re-curl `?phase=9` 1 lần để đóng nốt mục này.
|
||||
|
||||
## VERDICT
|
||||
|
||||
| Chân | Nội dung | Kết quả |
|
||||
|---|---|---|
|
||||
| **CHÂN-0** | push + path-filter + NO-Mig vế 1 | ✅ PASS |
|
||||
| **CHÂN-1** | CI run #431 success · gate **590** (45+545, 0 fail/skip) · delta **+3** vs #430 | ✅ PASS |
|
||||
| **CHÂN-2** | MenuItems **142** · MigHistory **69** · MIGTOP giữ · tables 96 · pool recycle chứng bằng pid đúng | ✅ PASS |
|
||||
| **CHÂN-3a** | bundle rotate **4/4** · marker khớp dự đoán từng đồng (1 / 10 / 7 / 0) · control ÂM 2 tầng | ✅ PASS |
|
||||
| **CHÂN-3b** | smoke 200/200/**400**/404 | ✅ PASS |
|
||||
| — | `hasSealedCopy` per-item live | ⚠️ **UNVERIFIED-LIVE** (prod 0 HĐ — đã đo, không phải lỗi deploy) |
|
||||
|
||||
### 🟢 **VERDICT = PASS** (5/5 chân; 1 mục treo do môi trường thiếu dữ liệu, KHÔNG phải lỗi)
|
||||
|
||||
### Ghi nhận 2 lần tao SUÝT SAI (giữ lại để lần sau không lặp)
|
||||
|
||||
1. **Control ÂM rỗng** — regex nháy-kép cho ra ÂM=0 *và* DƯƠNG=0; nếu chỉ nhìn vế ÂM đã báo "sạch". Vá: minifier dùng **backtick**. ⇒ **Luật: control ÂM chỉ có giá trị khi vế DƯƠNG dùng ĐÚNG hình-dạng regex đó trả về số > 0 mong đợi.**
|
||||
2. **Dự đoán `type=999` của tao SAI** — tao suy "không có validator cho `ListContractsQuery` (`IsInEnum` ở dòng 43 thuộc `CreateContractCommandValidator`, khác lệnh) ⇒ enum bind nhận số bừa ⇒ 200". Thực đo **400**: ASP.NET Core có `EnumTypeModelBinder` tự chặn giá trị enum không-định-nghĩa + `[ApiController]` → 400 tự động. **Brief đúng, tao sai.** ⇒ Nhờ ĐO thay vì khẳng định theo suy luận nên không báo sai. Giữ nguyên bài học: suy-luận-từ-code là GIẢ THUYẾT, prod mới là phán quyết.
|
||||
|
||||
---
|
||||
END sub-cicd-monitor-4 — **VERDICT=PASS** (CHÂN-0 ✅ · CHÂN-1 ✅ 590 · CHÂN-2 ✅ 142/69 · CHÂN-3a ✅ 4/4 rotate · CHÂN-3b ✅ 200/200/400/404 · 1 mục UNVERIFIED-LIVE do prod 0 HĐ)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user