[CLAUDE] Docs: chốt Session 20 turn 7 — Admin Ẩn/Hiện + Đổi tên menu eOffice (Chunk E)

Wrap-up docs cho 4 chunk code đã push:
- 2ea2d27 Chunk A — Mig 27 MenuItem +IsVisible +DisplayLabel + 3-file rule
- ef394f8 Chunk B — BE PATCH /menus/{key} + extend DTOs + UpdateMenuItemCommand
- 059bfcb Chunk C — FE Admin MenuVisibilityPage ~210 LOC + menu key + seed
- 1ed6530 Chunk D — FE User Layout filter !isVisible + render effectiveLabel

Files updated:
- docs/STATUS.md — Last updated + Recently Done row S20 turn 7 trên cùng (giữ
  S20 PE Detail UI row nguyên văn §6.5)
- docs/HANDOFF.md — Last updated + TL;DR Session 20 turn 7 trên đầu + pending
  S21+ + carry blockers (giữ TL;DR Session 20 + 19 nguyên §6.5)
- docs/changelog/migration-todos.md — Phase 9 Session 20 turn 7 done section
  + 3 defer item S21+ (giữ S20 + S19 nguyên §6.5)
- docs/changelog/sessions/2026-05-11-1700-menu-visibility-mig27.md (NEW) —
  session log đầy đủ Q&A + 4 chunk + verify chain + stats

KHÔNG đụng rules / architecture / PROJECT-MAP / workflow-contract / forms-spec
/ database-guide / schema-diagram / CLAUDE.md per §6.5 (drift S20 turn 7
defer cron audit 2026-06-01 — Mig 27 + 1 endpoint + 1 menu key sẽ check
chung lúc đó).

Path filter CI sẽ skip (docs-only commit).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-05-11 11:42:12 +07:00
parent 1ed6530fdd
commit aab88621e8
4 changed files with 256 additions and 2 deletions

View File

