Files
solution-erp/docs/changelog/sessions/2026-04-28-chot-session-4-budget.md
pqhuy1987 e0b4e7f096
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 2m53s
[CLAUDE] Docs: chốt session 4 — Budget BE module + 14 Solutions users
- STATUS.md: header Phase 7 + 3 row Recently Done (Budget BE / 14 users / Docs cleanup) + cumulative cột mới (51 tables / 14 mig / ~124 endpoints)
- HANDOFF.md: TL;DR session 4 (2 milestone Budget BE + 14 users) + Cảnh báo session 5 + Priority 0 (FE Budget + PE/HD integration + PE feature gap) + Credentials 30 user
- migration-todos.md: Phase 7 thêm section D Budget done + Phase 8 mới (FE Budget pages + integration) + pending migrations Budget
- architecture.md: §10 Budget module mới (ERD + state machine + auto-recompute + integration roadmap)
- database/schema-diagram.md: migration history rows 13+14 + §12 Budget ERD chi tiết
- ef-core-migration SKILL: migration 14 entry + Phase 8 pending Budget refinement
- CLAUDE.md root + docs: modules table thêm Budget row + scope Budget + count 51 bảng / 14 mig
- Session log 2026-04-28-chot-session-4-budget.md (10+ section detailed)

Stats: 51 tables (+4 Budget), 14 migrations (+AddBudgets), ~124 endpoints (+11 Budget),
30 demo user (16 sample + 14 Solutions thật), 38 gotchas, ~340 LOC Budget CQRS.
FE Budget pages chưa làm — Priority 0 session 5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 12:36:31 +07:00

13 KiB

Session log — 2026-04-28 (Phase 7 — Module Ngân sách BE + 14 Solutions users)

Topic: Module Ngân sách (Budget) BE chốt + 14 demo user Solutions thật + chốt MD session 4 → 5

Commits:

  • 309dcd9 · e71e0eb · e65578a — Docs cleanup từ session 3 (audit MD + tái cấu trúc + archive raw)
  • 8097892 — Infra: 14 demo user Solutions company (PRO 5 + CCM 7 + ISO 1 + CEO 1)
  • a05c57b — Domain+App+Api: Module Ngân sách (Budget) — 4 bảng + workflow simple 3-step
  • (Session log + chốt MD này — commit cuối session 4)

Migration: 14 AddBudgets — 4 bảng Budgets / BudgetDetails / BudgetApprovals / BudgetChangelogs + 2 cột nullable FK Contracts.BudgetId & PurchaseEvaluations.BudgetId.

A. Module Ngân sách BE

Domain (SolutionErp.Domain/Budgets/)

  • BudgetPhase enum 5-state — DangSoanThao(1) → ChoCCM(2) → ChoCEO(3) → DaDuyet(4) + TuChoi(99)
  • Budget aggregate root (AuditableEntity):
    • MaNganSach NS-{YYYYMM}-{Random:4d} (chưa atomic), TenNganSach required, Description
    • NamNganSach int (year), ProjectId FK Restrict, DepartmentId? FK Restrict, DrafterUserId FK Restrict
    • Phase enum, TongNganSach decimal(18,2) auto-recompute, SlaDeadline?, SlaWarningSent
    • Navigation: Details / Approvals / Changelogs collections
  • BudgetDetail flat row pattern — KHÔNG nested per-type:
    • GroupCode/GroupName (phân nhóm hạng mục), ItemCode, NoiDung, DonViTinh
    • KhoiLuong dec(18,4), DonGia dec(18,2), ThanhTien dec(18,2), Order, GhiChu
  • BudgetApproval workflow history (FromPhase/ToPhase/Decision reuse ApprovalDecision)
  • BudgetChangelog audit log với enum BudgetEntityType (Header/Detail/Workflow)
  • BudgetPolicy record + BudgetPolicy.Default hardcoded simple 3-step:
    • Drafter/DeptManager: DangSoanThao → ChoCCM (Trình) hoặc TuChoi
    • CostControl: ChoCCM → ChoCEO hoặc DangSoanThao (trả về)
    • Director/AuthorizedSigner: ChoCEO → DaDuyet hoặc DangSoanThao

Modify Contract & PE

  • Contract.BudgetId? Guid + index
  • PurchaseEvaluation.BudgetId? Guid + index
  • Không có FK constraint cứng — app layer guard validate khi pick Budget

