Commit Graph

117 Commits

Author SHA1 Message Date
778fc98b2f [CLAUDE] Supplier: Mig 62 expand 30-field + seed 4 NCC + FE form 2-app
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m7s
Phase A of the NCC/TP Excel-import backlog (anh Kiet FDC). Supplier
entity 9 -> 27 fields to hold the 30-column supplier database.

Backend:
- Supplier +18 nullable cols; SupplierType +CaHai=6 (append-only);
  new nullable SupplierStatus enum.
- Mig 62 ExpandSupplierFields (3-file): AddColumn x18 + guarded un-cram
  Sql (clear legacy crammed Note on the 4 seeded rows, exact-match).
  No new table (89), reversible Down.
- Seed fill-nulls-if-exists: populate 30 fields for TRUONGGIANG/TANPHU/
  TGN/DONGDUONG from Excel; idempotent, never clobbers existing cols.
- DTO + Create/Update commands + validators (MaximumLength-only, no
  NotEmpty so open-auth Create minimal payload stays valid) + 2 query
  projections.

Frontend (fe-admin + fe-user, byte-identical SHA-mirror):
- types/master.ts +18 fields +SupplierStatus; SuppliersPage form 4
  section groups + Status select + 3 NAS links via new shared PathLink
  (extracted from PE HoSoLink render+Copy). All new fields optional.

Excel upload auto-map = Phase B (deferred). Tests test-after (UAT mode).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 16:06:11 +07:00
9e12e80b48 [CLAUDE] FE-Admin·FE-User: badge " Đã được CEO duyệt" cho phiếu đi hết lên CEO (anh Kiệt FDC UAT)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m13s
- PeFinalizeChip (single-source-of-truth pill): +nhánh phase===DaDuyet && !endsBeforeCeo → " Đã được CEO duyệt" (đối xứng chip "⚑ Kết thúc · X" cho endsBeforeCeo=true)
- Wire phase ở 6 call-site (PeListPanel + PurchaseEvaluationsListPage ×2 app + Inbox + Dashboard user)
- FE-only, tận dụng endsBeforeCeo runtime (Mig 60 fix-3), no BE/mig; mirror 2-app SHA da9c3ed9, build ×2 PASS 0-TS-err

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 20:52:17 +07:00
8ee8f3e248 [CLAUDE] PurchaseEvaluation: cây Duyệt NCC node Dự án hiện mã dự án thay tên dài (anh Kiệt FDC)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m23s
Anh Kiệt FDC (Zalo + screenshot): node 📁 Dự án trong cây "Năm > Dự án >
Hạng mục > Phiếu" hiện TÊN dài ("Phân xưởng homecare 75 tấn/ngày và các
hạng mục") → user thấy vướng → "bắt mã dự án nhé".

BE: thread ProjectCode vào PurchaseEvaluationListItemDto + 3 projection
(list + inbox + approved-from-evaluation) + search khớp thêm mã dự án.
FE 2 app (SHA-mirror): PeListItem +projectCode; tree node 📁 render Code
(fallback Name nếu rỗng) + tooltip=tên đầy đủ + sort theo mã.

Verify: dotnet build 0/0 - npm build x2 PASS - test 434 (45D+389I).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 16:00:03 +07:00
f0bca7737c [CLAUDE] PurchaseEvaluation · FE-User · FE-Admin · Tests: PE note "Duyệt là KẾT THÚC quy trình (không trình CEO)" — 3 surface
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m58s
Phiếu mà quy trình duyệt có cấp bật AllowApproverFinalize (Mig 58) sẽ kết thúc tại cấp đó,
KHÔNG trình CEO. Hiển thị note cho MỌI NGƯỜI NẮM ở 3 surface (anh Kiệt FDC). KHÔNG migration
(cột AllowApproverFinalize đã có Mig 58, prod ở Mig 59).

BE (3 file, computed DTO):
- PurchaseEvaluationDtos.cs: +bool EndsBeforeCeo +string? FinalizeStepName +string? FinalizeLevelName
  trên DetailBundle + ListItem; flow-level +bool AllowApproverFinalize.
- PurchaseEvaluationFeatures.cs: detail compute first-reachable (Step.Order↑→Level.Order↑, dept-name
  in-memory); list + inbox projection qua 3 subquery EF-safe (lv.Step!.Name). V1 (workflowId==null) → false.
- CreateContractFromEvaluationFeatures.cs: ListApproved projection cùng DTO → +3 subquery y hệt.

FE 2-app (fe-user + fe-admin SHA-mirror component):
- PeFinalizeChip.tsx (MỚI, chip tím) ở 3 danh sách: PeListPanel + PurchaseEvaluationsListPage (cây) + InboxPage.
- PeWorkflowPanel.tsx: note callout trong phiếu, branch DaDuyet (past-tense) / đang-chạy; copy boundary-aware
  "...là KẾT THÚC, không trình CEO. Các cấp trước vẫn duyệt như thường." (tránh cấp giữa hiểu nhầm).
- UserDashboardPage.tsx (chỉ fe-user): dải "Phiếu Duyệt NCC gần đây" + chip (admin dashboard để nguyên).
- types: PeListItem/PeDetailBundle/PeApprovalFlowLevel +field.