@ -1,6 +1,66 @@
# HANDOFF — Brief 5 phút cho session tiếp theo
**Last updated:** 2026-05-11 (Session 20 — **🎯 PE Detail UI restructure 3 yêu cầu UX user (4 chunk `9dee00d``2bba851``f2f01f4`→Docs). FE-only restructure (1 hook BE nhẹ auto-seed Detail). Q1=a giữ Section "Chọn NCC TP" riêng / Q2=a NCC shared + 1 hạng mục demo / Q3=a chỉ hiện NV đã ký / Q4 public luôn (skip dotnet test, vẫn npm build × 2 app mỗi chunk vì rename/remove function). Chunk A: BE CreatePE handler thêm 1 PurchaseEvaluationDetail mặc định (NoiDung=TenGoiThau, ThanhTienNganSach=Budget.TongNganSach||BudgetManualAmount||0) + FE reorder section Hạng mục lên #2. Chunk B: ItemsTab restructure list HangMucCard 1 card / hạng mục với expand panel chứa NCC inline table 8 cột (NCC/Liên hệ/Điều khoản TT/File báo giá/ĐG chưa VAT/ĐG có VAT/Thành tiền/Action). Click cell quote → QuoteDialog reuse. Drop SuppliersTab function ~134 LOC dead code, giữ 2 dialog + SupplierAttachmentsCell. Section 4 NCC tham gia gộp vào Section 2 → 4 section final (Thông tin/Hạng mục nested/Chọn NCC TP thắng thầu/Ý kiến). Chunk C: LevelOpinionsSectionV2 forEach step → 1 StepOpinionsBox (replace grid-cols-2 N approvers). Header "Bước N — Tên" + dept badge + "X/Y đã duyệt" counter. Body filter signed opinions sort levelOrder asc + signedAt asc → StepOpinionEntry per signed (tên + Cấp badge + admin override badge + timestamp + comment). NV chưa duyệt KHÔNG hiển thị. KHÔNG đụng Mig 26 schema. Drop LevelOpinionBox function. 81 test pass unchanged (UAT defer).**)
**Last updated:** 2026-05-11 (Session 20 turn 7 **🎯 Admin Ẩn/Hiện + Đổi tên menu eOffice (Mig 27, 5 chunk: A schema → B BE API → C FE admin page → D FE user filter → E docs). User Q2=b: DisplayLabel CHỈ áp fe-user, admin giữ Label gốc. NEW MenuVisibilityPage trong fe-admin /system/menu-visibility — table inline edit Toggle Eye/EyeOff + Input rename + Lưu/Khôi phục. PATCH /api/menus/{key}. fe-user Layout filter 2 tầng + effectiveLabel. 27 mig, ~142 endpoints, 34 FE pages, +1 menu key MenuVisibility leaf System. 81 test pass unchanged.**)
## TL;DR Session 20 turn 7 — Admin Ẩn/Hiện + Đổi tên menu eOffice (Mig 27)
User UAT live yêu cầu thêm tính năng admin quản lý menu eOffice (fe-user) — Ẩn/Hiện + Đổi tên hiển thị. Hỏi xác nhận "chưa có?" → đúng, chưa có. User clarify **Q2=b "edit hiển thị bên ngoài, chỉ của eOffice thôi"** → admin sidebar luôn dùng Label gốc, DisplayLabel CHỈ áp render fe-user.
### Q&A chốt scope
- Q1=**a** Global (không per-role — permission matrix đã handle)
- Q2=**b** DisplayLabel chỉ fe-user, admin sidebar giữ Label gốc
- Q3=**a** Giữ USER_HIDDEN_KEYS hardcode + tầng IsVisible dynamic combine
- Q4=ok UAT iteration skip test, vẫn npm build mỗi chunk
### Chunk A (`2ea2d27`) — Schema + Migration 27
Domain MenuItem +IsVisible bool=true +DisplayLabel string?(200). EF config HasDefaultValue(true) + HasMaxLength(200). Migration 27 AddVisibilityAndDisplayLabelToMenuItems (2 AddColumn) — 3-file rule. Apply LocalDB Dev + Design qua --connection override.
### Chunk B (`ef394f8`) — BE API
DTO MenuNodeDto + MenuItemDto +isVisible +displayLabel. GetMyMenuTreeQueryHandler pass through (KHÔNG filter server-side — 2 FE app tự quyết render). NEW UpdateMenuItemCommand + Validator (Key required + DisplayLabel max 200) + Handler (whitespace → null). MenusController +PATCH /api/menus/{key} [Authorize Policy="Permissions.Update"].
### Chunk C (`059bfcb`) — FE Admin MenuVisibilityPage
Domain MenuKeys +MenuVisibility. DbInitializer +leaf System/MenuVisibility (Eye, Order=94). FE Admin: types/menu.ts mirror, lib/menuKeys.ts +const, Layout resolver +/system/menu-visibility, App.tsx +Route. NEW pages/system/MenuVisibilityPage.tsx ~210 LOC:
- PageHeader + description nhắc admin sidebar dùng Tên gốc
- 4 StatCard (Tổng / Hiển thị / Đã ẩn / Đã đổi tên)
- Search box (key | label | displayLabel)
- Table 5 cột: Key mono + parentKey ↳ / Tên gốc / Input "Tên hiển thị" inline (placeholder "Mặc định: {label}") / Toggle button emerald-Eye / amber-EyeOff / Lưu (khi dirty) + Khôi phục (khi custom)
- onSuccess invalidate `['menus','all']` + `['my-menu']` → live update
### Chunk D (`1ed6530`) — fe-user Layout filter + render
types/menu.ts mirror. Layout.tsx:
```tsx
function filterForUser(nodes: MenuNode[]) {
// 2 tầng: hardcode USER_HIDDEN_KEYS + dynamic !isVisible
return nodes.filter(n => !USER_HIDDEN_KEYS.has(n.key) && n.isVisible !== false)
.map(n => ({ ...n, children: filterForUser(n.children) }))
}
function effectiveLabel(n) { return (n.displayLabel?.trim()) || n.label }
```
Replace 3 callsite `{node.label}``{effectiveLabel(node)}`. **fe-admin Layout KHÔNG đụng** — render Label gốc + show hết menu (Q2=b).
### Pending S21+ (cumulative carry over)
1. Test V2 Service wire + Section gộp + B4 silent 403 + Mig 25 PATCH user-selectable
2. **Contract V2 wire (Mig 28+29 mirror PE)** — biggest pending
3. Phân quyền strict V2 + drop legacy V1 + Mig 15 cleanup
4. Test PATCH /api/menus/{key} validate (Mig 27)
5. Skill `permission-matrix` thêm section "menu visibility" — defer cron audit 2026-06-01
6. UX verify trong UAT: admin ẩn menu cha → children có ẩn theo không (FE filter chỉ check `!n.isVisible` per-node)
### Hard blockers ops (carry)
UAT thật / SMTP / Rotate creds / SQL backup schedule / win-acme fix / remove `.huypham.vn`
## TL;DR Session 20 — PE Detail UI restructure 3 yêu cầu UX user (previous)
Note: TL;DR Session 20 PE Detail UI giữ nguyên dưới (rule §6.5 KEEP narrative). Session 20 turn 7 này thêm trên cùng (admin menu visibility — chủ đề khác).
(4 chunk `9dee00d``2bba851``f2f01f4`→Docs). FE-only restructure (1 hook BE nhẹ auto-seed Detail). Q1=a giữ Section "Chọn NCC TP" riêng / Q2=a NCC shared + 1 hạng mục demo / Q3=a chỉ hiện NV đã ký / Q4 public luôn (skip dotnet test, vẫn npm build × 2 app mỗi chunk vì rename/remove function). Chunk A: BE CreatePE handler thêm 1 PurchaseEvaluationDetail mặc định (NoiDung=TenGoiThau, ThanhTienNganSach=Budget.TongNganSach||BudgetManualAmount||0) + FE reorder section Hạng mục lên #2. Chunk B: ItemsTab restructure list HangMucCard 1 card / hạng mục với expand panel chứa NCC inline table 8 cột (NCC/Liên hệ/Điều khoản TT/File báo giá/ĐG chưa VAT/ĐG có VAT/Thành tiền/Action). Click cell quote → QuoteDialog reuse. Drop SuppliersTab function ~134 LOC dead code, giữ 2 dialog + SupplierAttachmentsCell. Section 4 NCC tham gia gộp vào Section 2 → 4 section final (Thông tin/Hạng mục nested/Chọn NCC TP thắng thầu/Ý kiến). Chunk C: LevelOpinionsSectionV2 forEach step → 1 StepOpinionsBox (replace grid-cols-2 N approvers). Header "Bước N — Tên" + dept badge + "X/Y đã duyệt" counter. Body filter signed opinions sort levelOrder asc + signedAt asc → StepOpinionEntry per signed (tên + Cấp badge + admin override badge + timestamp + comment). NV chưa duyệt KHÔNG hiển thị. KHÔNG đụng Mig 26 schema. Drop LevelOpinionBox function. 81 test pass unchanged (UAT defer).**)
## TL;DR Session 20 — PE Detail UI restructure 3 yêu cầu user UX