14 KiB
K8-DRYRUN: ĐANG CHẠY — B0 PASS (backup 26,6MB + roster LIVE + login admin OK); B1.. đổ ruột liên tục bên dưới
sub-k8-dryrun — K8 dry-run E2E toàn trình (S168, 2026-08-01)
Mandate owner @S168 (verbatim): "Chạy dry-run hết luôn đi rồi tao giao tiếp plan khác". Kịch bản = spec-cụm3 §③ K8 + bảng B0-B16 (
sub-invest-fable-b2-cum3.mdK8.1) + vá-9..15 spec-final THẮNG nền. 🔴 Vá-12 owner-ratified @S164 "tạo PE Test SOLUTION-PE-1,2,3… không test trên phiếu thật" ⇒ bộ test RIÊNG (Project+NCC+gói ZZTEST/SOLUTION-PE-{n}), KHÔNG đụngPE/2026/A/049— câu giờ-G K8.2 của bản nền coi như ĐÃ trả. Người bấm mọi bước hôm nay = admin (duyệt thay — SignedByUserId track, banner "Admin duyệt thay" by-design); cột "Ai (thật)" trong form = roster LIVE để buổi chạy với người thật dùng lại.
B0 — PRE-FLIGHT (fail-closed) — ✅ PASS 16:2x-16:3x +07
- (i) Backup prod:
C:\Backups\SolutionErp\SolutionErp_preK8_S168.bak— 27.877.888 B @ 2026-08-01 16:28 (BACKUP DATABASE 3393 pages OK). (Scriptscripts/backup-sql.ps1defaultD:\— VPS KHÔNG có ổ D ⇒ dùngC:\Backups; default ĐÃ VÁC:\@S168 cùng lượt.) - (ii) Workflow LIVE (sqlcmd -E; ⚠️
$env:PROD_DB_PASSWORDKHÔNG tồn tại cả 3 scope trên VPS — persona-note stale cùng lớp F-9):- type-1 PE:
QT-DN-V2-001active+selectable · 3 trạm (P1: 4NV L1 + tra.bui L2[SkipToFinal,Delete] · P2: 4NV L1 + chuong.phan L2 [Finalize=1,SkipToFinal,Delete] · P3: truong.nguyen [SkipToFinal]). - type-10 KHKK: đủ 8 nhóm N1-N8 active;
KHKK-N43 trạm 11 người (Cung ứng: 4NV+tra.bui · Kiểm soát CP: 4NV+chuong.phan [Finalize=1] · BGĐ: truong.nguyen) — khớp anchor OG-3/OG-9. - type-3 HĐ:
QT-HD-V2-001active — 1 trạm 1 người: binh.le (Bước 1 - Phòng CCM).
- type-1 PE:
- (ii-b) Catalog:
ContractCatalogEntries= 86 dòng; nhóm-4 mẫu B1-01 Đá · B1-02 Cát · B1-03 Cọc tràm · B1-04 Bê tông · B1-05 Xi măng (chọn cho line test) · B1-06 Thép. - (iii) Dữ liệu test sẵn có: Projects ZZTEST = 0 · Suppliers TEST = 0 ⇒ TẠO MỚI qua API (GĐ0 dưới). Contracts prod = 0 (HĐ dry-run sẽ là HĐ ĐẦU TIÊN trên prod — seq cháy thuộc cặp prefix TEST, vô hại data thật).
- (iv) Dặn team: em KHÔNG có kênh Zalo/email — thay bằng ZZTEST-prefix mọi bản ghi + mục này để anh nhắn team "notification phiếu ZZTEST trong hôm nay — bỏ qua". KHAI trade-off, không im.
- (v) Login API prod:
POST /api/auth/loginadmin OK (accessToken 468c — fieldaccessTokenđúng bài S160).
B0-FORM 14 dòng {bước · người THẬT (roster LIVE) · tài khoản · ai bấm hôm nay} — vá-9 fail-closed
| B | Ai (thật, theo roster LIVE) | Tài khoản | Hôm nay |
|---|---|---|---|
| B1-B3 | BCH drafter (đại diện Cung ứng: Nguyễn Văn Duy) | duy.nguyen@solutions.com.vn | admin (tạo thay) |
| B4 | Trạm-1 PE/KHKK — 1 trong {duy.nguyen · binh.lethanh · long.chau · phuong.nguyen} + L2 tra.bui | (4+1 tài khoản trên) | admin duyệt thay |
| B5 | Trạm-2 — 1 trong {luu.tran · nguyen.ho · binh.le · truong.letrandang} | (4 tài khoản) | admin duyệt thay |
| B6 | TP.CCM Phan Văn Chương (Finalize) | chuong.phan@solutions.com.vn | admin duyệt thay (tick finalize) |
| B7 | CEO Nguyễn Văn Trường (nhánh B) | truong.nguyen@solutions.com.vn | admin duyệt thay |
| B8 | BCH/Admin kiểm khóa | — | admin |
| B9 | Người có Contracts.Create (câu III default: Drafter/Procurement/Admin — seeder K7 CanCreate=3) |
— | admin |
| B10 | Người bấm B9 | — | admin |
| B11 | Approver HĐ: Lê Văn Bình (QT-HD-V2-001 trạm duy nhất) | binh.le@solutions.com.vn | admin duyệt thay |
| B12 | HRA/CCM (HardCopyActorRoles) | — | admin |
| B13 | Bất kỳ + Admin (mở cây) | — | admin |
| B14 | Lead chốt sổ | — | lead |
⇒ 14/14 dòng CÓ CHỦ — fail-closed ĐẠT (không dòng nào trống).
Nhật ký bước (đổ ruột liên tục — ID ghi TẠI CHỖ cho rollback vá-11/13)
🔴 PHÁT HIỆN TRƯỚC GIỜ CHẠY — BLOCKER toàn trình: Lines-editor KHÔNG TỒN TẠI (vá tại chỗ @S168)
Truy vết trước khi bấm B1 (đúng tinh thần "K8 lộ wave thiếu"):
ContractSigningPlanFeatures.csauto-gen line mồiCatalogEntryId = null+ comment HẸN "Người soạn gán sau quaUpdateContractSigningPlanLineCommand" — command đó chỉ tồn tại TRONG COMMENT (grep toàn src + FE = 0 impl, 0 route, 0 call).ContractSigningPlanWorkflowService.SubmitAsync(vá-5) CHẶN THẬT line null:"Còn dòng chưa gán hạng mục…"+ đếm-so-khớp nhóm.- FE
KhkkDetailPagecột Hạng mục tự khai "Đường GÁN (Lines-editor) = K4b" — nhưng K4b THẬT ship việc khác (88e7ecf= nối?group=sidebar, đogit show --name-only). ⇒ mảnh rơi giữa build-order. - Hệ quả nếu không vá: MỌI phiếu KHKK tạo sau K2 kẹt Nháp vĩnh viễn — dry-run chết ở B3. Đây chính là chỗ cicd-K2 khai "mục-4 chân-lý-rỗng — đo lại khi K8 đẻ phiếu thật".
Vá @S168 (BE + FE ×2 app + 3 test): UpdateContractSigningPlanLineCommand(PlanId, LineId, CatalogEntryId) handler (EnsureDraftEditable + fail-fast entry sống/đúng-nhóm 409 + denorm TenHangMuc + changelog Line) · route PUT /contract-signing-plans/{id}/lines/{lineId} policy KeHoachKyKet.Update · FE select gán tại bảng (Nháp/TraLai, khoá dòng đã bắc cầu HĐ, options lọc ?approvalGroup=) mirror SHA-pair 21e0ca0507d4 ×2 app · 3 Fact (dương gán→submit-QUA · âm khác-nhóm 409 · âm phase). Gate + commit riêng trước khi chạy chuỗi.
GĐ0 — dựng bộ test — ✅ PASS (script k8run.py gd0, state k8-state.json scratchpad)
| Vật | ID |
|---|---|
Project ZZTEST-K8 "ZZTEST Du an dry-run K8 (SOLUTION-PE)" |
9c6caa7a-22b9-4482-bc74-2ef36fbebc54 |
Supplier ZZTEST-NCC-K8 |
10b60f58-1bb0-4164-b191-3cb9af3896fe |
WorkItem ZZTEST-WI-K8 |
a29c7932-411c-4763-9ca6-5546798c3d5c |
| Catalog line-test | B1-05 Xi măng 69a6db3a-30b1-4289-878b-a364a1fd1eab |
| Workflow ids | PE 8a0aa922… · KHKK-N4 bf90b962… · HĐ 12aee3bf… |
GĐ1 — PE 2 nhánh — ✅ TRỌN (B1-B7 phần PE)
- PE-1 nhánh A =
PE/2026/A/052(4e4ad413-30cb-4eda-b5cf-31f2936e8ec2; supplier-row512f6b41· detail55285053· quote 110tr-VAT isSelected · Bảng-so-sánh att50bbcf46): submit → 3 lượt trạm → lượt 4 giá-chốt NCC 110tr + finalize tại CCM (chuong.phan) ⇒ DaDuyet KHÔNG qua CEO (OG-9 nhánh A chứng ✓) → winner ZZTEST-NCC ✓. - PE-2 nhánh B =
PE/2026/A/053(a53db8b9-df60-42d0-92c0-e2ca4c80f2e5; row9e3d8060· detail1f98f925· att4a79abfd): submit → 5 lượt ĐỦ đường vớiapplyLevelFinalize=falseở mọi lượt (checkbox opt-out F-17a903cfchứng chạy thật) ⇒ qua CEO Trường → DaDuyet → winner ✓. - Sự-cố script tự bắt + sửa dọc đường (đều là THUỐC THỬ tốt cho form B0 buổi người-thật): ① PE detail đòi
GroupCode/GroupNamerequired · ②QuoteBody.BgVat/ChuaVat= decimal non-null · ③ submit-guard đòi đính kèm Bảng so sánh (purpose=4) · ④ cấp cuối đòi chọn giá chốt (Ncc/ProMin/ProMax/Ccm/ProMinMax — Mig 66) · ⑤ auth rate-limit 429 khi login mỗi-stage ⇒ cache token (JWT 1h) vào state · ⑥ 1 phiếu nháp orphan (script fail giữa) ⇒ DELETE 204 dọn liền — allow-list Nháp xoá được, đúng thiết kế.
GĐ2+ (KHKK → bridge → HĐ → bản-cứng → QĐ9) — CHỜ deploy line-editor (commit + push + cicd) rồi chạy stages khkk1…qd9-2
GĐ2→GĐ4 + QĐ9 — ✅ TRỌN CẢ 2 NHÁNH (sau deploy #444 line-editor live)
| Bước | Nhánh A | Nhánh B |
|---|---|---|
| KHKK tạo + gán hạng mục qua endpoint MỚI | KHKK/2026/001 (9cc64a5e), line 776faa92 ← B1-05 ✓ |
KHKK/2026/002 (3b11f7d3), line 0a9e67a0 ✓ |
| Duyệt | 4 lượt — finalize tại Chương (KHÔNG qua BGĐ) ✓ OG-9 | 5 lượt — QUA ĐỦ BGĐ/CEO (applyLevelFinalize=false mọi lượt — checkbox opt-out F-1 sống) ✓ |
| DaDuyet | phase=3, approvedTổng 110.000.000 chốt tại choke-point | phase=3, approvedTổng 110.000.000 |
| Bridge K7 → HĐ | HĐ 47b453d3 — mã RG-001 tự sinh ZZTEST-K8/NCC/SOL&ZZTEST-NCC-K8/01, giaTri == ApprovedAmount = 110tr ✓ |
(không bridge — spec chỉ cần 1 nhánh) |
| Duyệt HĐ | submit → 1 lượt (binh.le trạm duy nhất) → DaPhatHanh (9) — HĐ ĐẦU TIÊN trên prod, là ZZTEST đúng chủ đích | — |
| GĐ4 bản cứng | upload SealedCopy purpose=3 78be7327 → LIST hasSealedCopy=True ✓ (field là EXISTS tầng LIST — detail đọc attachments[]) |
— |
| B13 mối nối cây | khkk.line.contractId → 47b453d3 ✓ · pe.contractId → 47b453d3 (forward-provision K5) ✓ · hasSealedCopy ✓ — đúng 3 nguồn usePipelineStages:293-299 đọc |
line.contractId = null (đúng — chưa bridge) |
| QĐ9 freeze (đo 2 vế/nhánh) | (a) sửa quote nguồn PE DaDuyet → 409 "không thể chỉnh sửa Section 2" = nguồn khoá từ tầng dưới · (b) catalog-rename Xi măng→Xi măng (ZZTEST QD9) 204 → line GIỮ 'Xi măng' (denorm thắng join-ngược — bit TRƯỢT-ĐƯỢC thật) → restore 204 nguyên trạng |
(a) 409 y hệt · (b) rename→GIỮ→restore ✓ |
🔸 Khai đo: B13 đo ở tầng API-mối-nối (3 con trỏ cây đọc), KHÔNG chụp UI — dry-run kỹ thuật admin-duyệt-thay; buổi người-thật theo form B0 sẽ chụp ss-k8-* + bấm trên UI thật. QĐ9 nguyên bản ("đổi nguồn → số không đổi") nâng thành bằng chứng MẠNH HƠN ở vế (a): cửa đổi nguồn bị khoá hẳn 409.
B15 — SỔ BẢN-GHI-VĨNH-VIỄN + seq cháy (rollback theo ID, vá-11/13)
- BẤT TỬ by-design (sống chung, nhận diện ZZTEST/SOLUTION-PE): PE
PE/2026/A/052+PE/2026/A/053(DaDuyet) · KHKKKHKK/2026/001+/002(DaDuyet — HỐ-1-KHKK: chiếm slot (PE,N4); PE là test nên vô hại) · HĐZZTEST-K8/NCC/SOL&ZZTEST-NCC-K8/01DaPhatHanh (HỐ-1 numeric-guard chặn xóa; muốn dọn = sqlcmd soft-delete CHỜ ANH GẬT — lệnh:UPDATE Contracts SET IsDeleted=1 WHERE Id='47b453d3-…'+ NULL lạiLine.ContractId/pe.ContractIdnếu gỡ). - 🔴 Seq cháy KHÔNG thu hồi:
KHKK/2026seq ăn 001+002 (global-per-year — phiếu THẬT đầu tiên sẽ là 003, anh biết trước kẻo thắc mắc) · PE2026/Aseq ăn 052+053 · mã HĐ seq 01 thuộc CẶP PREFIX TEST (vô hại prefix thật). - Master test GIỮ làm bộ tái dùng (đúng tinh thần SOLUTION-PE-{n} owner ratify): Project
ZZTEST-K8· SupplierZZTEST-NCC-K8· WorkItemZZTEST-WI-K8. - Đã dọn trong-phiên: phiếu nháp orphan
0430d99fDELETE 204 · catalog B1-05 restore nguyên trạng ×2 lần đo. - Notification đã bắn tới roster thật trong lúc duyệt-thay — mọi tên mang ZZTEST; anh nhắn team "phiếu ZZTEST hôm nay bỏ qua" (B0.iv khai: em không có kênh Zalo/email).
- B16 rollback: KHÔNG kích hoạt (0 lần hỏng-phải-dừng).
END sub-k8-dryrun — VERDICT=K8 DRY-RUN PASS TOÀN TRÌNH 2 NHÁNH (GĐ1 PE 2 phiếu · GĐ2 KHKK 2 phiếu qua endpoint line MỚI · K7-bridge → GĐ3 HĐ DaPhatHanh · GĐ4 bản-cứng · QĐ9 4/4 vế · B15 sổ-ID đủ) — 1 blocker THẬT phát hiện + vá + ship trong phiên (Lines-editor) · 8 thuốc-thử guard ghi lại cho buổi người-thật
BỘ FIXTURE TEST (owner lệnh @S168 sau dry-run: "để là ADMIN_TEST… tạo luôn master data test… 1 bộ User test… chữ test trước… mỗi bộ 2-3 thôi")
🔴 LUẬT chốt từ lệnh này: mọi test từ nay chạy trên FIXTURE TEST — CẤM đụng master data / user thật. (Dry-run K8 đã theo đúng — bộ ZZTEST.)
Users (password chung Test@12345678 — policy prod đòi ≥12 ký tự; đổi sau buổi test nếu anh muốn):
| FullName | Roles | Id | |
|---|---|---|---|
| ADMIN_TEST | admin_test@solutions.com.vn | Admin | f0151cc7-32ad-4ec0-5da7-08deefbe0ee9 |
| TEST Nhân viên Soạn thảo | test.drafter@solutions.com.vn | Drafter + Procurement | 79de0ef1-4658-41cd-5da8-08deefbe0ee9 |
| TEST Người duyệt | test.approver@solutions.com.vn | CostControl + DeptManager | f4d02ccb-7466-4d7e-5da9-08deefbe0ee9 |
Verify: login ADMIN_TEST OK (token 471c) · 3/3 hiện GET /users?search=TEST. ⚠️ 2 user TEST muốn DUYỆT thật thì phải được gắn vào workflow qua Designer — ANH TỰ TAY ((54)-FINAL, em không đụng workflow); role hiện tại đủ THẤY màn.
Master data test (cộng bộ ZZTEST sẵn có từ GĐ0):
| Bộ | Thành viên (2-3/bộ) |
|---|---|
| Department (1) | TEST Phòng thử nghiệm ZZTEST-PB — 53044453… (3 user TEST gắn vào đây) |
| Projects (2) | ZZTEST-K8 (GĐ0) · ZZTEST-K8-2 "TEST Dự án thử nghiệm 2" — b1a77d48… |
| Suppliers (3) | ZZTEST-NCC-K8 (NCC, GĐ0) · ZZTEST-NTP-K8 (Thầu phụ) — 3c41bd4c… · ZZTEST-TD-K8 (Tổ đội) — 517f62c9… |
| WorkItems (2) | ZZTEST-WI-K8 (GĐ0) · ZZTEST-WI-K8-2 — 54ced5c2… |
Không bơm test vào ContractCatalogEntries (danh mục SP-002 chuẩn 86 dòng dùng chung — QĐ9 đã đo bằng rename+restore, không để vết).
END-FIXTURE — 1 dept + 3 users + 3 suppliers + 2 projects + 2 workitems, tất cả prefix TEST/ZZTEST, verify sống 2 phép