wal: flush 20260731T1720
This commit is contained in:
@ -1,9 +1,10 @@
|
||||
CICD-K2: IN-PROGRESS — 0/6 mục (đang đo)
|
||||
CICD-K2: PARTIAL — 5/6 mục (mục 4 = CHÂN-LÝ-RỖNG, không phải sạch)
|
||||
|
||||
# CI/CD verify K2 SP-002 — commit `0779f2d`
|
||||
|
||||
> Artifact chống #53 — ghi TỪNG MỤC NGAY KHI ĐO. Kết bằng `END … VERDICT=`.
|
||||
> Vai: cicd-monitor (READ-only). Ngày: 2026-07-31.
|
||||
> Artifact chống #53 — ghi TỪNG MỤC NGAY KHI ĐO. Vai: cicd-monitor (READ-only). Ngày: 2026-07-31.
|
||||
> Deploy KHỎE, KHÔNG khuyến nghị rollback. Điểm trừ duy nhất = **phép đo mục 4 không có răng**
|
||||
> (bảng rỗng), không phải lỗi deploy.
|
||||
|
||||
---
|
||||
|
||||
@ -17,67 +18,202 @@ $ git log origin/main..HEAD --oneline
|
||||
(RỖNG — đã push trọn)
|
||||
```
|
||||
|
||||
`git diff --name-only 0779f2d^..0779f2d` = **23 file**:
|
||||
- BE 9: Controller `ContractSigningPlansController.cs` · `ContractSigningPlanFeatures.cs` · Domain `ContractSigningPlan.cs` + `ContractSigningPlanLine.cs` · 2 Configuration · Service `ContractSigningPlanWorkflowService.cs` (+2 mig file dưới)
|
||||
- Mig 71: `20260731085624_AddKhkkApprovalGroupCatalogAndFinalizeRuntime.cs` + `.Designer.cs` + `ApplicationDbContextModelSnapshot.cs`
|
||||
- FE 8: fe-admin ×4 (Khkk{Create,Detail,List}Page.tsx + types/khkk.ts) · fe-user ×4 (đối xứng)
|
||||
- Test 3: `ContractSigningPlanApprovalTests.cs` · `ContractSigningPlanGroupAndCatalogTests.cs` · `ContractSigningPlanSchemaTests.cs`
|
||||
- paths-ignore 2 (KHÔNG chặn vì ≥1 file code): `docs/STATUS.md` · `.claude/skills/ef-core-migration/SKILL.md`
|
||||
|
||||
⇒ CI **PHẢI** chạy (không rơi SKIPPED-DOCS). Neo commit bằng SHA tuyệt đối `0779f2d^..0779f2d` (LUẬT S162: cấm `HEAD~1` vì Stop-hook WAL auto-commit).
|
||||
|
||||
---
|
||||
`git diff --name-only 0779f2d^..0779f2d` = **23 file**: BE 9 · Mig 71 ×3 file (3-file rule đủ) ·
|
||||
FE 8 (admin ×4 + user ×4 đối xứng) · test 3 · paths-ignore 2 (`docs/STATUS.md`,
|
||||
`.claude/skills/ef-core-migration/SKILL.md` — KHÔNG chặn vì ≥1 file code).
|
||||
Neo bằng SHA tuyệt đối `0779f2d^..0779f2d` (LUẬT S162: cấm `HEAD~1`, Stop-hook WAL auto-commit).
|
||||
|
||||
## Mục 0b — SNAPSHOT PRE-MIGRATE (đo lúc run #435 còn `running`, 17:07)
|
||||
|
||||
```
|
||||
$ ssh vietreport-vps "sqlcmd ... -Q 'SELECT MAX(MigrationId)...; COUNT(*)...; SUM(...)'"
|
||||
MIGTOP=20260731072441_AddContractCatalogEntries <- Mig 70 (K1), Mig 71 CHƯA áp
|
||||
PLANS=0
|
||||
LINES=0
|
||||
SUMPE=NULL|SUMPROP=NULL
|
||||
SYSTABLES=97
|
||||
PLANS=0 · LINES=0 · SUMPE=NULL|SUMPROP=NULL · SYSTABLES=97
|
||||
admin /assets/index-CKgq0YlH.js + /assets/index-DD3xQhNt.css
|
||||
eoffice /assets/index-CHMCU35C.js + /assets/index-CdXRNT7E.css (khớp mốc K1 #434)
|
||||
```
|
||||
|
||||
Bundle PRE (khớp mốc K1 run #434 do em main đưa):
|
||||
```
|
||||
admin /assets/index-CKgq0YlH.js + /assets/index-DD3xQhNt.css
|
||||
eoffice /assets/index-CHMCU35C.js + /assets/index-CdXRNT7E.css
|
||||
```
|
||||
|
||||
🔴 **KHAI TRƯỚC — MỤC 4 SẼ RỖNG, KHÔNG PHẢI SẠCH.** `ContractSigningPlans` prod có **0 dòng**
|
||||
TRƯỚC migrate. ⇒ 3 acceptance của mục 4 rơi vào **chân-lý-rỗng (vacuous)**:
|
||||
`COUNT(group=1) == COUNT(*)` thành `0 == 0`; `COUNT(NOT BETWEEN 1 AND 8)` thành `0`; Σ tiền
|
||||
`NULL == NULL`. Cả ba đều "xanh" mà **không mang thông tin nào** về việc backfill có chạy đúng.
|
||||
Chính tác giả Mig 71 đã khai bẫy này ở comment ("đo local Σ = tập RỖNG hai phía … phép đo prod
|
||||
mới có răng") — nay prod cũng rỗng nốt, nên **phép đo prod cũng KHÔNG có răng**.
|
||||
Đối-sách: thay bằng bằng-chứng KHÔNG-rỗng ở mục 4 (xem dưới): cột tồn tại đúng kiểu/nullability
|
||||
(`INFORMATION_SCHEMA`), **hoán-đổi index có/mất** (`sys.indexes` — đây là phép đo CÓ RĂNG THẬT
|
||||
vì không phụ thuộc số dòng), default-constraint, và **EF materialize qua API** (nếu cột thiếu
|
||||
thì `SELECT` của EF ném 500 chứ không trả 200 ⇒ 200 = chứng cột tồn tại end-to-end).
|
||||
🔴 **KHAI TRƯỚC — MỤC 4 SẼ RỖNG, KHÔNG PHẢI SẠCH.** Xem mục 4.
|
||||
|
||||
---
|
||||
|
||||
## Mục 1 — Gitea Actions run
|
||||
## Mục 1 — Gitea Actions run ✅ PASS
|
||||
|
||||
(đang đo — run #435 id=548 `0779f2d4` status=running, created 17:05:33)
|
||||
| | |
|
||||
|---|---|
|
||||
| Run | **#435** (id=548), `0779f2d4` |
|
||||
| Status | **success** |
|
||||
| Cửa sổ | created `17:05:33` → updated `17:11:45` = **6m12s** |
|
||||
| URL | https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp/actions/runs/435 |
|
||||
|
||||
## Mục 2 — Test gate 609 (45D + 564I)
|
||||
Poll 6 vòng (17:08:31 → 17:12:26), running×5 → success. 6m12s ≈ K1 #434 (6m31s) — hợp lý cho
|
||||
+Mig +11 test, chưa tới ngưỡng escalate.
|
||||
|
||||
(chưa đo)
|
||||
## Mục 2 — Test gate 609 ✅ PASS (khớp TÁCH-PHẦN, không chỉ khớp tổng)
|
||||
|
||||
## Mục 3 — EF migration prod + chứng-restart
|
||||
Log web-UI `.../actions/runs/435/jobs/0/logs` (18.677 B), grep nới `Passed![^\r\n]*`:
|
||||
```
|
||||
Passed! - Failed: 0, Passed: 45, Skipped: 0, Total: 45, Du
|
||||
Passed! - Failed: 0, Passed: 564, Skipped: 0, Total: 564, Du
|
||||
```
|
||||
| | Domain | Infra | Tổng |
|
||||
|---|---|---|---|
|
||||
| K1 #434 | 45 | 553 | 598 |
|
||||
| K2 #435 | **45** | **564** | **609** |
|
||||
| delta | **0** | **+11** | +11 |
|
||||
|
||||
(chưa đo)
|
||||
Kỳ vọng 609 = 598 + 9 lane + 2 gate-fix ⇒ khớp **từng vế**: Domain đứng yên, +11 rơi TRỌN vào
|
||||
Infra — đúng nơi 3 file test mới nằm (`ContractSigningPlanApprovalTests` /
|
||||
`~GroupAndCatalogTests` / `~SchemaTests`). 0 fail, 0 skipped.
|
||||
Control ÂM: grep chuỗi bịa `ZZZ_KHONG_TON_TAI_9x7` = **0 hit**.
|
||||
⚠️ Dùng regex nới ngay từ đầu vì bài K1: log dùng **2 khoảng trắng** sau `Passed!`.
|
||||
|
||||
## Mục 4 — Data prod sau migrate
|
||||
## Mục 3 — EF migration prod + chứng-restart ✅ PASS
|
||||
|
||||
(chưa đo)
|
||||
```
|
||||
MIGTOP=20260731085624_AddKhkkApprovalGroupCatalogAndFinalizeRuntime <- TOP, đúng Mig 71
|
||||
MIGCOUNT=71
|
||||
SYSTABLES=97 (GIỮ NGUYÊN — Mig 71 có 0 CreateTable)
|
||||
```
|
||||
`sys.tables` 97 == 97 khớp phép đo nguồn `grep -c "CreateTable"` = **0** (control dương:
|
||||
`grep -c "AddColumn"` = **4** ⇒ grep có tìm được thứ có thật).
|
||||
|
||||
## Mục 5 — Bundle ×2 app
|
||||
**3-CHÂN-KIỀNG (né bẫy #423 đo-trước-recycle):**
|
||||
1. *Restart thật:* `appcmd list wp` → `WP "5364" (applicationPool:SolutionErp-Api)`;
|
||||
`Get-Process w3wp` → PID **5364 StartTime 17:11:25** ∈ cửa sổ deploy (17:05:33–17:11:45).
|
||||
(5 w3wp còn lại là pool VIETREPORT/Default — đã map PID→pool để không nhận nhầm.)
|
||||
2. *Dòng ĐẦU Serilog:* `2026-07-31 17:11:27.310 +07:00 [INF] Applying migrations...`
|
||||
3. *Mọi phép đo DB dưới đây chạy từ 17:12+* ⇒ SAU mốc recycle.
|
||||
|
||||
(chưa đo)
|
||||
## Mục 4 — Data prod sau migrate ⚠️ PARTIAL — **CHÂN-LÝ-RỖNG**
|
||||
|
||||
## Mục 6 — Smoke
|
||||
Số đo nguyên văn (POST-migrate, sau recycle):
|
||||
```
|
||||
TOTAL=0 · GROUP1=0 · OUTOFRANGE=0 · LINES=0 · SUMPE=NULL|SUMPROP=NULL
|
||||
CTRL_SUPPLIERS=60 · CTRL_CATALOG=86 <- control dương: bộ đếm CÓ đếm được
|
||||
```
|
||||
| Acceptance yêu cầu | Kết quả | Giá trị bằng chứng |
|
||||
|---|---|---|
|
||||
| `COUNT(ApprovalGroup=1) == COUNT(*)` | `0 == 0` ✅ | **RỖNG — 0 bit thông tin** |
|
||||
| `COUNT(ApprovalGroup NOT BETWEEN 1 AND 8) = 0` | `0` ✅ | **RỖNG** |
|
||||
| Σ `PeReferenceAmount`/`ProposedAmount` | `NULL\|NULL` (PRE cũng `NULL\|NULL`) | **RỖNG hai phía** |
|
||||
|
||||
(chưa đo)
|
||||
🔴 `ContractSigningPlans` prod có **0 dòng cả TRƯỚC lẫn SAU**. Ba acceptance "xanh" nhưng
|
||||
**không mang thông tin nào** về việc backfill có chạy đúng — backfill hụt sẽ trông y hệt.
|
||||
Chính tác giả Mig 71 đã khai bẫy này ("đo local Σ = tập RỖNG hai phía … phép đo prod mới có
|
||||
răng"); nay prod cũng rỗng ⇒ **phép đo prod cũng KHÔNG có răng**. Không hạ thành FAIL (không có
|
||||
gì sai), nhưng CẤM đọc thành PASS.
|
||||
|
||||
**Bằng chứng THAY THẾ — không phụ thuộc số dòng (CÓ RĂNG):**
|
||||
|
||||
*(a) 4 cột, đúng kiểu/nullability/default (`INFORMATION_SCHEMA.COLUMNS`):*
|
||||
```
|
||||
ContractSigningPlans |ApprovalGroup |int |null=NO |def=((0))
|
||||
ContractSigningPlans |EndedByLevelFinalize|bit |null=NO |def=(CONVERT([bit],(0)))
|
||||
ContractSigningPlanLines |CatalogEntryId |uniqueidentifier|null=YES|def=-
|
||||
ContractSigningPlanLines |TenHangMuc |nvarchar(500) |null=YES|def=-
|
||||
```
|
||||
|
||||
*(b) HOÁN-ĐỔI INDEX — chứng bằng **liệt kê TRỌN HỌ** (14 index cả 2 bảng), không bằng grep-rỗng:*
|
||||
```
|
||||
✅ CÓ : IX_ContractSigningPlanLines_ContractSigningPlanId_SupplierId_CatalogEntryId
|
||||
unique=1 | filter=([IsDeleted]=(0)) | cols=ContractSigningPlanId,SupplierId,CatalogEntryId
|
||||
✅ CÓ : IX_ContractSigningPlanLines_CatalogEntryId (cols=CatalogEntryId)
|
||||
✅ CÓ : IX_ContractSigningPlans_ApprovalGroup_Phase (cols=ApprovalGroup,Phase)
|
||||
❌ MẤT: IX_ContractSigningPlanLines_ContractSigningPlanId_SupplierId (unique 2-cột cũ)
|
||||
```
|
||||
Vắng-mặt của index cũ suy ra từ **danh sách đầy đủ 14 index có thật**, nên đây là vắng-mặt ĐO
|
||||
ĐƯỢC chứ không phải "truy vấn trả rỗng đọc thành sạch". Đây là phép đo mạnh nhất của mục 4.
|
||||
|
||||
*(c) Bất-biến Σ tiền — chứng theo CẤU TRÚC bằng phép ĐO nguồn:*
|
||||
`grep -nE "PeReferenceAmount|ProposedAmount|ApprovedAmount"` trên Mig 71 → chỉ **2 hit, cả 2 ở
|
||||
dòng 23-24 và đều là comment `//`** ⇒ **0 câu lệnh thực thi** chạm cột tiền. `migrationBuilder.Sql`
|
||||
= đúng **1** câu (dòng 61, backfill `ApprovalGroup=1`). Σ bất biến đúng kể cả khi bảng có dữ liệu.
|
||||
|
||||
*(d) Materialize qua EF:* xem mục 6 — `?group=N` trả **200** (không 500) ⇒ cột `ApprovalGroup`
|
||||
tồn tại & query được xuyên Domain→Infra→Api trên DB thật.
|
||||
|
||||
## Mục 5 — Bundle ×2 app (#77) ✅ PASS — 4/4 ROTATE
|
||||
|
||||
| app | asset | TRƯỚC (K1 #434) | SAU (K2 #435) |
|
||||
|---|---|---|---|
|
||||
| admin | js | `CKgq0YlH` | **`DVQEwGwf`** |
|
||||
| admin | css | `DD3xQhNt` | **`D050EVYG`** |
|
||||
| eoffice | js | `CHMCU35C` | **`CZAYiWWa`** |
|
||||
| eoffice | css | `CdXRNT7E` | **`DX1FRk5n`** |
|
||||
|
||||
*Hash CŨ chết (control âm tầng-2 — bundle cũ biến mất khỏi đĩa):*
|
||||
```
|
||||
admin /assets/index-CKgq0YlH.js -> 200|text/html|900 (SPA fallback, không phải JS)
|
||||
eoffice/assets/index-CHMCU35C.js -> 200|text/html|876
|
||||
admin /assets/index-ZZBIADAT.js -> 200|text/html|900 <- hash BỊA, cùng dấu hiệu
|
||||
```
|
||||
Hash bịa cho ra ĐÚNG dấu hiệu của hash cũ ⇒ `text/html` thật sự nghĩa là "file không tồn tại"
|
||||
(né bẫy SPA-fallback-200 S72; dùng `Content-Type` chứ không neo byte).
|
||||
|
||||
*Last-Modified in-window:* admin `10:10:20 GMT` = 17:10:20 +07 · eoffice `10:11:20 GMT` =
|
||||
17:11:20 +07 — cả hai ∈ (17:05:33, 17:11:45). `Cache-Control: no-cache` cả 2 (hardening S88).
|
||||
|
||||
## Mục 6 — Smoke ✅ PASS
|
||||
|
||||
| Phép đo | Kỳ vọng | Thực tế |
|
||||
|---|---|---|
|
||||
| `/health/ready` | 200 | **200** |
|
||||
| `/health/live` | 200 | **200** |
|
||||
| `/health` trần | (control) | **404** ⇒ 200 ở trên có nghĩa |
|
||||
| `GET /api/contract-signing-plans?group=2` KHÔNG token | 401 | **401** |
|
||||
| route BỊA `/api/contract-signing-plans-KHONG-TON-TAI?group=2` | 404 | **404** |
|
||||
| route BỊA 2 `/api/zzz-fake-9x7` | 404 | **404** |
|
||||
| admin.solutions.com.vn | 200 | **200** |
|
||||
| eoffice.solutions.com.vn | 200 | **200** |
|
||||
|
||||
401 (route có thật, có gác) tương phản 404 ×2 (route không có) ⇒ **401 CÓ NGHĨA**.
|
||||
|
||||
*Có token admin* (login `/api/auth/login`, `accessToken` len=468):
|
||||
```
|
||||
?group=1 -> 200 {"items":[],"total":0,"page":1,"pageSize":20,"totalPages":0,...}
|
||||
?group=2 -> 200 (thân y hệt)
|
||||
?group=8 -> 200 (thân y hệt)
|
||||
inbox -> 200 deleted -> 200
|
||||
```
|
||||
"mọi item `approvalGroup==1`" ⇒ **VACUOUS (0 item)** — không tính là bằng chứng.
|
||||
⚠️ Đã soi **thân RAW** (không tin bộ parse) đúng bài K1 "0-hit là dương-giả tới khi soi format":
|
||||
thân thật là `{"items":[],"total":0}` ⇒ rỗng THẬT, không phải lỗi đọc format.
|
||||
|
||||
**Chứng `group` ĐƯỢC WIRE (không bị nuốt im lặng):**
|
||||
```
|
||||
?group=abc -> 400 <- bind int THẬT; nếu param không tồn tại, ASP.NET bỏ qua query lạ và trả 200
|
||||
```
|
||||
Khớp nguồn: `ContractSigningPlansController.cs:42` → `[FromQuery(Name = "group")] int? group = null`
|
||||
và `:49` truyền vào `ListContractSigningPlansQuery(..., group)`.
|
||||
|
||||
**Control DƯƠNG cho đường ống list:** `GET /api/catalogs/contract-catalog` → **86 item**
|
||||
(seed K1 còn nguyên) ⇒ token + serializer + đường ống list CHẠY, nên `items:[]` của KHKK là
|
||||
bảng rỗng thật, không phải ống vỡ.
|
||||
|
||||
---
|
||||
|
||||
## Lệch / quan sát (không chặn deploy)
|
||||
|
||||
1. **`?group=999` → 200** (không 400). Miền nghiệp vụ là 1..8 nhưng biên API không chặn
|
||||
ngoài-miền; hiện vô hại (trả rỗng) và mục 4 đã xác nhận 0 dòng ngoài 1..8. Ghi cho K4b cân
|
||||
nhắc cùng lớp với validator `CatalogEntryId` bắt buộc mà Mig 71 đã hẹn.
|
||||
2. **Ghost-window `EndedByLevelFinalize`** — tác giả khai trước: K2 đẻ cột, K3 tiêu thụ; tới khi
|
||||
K3 land cột luôn = 0. Đã xác minh cột tồn tại `bit NOT NULL default 0`; **không** coi
|
||||
"toàn 0" là dữ liệu hỏng.
|
||||
3. **Mục 4 rỗng** — xem trên. Khi có phiếu KHKK thật trên prod, cần đo LẠI 3 acceptance đó thì
|
||||
mới có răng; hiện chưa thể kết luận backfill đúng/sai từ dữ liệu.
|
||||
|
||||
## Bảng tổng
|
||||
|
||||
| # | Mục | Verdict |
|
||||
|---|---|---|
|
||||
| 1 | Gitea run `0779f2d` success | ✅ PASS |
|
||||
| 2 | Test gate 609 = 45D + 564I | ✅ PASS |
|
||||
| 3 | Mig 71 TOP + chứng-restart | ✅ PASS |
|
||||
| 4 | Data prod sau migrate | ⚠️ **PARTIAL — vacuous** (schema/index CÓ răng ✅) |
|
||||
| 5 | Bundle ×2 app rotate + hash cũ chết | ✅ PASS |
|
||||
| 6 | Smoke 401/404/200 + group wired | ✅ PASS |
|
||||
|
||||
**Không ghi gì lên prod ngoài đọc** (toàn bộ là SELECT / curl GET / login POST lấy token).
|
||||
|
||||
END — VERDICT=PARTIAL 5/6 (mục 4 vacuous, deploy khỏe, không rollback)
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
K3-BE: IN-PROGRESS — bước-0 XONG (lead), §1-8 p2 đang chạy
|
||||
|
||||
# sub-implbe-k3 — K3 BACKEND (S165, wave 3/8: 8 workflow nhóm + finalize + sweep)
|
||||
|
||||
> 🔴 **KHAI VẾT:** p1 wf_a04124a7-0fe = class *engine-process-exit* (35 tool-use/458s nhưng **0 delta đĩa
|
||||
> + 0 artifact + return rỗng** — lượt chạy coi như chưa từng tồn tại; #53 tally cả wave). Bước-0 dưới đây
|
||||
> = **LEAD tự chạy** (ssh + sqlcmd trực tiếp), p2 seed từ bảng ĐÃ VERIFY này, không cần ssh lại.
|
||||
|
||||
## §0 [LEAD] FAIL-CLOSED verify đội-hình QT-DN-V2-001 LIVE — PASS
|
||||
|
||||
- Instance prod = `localhost\SQLEXPRESS` (named instance — `-S localhost`/`tcp:1433` đều fail; ghi lại cho
|
||||
mọi lane sau đỡ dò). Windows-auth `-E` qua `ssh vietreport-vps` chạy được.
|
||||
- `ApprovalWorkflows WHERE Code='QT-DN-V2-001'` = **3 row: 2 archived (IsActive=0) + 1 LIVE (IsActive=1)**,
|
||||
ApplicableType=**1** (Duyệt NCC/PE — nguồn đội-hình, đúng OG-2 + note owner slot-54 "lấy đúng bộ người
|
||||
duyệt đang cấu hình ở workflow Duyệt NCC prod"). TotalWf active toàn hệ = 7.
|
||||
- **ROSTER bản LIVE (nguyên văn sqlcmd, mojibake console đã chuẩn hoá dấu theo email đã biết):**
|
||||
|
||||
| Bước | Dept | Cấp | Email | Tên |
|
||||
|---|---|---|---|---|
|
||||
| 1 «Phòng 1» | Phòng Cung Ứng (PRO) | 1 (OR-4) | phuong.nguyen@solutions.com.vn | Nguyễn Thị Bích Phượng |
|
||||
| 1 | Phòng Cung Ứng | 1 | long.chau@solutions.com.vn | Châu Tạ Kim Long |
|
||||
| 1 | Phòng Cung Ứng | 1 | duy.nguyen@solutions.com.vn | Nguyễn Văn Duy |
|
||||
| 1 | Phòng Cung Ứng | 1 | binh.lethanh@solutions.com.vn | Bình Lê Thanh |
|
||||
| 1 | Phòng Cung Ứng | 2 | tra.bui@solutions.com.vn | Bùi Lê Thủy Trà |
|
||||
| 2 «Phòng 2» | P. Kiểm soát Chi phí (CCM) | 1 (OR-4) | luu.tran@solutions.com.vn | Trần Xuân Lưu |
|
||||
| 2 | P. Kiểm soát Chi phí | 1 | truong.letrandang@solutions.com.vn | Lê Trần Đăng Trường |
|
||||
| 2 | P. Kiểm soát Chi phí | 1 | binh.le@solutions.com.vn | Lê Văn Bình |
|
||||
| 2 | P. Kiểm soát Chi phí | 1 | nguyen.ho@solutions.com.vn | Hồ Thị Nữ Nguyên |
|
||||
| 2 | P. Kiểm soát Chi phí | 2 | chuong.phan@solutions.com.vn | **Phan Văn Chương** (TP.CCM — giữ cờ finalize OG-3/OG-9) |
|
||||
| 3 «Phòng 3» | Ban Giám đốc (CEO) | 1 | truong.nguyen@solutions.com.vn | Nguyễn Văn Trường |
|
||||
|
||||
- **Vá-11 danh-tính (phân giải bằng dept trên bản LIVE):** `truong.letrandang` (CCM C1) ⟂ `truong.nguyen`
|
||||
(BGĐ C1 = CEO) — 2 người khác dept, không nhầm; `binh.lethanh` (PRO C1) ⟂ `binh.le` (CCM C1) — khác dept,
|
||||
không nhầm. Cặp "tring.le"/"thanh.lethanh" trong câu-đố spec KHÔNG xuất hiện trên roster LIVE ⇒ là bẫy
|
||||
chính-tả từ ảnh, roster email là chân lý.
|
||||
- ⇒ **Mô-hình 3 trạm PRO → CCM → CEO** với OR-of-N cấp 1 mỗi trạm + cấp 2 = trưởng phòng. Seed 8 workflow
|
||||
KHKK-N1..N8 mirror ĐÚNG cấu trúc này (3 Steps × Levels như bảng), resolve user theo EMAIL.
|
||||
|
||||
(§1-8 p2 ghi tiếp bên dưới)
|
||||
@ -26,7 +26,7 @@
|
||||
```
|
||||
|
||||
## Tick 0-8 (cap nhat dan)
|
||||
- [ ] 0. FAIL-CLOSED verify doi-hinh LIVE prod (OG-2)
|
||||
- [x] 0. FAIL-CLOSED verify doi-hinh LIVE prod (OG-2) — **THAY: workflow LIVE ton tai** (chi tiet duoi)
|
||||
- [ ] 1. Seed 8 workflow KHKK-N1..N8 type-10
|
||||
- [ ] 2. Port nhanh LEVEL-FINALIZE vao ContractSigningPlanWorkflowService
|
||||
- [ ] 3. Sweep ep-false va-3 (>=3 site BE)
|
||||
@ -37,3 +37,73 @@
|
||||
- [ ] 8. build 0W/0E + test FULL (baseline 609)
|
||||
|
||||
---
|
||||
|
||||
# Muc 0 — FAIL-CLOSED verify doi-hinh LIVE (OG-2) — **PASS, workflow LIVE co that**
|
||||
|
||||
## Cach do (READ-ONLY, 0 ghi prod)
|
||||
`ssh vietreport-vps` → `sqlcmd -S '.\SQLEXPRESS' -d SolutionErp -E` (integrated auth `-E`, KHONG cham password vrapp — khuon S147).
|
||||
Nhan tieng Viet doc qua `CONVERT(varchar(N), CAST(col AS varbinary(N)), 2)` → hex → decode `utf-16-le` phia client
|
||||
(khuon cicd-verify-dot2: sqlcmd mangle `Duy?t` khong phan biet duoc dau).
|
||||
|
||||
⚠️ 3 lech vs tai lieu, da tu sua khi do (khong bao "khong query duoc"):
|
||||
1. De-bai ghi `QT-DN-V2-001` **type 3** → LIVE la **ApplicableType=1** (DuyetNcc). Type 3 = `QT-HD-V2-001` (HD). Doi-hinh dung van la QT-DN-V2-001.
|
||||
2. Bang Identity ten **`Users`** khong phai `AspNetUsers` (rename Mig 1).
|
||||
3. FK ten **`ApprovalWorkflowLevels.ApprovalWorkflowStepId`** khong phai `StepId`.
|
||||
|
||||
## Ban do LIVE — `QT-DN-V2-001` **Version 4** (IsActive=1)
|
||||
|
||||
Chung "khong phai archived": 3 version tren prod — v2 `IsActive=0`, v3 `IsActive=0`, **v4 `IsActive=1` + IsUserSelectable=1**.
|
||||
```
|
||||
QT-DN-V2-001|2|1|0|0
|
||||
QT-DN-V2-001|3|1|0|0
|
||||
QT-DN-V2-001|4|1|1|1 <- LIVE
|
||||
```
|
||||
|
||||
### BANG ROSTER NGUYEN VAN (11 slot, decode tu hex)
|
||||
|
||||
| Ver | Buoc | Dept | Cap | Email | Fin | Skp | Bud | Ho ten (LIVE) | Chuc danh (LIVE) |
|
||||
|---|---|---|---|---|---|---|---|---|---|
|
||||
| 4 | 1 | PRO | 1 | `binh.lethanh@solutions.com.vn` | 0 | 0 | 1 | Binh Le Thanh | Nhân viên |
|
||||
| 4 | 1 | PRO | 1 | `duy.nguyen@solutions.com.vn` | 0 | 0 | 1 | Nguyễn Văn Duy | Nhân viên Cung ứng |
|
||||
| 4 | 1 | PRO | 1 | `long.chau@solutions.com.vn` | 0 | 0 | 1 | Châu Tạ Kim Long | Nhân viên Cung ứng |
|
||||
| 4 | 1 | PRO | 1 | `phuong.nguyen@solutions.com.vn` | 0 | 0 | 1 | Nguyễn Thị Bích Phượng | Nhân viên Cung ứng |
|
||||
| 4 | 1 | PRO | 2 | `tra.bui@solutions.com.vn` | 0 | 1 | 1 | Bùi Lê Thủy Trà | TP Cung ứng |
|
||||
| 4 | 2 | CCM | 1 | `binh.le@solutions.com.vn` | 0 | 0 | 1 | Lê Văn Bình | Nhân viên Kiểm soát Chi phí |
|
||||
| 4 | 2 | CCM | 1 | `luu.tran@solutions.com.vn` | 0 | 0 | 1 | Trần Xuân Lưu | Nhân viên Kiểm soát Chi phí |
|
||||
| 4 | 2 | CCM | 1 | `nguyen.ho@solutions.com.vn` | 0 | 0 | 1 | Hồ Thị Nữ Nguyên | Nhân viên Kiểm soát Chi phí |
|
||||
| 4 | 2 | CCM | 1 | `truong.letrandang@solutions.com.vn` | 0 | 0 | 1 | Lê Trần Đăng Trường | Nhân viên |
|
||||
| 4 | 2 | CCM | 2 | `chuong.phan@solutions.com.vn` | **1** | 1 | 1 | Phan Văn Chương | TP Kiểm soát Chi phí |
|
||||
| 4 | 3 | BOD | 1 | `truong.nguyen@solutions.com.vn` | 0 | 1 | 1 | Nguyễn Văn Trường | Tổng Giám đốc (CEO) |
|
||||
|
||||
⇒ Hinh dang = **PRO C1 OR-of-4 + C2 ×1 · CCM C1 OR-of-4 + C2 ×1 · BOD C1 ×1** — KHOP y nguyen K3.a nen.
|
||||
⇒ `AllowApproverFinalize=1` **DA CO SAN tren prod** dung o chuong.phan (CCM C2) — tien le song, khong phai co-che moi.
|
||||
⇒ Ten Buoc tren LIVE la "Phòng 1/2/3" (nhat nheo); K3.a nen dat ten mo-ta ("Phòng Cung ứng"/"Phòng KSCP"/"Ban Giám đốc") — **ten = display-only, danh tinh = Dept + ApproverUserId** ⇒ dung ten nen, khai lech o day.
|
||||
|
||||
## VA-11 — DO DANH TINH 2 CAP GAN-TRUNG: **CA 2 DEU LA TRUNG-TAI-KHOAN THAT tren prod**
|
||||
|
||||
Phat hien nang: **prod co 2 tai khoan cho CUNG 1 nguoi**, va **workflow LIVE dung tai khoan TAO TAY, khong phai tai khoan seeder**.
|
||||
|
||||
| Cap | Tai khoan A (DbInitializer seed) | Tai khoan B (tao tay tren prod) | LIVE workflow dung | Phan giai |
|
||||
|---|---|---|---|---|
|
||||
| PRO "Thanh/Bình" | `thanh.lethanh@` — PRO — "Lê Thanh Bình" — *Nhân viên Cung ứng* (`DbInitializer.cs:1617`) | `binh.lethanh@` — PRO — "Binh Le Thanh" (**khong dau**) — *Nhân viên* | **B `binh.lethanh@`** | Cung dept PRO, cung nguoi; chuc danh khac ("Cung ứng" vs tran). Phan giai bang **bang LIVE**: slot Buoc1/Cap1 tro toi B. |
|
||||
| CCM "Trưởng" | `truong.le@` — CCM — "Lê Trần Đăng Trường" — *Nhân viên Kiểm soát Chi phí* (`DbInitializer.cs:1626`) | `truong.letrandang@` — CCM — "Lê Trần Đăng Trường" (**ten y het**) — *Nhân viên* | **B `truong.letrandang@`** | Ten TRUNG KHIT ⇒ khong the match bang ten. Phan giai bang **bang LIVE**: slot Buoc2/Cap1 tro toi B. |
|
||||
|
||||
3 ung vien nhieu loan da loai dut khoat bang **dept**:
|
||||
- `tring.le@` = "Lê Tự Đăng Trình" (CCM) — **nguoi KHAC han**, KHONG co trong workflow LIVE ⇒ loai.
|
||||
- `truong.nguyen@` = "Nguyễn Văn Trường" (**BOD**, CEO) — o Buoc 3, khong phai CCM ⇒ khong nham voi `truong.le*`.
|
||||
- `binh.le@` = "Lê Văn Bình" (**CCM**) vs `binh.lethanh@` (**PRO**) — tach bang dept, ca 2 DEU trong roster nhung khac buoc.
|
||||
|
||||
Kiem ton tai + active (prod): **11/11 email = IsActive 1**. 3 dept `PRO`/`CCM`/`BOD` deu `IsDeleted=0`.
|
||||
|
||||
### 🔴 QUYET-DINH ky thuat rut ra (khai de owner soi)
|
||||
Seeder **KHONG the hardcode 1 email duy nhat/slot**: email LIVE (`binh.lethanh@`, `truong.letrandang@`) **khong ton tai tren Dev/local/test** (DbInitializer chi tao `thanh.lethanh@`/`truong.le@`) ⇒ seed se fail-soft bo qua toan bo, Dev 0 workflow.
|
||||
⇒ Dung **chuoi uu-tien alias/slot**: thu email LIVE TRUOC, khong co thi lui ve email seeder. Prod → khop dung nguoi dang duyet that; Dev/test → khop tai khoan seeder. Ca 2 vang mat moi fail-soft. Moi lan dung alias-du-phong deu `LogWarning` neu ro → co dau vet.
|
||||
⚠️ Day KHONG phai quyet dinh danh-tinh moi: uu tien 1 = **dung nguoi tren ban LIVE** (OG-2). Chi la duong lui cho moi truong khong co ban sao tay.
|
||||
⚠️ De-xuat cho owner (NGOAI pham vi wave nay, khong tu lam): don trung 2 cap tai khoan tren prod (vo hieu 1 ben) — hien 1 nguoi 2 tai khoan la nguon nham lan that.
|
||||
|
||||
## Muc 0 — VERDICT
|
||||
**PASS** — workflow LIVE `QT-DN-V2-001` v4 ton tai (IsActive=1, khong archived), roster 11 slot ghi nguyen van o tren,
|
||||
2 cap gan-trung phan giai xong bang dept + chuc danh + vi tri slot tren ban LIVE. **Duoc phep seed.**
|
||||
Doi chung nen: prod hien **0** workflow `ApplicableType=10`, **0** Code `KHKK-N%` ⇒ seed lan dau se tao dung 8.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user