Files
solution-erp/docs/changelog/sessions/2026-06-25-S89-pe-visibility-finalize-userclean-guide.md
pqhuy1987 946c5b21ae [CLAUDE] Docs: S89 closeout — PE visibility/finalize + user-cleanup + Word guide
- STATUS/HANDOFF: prepend S89 (demote S88); state Mig 59 · 422 test · prod 17 user
- session log 2026-06-25-S89 (D1 draft-privacy IDOR · D2 CCM suggested-price !readOnly · D3 finalize-note 3-surface + flow badge + matrix flag · prod user-delete · Word guide)
- docs/Huong-dan-Duyet-NCC.docx (skill docx — logo Solution, 8 sections, khoanh-do 1->2->3; real screenshots pending anh)
- harvest residual workflow-sub agent-memory (cicd / investigator-codebase / reviewer + 2 plan-reviews)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 17:05:49 +07:00

50 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# S89 (2026-06-25) — PE visibility/finalize batch + xóa User test prod + Word guide
> Phiên CỰC LỚN, HMW-mode ON. anh Kiệt FDC UAT realtime. ~6 commit prod-verified + 1 prod data-op + 1 deliverable Word. em-main-led + Workflow fan-out (2: invest finalize-note + impl finalize-note) + cicd-monitor ×3. Nhiều #53 truncation (impl-frontend + cicd return rỗng) → recover-disk + self-gate.
## Bối cảnh
anh giao liên tiếp qua Zalo (anh Kiệt FDC + screenshot): (1) CCM không nhập được giá đề xuất, (2) finalize-note "không trình CEO" ra 3 surface, (3) màn hình CEO hiện nháp người khác, (4) Word hướng dẫn + danh sách user + xóa user test.
## D1 — Phiếu nháp RIÊNG TƯ người tạo (`a71753b`, Run #465 PASS, test 419→421)
**Triệu chứng:** màn hình CEO ở "chỗ thao tác" hiện bản nháp/phiếu chưa xong của NGƯỜI KHÁC.
**Root cause (2 đường lộ):** `PurchaseEvaluationFeatures.cs` IDOR filter — nháp (DangSoanThao) lộ qua **cond #2** role-eligible (`GetEligiblePhases` map Drafter/DeptManager→DangSoanThao :645) + **cond #3 V2-approver** (workflow PIN lúc TẠO phiếu `:149 ApprovalWorkflowId=request.*` → CEO là approver → thấy MỌI nháp). cond #3 = leak chính trên màn CEO.
**Fix 4 chỗ (nháp = owner-only + Admin):** GetEligiblePhases bỏ DangSoanThao · admin inbox-array bỏ DangSoanThao · list cond#3 guard `!=DangSoanThao` · detail-authz guard `isV2Approver` cho draft. +`PeDraftVisibilityTests` (2 test, test-before security — owner thấy / drafter khác KHÔNG / **CEO V2-approver KHÔNG** / admin thấy hết / phiếu đã-gửi vẫn hiện). Inbox: anh chốt "bỏ nháp khỏi inbox hẳn".
**Lesson:** `feedback_cardinality_change_grep_consumers` mở rộng — category-error (DangSoanThao=drafting phase đặt nhầm vào approval-eligible set); FK recon trước khi đụng visibility.
## D2 — CCM giá đề xuất nhập được (`f7bd97a`, cùng Run #465)
**Triệu chứng:** "PRO oki nhưng CCM giá đề xuất không nhập được" (anh Trần Xuân Lưu CCM).
**Root cause:** `SuggestedPriceRows` (PeDetailTabs:1726) gate `!readOnly && ev.canEdit*SuggestedPrice` — thêm tầng `!readOnly` mà ô **ngân sách song song KHÔNG có** (`editable={bs.canEditCcm}` role-only). Ở view readOnly=true (preview / Duyệt chưa-tới-lượt `!pendingMe`), CCM sửa ngân-sách được nhưng giá-đề-xuất rớt read-only. Vi phạm BE intent "không ràng Phase, chỉnh như tài liệu sống".
**Fix:** gỡ `!readOnly`, gate thuần role (BE setter fail-closed Forbidden = chốt chặn). Gỡ luôn prop readOnly không dùng. 2 app SHA-mirror (6 edit).
**Lesson:** 2 ô cạnh nhau cùng "nhập theo role" mà khác hành vi = gần chắc 1 ô gate sai trục (role ⟂ view-state).
## D3 — Finalize-note "không trình CEO" × 3 surface (`f0bca77`, Run cicd, test 421→422) + flow badge (`9c920ad`) + matrix flag (`fef4c33`)
**Yêu cầu:** phiếu mà quy trình có cấp bật `AllowApproverFinalize` (Mig 58) → note "kết thúc, không trình CEO" cho mọi người nắm ở dashboard + sidebar + trong phiếu.
**Invest Workflow** `wf_341f7b29-467` (4 invest investigator-codebase → design → 2 reviewer): bắt finalize-flag CHỈ lộ cho current-level → cần expose whole-flow. 2 reviewer bắt: **InboxPage SÓT** (surface sidebar) + path sai `pages/pe/` + copy phải nói "các cấp trước vẫn duyệt" (boundary cho cấp giữa) + dashboard chưa cam-kết.
**Impl Workflow** `wf_3f57edb6-514` (BE ∥ FE): BE OK (+caught CreateContractFromEvaluationFeatures.cs cùng DTO); **FE return RỖNG #53** → em-main self-gate recover-disk: fe-user 6 file + new PeFinalizeChip OK, **fe-admin chỉ types** → em-main mirror 4 file SHA-identical (cp) + verify 5 render-site + +PeFinalizeProjectionTests (EF-translate smoke 3-subquery).
**BE (no migration):** +EndsBeforeCeo/FinalizeStepName/FinalizeLevelName trên detail+list DTO + AllowApproverFinalize trên flow-level; first-reachable Step.Order→Level.Order; list/inbox/approved 3 subquery EF-safe (lv.Step!.Name); V1 null→false.
**Flow badge (`9c920ad`):** PeWorkflowPanel sơ-đồ — badge tím "⚑ Duyệt thay CEO" trên cấp finalize + làm-mờ Bước CEO "không trình tới" (anh muốn thấy NGAY trong sơ đồ).
**Matrix flag (`fef4c33`):** `WorkflowMatrixViewPage` (user, build S24 với 7 flag) **thiếu flag thứ 8** `allowApproverFinalize` (thêm Mig 58 S87 chỉ vào Designer) → "chưa hiển thị chính xác". BE đã gửi sẵn, FE matrix + AwLevelDto thiếu → thêm.
**Lesson:** (a) versioning — Designer "Lưu" = `CreateAwDefinitionCommandHandler` tạo **version MỚI** (Version++ theo Code + deactivate cũ); phiếu pin ApprovalWorkflowId lúc tạo → phiếu CŨ giữ version cũ, finalize chỉ hiện trên phiếu MỚI (đây là lý do anh "check rồi mà không thấy"). (b) doc-drift điển hình: thêm flag vào 1 surface (Designer) quên surface song song (matrix) — thêm field phải grep MỌI nơi render flag-set.
## Xóa User TEST khỏi prod (`681b1ed`, prod data-op)
anh: "Xóa hết User test, giữ User Solution thật". Quy trình S59/S85 chuẩn: **recon → AskUserQuestion chốt → backup → script → run → verify**.
**Recon (ssh sqlcmd prod):** 55 user. FK: `ApproverUserId` NO_ACTION (chặn) nhưng **KHÔNG user test nào là approver** (10 approver đều thật) → an toàn; 5 bảng con CASCADE; `nv.test` 1 PE (DrafterUserId loose, không FK). Edge: `chuong.phan@solution.com.vn` typo-domain (anh chốt xóa).
**Script `scripts/s89-delete-test-users.sql`:** whitelist-keep 17 + BACKUP (`SolutionErp_S89_preuserdelete.bak`) + XACT_ABORT + count-guard[30,45]. Chạy: count=38, PE=1, **còn đúng 17 user thật**.
**Seed (`DbInitializer.cs`):** gỡ 16 user mẫu khỏi `SeedDemoUsersAsync` + gỡ `LockDemoSampleUsersAsync` (call+method). SeedItDepartmentStaff + sample-workflow seeds null-guard → deploy KHÔNG resurrect/crash. **PHẢI deploy** (binary cũ chứa seed-test sẽ tái-tạo khi prod restart).
**Lesson:** whitelist-keep > blacklist (an toàn — chỉ giữ tập đã verify); count-guard + backup + XACT_ABORT = 3 lớp chống xóa-nhầm; `chuong.phan@solution`(typo) KHÔNG phải approver → xóa an toàn, anh Chương dùng bản `@solutions` (pass seed `User@1234567`).
## Word guide — `docs/Huong-dan-Duyet-NCC.docx`
anh: "làm file Word hướng dẫn Duyệt NCC theo mẫu, logo Solution, kiểu 1→2→3 khoanh đỏ". Dùng skill `docx` (docx-js Node). Logo `fe-user/public/logo.png` (407×145) nhúng. 8 phần step-by-step + 12 ô chừa ảnh nét-đứt kiểu "khoanh đỏ theo số (1→2→3)" + Quy ước ảnh + TOC + cover + footer. Valid (ZIP+XML UTF-8 OK; validator charmap-error = bug encoding script trên Windows, không phải lỗi file). Copy sang Downloads.
**Pending:** ẢNH THẬT chưa chèn — em KHÔNG chụp được app từ máy (không trình-duyệt nối prod + pass role; lái máy anh cần quyền + tạo rác prod vừa-dọn). Cần anh chụp 12 màn gửi → em annotate khoanh-đỏ + chèn. (Mẫu PDF anh không render được pdftoppm/pypdf/fitz đều thiếu → dựng layout-chuẩn-Solution.)
## State THẬT (cuối S89)
**Mig 59 · 88 bảng · 422 test (45D+377I) · gotcha 73 · menu 54 · bundle admin `DalcOhvb`/user `CdS4tX_2`** (sau `9c920ad`; `fef4c33` matrix rotate user→`CdS4tX_2` — verify "không trình tiếp CEO" in-bundle). Prod **17 user thật**.
## 🔴 NEXT
- **Anh:** ⚠️ restart CLI (carry budget/cmd). **Chèn ảnh guide:** chụp 12 màn (theo nhãn ô) gửi em → em khoanh-đỏ 1→2→3 + chèn → xuất bản. Hoặc bật Chrome+extension Claude-in-Chrome + pass admin → em tự chụp.
- **Em (carry):** 🔴 curate `test-specialist` L1 **34.8KB OVER-SOFT** + cicd 28KB + reviewer 27.7KB (archive-gate). **Monthly 2026-07-01:** ef-core skill Mig→59 · STATUS/HANDOFF re-tier mega-line · 3 vocab-fork alias-map · docs/CLAUDE Budget-removed · matrix-flag-count comment.
- **Pending product:** Section B cột Dự-án wire · Ngưỡng giá CEO Mig 54 Designer UAT · "C" chuyển phiếu→dự án spec.
- **Ops:** email typo anh Chương (đã xóa bản typo S89) · 5 real-staff pw · gán CNTT.
**Residual:** 5 file agent-memory (cicd/inv/reviewer MEMORY + 2 plan-review reviewer) = harvest hợp-lệ sub-workflow, commit kèm closeout.