Application (SolutionErp.Application/Budgets/)

BudgetFeatures.cs ~340 LOC, 11 CQRS handler:

  1. CreateBudgetCommand + Validator + Handler — gen MaNganSach, set Phase=DangSoanThao, log Changelog
  2. UpdateBudgetDraftCommand — chỉ DangSoanThao, log field changes JSON
  3. TransitionBudgetCommand — guard BudgetPolicy.Default.IsTransitionAllowed, append BudgetApproval, log Changelog Transition
  4. ListBudgetsQuery — Page/Search/Filter Phase/ProjectId/NamNganSach
  5. GetBudgetQuery — return BudgetDetailBundleDto (Header + Details + Approvals + Workflow summary)
  6. DeleteBudgetCommand — chỉ DangSoanThao/TuChoi (soft delete)
  7. AddBudgetDetailCommand — auto recompute Sum(ThanhTien) lại Header
  8. UpdateBudgetDetailCommand — auto recompute
  9. DeleteBudgetDetailCommand — auto recompute
  10. ListBudgetChangelogsQuery — order CreatedAt DESC

Api (SolutionErp.Api/Controllers/)

BudgetsController.cs 11 endpoint REST:

GET    /api/budgets                             list paged
GET    /api/budgets/{id}                        bundle
POST   /api/budgets                             create
PUT    /api/budgets/{id}                        update draft
POST   /api/budgets/{id}/transitions            phase transition
DELETE /api/budgets/{id}                        soft delete
POST   /api/budgets/{id}/details                add detail
PUT    /api/budgets/{id}/details/{detailId}     update detail
DELETE /api/budgets/{id}/details/{detailId}     delete detail
GET    /api/budgets/{id}/changelogs             audit log

Menu seed (DbInitializer)

  • Root Budgets (MenuKeys.Budgets) order=27 icon Wallet
  • 3 leaf:
    • Bg_List "Danh sách ngân sách" → /budgets
    • Bg_Create "Tạo ngân sách" → /budgets/new
    • Bg_Pending "Ngân sách chờ duyệt" → /budgets?phase=Pending
  • FE chưa wire route + menu resolver — Priority 0 session 5

B. 14 demo user Solutions company thật

