8.4 KiB
8.4 KiB
lens2-evi — 8 verdict vs code
Findings
V-a (claim: Line per-NCC + UNIQUE(PlanId,SupplierId) filtered + ContractId per-line KHÔNG unique) = ĐÚNG
Domain/ContractSigningPlans/ContractSigningPlanLine.cs:14-25—ContractSigningPlanId+SupplierId+ContractId?(:25).Infrastructure/Persistence/Configurations/ContractSigningPlanLineConfiguration.cs:22-24—HasIndex(PlanId, SupplierId).IsUnique().HasFilter("[IsDeleted] = 0").:26HasIndex(x => x.ContractId)KHÔNG.IsUnique()⇒ N-line→1-HĐ (OG-1 gộp) hợp khuôn schema hiện tại. ĐÚNG 3/3 vế.
V-b (claim: create validator CHỈ check ApplicableType==10, không check IsActive) = ĐÚNG
Application/ContractSigningPlans/ContractSigningPlanFeatures.cs:209-220—EnsureWorkflowTypeAsyncchỉSelect(w => (int?)w.ApplicableType)(:214) + nhánh NotFound (:216-217) + so type (:218-219). 0 đọcIsActive/IsUserSelectable.- Call-site:
:350(Create) +:460(Update pin) — cả 2 nhánh cùng guard.
V-c (claim: picker FE lọc isUserSelectable) = ĐÚNG
fe-user/src/pages/khkk/KhkkCreatePage.tsx:56-66— GET/approval-workflows-v2?applicableType=10→types.find(...).history→.filter(w => w.isUserSelectable).- Chuỗi bổ trợ (lens2 tự đo, sub-invest KHÔNG nêu):
ApprovalWorkflowV2AdminFeatures.cs:117-134overview KHÔNG lọcIsActive⇒ history trả CẢ bản inactive; POST tạo mới:341-343chỉ setIsActive=falsecho bản cũ, KHÔNG đụngIsUserSelectable(:352-353bản mới = true) ⇒ 8 workflow cùng type-10 vẫn hiện đủ ở picker. Verdict "only-ONE-active VÔ HẠI" ĐỨNG VỮNG cho đường picker.
V-e (claim: KHKK service KHÔNG port CeoApprovalThreshold ⇒ set = config-lie #78) = ĐÚNG
- Grep
CeoApprovalThreshold|AllowApproverFinalizetrên toàn*ContractSigningPlan*(src/Backend): hit DUY NHẤT = commentContractSigningPlanWorkflowService.cs:44+ Designer migration (schemaApprovalWorkflow). 0 hit đọc-giá-trị trong code KHKK ⇒ 0 consumer THẬT (không phải chỉ comment khai).
V-f (claim: leaf key KHÔNG infix G1) = ĐÚNG
DbInitializer.cs:1780-1787—Khkk_G1(group) + 6 leafKhkk_WfView/List/Create/Pending/Approved/Deletedparent ="Khkk_G1", key leaf KHÔNG mang G1.
V-d (claim: GĐ3/4 đã có c.type; PipelineStage leaves PHẲNG, muốn nhóm thì groups? hoặc content) = ĐÚNG
fe-user/src/components/pipeline/PipelineStageFolders.tsx:58-72—PipelineStage = {n, leaves[], locked?, failed?, loading?, content?, count?, truncated?}— KHÔNG cógroups.:74-75stageCount=content !== undefined ? (count ?? 0) : leaves.length⇒ đi đườngcontentthìcountPHẢI truyền tay (bẫy đếm S162).usePipelineStages.ts:240navigate('/hard-copies?type=' + c.type)⇒c.typecó trên leaf GĐ4; GĐ3:220-229dùng cùng objectc⇒ group-by type = thuần FE. ĐÚNG.- BONUS ĐO ĐƯỢC (mirror claim K5): sha256
usePipelineStages.tsfe-user == fe-admin =7144eeb7…ab148;PipelineStageFolders.tsx=d449cc8d…cdc2d— 2/2 cặp IDENTICAL, tiền-đề "mirror SHA ×2 app" ĐÚNG tại HEAD.
F-L2-1 [HIGH] "Phiếu per NHÓM" (quyết-định ②.2) VA vào rào 1-PE-1-phiếu đang sống — K2 không liệt site này
ContractSigningPlanFeatures.cs:342-347— Create chặn:AnyAsync(p => p.PurchaseEvaluationId == pe.Id && p.Phase != TuChoi)⇒ 409 "Phiếu Duyệt NCC này đã có kế hoạch ký kết."- Cặp sinh đôi ở picker:
:1201-1202!db.ContractSigningPlans.Any(pl => pl.PurchaseEvaluationId == e.Id && pl.Phase != TuChoi)⇒ PE biến mất khỏi dropdown ngay sau phiếu ĐẦU. - Hệ quả: 1 gói thầu có hạng mục thuộc >1 nhóm duyệt ⇒ phiếu nhóm thứ 2 KHÔNG tạo được. Spec K2 (§③) chỉ liệt Mig 71 + validator + FE lines editor — 2 vị-ngữ trên KHÔNG có trong phạm vi.
- DoD K2 hiện tại ("tạo phiếu nhóm X + N hạng mục; line khác nhóm → 409") PASS mà lỗ vẫn còn ⇒ acceptance mù đúng chỗ nguy hiểm.
- Falsifier: nếu owner chốt "1 PE chỉ thuộc ĐÚNG 1 nhóm" thì finding rớt xuống LOW — nhưng khi đó "phiếu per NHÓM" == "phiếu per PE", cần khai rõ.
- Đề nghị: thêm dòng K2 "đổi 2 vị-ngữ uniqueness sang (PeId, ApprovalGroup)" + DoD "tạo phiếu nhóm 2 CÙNG PE → 201".
F-L2-2 [MED] "8 designer entry" (K6 DoD) không khả thi với hình-dạng route hiện tại
- Deep-link designer là PER-TYPE: fe-admin staticMap literal
Khkk_WfView: '/system/approval-workflows-v2/ContractSigningPlan'(fe-admin/src/components/Layout.tsx:35), route:code= TYPE-code. resolvePathnhánhAwV2_chỉ nhận 3 codeDuyetNcc|DuyetNccPhuongAn|Contract(fe-admin/Layout.tsx:166-172) ⇒ leafAwV2_*code mới trảnull= leaf RỚT IM LẶNG (gotcha #50, chính comment:40cảnh báo).- ⇒ muốn 8 entry designer phải (a) mở regex/whitelist + (b) route nhận per-workflow (Code/Id), không có trong K3/K6 scope.
F-L2-3 [MED] Leaf WfView (và Create) không có đường mang group — K4 DoD chỉ đo leaf list
WorkflowMatrixViewPage.tsx:52-71lọc DUY NHẤT theo?type=(typeIntwhitelist 1|2|3|10) rồi rendersummary.history(mọi workflowisUserSelectablecủa type) ⇒ 8 leafKhkk_G{n}_WfViewsẽ trỏ CÙNG/khkk/workflow-matrix?type=10và hiện CẢ 8 nhóm.- K4 DoD (§③) chỉ đòi "bấm từng leaf list lọc đúng ApprovalGroup" ⇒ 8/48 leaf WfView + 8/48 leaf Create nằm NGOÀI phép đo.
F-L2-4 [LOW-MED] Citation §D K5 gọi tên BE-artifact KHÔNG tồn tại
- Sub-invest §D K5: "BE:
KhkkListItemDto+approvalGroup". Grepsrc/Backend: 0 hitKhkkListItemDto; record thật =ContractSigningPlanListItemDto(ContractSigningPlanFeatures.cs:34).KhkkListItemDtolà type FE (fe-user/src/types/khkk.ts:106).
F-L2-5 [LOW] Số leaf trong ②.6 mâu thuẫn với §C-6
- Spec ②.6: "nhóm 2-8 = key mới
Khkk_G{n}_*(48 leaf…)" — đọc như 48 leaf MỚI; §C-6 sub-invest ghi "48 leaf TỔNG". Đúng số: 7 nhóm mới × 6 = 42 leaf mới + 7 group-key mới = 49 row menu mới; tổng leaf = 48. - Ảnh hưởng thật: 2 danh sách key TRONG DbInitializer phải khớp từng dòng —
KhkkKeys()(DbInitializer.cs:2185-2188, 7 key) và bộ grant (:2418-2424) — sai số ở spec = sai 2 chỗ enumerate.
F-L2-6 [MED] K4 liệt 2 site BE nhưng có 3 — KhkkKeys() bị bỏ sót (đúng lớp S155 mà spec tự trích)
- Site 1 menu seed:
DbInitializer.cs:1780-1787(SeedMenuTreeAsync:1737). - Site 2 grant KHKK:
SeedKeHoachKyKetAccessAsync(:2415, key-list:2418-2424). - Site 3 KHÔNG được spec nêu:
KhkkKeys():2185-2189(7 key hardcode) →:2216.Concat(KhkkKeys())bên trongSeedAllRolesReviewReadPermissionsAsync(:2144). Chính comment:2204-2205cảnh báo lớp này: "phải có mặt ở CẢ HAI danh sách permission … quên 1 bên = quyền lệch". - Quên site 3 ⇒ 42 leaf mới không có CanRead trên đường review-scope (fresh-DB / env khác) — lỗi IM LẶNG kiểu menu-vắng.
Ghi chú kiểm-chứng phụ (không tính là finding)
- "0 workflow type-10 seed" (§B.7) ĐÚNG 2 nguồn độc lập: grep
ContractSigningPlantrongDbInitializer.cs= 0 hit ngoàiKhkk_*menu; danh sách hàm seeder (:171,:223,:273,:325,:373,:421,:469) có Contract/Proposal/Leave/Ot/Travel/Vehicle — KHÔNG có ContractSigningPlan. - Khuôn được trích tồn tại thật:
SeedRealMasterDataAsync:2901(K1) ·SeedSampleApprovalWorkflowsV2Async:171(K3) ·isAdminHiddenchỉCt_fe-admin/Layout.tsx:182-184(K6). - FE tree ĐÃ chịu được N-phiếu/1-PE:
usePipelineStages.ts:110-121Map<string, KhkkListItemDto[]>(bucket mảng + sort desc) ⇒ F-L2-1 là rào BE thuần, FE không phải sửa.
Verdict
LENS2: 8/11 claim ĐÚNG · 1 SAI · 2 LỆCH-NHẸ. 6 claim chịu-lực (a)-(f) = 6/6 ĐÚNG ⇒ nền kỹ-thuật của 8 verdict §C VỮNG. Rủi ro không nằm ở evidence sai mà ở phần spec KHÔNG nói: F-L2-1 (HIGH, rào 1-PE-1-phiếu chặn thẳng quyết-định "phiếu per NHÓM") + F-L2-6 (MED, thiếu 1 site permission) + F-L2-2/3 (MED, designer-entry & leaf WfView/Create ngoài phép đo K4/K6).
(XONG — 6 verdict verify + 6 finding, không còn mục treo)