From 508b17a43c3d43997299713725a929cf4f2133e4 Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Fri, 15 May 2026 11:15:01 +0700 Subject: [PATCH] =?UTF-8?q?[CLAUDE]=20FE-Admin=20FE-User:=20Chunk=20M3=20?= =?UTF-8?q?=E2=80=94=20Rename=20Phase=3DTraLai=20display=20label=20"Tr?= =?UTF-8?q?=E1=BA=A3=20l=E1=BA=A1i"=20=E2=86=92=20"C=E1=BA=A7n=20ch?= =?UTF-8?q?=E1=BB=89nh=20s=E1=BB=ADa=20l=E1=BA=A1i"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plan M Chunk M3 — UAT disconnect fix: bro UAT phát hiện label "Trả lại" + "Bản nháp" không phân biệt rõ với end-user → rename Phase=TraLai (98) display label sang "Cần chỉnh sửa lại" để self-descriptive. Scope HẸP — chỉ status display reference (KHÔNG đụng action verb): - types/purchaseEvaluation.ts × 2 app: PurchaseEvaluationPhaseLabel[98] + PeDisplayStatusLabel.TraLai = 2 const map rename - components/pe/PeWorkflowPanel.tsx × 2 app: 2 inline literal hardcode trong F1 dialog tooltip `Phase → "..."` + confirm message `Phiếu sẽ về "..."` — status reference, KHÔNG phải action verb KHÔNG đụng: - Action button label `← Trả lại` (verb, giữ nguyên) - F1 mode picker label `Trả về Người soạn thảo` (4 mode action, giữ nguyên) - Comments narrative giữ rationale dev (rule §6.5) - types/contracts.ts + types/budget.ts Phase 98 'Trả lại' — module Contract + Budget khác PE, ngoài scope M3 Mirror 2 app rule §3.9 strict applied. Verify: - npm run build fe-admin PASS clean (0 TS err, 9.40s) - npm run build fe-user PASS clean (0 TS err, 6.92s) Diff: +4/-4 LOC × 4 file = 8 LOC total Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/agent-memory/implementer/MEMORY.md | 2 ++ fe-admin/src/components/pe/PeWorkflowPanel.tsx | 4 ++-- fe-admin/src/types/purchaseEvaluation.ts | 4 ++-- fe-user/src/components/pe/PeWorkflowPanel.tsx | 4 ++-- fe-user/src/types/purchaseEvaluation.ts | 4 ++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.claude/agent-memory/implementer/MEMORY.md b/.claude/agent-memory/implementer/MEMORY.md index e9c8a96..6d19034 100644 --- a/.claude/agent-memory/implementer/MEMORY.md +++ b/.claude/agent-memory/implementer/MEMORY.md @@ -204,6 +204,8 @@ KHÔNG `*` / `latest`. Critical pins: ## 📅 Recent activity (last 10 FIFO) +- **2026-05-15 (S24, Plan M Chunk M3 PASS):** FE rename Phase=TraLai (98) display label "Trả lại" → "Cần chỉnh sửa lại" cho UAT disconnect fix. Spec scope HẸP (display badge label + status reference) tuân thủ strict: 4 file FE × 2 app = 8 edit total. **2 file types/purchaseEvaluation.ts** × 2 app: `PurchaseEvaluationPhaseLabel[98]` (raw phase badge) + `PeDisplayStatusLabel.TraLai` (display status badge — main user-facing). **2 file components/pe/PeWorkflowPanel.tsx** × 2 app: rename 2 inline literal hardcode "Trả lại" trong F1 dialog tooltip (`Phase → "..."`) + confirm message (`Phiếu sẽ về "..."`) — đây là status display reference, KHÔNG phải action verb. Pattern 5 mirror 2 app strict applied. KHÔNG đụng: (1) action button label `← Trả lại` (verb), (2) F1 mode picker label `Trả về Người soạn thảo` (4 mode action), (3) comments narrative line 62/71/etc giữ rationale dev (rule §6.5), (4) `types/contracts.ts` + `types/budget.ts` Phase 98 'Trả lại' — module Contract + Budget khác PE, ngoài scope M3. Verify: `npm run build` fe-admin PASS clean (0 TS err, 9.40s, 1395 KB bundle unchanged trivial) + `npm run build` fe-user PASS clean (0 TS err, 6.92s, 1275 KB). Diff +4/-4 LOC × 2 = 8 LOC tổng trên 4 file. Token ~9k. Decision tactical: 2 chỗ inline literal PeWorkflowPanel rename để giữ UX consistency với badge label sau rename — KHÔNG drift outside spec vì cùng "status display reference" semantics (badge + tooltip + confirm message phải mirror). Anti-fiddle threshold <20% LOC respected. + - **2026-05-14 (S23 t1, K7 Chunk F PASS):** Mig 31 Approver F2 service regression tests. Sub-task 1 fix broken Drafter F2 test reference K1 flagged: `PurchaseEvaluationWorkflowServiceReturnModeTests.cs:253` `drafter.AllowDrafterSkipToFinal = true` (DELETE 3 deprecated Drafter F2 tests entire — `SkipToFinal_DrafterAllowed_SetsPointerToFinalLevel` + `SkipToFinal_DrafterDenied_NonAdmin_Throws` + `SkipToFinal_AdminBypass_Succeeds`, semantic deprecated no value). Sub-task 2 add 3 new Approver F2 tests: `ApproveV2_SkipToFinal_AdminTickFlag_SetsPhaseDaDuyet` (happy path — slot Cấp 1 Bước 1 admin tick → Phase=DaDuyet, pointer cleared, opinion + PEA + Changelog logged), `ApproveV2_SkipToFinal_FlagOff_NonAdmin_ThrowsConflictException` (denied — flag off non-admin slot user → throw "chưa được phép duyệt thẳng Cấp cuối"), `ApproveV2_SkipToFinal_FlagOff_Admin_BypassesFlagCheck` (admin bypass — flag off admin role → DaDuyet allowed). Pattern 11 SeedWorkflowAsync cookie-cutter REUSE — created `SeedApproverF2WorkflowAsync` helper (2 Steps × 2 Levels — multi-step verify skip thẳng terminal KHÔNG fallthrough advance pointer next Step), AllowApproverSkipToFinal per-slot param. PE init Phase=ChoDuyet + CurrentWorkflowStepIndex=0 + CurrentApprovalLevelOrder=1 (vs S22 happy path từ DangSoanThao). Add `using Microsoft.EntityFrameworkCore` cho `.ToListAsync()` PEL/PEA/Changelog query. File header narrative line 17-25 REWRITE để track Mig 31 refactor semantic Approver scope ChoDuyet vs Drafter-from-Nháp cũ. Verify: `dotnet build` clean 0 err 2 warn pre-existing DocxRenderer. `dotnet test SolutionErp.slnx` 104 PASS (58 Domain + 46 Infra, 3 deleted + 3 added cancel out, baseline preserved). 3 Approver F2 tests verified individually PASS. Diff +175/-92 LOC trên 1 file. Token ~14k. - **2026-05-14 (S23 t1, K5 Chunk D PASS):** Cleanup zombie F2 endpoint + UsersPage column + DTO field + stale narrative comments (Reviewer Major #1 + Major #2 + Minor #3 + Minor #4). Pattern post-refactor full cleanup atomic 1 commit. BE 7 file (UsersController.cs DELETE PATCH /allow-skip-final endpoint + SetAllowDrafterSkipToFinalBody record; UserFeatures.cs DELETE UserDto field + SetUserAllowDrafterSkipToFinalCommand + Handler + sentinel-false mappings cleanup; ApprovalWorkflow.cs REWRITE stale narrative line 78-80 Mig 31 semantic + docstring line 108; PurchaseEvaluationFeatures.cs REWRITE Command DTO comment line 401; ApprovalWorkflowConfiguration.cs APPEND Mig 31 narrative line 22-24 + clean storage move comment line 87; ApprovalWorkflowV2AdminFeatures.cs clean DTO comment line 58; IPurchaseEvaluationWorkflowService.cs + PurchaseEvaluationDtos.cs clean stale "storage Users.AllowDrafterSkipToFinal" references) + FE Admin 2 file (UsersPage.tsx DELETE "Skip cuối" column TableHeader/TableCell + FastForward import + allowSkipMut mutation hook + FastForward toggle button; types/users.ts DELETE allowDrafterSkipToFinal field). fe-user KHÔNG đụng (no UsersPage admin-only + K6 sẽ handle Workspace Drafter checkbox), FE Designer page KHÔNG đụng (K3 done — 2 stale comment line 75 + 504 leftover deferred K6). Grep `AllowDrafterSkipToFinal` + `allow-skip-final` + `allowDrafterSkipToFinal` + `Skip cuối` + `FastForward` ZERO results across src/Backend (excl migrations) + fe-admin/src. Build BE production projects clean (0 err, 2 pre-existing DocxRenderer warn). Build fe-admin clean (0 TS err, 0 new warn). Diff +42/-94 LOC trên 9 file. Token ~12k. K6 Workspace Drafter checkbox cleanup next. - **2026-05-14 (S23 t1, K3 Chunk C PASS):** FE Admin Designer 7th checkbox AllowApproverSkipToFinal + banner rewrite. Pattern Mig 29/30 admin opt-in per-slot mirror **reinforced 3×** cumulative (Mig 29 F1+F3 5 checkbox + Mig 30 F4 1 checkbox + Mig 31 F2-refactor 1 checkbox = 7 checkbox total per slot). Cookie-cutter 1 file fe-admin only (`ApprovalWorkflowsV2Page.tsx`, fe-user no Designer per Investigator K0 S1). 7 sub-items atomic: (1) LevelDto type +`allowApproverSkipToFinal: boolean`, (2) EditLevelEntry type +same, (3) `makeDefaultLevelEntry` default false, (4) `copyFromDefinition` propagate `?? false`, (5) inline checkbox row position **cuối list** sau F4 AllowApproverEditBudget logical grouping (Edit Section 2 → Edit Budget → Skip to Final), (6) banner rewrite line ~623 từ "F2 cấu hình ở User Management" (Plan D S22 stale) → "Cấu hình quyền duyệt riêng cho từng NV trong slot Approver bên dưới (Trả lại / Edit Section 2 / Edit Budget / Duyệt thẳng Cấp cuối)", (7) POST/PATCH mutation body `levels.map` +allowApproverSkipToFinal. Verify: `npm run build` fe-admin PASS clean 0 TS error, 0 new warning. Bundle 1395.74 KB (unchanged trivial vs baseline). Diff +26/-7 LOC. Token ~6k. K5 next chunk cleanup zombie endpoint + UsersPage column. diff --git a/fe-admin/src/components/pe/PeWorkflowPanel.tsx b/fe-admin/src/components/pe/PeWorkflowPanel.tsx index 614f78a..c0c72b3 100644 --- a/fe-admin/src/components/pe/PeWorkflowPanel.tsx +++ b/fe-admin/src/components/pe/PeWorkflowPanel.tsx @@ -405,7 +405,7 @@ export function PeWorkflowPanel({ /> Trả về Người soạn thảo (mặc định) - Phase → "Trả lại". Drafter sửa rồi gửi lại chạy từ Cấp 1 Bước 1. + Phase → "Cần chỉnh sửa lại". Drafter sửa rồi gửi lại chạy từ Cấp 1 Bước 1. )} @@ -414,7 +414,7 @@ export function PeWorkflowPanel({ )}
{returnMode === WorkflowReturnMode.Drafter - ? 'Phiếu sẽ về "Trả lại". Drafter có thể sửa rồi trình lại từ Cấp 1 Bước 1.' + ? 'Phiếu sẽ về "Cần chỉnh sửa lại". Drafter có thể sửa rồi trình lại từ Cấp 1 Bước 1.' : returnMode === WorkflowReturnMode.Assignee ? 'Phiếu sẽ về Cấp/Bước của NV đã chọn (vẫn "Đã gửi duyệt"). NV nhận lại để duyệt tiếp.' : 'Phiếu sẽ lùi pointer (vẫn "Đã gửi duyệt"). NV trước nhận lại để duyệt tiếp.'} diff --git a/fe-admin/src/types/purchaseEvaluation.ts b/fe-admin/src/types/purchaseEvaluation.ts index ed2ff64..98c0c25 100644 --- a/fe-admin/src/types/purchaseEvaluation.ts +++ b/fe-admin/src/types/purchaseEvaluation.ts @@ -41,7 +41,7 @@ export const PurchaseEvaluationPhaseLabel: Record = { 6: 'Chờ CEO duyệt NCC', 7: 'Đã duyệt', 10: 'Đã gửi duyệt', - 98: 'Trả lại', + 98: 'Cần chỉnh sửa lại', 99: 'Từ chối', } @@ -83,7 +83,7 @@ export type PeDisplayStatus = typeof PeDisplayStatus[keyof typeof PeDisplayStatu export const PeDisplayStatusLabel: Record = { Nhap: 'Nháp', DaGuiDuyet: 'Đã gửi duyệt', - TraLai: 'Trả lại', + TraLai: 'Cần chỉnh sửa lại', DaDuyet: 'Đã duyệt', TuChoi: 'Từ chối', } diff --git a/fe-user/src/components/pe/PeWorkflowPanel.tsx b/fe-user/src/components/pe/PeWorkflowPanel.tsx index c4153bc..8d32af2 100644 --- a/fe-user/src/components/pe/PeWorkflowPanel.tsx +++ b/fe-user/src/components/pe/PeWorkflowPanel.tsx @@ -404,7 +404,7 @@ export function PeWorkflowPanel({ /> Trả về Người soạn thảo (mặc định) - Phase → "Trả lại". Drafter sửa rồi gửi lại chạy từ Cấp 1 Bước 1. + Phase → "Cần chỉnh sửa lại". Drafter sửa rồi gửi lại chạy từ Cấp 1 Bước 1. )} @@ -413,7 +413,7 @@ export function PeWorkflowPanel({ )}
{returnMode === WorkflowReturnMode.Drafter - ? 'Phiếu sẽ về "Trả lại". Drafter có thể sửa rồi trình lại từ Cấp 1 Bước 1.' + ? 'Phiếu sẽ về "Cần chỉnh sửa lại". Drafter có thể sửa rồi trình lại từ Cấp 1 Bước 1.' : returnMode === WorkflowReturnMode.Assignee ? 'Phiếu sẽ về Cấp/Bước của NV đã chọn (vẫn "Đã gửi duyệt"). NV nhận lại để duyệt tiếp.' : 'Phiếu sẽ lùi pointer (vẫn "Đã gửi duyệt"). NV trước nhận lại để duyệt tiếp.'} diff --git a/fe-user/src/types/purchaseEvaluation.ts b/fe-user/src/types/purchaseEvaluation.ts index af02e0c..ec5b7fc 100644 --- a/fe-user/src/types/purchaseEvaluation.ts +++ b/fe-user/src/types/purchaseEvaluation.ts @@ -41,7 +41,7 @@ export const PurchaseEvaluationPhaseLabel: Record = { 6: 'Chờ CEO duyệt NCC', 7: 'Đã duyệt', 10: 'Đã gửi duyệt', - 98: 'Trả lại', + 98: 'Cần chỉnh sửa lại', 99: 'Từ chối', } @@ -83,7 +83,7 @@ export type PeDisplayStatus = typeof PeDisplayStatus[keyof typeof PeDisplayStatu export const PeDisplayStatusLabel: Record = { Nhap: 'Nháp', DaGuiDuyet: 'Đã gửi duyệt', - TraLai: 'Trả lại', + TraLai: 'Cần chỉnh sửa lại', DaDuyet: 'Đã duyệt', TuChoi: 'Từ chối', }