All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m24s
Sếp chốt deadline 15:00 (Zalo 11:02-11:17): flow tạo phiếu chọn quy trình → dự án → HẠNG MỤC → NCC/TP; phiếu dạng «Dự án – Hạng mục»; all-user thấy Duyệt NCC + master config; clear data cũ. - Mig 49 AddWorkItemToPurchaseEvaluation: PE.WorkItemId Guid? loose-Guid + index (KHÔNG FK vật lý — convention PE, database-agent design). Validator NotEmpty (create) + FK-guard AnyAsync(IsActive) → Conflict + UpdateDraft NULL-SAFE (client không gửi → giữ, chống null-hóa bug-class S42). 3 projection ListItemDto LEFT-join WorkItems. - FE ×2 app: PeWorkspaceCreateView select «c. Hạng mục *» + PeHeaderForm (load existing + PUT gửi lại, SHA256 IDENTICAL) + PeDetailTabs (header «Dự án – Hạng mục» + FormRow + inline khóa) + types. Route reuse /catalogs/work-items. - Perm: SeedAllRolesReviewReadPermissionsAsync extend Pe_* 11 key (factory — Pe leaf không nằm All) CanRead+CanCreate upgrade-only mọi role; PeWf_*/AwV2 GIỮ Admin. HRM/Office/Master/Catalogs CanRead (S57). Master write-lock Admin,CatalogManager ×3 controller. - Menu «Cá nhân» (Personal root 30, mirror Puro) + Chấm công re-parent + HrmConfig→Master + parentBackfill idempotent + admin bỏ ẩn Master (đảo S29). - LockDemoSampleUsersAsync: khóa 14/16 sample (GIỮ nv.cao+nv.truong IT-pool + catalog.manager) — ungated idempotent, IsActive=0+Lockout+SecurityStamp rotate. - Tests +12 PeWorkItemGuardTests (validator/FK-guard/null-safe) → 240 PASS. npm ×2 + BE 0W/0E. - Excel (3) đối chiếu: 62/71/3 identical S55 — no data change. - Gate: em main evidence-checklist (2 reviewer-spawn die-0-byte — resume-kill; backstop 12 guard-test + authz-key/role-string/Mig-49 evidence-lệnh). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5.7 KiB
5.7 KiB
S57bis (2026-06-11) — PE gắn Hạng mục công việc (Mig 49) + mở quyền all-role + menu "Cá nhân" + khóa demo user + Harness-4 runtime-VERIFIED
Bối cảnh: sếp chốt qua Zalo 11:02-11:17 (deadline 15:00 cùng ngày): (1) kiểm tra mapping master data ngoài eoffice; (2) phân quyền TẤT CẢ user thấy Duyệt NCC + cấu hình master data; (3) flow tạo phiếu: chọn quy trình → chọn dự án → chọn hạng mục công việc → chọn/nhập NCC/TP → chuyển duyệt, phiếu dạng "Dự án (năm) – Hạng mục công việc"; (4) clear dữ liệu cũ. Anh chốt scope qua AskUserQuestion: xóa demo = CHỈ khóa user sample · quyền PE = Xem + Tạo · hạng mục = header phiếu, 1 phiếu 1 hạng mục.
Việc đã làm
A — Đối chiếu Excel (3) vs master data S55: ✅ NO-CHANGE
- Python openpyxl dump 7 sheet → diff vs
scripts/master-import-data.generated.md: 62 Projects + 71 WorkItems (16VT/30TP/9MEP/16TB) + 3 Suppliers identical 100%. 2 sheet hợp đồng = catalog tham khảo, không thuộc DB. Không patch gì.
C — PE gắn Hạng mục công việc (Mig 49 AddWorkItemToPurchaseEvaluation)
- Design (🔵 database-agent introspect LocalDB):
PurchaseEvaluations.WorkItemId Guid?scalar loose-Guid + index, KHÔNG FK vật lý — nhất quán convention PE (ProjectId/SelectedSupplierId đều loose; duy nhất ApprovalWorkflowId có FK). Guard = validator + handler (mirror S43 FK-invariant). WorkItems = catalog GLOBAL (không ProjectId) → 2 dropdown độc lập; "Dự án (năm) – Hạng mục" = chuỗi ghép hiển thị. KHÔNG đụng CodeSequences (mã phiếu giữPE/{YYYY}/{A|B}/{Seq}). - BE: entity + config index + Mig 49 3-file (AddColumn nullable + CreateIndex, Down reversible) + Create/UpdateDraft command
WorkItemId+ validatorNotEmpty(create bắt buộc; DB nullable backward-compat 4 phiếu cũ) + FK-guardAnyAsync(w.Id==x && w.IsActive)→ Conflict + UpdateDraft null-safe (if (request.WorkItemId is not null)— client không gửi → GIỮ, chống null-hóa bug-class S42) + 3 projection ListItemDto (List/Inbox/CreateContractFrom) LEFT-join WorkItems. - FE ×2 app (logic-identical, PeHeaderForm SHA256 IDENTICAL):
PeWorkspaceCreateViewselect "c. Hạng mục công việc *" sau Dự án (option[Category] Code — Name, canSubmit require) +PeHeaderForm(select + load existing + PUT/POST gửi workItemId) +PeDetailTabs(header subtitle "Dự án – Hạng mục" + FormRow display + inline-edit khóa) + types +3 field. Route reuse/catalogs/work-items(không endpoint mới). - 🟪 Test +12 (
PeWorkItemGuardTests): 228→240 PASS. Validator 3 + create-FK-guard 4 + update-null-safe 5. Finding:NotEmpty()trênGuid?không chặnGuid.Empty→ FK-guard handler bắt (defense-in-depth, locked 2 test).
B — Mở quyền all-role (extend S57-WIP SeedAllRolesReviewReadPermissionsAsync)
- Pe_ (11 key: root + 5 leaf × 2 type, build qua factory vì Pe_ leaf KHÔNG nằm
MenuKeys.All— recon catch):** CanRead+CanCreate=true mọi role, upgrade-only (row cũ 7 role nâng cờ false→true, KHÔNG hạ, KHÔNG đụng Update/Delete). PeWf_*/AwV2/PeWorkflows GIỮ Admin (prefixPe_không match — ký tự thứ 3). - HRM/Office/Personal/Master/Catalogs: CanRead-only skip-existing (S57 giữ nguyên). PE controller
[Authorize]class-level → mở menu không silent-403 (gotcha #44 không áp).
D — Khóa 14/16 demo sample user (LockDemoSampleUsersAsync)
- Ungated idempotent NGAY trong DbInitializer (sau SeedDemoUsers + SeedItDepartmentStaff) → tự áp prod khi deploy, bền mọi startup.
IsActive=0 + LockoutEnabled + LockoutEnd=Max + SecurityStamp rotate. - GIỮ ACTIVE có chủ đích:
nv.cao+nv.truong(IT helpdesk round-robin pool S52 — khóa nốt SAU khi anh gán user thật vào dept IT, ops-pending S56) +catalog.manager(account chức năng).
S57-WIP ship kèm (từ 06-10, đã nằm working tree)
- Menu nhóm "Cá nhân" (Personal root order 30, mirror Puro) + Chấm công re-parent Off→Personal + HrmConfig re-parent Hrm→Master + HrmDashboard order 1 + Contracts 30→31 +
parentBackfillidempotent + admin bỏ ẩn Master (đảo S29) + Master write-lock[Authorize(Roles="Admin,CatalogManager")]×3 controller.
Harness-4 closeout (governance, commit riêng)
- Spawn-test 2 chiều post-restart PASS: H1 tooling-auditor (demote pin) self-report
claude-opus-4-8[1m]+ H2 harvest-curator (promote inherit) self-reportclaude-fable-5[1m]→ nấc RUNTIME-VERIFIED 06-11 (adap-report §2/§5 + STATUS row promoted;[1m]1M-resolve SE tự verify). Email update2026-06-11-se-to-ai_infra-harness-4-runtime-verified(honest n=1/chiều; hmw.js executed-file giữ). Lesson env: CCD cache agent frontmatter — restart CLI mới ăn (proved 2 data-point 06-10/06-11).
Multi-agent & lessons
- HMW-mode ON carry từ S55. Fan-out: 2 monitor (kiêm spawn-test) + 2 recon (investigator-codebase catch Pe_*-leaf-not-in-All + database-agent design Mig 49) + 2 builder + test-specialist + reviewer ×2.
- ⚠️ 2 builder return-truncated giữa task (gotcha #53 — BE chết trước projection-3/migration, FE chết giữa mirror fe-admin) → em main solo vá cross-stack (disk/git truth, không tin return): fix CS7036 + CS8019 + Mig 49 + null-safe + mirror 7 edits PeHeaderForm + 3 edits PeDetailTabs ×2 app. Reviewer email-gate đầu cũng mất tích → gộp 1 gate trọn cuối.
- Excel (3) đối chiếu bằng raw-dump trước parse (tránh lặp data-quality trap S55 MEP-col).