Tests: +PeFinalizeProjectionTests (EF-translate smoke 3 subquery + first-reachable + V1-false). Full suite 421→422.
em-main self-gate sau workflow (impl-frontend return rỗng #53 → mirror fe-admin + verify 5 site recover-disk).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 14:58:54 +07:00
f1b10e9c33 [CLAUDE] PurchaseEvaluation: CCM 3-fix — multi-winner sum + budget=0 hợp lệ + cấp KẾT THÚC quy trình (Mig 58, anh Kiệt FDC)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m10s
CCM (Lưu Trần / anh Kiệt FDC) — làm 3/4 mục (mục 3 "CCM sửa ngân sách" để riêng):

1. Multi-winner: chọn NHIỀU NTP/NCC/ĐVDV cùng trúng → winnerQuoteTotal = SUM
   ThanhTien MỌI đơn vị isWinner (vd 3 ông 37.8+9+10 = 56.8tr). Cột mới
   PurchaseEvaluationSupplier.IsWinner (Mig 58, backfill từ SelectedSupplierId).
   SelectWinner → multi-toggle SupplierIds[]. FE: bảng so sánh tick nhiều ô +
   dòng "Tổng chi phí đã chọn"; mọi guard/checklist/computeGiaChaoThau/tạo-HĐ
   đổi sang isWinner (selectedSupplierId = null khi liên-danh ≥2).

2. Ngân sách = 0 hợp lệ: nới submit-guard + 3 validator (chỉ chặn khi NULL,
   số 0 cố ý đi qua; fallback ProInitial chỉ khi null). Mirror BE + FE.

3. Cấp KẾT THÚC quy trình: ApprovalWorkflowLevel.AllowApproverFinalize (Mig 58)
   — admin bật per-cấp trong Workflow Designer; duyệt tới cấp đó TỰ DaDuyet,
   bỏ qua CEO (AUTO theo cấu hình quy trình, không ô-tích runtime — anh Kiệt
   chốt). FE: banner cảnh báo + bắt chọn giá chốt.

Mig 58 AddPeMultiWinnerAndLevelFinalize (2 AddColumn bool + backfill IsWinner,
additive/reversible). Test 377→395 (+PeMultiWinnerTests +PeApproverFinalizeTests
+budget=0; auto-model gọn bớt 2 test bypass/opt-out). FE 2 app SHA-mirror.
Build sạch BE + 2 FE local.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 15:22:35 +07:00
fa6654b8f4 [CLAUDE] FE: PE tach chon-phieu (inline 3-panel nhu cu) khoi mo-rong (overlay) + nut Xem mo rong moi dong
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m47s
anh (annotate 2026-06-19): bam dong phieu = xem thuong inline 3-panel NHU CU; them nut 'Xem mo rong' (Maximize2) goc moi dong -> overlay full-man. Param ?expand=1 tach khoi ?id: click row=select (wide: inline 3-panel / narrow <lg: overlay vi 3-panel khong vua man); 'Xem mo rong'=id+expand; Thu gon/Esc/backdrop=bo expand GIU id (ve inline); Dong/duyet/xoa=clear ca 2 (ve list). Overlay render khi id&&expand; inline detail khi id&&!isExpand. em-main review them !isExpand guard vao 2 panel inline -> tranh double-mount PeDetailTabs/PeWorkflowPanel phia sau overlay (intent comment co nhung code sot). Giu tree 4 tang + PeUrgentChips + overlay a11y (slide/Esc/focus-trap). FE-only, 2 app SHA256-identical. Build PASS x2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 14:57:10 +07:00
3b98845976 [CLAUDE] FE: PE tra danh sach ve layout goc (bam trai lap day) + giu focus overlay bam phieu
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m40s
anh Kiet/Tra Sol UAT: list state dang canh giua (max-w-5xl) trong 2 ben -> tra ve bo cuc goc 8e68ed1: grid lg:[400px_1fr_360px], list bam trai + 2 placeholder panel lap day man hinh, KHONG canh giua. Giu nguyen focus overlay S78 (bam phieu -> overlay truot tu phai che het menu+list; Duyet/Thu gon/Esc -> dong ve danh sach). <lg single-col compact. 2 app SHA256-identical. FE-only, 0 BE, 0 migration. Build PASS x2. Recover tu agent process-death (edit hoan chinh tren disk, em-main build-verify + mirror fe-admin).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 13:53:11 +07:00
398b01d0a6 [CLAUDE] FE: PE che do tap trung duyet phieu (overlay truot phai, an menu+list) + responsive laptop nho
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m40s
Bam phieu -> focus overlay (fixed inset-0 z-50) truot tu phai, che menu+TopBar+list rail; phieu full-width tu cuon + panel duyet ben canh (stack xuong duoi tren man nho). Thu gon/Esc/backdrop HOAC Duyet (chi forward-approve; Tra lai/Tu choi giu overlay) -> dong ve danh sach. List state = panel giua mx-auto max-w-5xl, giu cay 4 tang + PeUrgentChips + search/filter/SLA. Responsive lg-pivot (flex-col stack <lg, flex-row >=lg), compact laptop nho, KHONG dong cham man hinh to (anh: 'man to OK roi'). PeWorkflowPanel +onApproved (wasReject byte-mirror isReject). 2 app SHA256-identical. a11y role=dialog/Esc/focus-trap/scroll-lock/reduced-motion. FE-only, 0 BE, 0 migration. Build PASS x2. Note: backend down luc design -> live authed verify sau deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 13:28:26 +07:00
8e68ed1892 [CLAUDE] FE: PE co gap PILL (do PRO / xanh CCM) dong bo moi danh sach + inbox
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m46s
Surface co gap GAP tren MOI danh sach phieu de CEO/nguoi duyet thay urgency ngay tren danh sach khong can mo phieu (anh Kiet FDC). Cay danh sach: emoji -> pill labeled. Khung 'Danh sach phieu' cho duyet (Workspace + picker) + inbox 'phieu cho toi duyet': them pill (truoc day thieu). NEW PeUrgentChips.tsx single-source-of-truth (style khop badge detail S69) x2 app. FE-only, 0 BE, 0 migration — DTO da co IsUrgentByPro/Ccm tu S69 Mig 53. Build PASS x2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 12:31:08 +07:00
e33481efb6 [CLAUDE] PurchaseEvaluation: Mig 56 ngan sach MA TRAN 3 cot (Du an|PRO|CCM) + badge quyen NS theo role
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m57s
S76 (anh Kiet FDC + chi Tra Sol) — form ngan sach + hien thi quyen nhap NS trong flow:
- Part 1: form ngan sach -> MA TRAN 3 cot, moi phong nhap+dieu chinh cot minh
  (PRO canEditPro / CCM canEditCcm / Du an FE hien-thi-only). Mig 56
  +ProInitialAmount/ProAdjustmentAmount (additive-nullable + data-migrate
  ProEstimate->ProInitial). full moi cot = ban hanh + hieu chinh.
- Part 2: Workflow Designer (fe-admin) +badge "NS PRO/CCM" canh approver
  (suy tu role Admin|Procurement / Admin|CostControl, hien-thi-only no-authz).
- Part 3: flow quy trinh fe-user/fe-admin (Duyet NCC) +badge tuong tu.
- Fix race mat-du-lieu Part 1 (useIsFetching khoa Luu khi refetch — dong
  cua-so stale-echo, reviewer Part2/3 bat).
- Test 339->344 (+5). 2 workflow review (Part 1 PASS + Part 2/3 PASS).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:02:47 +07:00
ebd7e1c42f [CLAUDE] PurchaseEvaluation: cờ gấp PRO/CCM + CCM duyệt-final theo ngưỡng giá trị (Mig 53) + 14 test
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m41s
Yêu cầu anh Kiệt FDC (sau họp sếp). Mig 53 AddPeUrgentAndCeoApprovalThreshold — 3 AddColumn, no new table (Mig 52→53). Rollout an toàn: cột nullable, ngưỡng null = giữ luồng duyệt cũ 100% cho tới khi admin set.

B — CCM duyệt-final theo NGƯỠNG GIÁ TRỊ ("gói CEO phân quyền theo giá trị"):
- ApprovalWorkflow += CeoApprovalThreshold (decimal?, admin nhập trong Workflow Designer).
- ApproveV2Async: actor role CostControl (CCM) + winnerQuoteTotal (tổng giá NCC được chọn) < ngưỡng → DaDuyet luôn (bỏ CEO); ≥ ngưỡng → đẩy lên CEO như cũ. Ngưỡng null = luồng tuyến tính cũ. Q4 chốt nhận diện theo ROLE người duyệt.
- reviewer PASS 0 blocker: cascade-safe (Off/role không lan), tested load-bearing (CCM dưới ngưỡng → DaDuyet skip CEO).

A — cờ gấp per-vai (visibility-only, Q3 KHÔNG đổi luồng):
- PE += IsUrgentByPro (PRO đỏ) / IsUrgentByCcm (CCM xanh).
- Endpoint PUT /purchase-evaluations/{id}/urgent role-gated (Procurement→ByPro, CostControl→ByCcm, Admin→cả 2, khác→Forbidden) + notify CEO (Director) khi MỚI bật (best-effort).

FE ×2 app: Workflow Designer ô "Ngưỡng giá trị gói CEO" (fe-admin) + PE detail nút bật/tắt cờ gấp đỏ/xanh theo role + badge GẤP + hint "giá trị gói vs ngưỡng → CCM duyệt-final/cần CEO" + PE list badge gấp.
DTO: PE detail += isUrgentByPro/Ccm + winnerQuoteTotal + ceoApprovalThreshold; list += isUrgentByPro/Ccm; workflow V2 += ceoApprovalThreshold.

+14 test (292→306): PeCcmThresholdFinalizeTests 5 (B routing) + PeUrgentToggleAuthzTests 9 (A authz). Build slnx 0/0 · npm build ×2 0 err · dotnet test 306 PASS.

C (sau duyệt xong chuyển phiếu đến dự án) — chờ anh Kiệt làm chi tiết form, CHƯA làm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 13:27:50 +07:00
c556f6cfa2 [CLAUDE] FE: Văn phòng số re-skin toàn module — 10 page PURO layout + CSS Hồ sơ NS (PageHeader/KpiCard/WidgetCard), phẫu thuật giữ nguyên logic
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m42s
Re-skin TRỌN module Office sang bố cục PURO (NamGroup) + ngôn ngữ thị giác Hồ sơ Nhân sự, tái dùng 3 shared component foundation. Phẫu thuật trình bày — logic byte-identical (reviewer verify mọi api.get/post/put/delete + queryKey zero-delta HEAD vs working tree, cả 2 app build PASS).

10 page (9 fe-user → mirror fe-admin SHA256-identical + AttendanceReport fe-admin-only):
- Danh bạ nội bộ — PageHeader + KpiCard tổng hợp (NV/phòng ban) + card icon-chip.
- Phòng họp (lịch + quản lý phòng) — PageHeader amberx + calendar/table trong card-accent.
- Đề xuất (List/Create/Detail) — List: status filter → KpiCard row (6 trạng thái + inbox "Cần tôi duyệt"); Create/Detail: card-accent section + Field idiom.
- Đơn từ/Đặt xe (List/Detail, :kind leave/ot/travel/vehicle) — PageHeader teal + KpiCard status filter (client-side view over fetched) + card-accent detail.
- Ticket CNTT — PageHeader violet + KpiCard 5-status filter + Quá hạn SLA + kanban card-accent.
- Báo cáo chấm công (fe-admin only) — PageHeader + KpiCard tổng hợp + bảng card-accent + Excel-export giữ nguyên.

- Accent chỉ dùng stop hợp lệ (teal/violet/amberx/greenx 50/100/500/600/700; brand 50-900); gotcha #66 clean. a11y giữ/nâng (focus-visible, KpiCard role/aria-pressed/keyboard).
- Build PASS x2 (fe-user index-C8-p69Kn / fe-admin index-yFhLO2Wp). reviewer PASS 0 blocker; 2 concern cosmetic (badge dup ProposalDetail header+row; KpiCard filter lọc trên trang đầu đã fetch — giới hạn pagination có sẵn).
- Office VẪN ẨN non-Admin (chưa golive). 9 page fe-user↔fe-admin SHA256-identical.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 09:57:46 +07:00
a8bbdaeeea [CLAUDE] FE: Văn phòng số foundation — shared PageHeader/KpiCard/WidgetCard + Dashboard landing (PURO · CSS Hồ sơ NS) + sync fe-admin index.css + menu Off_Dashboard
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m41s
- 3 shared component PageHeader/KpiCard/WidgetCard ×2 app SHA256-identical; tái dùng token Hồ sơ NS (.app-gradient-brand/.card-accent/.icon-chip/.stat-value/.label-eyebrow + accent palette teal/violet/amberx/greenx); gotcha #66 text-white! trên gradient header.
- OfficeDashboardPage 2-cột widget kiểu PURO HomePage: Đề xuất/Đơn từ/Ticket/Phòng họp hôm nay + "Công việc của tôi" + Thao tác nhanh. Reuse query endpoint sẵn có (shared TanStack cache, KHÔNG BE/API mới), đếm client-side, loading/error/empty mỗi widget.
- Sync fe-admin/src/index.css ← fe-user (đóng drift S66-S68: heading 600→700, ink #0f172a→#0b1220, label-eyebrow slate→brand-600 + rule gotcha #66). Nay 2 app đồng bộ.
- Menu key Off_Dashboard (MenuKeys.cs const + All[] + DbInitializer seed Order 0 dưới Off) — no migration, idempotent. GIỮ ẨN non-Admin (RevokeTemporarilyHiddenModules StartsWith Off). Chưa golive.
- Wire 4-place ×2 app: App.tsx route /office/dashboard + menuKeys.ts + Layout staticMap.
- Fix KpiCard activeBorder -300 → -500 (accent palette chỉ 50/100/500/600/700 — chống "vỡ màu im lặng" Tailwind v4: border-teal-300 rơi default Tailwind, border-amberx-300 drop hẳn).
- Build PASS x2 (fe-user index-DrxDysO7 / fe-admin index-TbkadgKd) + dotnet slnx 0/0. reviewer PASS 0 blocker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 09:24:17 +07:00
37752eb914 [CLAUDE] FE: Hồ sơ NS — tên NV đen→trắng (ép text-white! thắng rule h1-h4 ngoài @layer, Tailwind v4) + thu nhỏ text-lg font-bold — x2 app SHA256
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m33s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 19:54:46 +07:00
6983609c7b [CLAUDE] FE: Hồ sơ NS — header chi tiết NV nổi bật (tên text-xl extrabold + drop-shadow · meta 13px font-medium trắng · badge trạng thái màu emerald/amber/slate) — x2 app SHA256
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m48s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 19:34:35 +07:00
91aaf058fb [CLAUDE] FE: Hồ sơ NS — list pane flex-row gọn (hết tràn ngang rail) + đồng nhất cỡ chữ (x2 app SHA256)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m33s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 14:20:23 +07:00
292d64d843 [CLAUDE] FE-Admin: mirror Hồ sơ Nhân sự master-detail từ fe-user (page SHA256 identical + accent tokens index.css)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m19s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 13:51:20 +07:00
8c8179cda0 [CLAUDE] FE-Admin: chọn "Phòng cha" trong quản lý phòng ban — dựng cây tổ chức
Some checks failed
Deploy SOLUTION_ERP / build-deploy (push) Failing after 1m4s
Anh chốt self-service: admin gán phòng cha để dựng sơ đồ org cho trang Hồ sơ Nhân sự.
DepartmentsPage: +Select "Phòng cha (Thuộc khối/phòng)" (option "— Không có (cấp gốc) —"
= null) + query departments-all (pageSize 200) + cột "Thuộc" hiện tên phòng cha + gửi
parentId trong Create/Update + pre-select khi sửa + loại-trừ-chính-nó khỏi dropdown
(cycle sâu hơn = BE 409 ConflictException -> toast). +parentId vào type Department.
Build PASS fe-admin (0 TS error). Mirror fe-user defer (quản lý phòng ban = admin).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 10:41:00 +07:00
79ef8da9f4 [CLAUDE] PurchaseEvaluation: ngan sach goi thau theo Excel anh Kiet - bang tong hop 2 block + nhap theo role PRO/CCM + xoa module Budget cu (Mig 50)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m31s
- Mig 50 ReplaceBudgetModuleWithPeWorkItemBudgets: bang moi PeWorkItemBudgets (1 record/cap Du an x Hang muc, UNIQUE filtered [IsDeleted]=0) + drop 5 bang Budget cu + PE/Contracts drop BudgetId + backfill BudgetManualAmount->BudgetPeriodAmount TRUOC DropColumn (phieu UAT giu so) + DELETE menu/permission Bg_* IN-list children-first
- BE: PUT {id}/budget/pro (role Procurement) + {id}/budget/ccm (role CostControl, Adjustment cho phep AM) fail-closed Forbidden-truoc-side-effect + EnsureTrackedAsync race-safe (catch unique -> re-fetch winner, loi khac rethrow) + auto-create record khi tao phieu + budgetSummary DTO (luy ke trinh-truoc/chon-thau-truoc/de-xuat-ky-nay + full fallback du-tru-PRO + canEdit flags) + submit-guard (3) doi predicate BudgetPeriodAmount -> "chua nhap Ngan sach ky nay" + PATCH budget-adjust absolute-set 2 field moi + Contract GIU BudgetManual* (HD nhap tay khong doi) + ke thua HD map BudgetPeriodAmount
- FE x2 app SHA256 identical: bang "TONG HOP NGAN SACH TRINH KY" block A (full dam + ban hanh + V0 hieu chinh + du tru PRO + ghi chu, editable theo canEditPro/canEditCcm) + block B 9 dong cong thuc Excel (5=1+3, 6=2+4, 7=full-5, 8 tu nhap default 7, 9=4+8) + to mau vuot ngan sach #C00000 / am do / red-soft row8>row7 + "Chua chon" khi count=0 + banner phieu chua gan Hang muc + o "Ngan sach ky nay" o create/header + XOA pages/components/types budgets + routes + menuKeys + Layout staticMap 4-place
- Tests: +22 PeWorkItemBudgetTests (auto-create x3, ensure/race x2, authz matrix PRO x5 + CCM x3, budgetSummary aggregates x5, adjust x4) - 14 BudgetPolicyTests xoa theo module - 1 test via-BudgetId -> 263 PASS (45 Domain + 218 Infra, 0 fail)
- database-agent advise adopted: khong FK vat ly PE/Contracts->Budgets (DropColumn khong can DropForeignKey) + DropIndex truoc DropColumn (SQL 5074) + IN-list thay LIKE Bg_% (underscore wildcard + miss root) + khong Serializable wrap (nested-tx conflict codegen)
- Reviewer PASS-with-minor 0 blocker (verdict-first survived); 2 minor da sua truoc commit (comment adjustMut absolute-set + dead key budgetId); note: F4 approver-edit-budget UI entry tam drafter-only, BE van cho approver scope - cho UAT anh Kiet
- Scaffold-bug caught: EF tu sinh RenameColumn BudgetManualAmount->ExpectedRemainingAmount (SAI semantics) -> thay bang Add+UPDATE+Drop

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 01:07:27 +07:00
c869d2617d [CLAUDE] PurchaseEvaluation: rename 71 WorkItems theo format PMH anh Kiet FDC chot (MAT-n/SUB-n/MEP-SUB-n/MEP-EQU-n + ten "STT nhom ten") + FE sort numeric
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m33s
- anh Kiet 16:59: "MA CV gom chu MEP-SUB-1 roi ten 1 MEP Sub MEP (Full) - dung kieu vay".
- DbInitializer seed tuples 71 ma moi (VT->MAT, TP->SUB, MEP-0n->MEP-SUB-n, TB->MEP-EQU-n).
- scripts/s59-rename-workitems-pmh.sql DA CHAY prod + LocalDB Dev TRUOC push (UPDATE giu Id,
  71/71, OLD-CODES=0, verify JSON qua API prod tieng Viet nguyen ven).
- FE x2 app (SHA256 mirror): PeWorkspaceCreateView + PeHeaderForm sort numeric-aware
  (ma khong pad -> string-sort loan "10"<"2") + tree Panel 1 workItemName numeric:true.
- scripts/master-import-data.generated.md sync 71 dong W| + note mapping.
2026-06-11 17:14:06 +07:00
0eafcd36e7 [CLAUDE] PurchaseEvaluation: tree Panel 1 chot 4 tang "Nam > Du an > Hang muc cong viec > Phieu" (anh chot follow-up, SHA256 mirror x2 app)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m51s
- Doi tu "Du an (Nam)" gop 1 node -> Nam la tang ngoai cung (DESC, bg-slate-50),
  trong Nam chua Du an (A-Z vi), trong Du an chua Hang muc cong viec, roi phieu.
- yearGroups useMemo thay projectGroups + expand-state localStorage key v3.
- Build x2 PASS, SHA256 mirror identical 95D524EE.
2026-06-11 16:36:59 +07:00
56882acc4f [CLAUDE] PurchaseEvaluation: tree Panel 1 doi nhom theo anh Kiet FDC "Du an (Nam) > Hang muc cong viec > Phieu" (bo tang NCC, SHA256 mirror x2 app) + wipe testing data prod S59
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m27s
- Tree Panel 1: moi cap (Du an, Nam-tao-phieu) = 1 folder label "Ten du an (Nam)",
  level 2 = Hang muc cong viec (WorkItemId Mig 49, phieu cu null -> "(Chua gan hang muc)"),
  bo tang NCC khoi tree (van hien o card/detail). Expand-state localStorage key v2.
- scripts/s59-wipe-testing-data.sql DA CHAY prod (anh chot AskUserQuestion): xoa 10 PE
  + 7 HD [DEMO] + 64 notif + 1 workflow V2 cu inactive; reset PeSeq/CtSeq -> ma moi tu 001;
  GIU master 70/86/22 + users 55 + templates 9 + 7 workflow ghim. Uploads orphan da don.
2026-06-11 15:35:25 +07:00
7feb53ee20 [CLAUDE] FE-Admin: redesign Phase 1 — density-first design system (NAMGROUP-ref, giữ brand)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m24s
Tham khảo NAMGROUP density conventions, GIỮ brand #1F7DC1 + Be Vietnam Pro.
- index.css: density heading ladder (semibold, drop font-bold) + .label-eyebrow util
- 6 UI primitives (Button/Input/Label/Select/Textarea/Dialog): text-xs font-semibold, py-1.5 ≤36px, rounded-lg, brand focus-ring
- 6 shell (DataTable sticky-thead+RowActions/Layout brand-rail/TopBar/PageHeader/PhaseBadge/EmptyState)
- DashboardPage flagship: KPI cards + brand-tinted icon chips + uppercase labels

Visual-only — functionality unchanged (Button variant/size keys stable 51 call-sites, props/forwardRef intact). build 0 TS err. reviewer PASS 0 blocker (2 minor slate-400 hint a11y defer). fe-admin only (fe-user mirror = Phase 3). Dashboard live-visual blocked by dev auth-rig → xem live sau deploy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:50:59 +07:00
69cb3937bb [CLAUDE] Master: nạp master data thật từ Excel (62 dự án + 71 hạng mục + 3 NCC) + Project +4 cột (Mig 48)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m33s
Nạp master data công ty từ file Excel 'HẠNG MỤC CÔNG VIỆC DỰ ÁN':
- 62 Projects (Mã + Năm; tên/CĐT/địa điểm/gói thầu cho ~6 dự án có chi tiết)
- 71 WorkItems: Vật tư 16 · Thầu phụ 30 · MEP 9 · Thiết bị 16
- 3 Suppliers (TRUONGGIANG/TANPHU/TGN)

Mig 48 AddProjectMasterFields: Project +4 cột nullable (Year/Investor/Location/Package) + ProjectFeatures DTO/Create/Update + ProjectsPage form ×2 app (SHA256 mirror).
SeedRealMasterDataAsync per-code idempotent, UNGATED → reaches prod (coexist demo). FLOCK01 collision → skip (demo wins).

Verify: build 0-err · test 216 PASS · runtime Dev proof (data landed, Investor col populates). Provenance: scripts/master-import-data.generated.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 09:27:04 +07:00
ca4b60277b [CLAUDE] Office: IT staff tự reassign ticket — authz Admin-OR-IT + capability endpoint (S54)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m17s
- BE: GetAssignableItStaffQuery {canReassign,staff} capability endpoint + AssignItTicketHandler authz Admin-OR-dept-IT (Forbidden) + assignee-must-IT (Conflict); controller /assign hạ [Authorize(Roles=Admin)]→[Authorize] (handler enforce fine-grained data-driven)
- FE: fe-admin + fe-user ItTicketsPage SHA256-identical (reverse S53 divergence), nút gate by canReassign, dropdown từ /assignable-staff (không /users)
- Test: +13 authz guard (203→216 PASS), reviewer PASS (role-string Admin chain-verified real)
- No migration (DepartmentId reuse), no menu change

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 16:12:14 +07:00
dbf66489a9 [CLAUDE] Office: P11-D ItTicket admin reassign-UI + P11-E AttendanceReport menu-key
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m21s
Task C - ItTicket admin reassign-UI (fe-admin only):
- Per-card reassign dialog on ItTicketsPage kanban (admin override of round-robin auto-assign).
- Reuses existing PUT /it-tickets/{id}/assign (Admin-only) + GET /users picker. No new BE endpoint.
- fe-admin intentionally diverges from fe-user (read-only) — admin-management action.

Task D - AttendanceReport menu-key (P11-E promote, no migration):
- MenuKeys.OffAttendanceReport 'Báo cáo chấm công' leaf under Văn phòng số (order 8), Admin-perm auto via All[].
- DbInitializer idempotent seed + fe-admin menuKeys.ts/Layout staticMap -> existing /attendance/report route.

Pipeline: implementer-backend -> implementer-frontend -> reviewer (PASS, 0 issues). dotnet+npm builds clean. Tests 203 (unchanged - no new BE logic/schema).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 15:00:30 +07:00
dcf76f8a9f [CLAUDE] Office: P11-D ItTicket auto-assign round-robin + SLA timer (Wave 2, Mig 46)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m17s
Mig 46 AddSlaFieldsToItTicket (SlaDueAt/SlaWarnedSent/SlaBreached). CreateItTicketHandler: round-robin least-loaded assign cho IT staff (dept Code=IT, tie-break Id) + SlaDueAt theo Priority (Urgent 4h/High 8h/Medium 24h/Low 72h). ItTicketSlaJob background (breach+warning notify, KHONG auto-transition). PUT /{id}/assign admin override. DbInitializer seed dept IT + 2 sample staff (nv.cao/nv.truong). FE ItTicketsPage +MaTicket+assignee+SLA badge (2 app SHA256 mirror). +9 test (191->200). Self-review PASS (seed<->query dept-code verified; em main solo review do session-limit kill reviewer-spawn).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 13:23:45 +07:00
6a664298fa [CLAUDE] Office: P11-E AttendanceReport+Excel+OtPolicy + P11-F MaTicket codegen (Wave 1)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m10s
P11-F: MaTicket gen-on-create qua WorkflowAppCodeGen (IT/2026/NNN Serializable atomic, kanban no-workflow). P11-E: GetAttendanceReportQuery monthly aggregate (day-type weekday/weekend/holiday OT x OtPolicy multiplier in-memory) + AttendanceReportExcelExporter (ClosedXML) + 2 endpoint Admin-only + fe-admin AttendanceReportPage. Migration-free. +5 test (186->191). reviewer PASS (gotcha #44 role-string verified, 0 blocker).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 12:34:48 +07:00
30a99aa03f [CLAUDE] Hrm: P11-C Vehicle+Driver catalogs (Mig 44) + gotcha #57 filtered-unique 3 HRM catalog (Mig 45)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m18s
P11-C: extend HrmConfigs +2 kind (Vehicle/Driver) declarative. Mig 44 AddVehicleAndDriverCatalogs (2 table filtered-unique Code, tables 91->93). Domain entity + EF config (filtered day-1) + 2 DbSet + HrmConfigFeatures Region5/6 CRUD + Controller +2 route-group (GET public / write Roles=Admin) + MenuKeys +2 +All (auto Admin perm) + DbInitializer 2 menu leaf + idempotent seed 2 veh/2 drv. FE declarative KIND_CONFIG +2 kind x2 app (SHA256 mirror) + 4-place (types/page/menuKeys/Layout staticMap), :kind-driven no new route.

gotcha #57 (bundled; OtPolicy missed in backlog, caught via grep) - Mig 45 FilterHrmCatalogUniqueIndexesByIsDeleted: LeaveType+ShiftPattern+OtPolicy bare .IsUnique() -> .HasFilter([IsDeleted]=0) (recreate-on-soft-deleted-slot 500 fix, mirror Holiday Mig 43). Tests +5 HrmConfigFilteredUniqueTests (181->186 PASS) test-before RED->GREEN. Reviewer caught FE<->BE Driver required-field mismatch -> fixed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-08 10:32:28 +07:00
350b2bfb28 [CLAUDE] FE-Admin/FE-User: login subtitle contrast a11y fix (slate-500 -> 600)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m12s
FD2 spawn-test outcome — login subtitle contrast ~4.6 -> ~7.5:1 over translucent
card (FD5 WCAG-AA floor). On-scale token, no layout shift. Mirror x2 app.
Build x2 PASS, 0 TS error. Test 181 unchanged (FE-only, no .cs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-03 00:06:18 +07:00
82d7fcff4d [CLAUDE] Workflow: LeaveBalance business logic — trừ phép khi duyệt + số dư (Phase 11 P11-B)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m8s
Số dư phép theo (User × LeaveType × Year) + trừ tự động khi đơn nghỉ duyệt cuối.
Policy: cho phép vượt số dư (âm) + cảnh báo (anh main chốt), tích hợp vào trang đơn nghỉ.

Schema (Mig 42 AddLeaveBalances — pure additive, 1 bảng):
- LeaveBalance: UserId + LeaveTypeId + Year + EntitledDays + UsedDays + AdjustmentDays.
  UNIQUE (UserId,LeaveTypeId,Year), FK LeaveType Restrict, decimal(5,2).
  Remaining = Entitled + Adjustment − Used (computed, không store).

Deduction hook (ApproveLeaveRequestHandler nhánh terminal DaDuyet — exactly-once):
- Upsert LeaveBalance(RequesterUserId, LeaveTypeId, StartDate.Year), auto-create từ
  LeaveType.DaysPerYear, UsedDays += NumDays. Guard Status!=DaGuiDuyet chặn re-approve.

FK invariant guard (em main thêm sau test reveal FK risk):
- Create + UpdateDraft validate LeaveTypeId tồn tại (AnyAsync) → ConflictException.
  Đóng cửa vào — bogus type không thể tới deduction FK insert (tránh 500 kẹt đơn).

CQRS LeaveBalanceFeatures.cs: GetMy (self, lazy merge active LeaveType) + GetUser (admin)
  + AdjustLeaveBalance (admin upsert carry-over). Controller [Authorize] + admin Roles=Admin.
Embed: GetLeaveRequestByIdHandler trả balance NGƯỜI TẠO (approver xem thấy đúng).
FE: WorkflowAppDetailPage ×2 — block "Số dư phép" + cảnh báo vượt khi kind=leave (SHA256 identical).

Tests (+11, 130→154 PASS): deduction single/multi-level/accumulate/negative-allowed/
  reject-return-no-deduct + lazy-merge + adjust upsert + Create guard bogus→Conflict.
  Cũng repair 2 test S42 terminal FK-fail (template BuildLeave +seed LeaveType).

Verify: build 0 error · 154 test · FE ×2 · reviewer Max PASS (deduction exactly-once +
  FK invariant fully closed, 2 minor concurrency/comment defer).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 11:10:44 +07:00
e47ef1d4ee [CLAUDE] FE-User: fix ProposalCreatePage workflow dropdown shape (latent S37 bug)
Follow-up cho bug flagged trong 75df04e. ProposalCreatePage (fe-admin + fe-user)
fetch /approval-workflows-v2 expect flat array, nhưng endpoint trả AwAdminOverviewDto
{types:[{applicableType, history:[...]}]} → workflows.data.map chạy .map trên object
→ TypeError/dropdown rỗng. Latent vì create-with-workflow chưa exercise UAT.

Fix: mirror pattern proven của ContractCreatePage + WorkflowAppDetailPage —
res.data.types.find(t=>t.applicableType===4)?.history.filter(isUserSelectable).
WorkflowDto +isUserSelectable. Render .map giữ nguyên (data giờ là array đúng).

Verify: tsc -b + vite build ×2 PASS (exit 0) · fe-admin/fe-user SHA256 identical
(91565D47...7697C771).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 10:19:17 +07:00
75df04ec82 [CLAUDE] Workflow: fix workflow picker 2 bug (P11-A Max re-review) + SetWorkflow endpoint
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m5s
Double-check chất lượng P11-A ở Max (agents trước chạy High + truncate 3×) →
phát hiện 2 bug THẬT trong workflow-picker FE của WorkflowAppDetailPage (core
approve/reject/return ĐÚNG, chỉ sub-flow chọn quy trình hỏng):

Bug #1 (HIGH) — pinWorkflow PUT /{id} chỉ gửi {approvalWorkflowId} → UpdateDraft
  validator (Reason NotEmpty, NumDays>0...) fail → 400. Nút "Lưu quy trình" vỡ.
Bug #2 (HIGH) — fetch workflow expect flat array nhưng endpoint trả
  AwAdminOverviewDto {types:[...]} → picker rỗng/crash. FE copy nhầm pattern hỏng
  của ProposalCreatePage thay vì PE/Contract proven.

Fix:
- BE: thêm endpoint chuyên dụng PUT /{id}/workflow + Set{Module}WorkflowCommand/Handler
  cho 4 module — chỉ set ApprovalWorkflowId trên draft Nhap/TraLai (verify ApplicableType
  per module), KHÔNG validate field khác. Single-responsibility, bulletproof.
- FE: sửa fetch mirror PE/Contract (data.types.find(t=>t.applicableType===X)?.history
  .filter(isUserSelectable)) + pin gọi endpoint mới. fe-admin+fe-user SHA256 identical.
- Test: +3 SetWorkflow (happy no-status-change / wrong ApplicableType Conflict / submitted
  guard) → 141→144 PASS.

Verify: BE build 0 error · 144 test PASS · FE build ×2 · SHA256 identical.
Bonus phát hiện: ProposalCreatePage (S37) có bug #2 có sẵn (latent, chưa exercise UAT)
  → flag spawn task riêng, KHÔNG fix trong commit này.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 10:14:34 +07:00
e7b66cd52b [CLAUDE] Workflow: wire ApproveV2 + LevelOpinions cho 4 WorkflowApps module (Phase 11 P11-A)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m6s
Wire full approval workflow V2 cho Leave/OT/Travel/Vehicle — cookie-cutter
mirror Proposal (Mig 38). Trước đây skeleton Phase 1 (Create+List), giờ
ApproveV2 advance-level + UPSERT LevelOpinion + atomic codegen.

Schema (Mig 41 WireWorkflowAppsApprovalV2 — 84→89 tables, pure additive):
- 4 bảng {Leave,Ot,Travel,Vehicle}LevelOpinions (UNIQUE composite + Cascade
  parent + Restrict Level — mirror ProposalLevelOpinion)
- 1 bảng WorkflowAppCodeSequences (shared atomic MaDonTu, Prefix-keyed)
- 4 cột RejectedFromStatus (smart return tracking)
- enum ApprovalWorkflowApplicableType.TravelRequest = 9

Application (LeaveOt + TravelVehicle ApprovalFeatures.cs — 30 handler):
- GetById detail (Include LevelOpinions + JOIN Step/Level) · UpdateDraft
- Submit (gen MaDonTu + DaGuiDuyet + level=1, verify ApplicableType per module)
- Approve (verify actor==ApproverUserId OR Admin, UPSERT opinion latest-write-wins,
  advance level OR terminal DaDuyet, empty comment → placeholder)
- Reject (→TuChoi) · Return (→TraLai + RejectedFromStatus)

Api: 4 controller +6 route mỗi cái (GET/{id}, PUT/{id}, submit/approve/reject/return)
Infra: DbInitializer seed 4 workflow V2 mẫu (QT-NP/OT/CT/XE-V2-001) → UAT test ngay
FE: WorkflowAppDetailPage.tsx declarative 4-kind (fe-admin+fe-user SHA256 identical)
  — workflow status + opinion timeline + action buttons; gỡ banner skeleton + row nav

Tests: +11 WorkflowAppApproveV2Tests (130→141 PASS) — state machine + UPSERT
  invariant + guards + codegen + forbidden + placeholder (Leave full + Ot smoke)

Verify: build 0 error · 141 test PASS · FE build ×2 · reviewer checklist
  (ApplicableType per-module + cross-module DbSet + [Authorize] — no copy-paste bug)
Known-minor (unreachable): Reject/Return actor-check skip nếu CurrentApprovalLevelOrder
  null — nhưng DaGuiDuyet luôn có set (defer hardening).
ItTicket KHÔNG đụng (kanban, no workflow V2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 09:44:00 +07:00
e54a22de0c [CLAUDE] Domain+App+Infra+Api+FE-Admin+FE-User: S38 G-O4+G-O5+G-O6+G-P1+G-H3 SKELETON full-stack
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m53s
Phase 10.3-10.4 SKELETON 5 plan combo finish — Mig 39+40 + BE skeleton 7 module +
FE 2 app SHA256 IDENTICAL + 11 menu key. UAT visible end-to-end.

⚠️ SKELETON Phase 1 trade-off rõ:
  - Status flat 5-state WorkflowAppStatus enum share Leave/OT/Travel/Vehicle
  - ApproveV2 workflow advance DEFER Phase 11 (Drafter Create OK, Approve flow chưa wire)
  - LevelOpinions per-module DEFER Phase 11
  - LeaveBalance calc + Auto-assign + SLA timer DEFER Phase 11
  - CodeGen atomic + MaDonTu/MaTicket gen DEFER Phase 11
  - Vehicle catalog + Driver catalog DEFER Phase 11 (free text VehicleLicense)
  - ItTicketComments thread DEFER Phase 11 (free text Resolution field)

Mig 39 (em main solo): 5 entity Workflow Apps schema
  - LeaveRequest (G-O4, FK LeaveType Hrm Mig 35, ApplicableType=5)
  - OtRequest (G-O4, FK OtPolicy optional, ApplicableType=6)
  - TravelRequest (G-O4, reuse ApplicableType=4 Proposal)
  - VehicleBooking (G-O5, free text vehicle, ApplicableType=7)
  - ItTicket (G-O6, NO workflow V2 — kanban status flow)

Mig 40 (em main solo): Attendance entity (G-P1)
  - GPS lat/long check-in/out + Source enum Web/Mobile/Device
  - UNIQUE composite (UserId, AttendanceDate)
  - WorkHours computed simple diff (NO OtPolicy multiplier yet)

BE CQRS (em main solo, single mega ~1100 LOC):
  - WorkflowAppsFeatures.cs 7 region (5 module Create+List + Attendance CheckIn/Out/GetMonth + HrDashboard)
  - 7 Controller: /api/leave-requests + /ot-requests + /travel-requests + /vehicle-bookings + /it-tickets + /attendances + /hr/dashboard
  - Class-level [Authorize] any authenticated
  - 13 endpoint total

FE 2 app (em main solo fallback gotcha #53 risk):
  - types/workflowApps.ts × 2 SHA256 IDENTICAL 77470e182a15de88 (all DTOs + Status badge)
  - WorkflowAppsListPage.tsx × 2 IDENTICAL 58139d0301a60ddf — generic declarative KIND_CONFIG handles 4 module (Leave/OT/Travel/Vehicle)
  - ItTicketsPage.tsx × 2 IDENTICAL d3062de2f54c794c — kanban 5 status column
  - MyAttendancePage.tsx × 2 IDENTICAL 86da48ae147db012 — GPS check-in/out + tháng calendar
  - HrmDashboardPage.tsx × 2 IDENTICAL d9c6c12a5a8694f8 — 4 KPI card + gender ratio + status breakdown
  - Pattern 16-bis 9× cumulative (App.tsx +4 routes + menuKeys +8 const + Layout staticMap +7 entry)
  - 7 amber banner "Skeleton Phase 1 — full feature Phase 11" rõ ràng UAT

Menu seed: +11 const + SeedMenuTreeAsync 8 row (Off_DonTu sub-group + 3 leaf + Off_DatXe + Off_ItTicket + Off_ChamCong + Hrm_Dashboard).
DbInitializer Sample workflow seed DEFER (workflows V2 already seeded từ S29+S37 reuse — admin clone tạo riêng per ApplicableType=5/6/7).

Verify:
- dotnet build PASS 0 error 2 pre-existing warning
- dotnet test 130/130 PASS baseline preserve
- npm build × 2 PASS clean
- SHA256 verify 5 file × 2 app all IDENTICAL

Plan G-* progress 11/11  (100% COMPLETE):
   G-H1 (S33) + G-O1 (S34) + G-H2 (S35) + G-O2 (S36) + G-O3 (S37) +
   G-O4 + G-O5 + G-O6 + G-P1 + G-H3 (S38 skeleton)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 16:19:42 +07:00
de1c378279 [CLAUDE] Domain+App+Infra+Api+FE-Admin+FE-User: S37 Mig 37 enum + Plan G-O3 Đề xuất full-stack
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m53s
Phase 10.3 G-O3 Đề xuất (Proposal) — Mig 37 enum extend +5 values + Mig 38
Proposal schema + BE CQRS 8 endpoint + FE 2 app SHA256 IDENTICAL.

Mig 37 (em main solo): extend ApprovalWorkflowApplicableType enum +5 values
  ProposalGeneral=4 / LeaveRequest=5 / OtRequest=6 / VehicleBooking=7 / ItTicket=8
  cookie-cutter Mig 22 pattern (Up/Down empty — enum mức Domain).

Mig 38 (em main solo): 4 entity Proposal (Code DX/YYYY/NNN) + ProposalAttachment
  + ProposalLevelOpinion (UNIQUE composite PEId+LevelId mirror PE Mig 26) +
  ProposalCodeSequence (Prefix PK atomic seq). 4 EF Config + 2 DbContext mod.

BE CQRS (em main solo ~700 LOC ProposalFeatures.cs sau Implementer truncate phase
exploration gotcha #53 5th + 529 Overload):
  - 4 Header handler (List paged + GetById detail + Create + UpdateDraft owner-OR-admin)
  - 4 Workflow handler (Submit gen MaDeXuat atomic + Approve UPSERT LevelOpinion advance + Reject + Return)
  - SERIALIZABLE transaction CodeGen
  - DTOs nested LevelOpinion với Step+Level metadata JOIN

ProposalsController 8 endpoint /api/proposals (List/GetById/Create/Update/Submit/Approve/Reject/Return)
class-level [Authorize] + handler-level owner-OR-admin guard.

DbInitializer: SeedSampleProposalWorkflowV2Async ~40 LOC seed QT-DX-V2-001 IsUserSelectable=true
NOT gated DemoSeed per gotcha #51. SeedMenuTreeAsync +4 row (Off_DeXuat sub-group + 3 leaf).

FE 2 app (em main solo + Implementer 529 fail fallback):
  - types/proposal.ts × 2 SHA256 IDENTICAL 95607052ff1138f2
  - ProposalsListPage.tsx × 2 IDENTICAL 603f0d9cf74cd09a — table 6 cột + Status badge + filter
  - ProposalCreatePage.tsx × 2 IDENTICAL 6aed3a76563dd576 — Form Header card
  - ProposalDetailPage.tsx × 2 IDENTICAL 3dc229ea8dcc9bc0 — 3 Section + WorkflowActions
  - Pattern 16-bis 8× cumulative (App.tsx + menuKeys + Layout staticMap 3 entry)

Verify:
- dotnet build PASS 0 error 2 warning pre-existing DocxRenderer
- dotnet test 130/130 PASS baseline preserve
- npm build × 2 PASS (fe-admin 14.72s + fe-user 6.40s)
- SHA256 verify 4 file × 2 app all IDENTICAL

Pattern reinforced cumulative S37:
- Pattern 12-bis cross-module mirror 11× (PE V2 → Proposal V2 ApproveV2)
- Pattern 16-bis 4-place mirror cross-app 8×
- gotcha #53 5th occurrence Implementer mid-exploration truncation + 529 Overload 1× — em main solo fallback proven

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 15:51:14 +07:00
f45090b654 [CLAUDE] Domain+App+Infra+Api+FE-Admin+FE-User: S36 Plan G-O2 Phòng họp Mig 36 + BE CRUD + FE 2 app
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m55s
Phase 10.2 G-O2 Phòng họp BookingCalendar — Mig 36 schema + BE CQRS + FE 2 app
mirror cookie-cutter G-H2 HrmConfig pattern. Standalone không depend workflow.

BE schema (Mig 36 — em main solo Step 4):
- 4 Domain new: MeetingRoom catalog + MeetingBooking header + MeetingBookingAttendee
  join table N-to-N (NOT JSON per Investigator verdict) + Enums (MeetingBookingStatus
  3-state: Confirmed/Cancelled/Completed)
- 3 EF Config: UNIQUE Code + composite index (RoomId, StartAt) range query + UNIQUE
  composite (BookingId, UserId) join
- FK strategy: Room→Restrict (preserve history) + Booking→Cascade attendees +
  User→Restrict (denorm FullName+Email tránh cascade wipe)
- Mig 36 3-file rule + ApplicationDbContextModelSnapshot updated + apply Dev+Design DB

BE CQRS (~584 LOC — Implementer Case 2):
- MeetingFeatures.cs 479 LOC 9 handler: 4 Room CRUD + 5 Booking (List + GetById +
  Create + Update + Cancel)
- SERIALIZABLE transaction overlap check via EXISTS query — throw 409 Conflict
  "Phòng đã được đặt trong khoảng thời gian này"
- MeetingRoomsController 49 LOC + MeetingBookingsController 56 LOC — class-level
  [Authorize] + Roles="Admin" for write
- Application.csproj +Microsoft.EntityFrameworkCore.Relational package (em main fix
  IsolationLevel overload — Implementer gotcha #53 4th truncation diagnose mid-task)
- MenuKeys.cs +4 const (Off_PhongHop sub-group + View/Manage/Book leaf)
- DbInitializer +SeedMeetingRoomsAsync 4 sample (PH-A Phòng họp lớn cap=20 + PH-B
  cap=8 + PHG-501 Giám đốc cap=6 + ONL-1 Online Zoom cap=50) — NOT gated DemoSeed
  per gotcha #51 INFRASTRUCTURE seed

FE 2 app (~1770 LOC × 2 — Implementer Case 2):
- types/meeting.ts × 2 SHA256 IDENTICAL (ce0ad9c6d017cde2) — DTO interface mirror
- MeetingCalendarPage.tsx × 2 SHA256 IDENTICAL (d6d160ae1e4f2285) ~530 LOC — custom
  HTML 7-day grid 8h-20h slot, NO FullCalendar dep (~80 KB bundle saved per
  Investigator verdict alternative)
- MeetingRoomsPage.tsx × 2 SHA256 IDENTICAL (ba35a7ef379a5e9c) ~270 LOC — admin
  catalog CRUD table + Dialog
- 4-place mirror Pattern 16-bis 7× cumulative: types + page + App.tsx route +
  menuKeys + Layout staticMap 3 entry (gotcha #50 silent sidebar drop prevention)

Verify:
- dotnet build SolutionErp.slnx PASS 0 error 2 pre-existing DocxRenderer warning
- dotnet test 130/130 PASS baseline preserve (58 Domain + 72 Infra)
- npm build × 2 app PASS 0 TS error (fe-admin 16.91s bundle 1490 KB / fe-user 8.56s
  bundle 1404 KB, +23 KB gzip both)

Pattern reinforced cumulative S36:
- Pattern 12-bis cross-module mirror 10× (PE → Contract V2 → Hrm → Office)
- Pattern 16-bis 4-place mirror cross-app 7×
- Smart Friend Implementer truncation gotcha #53 4th — mitigation tight brief WORK
  (FE 2 app no truncation, BE truncate diagnose mid only)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 15:06:12 +07:00
021674a66a [CLAUDE] FE-Admin+FE-User: S35 Plan G-H2 Task 4 — HrmConfigsPage declarative 4 catalog × 2 app
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m37s
Pattern 12-bis × 16-bis cookie-cutter cumulative 9× (Smart Friend Implementer catch).
Single page declarative KIND_CONFIG Record + URL `:kind` param + 4 sub-tab mirror
Master/Catalogs/CatalogsPage.tsx 321 LOC pattern. 4 catalog HRM (LeaveTypes/Holidays/
Shifts/OtPolicies) wire BE 16 endpoint /api/hrm-configs/{kind} từ commit `909655c`.

## Scope (Implementer Case 2 ~25K spawn)
- types/hrm-config.ts (NEW 98 LOC × 2 app SHA256 IDENTICAL `228917e5fac2cdc6`)
- HrmConfigsPage.tsx (NEW ~470 LOC × 2 app SHA256 IDENTICAL `6378fbc71ff90260`)
- App.tsx +3 LOC × 2 app (route + Navigate redirect default `/hrm/configs` → `leave-types`)
- Layout.tsx staticMap +6 LOC × 2 app — Pattern 16-bis 4-place enforcement
  (em main spec line 24 GAP — Smart Friend Implementer caught + fixed proactive)

## 4 kind FieldDef declarative
- leave-types: code/name/daysPerYear/isPaid/requiresAttachment/description
- holidays: year/date/name/isRecurring/isPaid/description
- shifts: code/name/startTime/endTime/breakMinutes/workDays(multiselect-weekday)/description
- ot-policies: code/name/multiplier×3/maxHours×3/description

## Pattern 16-bis 4-place mirror Pattern 16-bis 6× cumulative
- types/hrm-config.ts (place 1)
- pages/hrm/HrmConfigsPage.tsx (place 2)
- App.tsx routes (place 3)
- Layout.tsx staticMap (place 4 — em main MISS, Implementer caught via gotcha #50 prior knowledge)

## Verify
- npm build × 2 PASS (fe-admin 14.33s + fe-user 744ms, 0 TS error)
- SHA256 IDENTICAL × 2 NEW pair (types + page)
- Reviewer pre-commit PASS Cat A-D clean (5K token tight scope no truncation)
- gotcha #50 silent sidebar drop prevention — Pattern 16-bis discipline reinforced
- Smart Friend 9× clean cumulative S22+S25+S29×2+S33×2+S35×3

## Multi-agent ROI S35 chunk 3 ~30K
- Implementer Case 2 declarative single-page mega + spec gap catch
- Reviewer tight 5K verdict Cat A-D PASS

## State delta S35 cumulative
- 0 mig add (Mig 35 schema S34)
- 0 BE endpoint add (16 endpoint commit `909655c`)
- +1 FE page (HrmConfigsPage) × 2 app routes
- Pattern 12-bis cumulative 3× + Pattern 16-bis 6× + Pattern 12-ter 6× (FE forms)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 10:01:43 +07:00
c3cd343bae [CLAUDE] FE-Admin+FE-User: S35 Phase 1.5 Item 3-FE — inline forms 5 satellite cookie-cutter
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m51s
Pattern 12-ter (within-module N-satellite) × Pattern 16-bis (cross-app mirror) cumulative
6×. FE inline expandable form Add/Edit/Delete cho 5 satellite EmployeeProfile (WorkHistory
+ Education + FamilyRelation + Skill + Document) — close Phase 1.5 backlog Item 3 FE side.

## Scope (Implementer Case 2 ~30K spawn)
- Section component extend optional `actions?` prop (backward-compat 100%)
- 5 inline form components per app: WorkHistory/Education/FamilyRelation/Skill/Document
- 3 DRY helpers: FormField + FormFooter + RowActions (45 usage site)
- DRY helper `invalidate()` line 268 — 15 mutations × 1 shared = clean
- 5 Input types append types/employee.ts (CreateEmployeeWorkHistoryInput + 4 more)
- 15 useMutation per app (5 sat × 3 verb) = 30 total cross-app
- Wire BE 15 endpoint S34 ready: POST/PUT/DELETE /api/employees/{id}/{satellite-path}
- gotcha #44 mitigation ACTIVE: per-action policy Hrm_HoSo.{Create|Update|Delete}

## Stats
- fe-admin EmployeesListPage.tsx 573 → 1200 LOC (+627, +110%)
- fe-user EmployeesListPage.tsx mirror SHA256 IDENTICAL `802d01fd1ee79925`
- 2 types file +53 LOC each, SHA256 IDENTICAL `db29156a61af76e9`
- npm build × 2 PASS (fe-admin 31.57s + fe-user 23.39s, 0 TS error)
- BE files NOT touched (15 endpoint scaffold S34 ready)
- Test gate 130 PASS baseline preserve (FE-only)

## Multi-agent ROI S35 ~70K
- Implementer Case 2 ~30K (FE cookie-cutter scaffold)
- Investigator ~8K (G-H2 BE CRUD pre-flight, defer Plan G-H2 next chunk)
- Reviewer pre-commit ~15K Cat 1 wire BE PERFECT + em main verify Cat 2-6 PASS
- CICD warm-up ~15K (Run #241 baseline verified + standby S35 push)

Smart Friend 7× clean cumulative S22+S25+S29×2+S33×2+S35.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 09:38:56 +07:00
ea440da990 [CLAUDE] Domain+App+Api+Infra+FE-Admin+FE-User: S34 Plan 2 G-O1 Danh bạ nội bộ
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m46s
Phase 10.2 Văn phòng số — Internal Directory (1 endpoint reuse Users +
EmployeeProfiles + Departments, FE card grid avatar/dept/email/phone/Ext).

BE Task 1+2 (em main solo):
- Application/Office/DirectoryFeatures.cs — GetDirectoryQuery + DirectoryItemDto
  12 field LEFT JOIN Users.IsActive + Departments + EmployeeProfiles
- Api/Controllers/DirectoryController.cs — GET /api/directory?search=&departmentId=
  class-level [Authorize] (mọi authenticated NV tra cứu danh bạ nội bộ)
- MenuKeys.cs +Off+OffDanhBa const + All[] update
- DbInitializer.SeedMenuTreeAsync Off Order=29 + OffDanhBa Order=1 dưới Off

FE Task 3 (Implementer Case 2 Pattern 16-bis 4-place mirror cross-app — 5×):
- types/directory.ts SHA256 7349d9f64e78 × 2 app IDENTICAL
- pages/office/InternalDirectoryPage.tsx SHA256 2aa7e0eed2c8 × 2 app IDENTICAL
  Card grid responsive 1/2/3/4 col + filter dept dropdown + search input
  Avatar 14×14 initials gradient PALETTE 6 màu (Pattern 14 Tailwind JIT)
  EmployeeCode badge + Department emerald badge + email mailto + phone tel
  Internal phone Ext: amber badge + empty/loading state Vietnamese 100%
- App.tsx route /directory × 2 app
- lib/menuKeys.ts Off+OffDanhBa const × 2 app
- components/Layout.tsx resolvePath staticMap Off_DanhBa:/directory × 2 app
  (gotcha #50 — 5 places mirror crossapp DON'T MISS)

Verify:
- dotnet build PASS (2 warn DocxRenderer existing, 0 error)
- dotnet test 120/120 PASS (58 Domain + 62 Infra baseline preserve)
- npm build × 2 app PASS 0 TS err (fe-admin 1436KB / fe-user 1350KB)

Implementer MEMORY Pattern 16-bis reinforced 5× cumulative (S29 Plan CA HF1 +
S29 Plan B Chunk D + S33 Plan B G-H1 Task 5 + S34 Plan G-O1 Task 3).

Endpoint smoke pending CICD post-deploy Stage 4 (Run #XXX expected ~3m30s).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 13:39:10 +07:00
9616ae219c [CLAUDE] FE-Admin+FE-User: Plan B G-H1 Task 5 — EmployeesPage 2-panel + EmployeeCreatePage cookie-cutter mirror
Phase 10.1 G-H1 Phase 2 Task 5 — FE 2 app cookie-cutter mirror PE pattern.
Phase 1 ULTRA-MINIMAL scope (Implementer afdc812 scaffold):
- 2-panel ListPage (filter left + list+detail right, KHÔNG 3-panel vì Hrm
  no workflow)
- 6-section inline collapsible detail (Cơ bản/Công tác/Đào tạo/Thân nhân/
  Kỹ năng/Hồ sơ) — NO separate DetailTabs component file
- CreatePage Header form minimal (UserId picker + Status + DateOfBirth +
  Gender + Phone + HireDate + Nationality)
- Display read-only Phase 1 satellite (no inline edit — defer Phase 1.5)

## Files (6 new + 6 modified × 2 app = 12)

### NEW (3 × 2 app, SHA256 IDENTICAL cross-app mirror)

| File | LOC | SHA256 prefix |
|------|----:|---|
| `fe-{admin,user}/src/types/employee.ts` | 283 | CCFC70666568 |
| `fe-{admin,user}/src/pages/hrm/EmployeesListPage.tsx` | 417 | DC859C897C5C |
| `fe-{admin,user}/src/pages/hrm/EmployeeCreatePage.tsx` | 178 | C796F25D01AC |

10 const-object enum mirror BE Domain.Hrm.Enums + DTOs:
- EmployeeStatus/Gender/MaritalStatus/EmployeeType/DegreeLevel/
  EducationMode/GradeLevel/FamilyRelationKind/SkillKind/EmployeeDocumentType
- EmployeeListItem + EmployeeDetail + 5 satellite DTO type

### MODIFIED (3 × 2 app)

- `fe-{admin,user}/src/lib/menuKeys.ts` — +Hrm + HrmHoSo const
- `fe-{admin,user}/src/components/Layout.tsx` — +Hrm_HoSo:'/employees' staticMap
  (LESSON Plan CA Hotfix 1 gotcha #50: page route mới phải thêm staticMap
  entry cùng commit, else silent sidebar drop)
- `fe-{admin,user}/src/App.tsx` — +2 route /employees + /employees/new

## Pattern reinforcement

- **Pattern 16-bis 4-place mirror cross-app** reinforced 4× cumulative (S29
  Plan CA HF1 + S29 Plan B Chunk D + S33 Task 5 admin + S33 Task 5 user).
  Comment header trong Layout.tsx ghi explicit Plan CA Hotfix 1 #50 lesson.
- **Pattern 12-bis cross-module entity FE port PE → Hrm** reinforced 4× (Plan
  B Chunk C Mig 33 + G-H1 Task 4 BE + Task 5 FE types mirror PE types/page
  structure mirror PE 2-panel scope-down 3→2 panel).

## Reviewer ae752c0 verdict: PASS (commit 0e191de earlier)

- Smart Friend 6× cumulative clean (em main + Implementer quality genuine)
- gotcha #50 Layout staticMap mirror ✓ (cả fe-admin + fe-user)
- menuKeys.ts FE drift pre-existing intentional (fe-admin minimal vs fe-user
  expanded Catalogs/Suppliers/Projects/Departments) — NOT blocking, follow-up
  task add Budgets/Catalogs to fe-admin OR document intentional minimal scope.

## Verify

- fe-admin npm build: PASS 21.4s · 0 TS6 err · 1,431 KB bundle
- fe-user npm build: PASS 9.2s · 0 TS6 err · 1,345 KB bundle
- dotnet build: PASS 1.59s · 0 warn 0 err (no BE change)
- dotnet test: 120/120 PASS baseline preserved

## Defer Phase 1.5 (per Reviewer recommend)

1. PermissionGuard wrapper menuKey HrmHoSo + per-action Hrm_HoSo_View/Create
2. Convert 3 bool field UpdateCommand thành bool? safe partial update
3. Satellite CRUD endpoint + form (WorkHistory/Education/FamilyRelation/
   Skill/Document)
4. Test bundle (Create UNIQUE conflict + List filter + codeGen race)
5. Add Bg_*/Catalog* to fe-admin menuKeys.ts sync với fe-user

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 20:27:25 +07:00
62b50d112b [CLAUDE] FE-Admin+FE-User: Plan B Chunk D — ContractCreatePage Workspace V2 Select dropdown
Mirror PE PeWorkspaceCreateView Workspace pattern. Drafter pick V2
workflow IsUserSelectable=true filter ApplicableType=Contract(3).

Changes × 2 app:
- Add useQuery fetch /api/approval-workflows-v2?applicableType=3 + filter
  client-side isUserSelectable=true (mirror PE Mig 25 pattern)
- Add Select dropdown "Quy trình duyệt V2 (tùy chọn)" trong
  ContractHeaderForm (create mode panel 2)
- Wire approvalWorkflowId vào CreateContractCommand POST body
- Conditional UI: blank = V1 fallback auto pick (7 prod contract behavior
  giữ nguyên); user pick V2 → pin ApprovalWorkflowId Mig 32 schema
- Hint khi 0 workflows V2 admin ghim → message rõ V1 fallback

Verify:
- npm run build × 2 app PASS 0 TS err (1.32MB fe-user, 1.40MB fe-admin)
- Mirror 2 app §3.9: +44 LOC mỗi file = +88 LOC total byte-similar
- API endpoint /api/approval-workflows-v2 existing (Mig 25 Plan AA S24)
- BE CreateContractCommand.ApprovalWorkflowId field đã add Chunk E1
  (em main commit prior) — FE wire safe
- Backward compat: V1 contract path unchanged khi user bỏ trống dropdown

Plan B chain (6 chunks):
- A1 58898e8  Entity ApprovalWorkflowId + CurrentApprovalLevelOrder
- A2 a85e437  Mig 32 + Seed sample V2 Contract workflow
- B 138469d  Service ApproveV2 branch (PE pattern mirror)
- C 26c98d3  Mig 33 ContractLevelOpinions
- B2 1f199b0  UPSERT LevelOpinion block (PE Mig 26 mirror)
- D (this)  FE Workspace V2 dropdown
- E FE Section 5 V2 (em main + Implementer split E1+E2 sau)

Pattern 16-bis 4-place mirror check:
- Page file × 2 app: edited (insertion mirror byte-similar)
- App.tsx Routes: N/A (enhance existing /contracts/new route)
- menuKeys.ts: N/A (không thêm menu key mới)
- Layout staticMap: N/A (route unchanged)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 12:34:00 +07:00
d99069a305 [CLAUDE] FE-User+FE-Admin: Plan AG6 — Compact PE card 3 row gọn đẹp
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m21s
Anh feedback 2026-05-21: "Cho thông tin bên trong này nó gọn đẹp lại nhé".
PE card hiện 4-5 row hơi dài. Compact xuống 3 row tightly packed:

Row 1: [Tên gói thầu]                        [Status badge]
Row 2: PE/2026/A/035 · 10:40 19/05/2026
Row 3: 👤 Drafter · Phòng ban                [✓ HĐ if any]

Changes:
- py-2.5 → py-2 (compact vertical padding)
- Drop Type label "Duyệt NCC" badge redundant (page header đã hiện)
- Combine maPhieu + createdAt vào 1 row với separator ·
- Combine drafter + department + contract badge vào 1 row (conditional render)
- "✓ Đã tạo HĐ" → "✓ HĐ" short label inline cuối row 3
- Separator color slate-300 nhẹ hơn slate-500

Verify:
- npm build fe-user PASS 0 TS err 1292.66 KB (gzip 337.19 KB)
- npm build fe-admin PASS 0 TS err 1404.01 KB (gzip 357.70 KB)
- 2 file SHA256 IDENTICAL 3645307C... (mirror §3.9)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 22:50:14 +07:00
083b601ea4 [CLAUDE] FE-User+FE-Admin: Plan AG5 — PE List tree 3-level Project > Năm > NCC > PE
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m32s
Anh feedback 2026-05-21: "Folder cấp dưới dự án là theo năm và dưới năm là theo NCC nhé".
Plan AG3 chỉ 1-level Project > PE. Plan AG5 extend xuống 3 cấp: Năm + NCC.

Group structure:
- Level 1: 📁 Project (bg-slate-50, font-medium 13px)
- Level 2: 📅 Năm {year} (border-l ml-3, 12px)
- Level 3: 🏢 NCC (border-l ml-3, 12px, italic slate-400 nếu "Chưa chọn NCC")
- Leaf: PE card (border-l ml-3, giữ nguyên content)

Sort:
- Project A-Z (vi locale)
- Năm DESC (2026 trước 2025)
- NCC A-Z (vi locale)
- PE within NCC: createdAt DESC

Fallback:
- empty projectName → "(Dự án đã xoá)"
- selectedSupplierName null (PE chưa DaDuyet) → "(Chưa chọn NCC)" group + italic style

Drop redundant selectedSupplierName line trong PE card (đã hiện ở NCC group header).

localStorage keys:
- Project: projectId
- Năm: `${projectId}::y${year}`
- NCC: `${projectId}::y${year}::s${supplierId|'_none_'}`

Verify:
- npm build fe-user PASS 0 TS err 1292.68 KB (gzip 337.18 KB) 1907 modules
- npm build fe-admin PASS 0 TS err 1404.02 KB (gzip 357.70 KB) 1926 modules
- 2 file SHA256 IDENTICAL E5FE4979... (mirror §3.9)
- KHÔNG BE change, KHÔNG Mig, KHÔNG test (UAT mode)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 22:41:58 +07:00
2bf01184ca [CLAUDE] App+FE-User+FE-Admin: Plan AG4 — bổ sung Drafter + Department vào PE List card
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m27s
Anh UAT 2026-05-21: PE card danh sách thiếu người tạo + phòng ban tạo. Bổ sung 4 field
qua BE JOIN Users + Departments LEFT (cả 2 nullable theo PE entity).

BE — 4 file:
- PurchaseEvaluationDtos.cs: +4 fields DrafterUserId/DrafterName/DepartmentId/DepartmentName
- PurchaseEvaluationFeatures.cs ListHandler: JOIN Users + Departments LEFT, projection +4
- PurchaseEvaluationFeatures.cs InboxHandler: mirror JOIN + projection +4
- CreateContractFromEvaluationFeatures.cs ListApproved: mirror JOIN + projection +4

FE — 4 file × 2 app mirror:
- types/purchaseEvaluation.ts: PeListItem +4 fields
- pages/pe/PurchaseEvaluationsListPage.tsx: PE card render thêm dòng "👤 {drafterName} · {departmentName}"
  giữa Mã phiếu và Supplier. Conditional: chỉ render khi có ít nhất 1 field.

Verify:
- dotnet build clean 0 err
- dotnet test SolutionErp.slnx 111/111 PASS (58 Domain + 53 Infra) — no regression
- npm build fe-user PASS 0 TS err 1290.31 KB (gzip 336.79 KB) 1907 modules
- npm build fe-admin PASS 0 TS err 1401.66 KB (gzip 357.30 KB) 1926 modules
- 2 FE PE List file SHA256 IDENTICAL C6996194... (mirror §3.9)
- KHÔNG Mig (chỉ DTO + projection extend)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 18:52:04 +07:00
fbad4a9251 [CLAUDE] FE-User+FE-Admin: Plan AG3 — PE List tree consistent (drop single-PE flat branch)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m19s
Anh feedback 2026-05-21: "nếu có 1 thì cũng để tương tự luôn nhé, đừng để khác các thằng kia".
Plan AG2 render single-PE project flat card + UPPERCASE label phía trên — khác phong cách
với multi-PE project (folder <details>). UX inconsistent.

Plan AG3 drop nhánh single-PE flat. Mọi dự án dù 1 hay nhiều PE đều render <details>
folder collapsed với badge count "(N)" — consistent visual.

Diff: -60 LOC (drop entire single-PE flat block).

Verify:
- npm build fe-user PASS 0 TS err
- npm build fe-admin PASS 0 TS err
- 2 file SHA256 IDENTICAL 749FF703... (mirror §3.9)
- KHÔNG BE change, KHÔNG Mig, KHÔNG test (UAT mode)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 18:35:25 +07:00
c5429c0d10 [CLAUDE] FE-User+FE-Admin: Plan AG2 — Simplify PE List tree 1-level + Panel 1 widen 400px
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m29s
Anh feedback Plan AG (2-level Project > Gói thầu > PE) cầu kỳ quá. Simplify
xuống 1-level + widen panel cho dễ đọc.

3 changes:
1. Panel 1 widen 340px → 400px (lg:grid-cols-[400px_1fr_360px])
2. Drop GoiThauGroup nested type + inner <details> tree, useMemo group 1-level
   Project > PE[]; PE sort by createdAt DESC trong group (mirror BE sort)
3. Smart render: single-PE project → flat card (no <details> wrapper, project
   name UPPERCASE label inline) / multi-PE project → <details> tree expand
4. localStorage key rename 'pe_list_expanded_projects' (drop ::gtKey composite suffix)

UAT visual: dự án solo PE hiện flat (không cần click expand), dự án có nhiều
phiếu render tree compact.

Drop redundant projectName ở PE card (đã có ở group header / UPPERCASE label).

Verify:
- npm build fe-user PASS 0 TS err 1291.76 KB (gzip 336.90 KB) 1907 modules
- npm build fe-admin PASS 0 TS err 1403.10 KB (gzip 357.41 KB) 1926 modules
- 2 file SHA256 IDENTICAL 37520D01... (mirror §3.9)
- KHÔNG BE change, KHÔNG Mig, KHÔNG test (UAT mode per feedback_uat_skip_verify)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 18:24:59 +07:00
0bf6c7ec63 [CLAUDE] FE-User+FE-Admin: Plan AG Chunk A+B+C — PE List tree view 2-level Project > Gói thầu
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m39s
UAT feedback bro Tra Sol 2026-05-21: UI Duyệt NCC flat list "đám rừng" → tree view giống Outlook folder.

Phase 1 FE-only mirror 2 app §3.9 — KHÔNG schema mới (Phase 2 ProjectPackage defer sau UAT confirm).

Chunk A — Data transform useMemo group:
- Map<projectId, Map<normalizedGoiThau, PeListItem[]>>
- Normalize TenGoiThau: trim + toLowerCase, display raw đầu tiên trong group
- Sort: Project A-Z + gói thầu A-Z (vi locale)
- Fallback: "(Dự án đã xoá)" empty projectName + "(Chưa phân loại)" empty TenGoiThau
- Filter (pendingMe → DaGuiDuyet) áp dụng TRƯỚC group

Chunk B — UI render <details>/<summary> 2-level:
- Replace flat <ul><li> bằng nested <details> HTML native (no shadcn Accordion — gap component lib)
- 📁 Project + 📄 Gói thầu icon + count badge inline
- Chevron rotation via Tailwind group-open/proj + group-open/gt named groups
- PE card content preserve nguyên (line 209-248 unchanged)

Chunk C — Expand state localStorage persist:
- Key 'pe_list_expanded_groups' Set<string>
- Project level key: projectId; Gói thầu level key: ${projectId}::${normalizedGoiThau}
- Default empty Set (all collapse) — bro Tra Sol expect Outlook-style closed default

Verify:
- npm build fe-user PASS 0 TS err 1291.33 KB (gzip 337.00 KB) 1907 modules 16.05s
- npm build fe-admin PASS 0 TS err 1402.68 KB (gzip 357.51 KB) 1926 modules 6.86s
- KHÔNG BE change, KHÔNG Mig, KHÔNG test (UAT mode per feedback_uat_skip_verify)

Pending: Reviewer pre-commit + CICD Run #222 verify

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 17:46:17 +07:00
83c9f7b45d [CLAUDE] PurchaseEvaluation FE-Admin FE-User: Chunk L5 — PE list UX: ngày tạo thay SLA countdown + sort UpdatedAt DESC
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m10s
Bro UAT S23 t2 yêu cầu 2 UX changes PE list:

1. Đổi "Còn N ngày Mh" (SlaTimer countdown) → "DD/MM/YYYY HH:mm" (ngày giờ tạo phiếu).
2. Sort: phiếu vừa update (Tạo / Gửi duyệt / Trả lại) đưa lên đầu, phiếu cũ phía dưới.

BE changes:
- PurchaseEvaluationListItemDto +UpdatedAt: DateTime? field (auto AuditingInterceptor refresh
  mọi SaveChanges — covers Insert/Update/Transition events natural).
- ListPurchaseEvaluationsQueryHandler sort: OrderByDescending(UpdatedAt ?? CreatedAt)
  (was: OrderByDescending(CreatedAt)).
- GetMyPurchaseEvaluationInboxQueryHandler sort: OrderByDescending(UpdatedAt ?? CreatedAt)
  (was: OrderBy(SlaDeadline ?? MaxValue) — SLA priority deprecated).
- CreateContractFromEvaluationFeatures.cs: +UpdatedAt arg trong DTO ctor (compile fix
  consumer downstream).
- Select projection 3 callsites populate UpdatedAt.

FE × 2 app (mirror rule §3.9):
- PeListItem type +updatedAt: string | null (optional — null khi phiếu chưa Update).
- PurchaseEvaluationsListPage: replace <SlaTimer deadline={p.slaDeadline} ... /> với
  Vietnamese date format "{DD/MM/YYYY HH:mm}" qua Intl.DateTimeFormat (vi-VN locale,
  full date+time options). title tooltip hiện full timestamp.
- Remove SlaTimer import (unused warning).

UpdatedAt sort logic insight: AuditingInterceptor (Infrastructure) auto-refresh
UpdatedAt mọi SaveChanges → mọi event tự nhiên (Drafter tạo / Gửi duyệt từ Workspace
/ Approver duyệt Cấp tiếp / Approver trả lại / Admin override) đều bump UpdatedAt
→ phiếu vừa action lên đầu list. Phiếu mới Insert UpdatedAt=null → fallback CreatedAt
→ vẫn lên đầu (vì CreatedAt vừa now).

Verify:
- dotnet build production projects clean (0 err, 2 pre-existing warn)
- dotnet test SolutionErp.slnx 104/104 PASS (DTO change KHÔNG impact test — tests
  don't construct ListItemDto)
- npm run build × 2 app pass clean

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 01:53:19 +07:00
098baa6da6 [CLAUDE] Docs: Chunk G — K8 Plan K wrap S23 t1: docs + session log + Designer comment cleanup + 3 agent MEMORY drift
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m30s
Plan K Mig 31 F2 refactor sang per-Approver-slot DONE — 8 commits cumulative
S23 t1 (`56868bf..<this>`). K8 wrap docs + dirty MEMORY.md commit:

Docs updates:
- docs/STATUS.md: Last updated S23 t1 entry với Plan K summary 8 chunk
- docs/HANDOFF.md: TL;DR S23 t1 đầy đủ (top) — multi-agent ROI evidence
- docs/database/schema-diagram.md §14: title Mig 22-31 (was 22-29) + add
  Mig 30 F4 + Mig 31 F2 blocks per slot Approver + DROP Users column note
- NEW docs/changelog/sessions/2026-05-14-s23-turn1-plan-k-mig31-f2-refactor.md
  session log đầy đủ 8 chunk timeline + multi-agent spawn cost table + pattern
  reinforced 3×

FE Admin Designer comment cleanup (Reviewer K2 follow-up):
- ApprovalWorkflowsV2Page.tsx lines 73-75 + 502-504: 2 stale narratives "F2
  AllowDrafterSkipToFinal xuống per User (User Management)" rewrite Mig 29+30+31
  cumulative narrative "7 Allow* ALL xuống per Level slot, pattern proven 3×"

3 agent MEMORY.md drift commit (dirty từ session start S23 + S22 chốt):
- Investigator: K0 pre-flight findings + 5 surprises catch
- Reviewer: K2 PASS report + new pattern "transient sentinel zombie" anti-pattern
- CICD Monitor: S22 chốt verify cumulative (Run #193 + S23 t1 pending K9 spawn)

User-level memory updates (cross-project diary persisted ngoài repo):
- feedback_per_nv_permission_scope.md: reinforcement S23 t1 — Pattern 3×
  cumulative (Mig 29 + Mig 30 + Mig 31). Pattern ALSO applies cho refactor existing
  scope, KHÔNG chỉ greenfield. Cross-ref discoveries Plan K (compile-break workaround,
  stale narrative drift, transient sentinel zombie anti-pattern caught Reviewer).
- MEMORY.md index: cumulative reinforcement note 3× Mig 31

Verify:
- dotnet build production projects clean
- npm run build fe-admin pass 17.76s, 0 TS err
- Test 104/104 PASS (S23 t1 K7 chunk maintained baseline)

Plan K state final: 31 mig · 59 tables · ~145 endpoints · 104 test · 47 gotcha
· 20 memory · 6 skills · 4 sub-agents active. CHƯA push remote — chờ bro confirm
K9 spawn CICD Monitor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 23:48:41 +07:00