SeedDemoUsersAsync thêm 14 user với reconcile pattern (per-user try-catch, gotcha #38 4-field Email/NormalizedEmail/UserName/NormalizedUserName).

PRO (Phòng Cung ứng) 5 user

Email Họ tên Vai trò
tra.bui@solutions.com.vn Bùi Lê Thủy Trà TPB.PRO
phuong.nguyen@solutions.com.vn Nguyễn Thị Bích Phượng NV.PRO
binh.lethanh@solutions.com.vn Lê Thanh Bình NV.PRO
danh.huynh@solutions.com.vn Huỳnh Tài Danh NV.PRO
dat.tran@solutions.com.vn Trần Văn Đạt NV.PRO

CCM (Phòng Kiểm soát chi phí) 7 user

Email Họ tên Vai trò
ngocanh.huynh@solutions.com.vn Huỳnh Thị Ngọc Ánh TPB.CCM
ha.dao@solutions.com.vn Đào Đức Hà NV.CCM
cuong.do@solutions.com.vn Đỗ Mạnh Cường NV.CCM
long.le@solutions.com.vn Lê Phụng Long NV.CCM
ha.nguyen@solutions.com.vn Nguyễn Thị Thu Hà NV.CCM
dung.nguyen@solutions.com.vn Nguyễn Phúc Dũng NV.CCM
anh.nguyen@solutions.com.vn Nguyễn Phước Tuấn Anh NV.CCM

ISO 1 user

Email Họ tên Vai trò
chau.le@solutions.com.vn Lê Bảo Châu NV.ISO

CEO 1 user

Email Họ tên Vai trò
huy.duong@solutions.com.vn Dương Quang Huy BOD

Pwd toàn bộ: User@123456. Tổng demo user = 30 (16 sample @solutionerp.local cũ + 14 Solutions thật @solutions.com.vn).

C. Docs cleanup từ session 3

3 commit dọn MD trước:

  • e65578a — chốt session 3 PE polish iter 2 + domain rebrand + 5 gotcha mới (#34-38)
  • e71e0eb — tái cấu trúc cleanup: archive raw dump, compact migration-todos, update CLAUDE+flows
  • 309dcd9 — chốt final session 3 audit MD + session log + minor fixes

D. Chốt MD session 4 → 5

Updated:

  • docs/STATUS.md — header + Recently Done 3 row mới (Budget BE / 14 users / Docs cleanup), cumulative table thêm cột "+Budget+30 users"
  • docs/HANDOFF.md — TL;DR session 4 (2 milestone Budget BE + 14 users) + Cảnh báo session 5 + Priority 0 (FE Budget + PE/HD integration + PE feature gap) + Credentials 30 user
  • docs/changelog/migration-todos.md — Phase 7 thêm section D Budget done, Phase 8 mới (FE Budget pages + integration), pending migrations Budget
  • docs/architecture.md — §10 Budget module mới (sơ đồ ERD + state machine + auto-recompute + integration roadmap), renumber §11 Liên quan
  • docs/database/schema-diagram.md — Migration history rows 13+14, §12 Budget ERD chi tiết (4 bảng + state machine + auto-recompute + pending refinement), §13 Liên quan
  • .claude/skills/ef-core-migration/SKILL.md — Migration 14 entry, total 51 bảng, Phase 8 pending Budget refinement
  • CLAUDE.md (root + docs/) — modules table thêm Budget row, scope Budget, count 51 bảng / 14 migration
  • ~/.claude/projects/.../memory/project_solution_erp.md — Phase 7 Budget BE + 14 user + tổng số mới + Session 5 priority

E. Session 5 carry-over

Priority 0 — FE Budget pages

Copy pattern PE:

  • fe-admin/src/types/budget.ts
  • fe-admin/src/pages/budgets/BudgetsListPage.tsx (3-panel)
  • fe-admin/src/pages/budgets/BudgetCreatePage.tsx
  • fe-admin/src/components/budgets/BudgetDetailTabs.tsx
  • fe-admin/src/components/budgets/BudgetWorkflowPanel.tsx
  • Mirror sang fe-user
  • Routes /budgets, /budgets/new, /budgets/:id
  • Menu resolver Bg_*

Priority 1 — PE/Contract → Budget integration

  • PE form thêm field Ngân sách select Budget (filter Phase=DaDuyet && NamNganSach=current && ProjectId match)
  • Contract form tương tự
  • PE Detail tab thêm cột "So với ngân sách" (compute từ BudgetDetail tương ứng)

Priority 2 — PE feature gap

  • PE Workflow admin designer UI /system/pe-workflows/:typeCode
  • Ý kiến 4 phòng ban (Phê duyệt/CCM/MuaHàng/SM-PM)
  • Export phiếu PDF/Excel

Optional

  • Budget MaNganSach atomic sequence (chốt format chính thức)
  • Budget versioned workflow (admin config UI)
  • Payment terms PE tách field
  • Auto-map PE Details → Contract Details
  • Matrix Quotes bulk paste

Ops

  • Remove binding cũ .huypham.vn
  • win-acme fix unhealthy
  • UAT thật 1 tuần với 2-3 user (30 user demo)
  • SMTP config Email outbox
  • Rotate credentials
  • Schedule SQL backup

F. Stats sau session 4

Trước session 4 Sau session 4
BE LOC ~11400 ~11750 (+340 Budget)
DB tables 47 51 (+4 Budget)
API endpoints ~113 ~124 (+11 Budget)
Migrations 13 14 (AddBudgets)
FE pages ~26 ~26 (Budget FE TODO)
Demo user 16 30 (+14 Solutions thật)
Docs ~48 ~50 (+ session log + chốt MD)
Gotchas 38 38 (no new)
Commits ~70 ~75

G. Lessons learned session 4

  1. Workflow simple hardcoded chấp nhận được khi user yêu cầu "tạm thời chưa có" — không over-engineer versioned WF + atomic sequence ngay từ đầu. User confirm BudgetPolicy.Default static + Random.Shared MaNganSach OK cho UAT, refine sau khi format chính thức chốt.

  2. Auto-recompute ở app layer thay vì DB trigger — đơn giản hơn, debug dễ. Mỗi handler Detail mutation gọi budget.TongNganSach = budget.Details.Sum(d => d.ThanhTien). Trade-off: nếu N người sửa Detail concurrent thì cuối cùng còn đúng do tx wrap.

  3. Reconcile pattern per-user try-catch chính xác cho seed user — 1 user fail (gotcha #38 4-field rename) không kill toàn bộ seed. Drift dept/position/role tự fix nếu user đã tồn tại.

  4. Link nullable thay vì required FK giữa Budget và Contract/PE — không bắt buộc tất cả HĐ phải có ngân sách → FE form optional + filter Phase=DaDuyet khi pick. Tránh chicken-and-egg khi roll-out module mới.

H. Cảnh báo session 5

  1. FE Budget chưa có gì — BE tested OK qua Swagger nhưng người dùng cuối chưa truy cập được. Đây là Priority 0.
  2. PE/Contract chưa thấy field Ngân sách — BE đã có FK nhưng FE chưa wire. Priority 1.
  3. Login emailadmin@solutionerp.local vẫn dùng (chỉ rebrand demo + sample user). Update khi UAT thật.
  4. Atomic sequence Budget chưa chốt — Random.Shared race condition risk thấp nhưng không zero. Nếu Solutions cần serial number nghiêm túc → migration AddBudgetCodeSequences + IBudgetCodeGenerator.
  5. Versioned workflow Budget chưa có — nếu Solutions muốn admin config 5-step thay vì 3-step → migration AddBudgetVersionedWorkflow (3 bảng + pin per Budget).

Files touched session 4

src/Backend/SolutionErp.Domain/Budgets/                    (NEW — 5 file)
  ├── BudgetPhase.cs
  ├── Budget.cs
  ├── BudgetDetail.cs
  ├── BudgetApproval.cs
  ├── BudgetChangelog.cs
  └── BudgetPolicy.cs

src/Backend/SolutionErp.Domain/Contracts/Contract.cs       (mod: +BudgetId?)
src/Backend/SolutionErp.Domain/PurchaseEvaluations/PurchaseEvaluation.cs (mod: +BudgetId?)
src/Backend/SolutionErp.Domain/Identity/MenuKeys.cs        (mod: +Budgets keys)

src/Backend/SolutionErp.Infrastructure/Persistence/Configurations/
  ├── BudgetConfiguration.cs                               (NEW — 4 entity config)
  ├── ContractConfiguration.cs                             (mod: +BudgetId index)
  └── PurchaseEvaluationConfiguration.cs                   (mod: +BudgetId index)

src/Backend/SolutionErp.Infrastructure/Persistence/
  ├── ApplicationDbContext.cs                              (mod: +4 DbSet Budget*)
  └── DbInitializer.cs                                     (mod: +14 Solutions user + Budget menu seed)

src/Backend/SolutionErp.Infrastructure/Persistence/Migrations/
  └── 20260428043508_AddBudgets.cs                         (NEW — migration 14)
  └── 20260428043508_AddBudgets.Designer.cs                (NEW)
  └── ApplicationDbContextModelSnapshot.cs                 (mod)

src/Backend/SolutionErp.Application/Common/Interfaces/IApplicationDbContext.cs (mod: +4 DbSet)
src/Backend/SolutionErp.Application/Budgets/                (NEW — 2 file)
  ├── BudgetFeatures.cs                                     (~340 LOC, 11 CQRS handler)
  └── Dtos/BudgetDtos.cs                                    (6 DTO)

src/Backend/SolutionErp.Api/Controllers/BudgetsController.cs (NEW — 11 endpoint)

docs/STATUS.md                                              (mod: header + Recently Done + cumulative)
docs/HANDOFF.md                                             (mod: TL;DR + Priority 0 + creds)
docs/changelog/migration-todos.md                           (mod: Phase 7 partial + Phase 8 mới)
docs/architecture.md                                        (mod: +§10 Budget)
docs/database/schema-diagram.md                             (mod: +migration 13+14, +§12 Budget)
docs/CLAUDE.md                                              (mod: Phase 7 row + scope Budget)
CLAUDE.md                                                   (mod: modules table + scope)
.claude/skills/ef-core-migration/SKILL.md                   (mod: migration 14)
docs/changelog/sessions/2026-04-28-chot-session-4-budget.md (NEW — file này)
~/.claude/projects/.../memory/project_solution_erp.md       (mod: Phase 7 + 14 user)