[CLAUDE] Docs: chốt session 2026-04-23 chiều — toolkit + 4-bảng + master + roles VN
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 2m47s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 2m47s
11 commit feature work (b75448e→ae59cfe) → docs sync. ## STATUS.md - Last updated 2026-04-23 16:00 - Phase header: Tier 3 + 4-bảng + master catalogs + roles VN - 7 Recently Done row mới (3-panel layout, 4-bảng overhaul, Thao tác 2-panel, Mã HĐ gen Create, master catalogs, roles VN demo users) - Cumulative table thêm cột "+Toolkit/Catalogs/Roles" (DB 36, endpoints ~80, migrations 11, commits ~47) - Session log link mới - Skill list count = 13 file ## HANDOFF.md - TL;DR cập nhật: 36 tables, 80 endpoints, 11 migrations - Phase table thêm 5 row Done (3-panel, 4-bảng, mã HĐ, master, roles) - Git state 18 commit gần nhất - Credentials block thêm 13 demo user (User@123456) — warn rotate trước UAT ## migration-todos.md Section "Session 2026-04-23 (chiều)" với 14 ticked checkbox + commit refs. ## schema-diagram.md - Header: 24 → 36 bảng - Migration table thêm row 9-11 (highlighted) - Section 8bis mới: chi tiết 7 Details + ContractChangelogs + 4 Catalogs + Role.ShortName + User.DepartmentId/Position ## Session log mới `docs/changelog/sessions/2026-04-23-1500-toolkit-data-roles.md` (~270 dòng) — outcome A→I, stats cumulative, 6 architectural decisions, next session priority. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -253,6 +253,23 @@
|
||||
- [ ] **Audit 2026-07-01**
|
||||
- [ ] (lập lại mỗi tháng đầu)
|
||||
|
||||
## Session 2026-04-23 (chiều) — Toolkit + 4-bảng + Master Catalogs + Roles VN
|
||||
|
||||
- [x] **3-panel layout HĐ list/inbox/thao tác** (commits b75448e/89c7e88/8c4b4da)
|
||||
- [x] **Sidebar accordion** menu loại HĐ (`7ea3957`)
|
||||
- [x] **Tách Tổng quan → /dashboard riêng** fix bug trùng /inbox (`d326e80`)
|
||||
- [x] **4-bảng overhaul** Header/7 Details/Workflow/Changelog (Migration 9, `70810e1`)
|
||||
- [x] **IChangelogService** + integrate vào CRUD/Workflow handlers (`71c035d`)
|
||||
- [x] **Details CRUD endpoints + Changelogs query** (`e684455`)
|
||||
- [x] **FE Panel 2 7/3 grid** (Chi tiết + Lịch sử inline, `ad0652d`)
|
||||
- [x] **Edit/Xóa hover row Panel 1 Thao tác** (mờ khi != DangSoanThao, `7f26ff9`)
|
||||
- [x] **Mã HĐ gen ngay tại Create + backfill legacy** (`51449d6`)
|
||||
- [x] **4 master catalogs** Units/Materials/Services/WorkItems (Migration 10, `e27c547`)
|
||||
- [x] **Admin CatalogsPage** + datalist autocomplete trong Details form (`16e24ed`)
|
||||
- [x] **Roles VN labels** ShortName + Description backfill (Migration 11, `330d529`)
|
||||
- [x] **Users +DepartmentId/Position** + 13 demo users seed (`330d529`)
|
||||
- [x] **FE UsersPage** dept dropdown + position field + role badge ShortName (`ae59cfe`)
|
||||
|
||||
## Tier 3 ERP (Session 2026-04-22) — feature-complete
|
||||
|
||||
- [x] **Attachment upload E2E** — IFileStorage + CQRS + FE drag-drop (gotcha path-traversal) — `c8d0070`
|
||||
|
||||
256
docs/changelog/sessions/2026-04-23-1500-toolkit-data-roles.md
Normal file
256
docs/changelog/sessions/2026-04-23-1500-toolkit-data-roles.md
Normal file
@ -0,0 +1,256 @@
|
||||
# Session 2026-04-23 ~15:00 — Toolkit + 4-bảng overhaul + master data + roles VN
|
||||
|
||||
**Focus:** Sang phiên 2 trong ngày — UX redesign toàn bộ surface HĐ
|
||||
(3-panel List/Detail/Workflow + Inbox + Thao tác), data model overhaul
|
||||
4-bảng (Header/Details/Workflow/Changelog), master catalogs cho Details,
|
||||
chi tiết Users/Departments/Roles VN.
|
||||
|
||||
11 commit (b75448e → ae59cfe), 2 migration (9 + 10 + 11), DB 24→36 bảng.
|
||||
|
||||
## Outcomes
|
||||
|
||||
### A. 3-panel layout cho List/Inbox (UX) ✓
|
||||
|
||||
- `MyContractsPage` (fe-user): `lg:grid-cols-[320px_1fr_360px]` —
|
||||
Panel 1 List + search + filter | Panel 2 Detail content |
|
||||
Panel 3 Workflow + Lịch sử duyệt
|
||||
- `ContractsListPage` (fe-admin): same pattern + Pagination compact
|
||||
- `InboxPage` (fe-user): same + 4 StatPill inline (Cần xử lý / Sắp QH /
|
||||
Quá hạn / Giá trị) + vai trò amber banner
|
||||
- URL state `?id=` selected — bookmarkable, refresh giữ
|
||||
- Mobile fallback (<lg): click row → fullpage `/contracts/:id`
|
||||
- Components reuse: `ContractDetailContent` + `WorkflowHistoryPanel`
|
||||
- Commits: b75448e, 89c7e88
|
||||
|
||||
### B. Sidebar accordion cho 7 loại HĐ ✓
|
||||
|
||||
- Chỉ 1 group `Ct_<Code>` expand cùng lúc (accordion)
|
||||
- Auto-expand theo URL `?type=X` qua useEffect + AccordionContext
|
||||
- Highlight active group: bg-slate-50 + text-slate-900
|
||||
- Commit: 7ea3957
|
||||
|
||||
### C. Tách "Tổng quan" → `/dashboard` riêng (fix bug trùng /inbox) ✓
|
||||
|
||||
- `UserDashboardPage` mới: 5-card "Của tôi" (DraftsInProgress / Pending /
|
||||
DueSoon / Overdue / TotalValue) + section HĐ gần đây
|
||||
- Layout resolvePath: Dashboard → /dashboard (không trùng Hộp thư)
|
||||
- App route: / redirect → /dashboard
|
||||
- Commit: d326e80
|
||||
|
||||
### D. Data model 4-bảng overhaul (Tier 3 follow-up) ✓
|
||||
|
||||
User decision Option B: bảng riêng cho mỗi loại HĐ.
|
||||
|
||||
**Migration 9 — `AddContractDetailsAndChangelog`:**
|
||||
- 7 Details bảng: ThauPhuDetails, GiaoKhoanDetails, NhaCungCapDetails,
|
||||
DichVuDetails, MuaBanDetails, NguyenTacNccDetails, NguyenTacDvDetails
|
||||
- Common base: ContractId FK Cascade, Order, ThanhTien decimal(18,2),
|
||||
GhiChu, audit fields
|
||||
- Schema chuyên biệt per loại HĐ (vd MuaBan có ThueVAT, NguyenTac có
|
||||
DonGiaToiThieu/ToiDa)
|
||||
- 1 ContractChangelogs bảng — unified audit log:
|
||||
- EntityType enum: Contract | Detail | Workflow | Comment | Attachment
|
||||
- Action enum: Insert | Update | Delete | Transition
|
||||
- PhaseAtChange + UserName denormalize + FieldChangesJson + ContextNote
|
||||
- DB 24 → 32 bảng
|
||||
|
||||
**IChangelogService (App + Infra):**
|
||||
- 5 method: LogContractChange / LogDetailChange / LogWorkflowTransition /
|
||||
LogCommentAdded / LogAttachment
|
||||
- Wired vào: CreateContract + UpdateContractDraft (with diff) +
|
||||
AddComment + Upload/Delete Attachment + ContractWorkflowService.Transition
|
||||
|
||||
**CQRS + API:**
|
||||
- GetContractDetailsQuery dispatch theo Type → bundle 7 lists
|
||||
- 7 typed AddXxxDetailCommand handler (Insert + log changelog)
|
||||
- DeleteContractDetailCommand generic (dispatch theo Type)
|
||||
- ListContractChangelogsQuery (read-only, desc CreatedAt, top 200)
|
||||
- 9 endpoints mới ContractsController
|
||||
|
||||
Commits: 70810e1, 71c035d, e684455
|
||||
|
||||
### E. FE Panel 2 — tabs → 7/3 grid layout (UX iter 2) ✓
|
||||
|
||||
**Iter 1 (b3762af):** Tabs Tổng quan / Chi tiết / Lịch sử
|
||||
**Iter 2 (ad0652d):** Bỏ tabs, hiển thị flat:
|
||||
- Tổng quan content (Info + Comments + Attachments) ở trên
|
||||
- Bên dưới grid 7-3: [Chi tiết Tab] [Lịch sử Changelog Tab]
|
||||
|
||||
`ContractDetailsTab`:
|
||||
- 7 table renderers per type (HEADERS_BY_TYPE + DeleteBtn)
|
||||
- AddRowForm với FIELDS_BY_TYPE (5-7 field per type)
|
||||
- buildPayload auto compute thanhTien (SL × DonGia × (1+VAT/100) cho MuaBan)
|
||||
- canEdit chỉ khi Phase=DangSoanThao
|
||||
|
||||
`ContractChangelogsTab`:
|
||||
- Render unified timeline desc CreatedAt
|
||||
- Icon + tone color theo EntityType
|
||||
- Expandable detail row hiển thị FieldChangesJson (Cũ → Mới)
|
||||
|
||||
### F. "Thao tác" — 2-panel + Edit/Xóa hover + Mở fullpage ✓
|
||||
|
||||
`ContractCreatePage` rewrite:
|
||||
- 2-panel: Panel 1 List HĐ theo type + button "+ Thêm mới" cuối |
|
||||
Panel 2 Header form (new/edit) + Chi tiết section
|
||||
- URL state: ?type / ?id / ?mode=new
|
||||
- Empty state khi chưa chọn
|
||||
- Action buttons hover row: Edit ✏ + Xóa 🗑 (luôn hiện, mờ khi
|
||||
Phase != DangSoanThao + tooltip "Chỉ sửa được khi Đang soạn thảo")
|
||||
- ContractDetailsPreview cho create mode — show table headers + lock
|
||||
icon + disabled add button (user thấy structure trước khi tạo Header)
|
||||
|
||||
Commits: 8c4b4da, ec0c983, 501b4de, 7f26ff9, 39031ca
|
||||
|
||||
### G. Mã HĐ gen ngay tại Create + backfill ✓
|
||||
|
||||
User feedback: HĐ phải có mã ngay khi tạo, không đợi DangDongDau.
|
||||
|
||||
- `CreateContractCommandHandler`: gen mã trước khi `db.Contracts.Add` —
|
||||
GenerateAsync chạy SERIALIZABLE riêng, entity chưa tracked nên không
|
||||
bị save kèm
|
||||
- TransitionAsync giữ defensive `if (MaHopDong is null) gen` cho legacy
|
||||
- `BackfillContractCodesAsync` trong DbInitializer — chạy 1 lần
|
||||
startup, idempotent (count NULL → skip nếu 0), log success/failed
|
||||
|
||||
Commit: 51449d6
|
||||
|
||||
### H. 4 master catalogs cho Details (migration 10) ✓
|
||||
|
||||
User feedback: thêm Master Data cho phần Chi tiết.
|
||||
|
||||
**Domain entities (4 mới):**
|
||||
- `UnitOfMeasure` (UnitsOfMeasure) — m2, kg, ngc, ...
|
||||
- `MaterialItem` (MaterialItems) — Code, Name, Category (NhomSP),
|
||||
DefaultUnit, Specification, OriginCountry, IsActive
|
||||
- `ServiceItem` (ServiceItems) — vận chuyển, bảo trì, tư vấn, ...
|
||||
- `WorkItem` (WorkItems) — đào móng, đổ bê tông, xây tường, ...
|
||||
|
||||
Common pattern: AuditableEntity, Code unique, Category index, IsActive.
|
||||
|
||||
**Migration 10 — `AddMasterCatalogs`:** DB 32 → 36 bảng.
|
||||
|
||||
**Seed defaults idempotent:**
|
||||
- 20 UnitsOfMeasure (m2/m3/kg/tan/l/cai/bo/goi/ngc/h/ca/...)
|
||||
- 15 MaterialItems demo (xi măng PCB40, cát vàng, đá 1x2, thép D10, ...)
|
||||
- 10 ServiceItems demo (vận chuyển, bảo trì, tư vấn, kiểm định, ...)
|
||||
- 15 WorkItems demo (đào móng, đổ bê tông, xây tường, lát gạch, ...)
|
||||
|
||||
**CQRS:** CatalogsFeatures.cs (~290 dòng) — 4 catalog × 5 handlers
|
||||
(List + Create + Update + Delete + unique code guard).
|
||||
|
||||
**Controller:** 13 endpoints — GET open cho mọi role (autocomplete);
|
||||
POST/PUT/DELETE Admin role only.
|
||||
|
||||
**Menu mới (5):**
|
||||
- Catalogs group "Danh mục chi tiết" dưới Master
|
||||
- 4 leaves: Đơn vị tính / Vật tư SP / Dịch vụ / Hạng mục công việc
|
||||
|
||||
**FE Admin CatalogsPage:** 1 page generic, URL `/master/catalogs/:kind`,
|
||||
4 sub-tabs (units/materials/services/work-items), per-kind FIELDS config,
|
||||
form Dialog với input/textarea/checkbox.
|
||||
|
||||
**FE Details Add form datalist autocomplete:**
|
||||
- Fetch 4 catalogs qua TanStack Query (cache 'catalogs')
|
||||
- HTML5 `<datalist>` per relevant field (donViTinh/maSP/tenSP/hangMuc/...)
|
||||
- Smart-fill: user pick code → autofill name + defaultUnit (sibling
|
||||
fields) qua handleFieldChange
|
||||
|
||||
Commits: e27c547, 16e24ed
|
||||
|
||||
### I. Roles VN labels + Users dept/position + 13 demo users (migration 11) ✓
|
||||
|
||||
**Entity changes:**
|
||||
- `Role` + `ShortName` (max 50) — Mã viết tắt VN
|
||||
- `User` + `DepartmentId` Guid? FK Departments (Restrict) + `Position`
|
||||
|
||||
**Migration 11 — `AddRoleShortNameAndUserDepartment`:** thêm cột, không
|
||||
table mới. DB vẫn 36 bảng.
|
||||
|
||||
**12 roles VN labels** (idempotent backfill nếu existing role thiếu):
|
||||
| Code | Short | Description |
|
||||
|---|---|---|
|
||||
| Admin | QTV | Quản trị viên hệ thống |
|
||||
| Drafter | NV.PB | Nhân viên phòng ban (soạn HĐ) |
|
||||
| DeptManager | TPB | Trưởng phòng ban |
|
||||
| ProjectManager | PM | Giám đốc dự án |
|
||||
| Procurement | PRO | Phòng Cung ứng |
|
||||
| CostControl | CCM | Phòng Kiểm soát chi phí |
|
||||
| Finance | FIN | Phòng Tài chính |
|
||||
| Accounting | ACT | Phòng Kế toán |
|
||||
| Equipment | EQU | Phòng Thiết bị |
|
||||
| Director | BOD | Ban Giám đốc |
|
||||
| AuthorizedSigner | NĐUQ | Người được Ủy quyền ký HĐ |
|
||||
| HrAdmin | HRA | Phòng Nhân sự - Hành chính |
|
||||
|
||||
**Identity Name = code English giữ nguyên** (FK + [Authorize] attr).
|
||||
Chỉ thêm 2 cột display VN.
|
||||
|
||||
**13 Demo users seed (password `User@123456`):**
|
||||
- bod.huynh + bod.le (BOD)
|
||||
- pm.nguyen (PM)
|
||||
- TPB cho CCM/PRO/FIN/ACT/EQU/HRA (6 user)
|
||||
- qs.hoang + qs.ngo (QS Drafter)
|
||||
- nv.cao + nv.dinh (PRO/FIN Drafter)
|
||||
|
||||
**FE Admin updates:**
|
||||
- `types/users.ts`: RoleShortName + RoleLabel + roleDisplayName helper
|
||||
- `UsersPage`: column Phòng ban + Chức vụ, badge Vai trò = ShortName
|
||||
(tooltip full label), Edit dialog mới (dept/position/active),
|
||||
Create dialog 2-col grid + dropdown Phòng ban, Roles checkbox
|
||||
"ShortName — Full Label"
|
||||
- `PermissionsPage` Panel 1: 2-line per role (ShortName semibold +
|
||||
Description small)
|
||||
|
||||
Commits: 330d529, ae59cfe
|
||||
|
||||
## Stats cumulative
|
||||
|
||||
| | Trước session | Sau session | Δ |
|
||||
|---|---|---|---|
|
||||
| BE LOC | ~4800 | ~7800 | +3000 |
|
||||
| DB tables | 24 | **36** | +12 (7 details + 1 changelog + 4 catalogs) |
|
||||
| Migrations | 8 | **11** | +3 (Migration 9/10/11) |
|
||||
| API endpoints | ~50 | **~80** | +30 (details CRUD + catalogs CRUD + changelogs) |
|
||||
| FE pages | ~20 | **~22** | +2 (UserDashboardPage + CatalogsPage) |
|
||||
| FE components | many | many+ | +ContractDetailContent/WorkflowHistoryPanel/ContractDetailsTab/ContractChangelogsTab/ContractDetailsPreview |
|
||||
| Commits session này | — | **22** | b75448e → ae59cfe |
|
||||
|
||||
## Architectural decisions
|
||||
|
||||
1. **Option B per-type Details** (vs single bảng + JSON): chuẩn schema,
|
||||
strict typing, TS strict mode FE bắt typo. Trade-off: 7 bảng riêng +
|
||||
nhiều handler lặp pattern. Worth.
|
||||
|
||||
2. **ContractChangelogs unified** — 1 bảng audit cho mọi entity HĐ
|
||||
(Contract/Detail/Workflow/Comment/Attachment), KHÁC ContractApprovals
|
||||
(workflow-only, dùng cho guard). View layer cho user đọc lịch sử.
|
||||
|
||||
3. **Mã HĐ gen tại Create** (vs DangDongDau) — trade-off: gap trong
|
||||
sequence khi reject, nhưng user có mã ngay từ đầu để reference.
|
||||
|
||||
4. **Datalist HTML5 native autocomplete** (vs library combobox) — đủ
|
||||
cho MVP, không add dependency, smart-fill qua handleFieldChange.
|
||||
|
||||
5. **Identity Name English giữ nguyên + thêm ShortName/Description VN**
|
||||
— không break FK, không cần data migration; FE/BE display layer
|
||||
convert qua dict mapping.
|
||||
|
||||
6. **Per-type bảng Details không có User-level approver runtime guard
|
||||
yet** — data model `WorkflowStepApprover.Kind=User` đã có, nhưng
|
||||
transition guard v1 chỉ check Role-kind. Iter sau enable.
|
||||
|
||||
## Next session priority
|
||||
|
||||
1. **UAT 2-3 user thật** — hard requirement
|
||||
2. Email outbox (chờ SMTP config)
|
||||
3. Rotate creds (SA/vrapp/JWT/admin)
|
||||
4. SQL backup Task Scheduler
|
||||
5. Roles CRUD admin (custom role ngoài 12 hardcoded)
|
||||
6. User-kind approver runtime guard
|
||||
7. PermissionsPage: grant Workflows.Read non-admin → Wf_* visible
|
||||
8. Update docs (sẽ làm trong commit chốt session này)
|
||||
|
||||
## Cron audit fire 2026-05-01
|
||||
|
||||
Cron task `solution-erp-skill-audit-monthly` sẽ chạy tự động đầu tháng
|
||||
sau — log vào `docs/changelog/skill-audit-2026-05.md` + commit auto.
|
||||
Reference in New Issue
Block a user