[CLAUDE] Docs: chốt session 4 — Budget BE module + 14 Solutions users
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 2m53s

- 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>
This commit is contained in:
pqhuy1987
2026-04-28 12:36:31 +07:00
parent a05c57b081
commit e0b4e7f096
9 changed files with 575 additions and 110 deletions

View File

@ -481,8 +481,10 @@ COMMIT;
| **10** | **`AddMasterCatalogs`** | **UnitsOfMeasure, MaterialItems, ServiceItems, WorkItems** |
| **11** | **`AddRoleShortNameAndUserDepartment`** | **+Role.ShortName + User.DepartmentId/Position (cột thêm, không bảng mới)** |
| **12** | **`AddPurchaseEvaluations`** | **10 bảng module Duyệt NCC: PurchaseEvaluations + Suppliers + Details + Quotes + Approvals + Changelogs + Attachments + WorkflowDefinitions + WorkflowSteps + WorkflowStepApprovers** |
| **13** | **`AddPurchaseEvaluationCodeSequences`** | **PurchaseEvaluationCodeSequences (Prefix PK, atomic seq mirror ContractCodeSequences). Format MaPhieu PE/{YYYY}/{A\|B}/{Seq:D3}** |
| **14** | **`AddBudgets`** | **4 bảng module Ngân sách: Budgets + BudgetDetails + BudgetApprovals + BudgetChangelogs. + nullable FK index Contract.BudgetId & PurchaseEvaluation.BudgetId** |
Tổng: **46 bảng** (+ `__EFMigrationsHistory` hệ thống).
Tổng: **51 bảng** (+ `__EFMigrationsHistory` hệ thống).
## 8bis. Bảng mới sau Migration 9-11
@ -625,7 +627,61 @@ PE.Phase=DaDuyet && SelectedSupplierId && !ContractId
→ navigate /contracts/{newId}
```
## 12. Liên quan
## 12. Budget module (Migration 14 — 4 bảng mới)
Module quản lý ngân sách dự án. Liên kết nullable Contract & PurchaseEvaluation cho đối chiếu chi phí. Workflow simple 3-step (chưa versioned, hardcoded `BudgetPolicy.Default`).
### Core (4 bảng):
| Bảng | Mục đích |
|---|---|
| `Budgets` | Header. **MaNganSach** `NS-{YYYYMM}-{Random:4d}` UK filtered, **TenNganSach** required, Description, **NamNganSach** int (year), **ProjectId** FK Restrict, **DepartmentId?** FK Restrict, **DrafterUserId** FK Restrict, **Phase** enum (5-state), **TongNganSach** decimal(18,2) auto-recompute từ Sum(BudgetDetails.ThanhTien), **SlaDeadline** DateTime?, **SlaWarningSent** bool. AuditableEntity (soft delete). |
| `BudgetDetails` | Flat row pattern (giống PE Details, KHÔNG nested). **BudgetId** FK Cascade, **GroupCode** (50 char) + **GroupName** (200) — phân nhóm hạng mục, **ItemCode** (100), **NoiDung** (500) required, **DonViTinh** (50), **KhoiLuong** decimal(18,4), **DonGia** decimal(18,2), **ThanhTien** decimal(18,2), **Order** int, **GhiChu** (1000). Index (BudgetId, Order). |
| `BudgetApprovals` | Workflow history. FromPhase/ToPhase/Decision (reuse `ApprovalDecision` enum), ApproverUserId, Comment, ApprovedAt. Index (BudgetId, ApprovedAt). |
| `BudgetChangelogs` | Audit log unified. **EntityType** enum `BudgetEntityType` (1=Header, 2=Detail, 3=Workflow), EntityId Guid?, **Action** enum `ChangelogAction` (Insert/Update/Delete/Transition), PhaseAtChange enum?, UserId Guid? + UserName denorm, Summary (500), FieldChangesJson nvarchar(max), ContextNote (2000). Indexes (BudgetId, CreatedAt) + (BudgetId, EntityType). |
### Link nullable từ Contract & PE:
```sql
ALTER TABLE Contracts ADD BudgetId UNIQUEIDENTIFIER NULL;
ALTER TABLE PurchaseEvaluations ADD BudgetId UNIQUEIDENTIFIER NULL;
CREATE INDEX IX_Contracts_BudgetId ON Contracts (BudgetId);
CREATE INDEX IX_PurchaseEvaluations_BudgetId ON PurchaseEvaluations (BudgetId);
```
Không có FK constraint cứng → Budget có thể bị soft-delete mà không ảnh hưởng HĐ/PE đã link. App layer guard validate khi chọn Budget (filter `Phase=DaDuyet && !IsDeleted`).
### State machine BudgetPhase (5-state):
```
DangSoanThao(1) ──Trình──► ChoCCM(2) ──Duyệt──► ChoCEO(3) ──Duyệt──► DaDuyet(4)
▲ │ │
└──Trả về───────────────┘ │
└──Trả về─────────────────────────────────────┘
└──Hủy──► TuChoi(99)
Role mapping (BudgetPolicy.Default):
- Drafter / DeptManager: DangSoanThao → ChoCCM (Trình) hoặc TuChoi (Hủy)
- CostControl (CCM): ChoCCM → ChoCEO (Duyệt) hoặc DangSoanThao (Trả về)
- Director / AuthSigner: ChoCEO → DaDuyet (Duyệt) hoặc DangSoanThao (Trả về)
```
### Auto-recompute TongNganSach:
```csharp
// AddBudgetDetailHandler / UpdateBudgetDetailHandler / DeleteBudgetDetailHandler
budget.TongNganSach = budget.Details.Where(d => !d.IsDeleted).Sum(d => d.ThanhTien);
db.Budgets.Update(budget);
```
Không trigger DB → app layer tính lại sau mỗi mutation Detail. Đơn giản, debug dễ.
### Pending refinement (Phase 8):
- **`AddBudgetCodeSequences`** — atomic SERIALIZABLE sequence khi format chốt chính thức (mirror Contract/PE pattern).
- **`AddBudgetVersionedWorkflow`** — nếu Solutions cần admin config UI thay vì hardcoded policy. Pattern: `BudgetWorkflowDefinitions` + `Steps` + `StepApprovers` + `Budget.WorkflowDefinitionId?` pinned at create.
## 13. Liên quan
- [`database-guide.md`](database-guide.md) — conventions + migration workflow + cheatsheet đầy đủ
- [`../architecture.md`](../architecture.md) — layered architecture + data flow