From e0b4e7f0966db4108d4c6d4c4d8ea33ce8fca842 Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Tue, 28 Apr 2026 12:36:31 +0700 Subject: [PATCH] =?UTF-8?q?[CLAUDE]=20Docs:=20ch=E1=BB=91t=20session=204?= =?UTF-8?q?=20=E2=80=94=20Budget=20BE=20module=20+=2014=20Solutions=20user?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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) --- .claude/skills/ef-core-migration/SKILL.md | 17 +- CLAUDE.md | 11 +- docs/CLAUDE.md | 13 +- docs/HANDOFF.md | 136 +++++---- docs/STATUS.md | 90 +++--- docs/architecture.md | 44 ++- docs/changelog/migration-todos.md | 54 +++- .../2026-04-28-chot-session-4-budget.md | 260 ++++++++++++++++++ docs/database/schema-diagram.md | 60 +++- 9 files changed, 575 insertions(+), 110 deletions(-) create mode 100644 docs/changelog/sessions/2026-04-28-chot-session-4-budget.md diff --git a/.claude/skills/ef-core-migration/SKILL.md b/.claude/skills/ef-core-migration/SKILL.md index ee75068..8001838 100644 --- a/.claude/skills/ef-core-migration/SKILL.md +++ b/.claude/skills/ef-core-migration/SKILL.md @@ -1,6 +1,6 @@ --- name: ef-core-migration -description: Tạo/sửa/revert EF Core 10 migration cho SOLUTION_ERP. Dùng khi thêm entity mới, thay đổi schema, rollback migration, debug DesignTimeDbContextFactory fail. Đã có 13 migration sẵn (Init → AddPurchaseEvaluationCodeSequences). Snapshot + Designer + Migration 3-file rule bắt buộc commit đủ. +description: Tạo/sửa/revert EF Core 10 migration cho SOLUTION_ERP. Dùng khi thêm entity mới, thay đổi schema, rollback migration, debug DesignTimeDbContextFactory fail. Đã có 14 migration sẵn (Init → AddBudgets). Snapshot + Designer + Migration 3-file rule bắt buộc commit đủ. when-to-use: - "thêm migration" - "EF Core migration" @@ -16,7 +16,7 @@ when-to-use: > **Context:** .NET 10 + EF Core 10 + SQL Server. DbContext: `ApplicationDbContext` ở `Infrastructure/Persistence/`. Startup: `SolutionErp.Api`. -## Migration history (12 migration hiện có) +## Migration history (14 migration hiện có) | # | Name | Tables added / changed | |---|---|---| @@ -33,13 +33,22 @@ when-to-use: | 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/Steps/StepApprovers** | | **13** | **`AddPurchaseEvaluationCodeSequences`** | **1 bảng `PurchaseEvaluationCodeSequences` (Prefix PK, LastSeq) — atomic sequence cho MaPhieu format `PE/{YYYY}/{A\|B}/{Seq:D3}`** | +| **14** | **`AddBudgets`** | **4 bảng module Ngân sách: Budgets + BudgetDetails + BudgetApprovals + BudgetChangelogs. + nullable FK index `Contracts.BudgetId` & `PurchaseEvaluations.BudgetId`** | -Total: **47 bảng** dbo + `__EFMigrationsHistory`. Xem `docs/database/schema-diagram.md` ERD đầy đủ. +Total: **51 bảng** dbo + `__EFMigrationsHistory`. Xem `docs/database/schema-diagram.md` ERD đầy đủ. -**Phase 7 pending (session sau):** +**Phase 7 pending:** - `AddPePaymentTermFields` — tách `PurchaseEvaluations.PaymentTerms` JSON thành 6 column riêng - `AddPeDepartmentOpinions` — thêm 4 field Ý kiến phòng ban (Phê duyệt/CCM/MuaHàng/SM-PM) vào header hoặc table riêng +**Phase 8 pending (Budget refinement):** +- `AddBudgetCodeSequences` — atomic sequence khi format MaNganSach chốt (mirror Contract/PE pattern, hiện Random.Shared) +- `AddBudgetVersionedWorkflow` — nếu Solutions cần admin config UI (3 bảng `BudgetWorkflowDefinitions/Steps/StepApprovers` + `Budgets.WorkflowDefinitionId?`) + +**Phase 7 update (2026-04-28):** +- Migration 14 `AddBudgets` — 4 bảng (Budgets/Details/Approvals/Changelogs) + 2 cột `BudgetId?` thêm vào Contracts & PurchaseEvaluations. Workflow hardcoded `BudgetPolicy.Default` (chưa versioned). +- 14 demo user thật `@solutions.com.vn` qua `SeedDemoUsersAsync` reconcile (PRO 5 + CCM 7 + ISO 1 + CEO 1). + **Phase 6 update (2026-04-24):** - Enum `PurchaseEvaluationAttachmentPurpose.ComparisonTable = 4` mới (file bảng so sánh tổng). Int column, không cần migration. diff --git a/CLAUDE.md b/CLAUDE.md index 634f4c6..4b42695 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -50,16 +50,17 @@ Kiến trúc: **.NET 10 Clean Architecture + 2 React FE (admin + user) + SQL Ser - Audit fields: `CreatedAt`, `UpdatedAt`, `CreatedBy`, `UpdatedBy` (`BaseEntity`) - Soft delete: `IsDeleted`, `DeletedAt`, `DeletedBy` (`AuditableEntity`) - Migrations: `dotnet ef migrations add --project src/Backend/SolutionErp.Infrastructure --startup-project src/Backend/SolutionErp.Api` -- **Hiện có 12 migration → 46 bảng** (Phase 6 thêm migration 12 `AddPurchaseEvaluations` — 10 bảng) +- **Hiện có 14 migration → 51 bảng** (Phase 7 thêm migration 14 `AddBudgets` — 4 bảng + 2 cột `BudgetId?` nullable trên Contracts/PurchaseEvaluations) ### Modules | Module | Namespace | Migration | Trạng thái | |---|---|---|---| | Contract (HĐ) | `Domain/Contracts/` | 1-11 | Feature-complete (7 ContractType × 9 phase) | -| PurchaseEvaluation (Duyệt NCC tiền-HĐ) | `Domain/PurchaseEvaluations/` | 12 | **Skeleton — còn chỉnh nhiều (Phase 7 WIP)** | +| PurchaseEvaluation (Duyệt NCC tiền-HĐ) | `Domain/PurchaseEvaluations/` | 12, 13 | UX polish complete — feature gap: Designer UI / Ý kiến 4 PB / Export PDF | +| **Budget (Ngân sách dự án)** | `Domain/Budgets/` | **14** | **BE done — FE pages chưa làm (Priority 0 session 5)** | | Master (Supplier/Project/Department) | `Domain/Master/` | 2, 10 | Feature-complete | -| Identity (User/Role/Permission/MenuItem) | `Domain/Identity/` | 1, 3, 11 | Feature-complete | +| Identity (User/Role/Permission/MenuItem) | `Domain/Identity/` | 1, 3, 11 | Feature-complete (30 demo user — 16 sample + 14 Solutions thật) | | Forms (Template + Clause) | `Domain/Forms/` | 4 | Feature-complete | | Notifications | `Domain/Notifications/` | 6 | In-app + SignalR OK, email SMTP TODO | @@ -69,7 +70,7 @@ Kiến trúc: **.NET 10 Clean Architecture + 2 React FE (admin + user) + SQL Ser [CLAUDE] : ``` -**Scope:** `Contract` · `PurchaseEvaluation` · `Form` · `Workflow` · `Supplier` · `Auth` · `Admin` · `Api` · `App` · `Domain` · `Infra` · `FE-Admin` · `FE-User` · `Docs` · `CICD` · `Scripts` · `Skill` +**Scope:** `Contract` · `PurchaseEvaluation` · `Budget` · `Form` · `Workflow` · `Supplier` · `Auth` · `Admin` · `Api` · `App` · `Domain` · `Infra` · `FE-Admin` · `FE-User` · `Docs` · `CICD` · `Scripts` · `Skill` ## 🛠️ Skills (.claude/skills/) — 6 skill PHẢI dùng khi task khớp @@ -97,7 +98,7 @@ Quy tắc: KHÔNG bulk-clone repo skill 3rd party. Chỉ thêm skill PROJECT-SPE | [`docs/workflow-contract.md`](docs/workflow-contract.md) | State machine 9 phase HĐ + role matrix | | [`docs/forms-spec.md`](docs/forms-spec.md) | Catalog 8 form + quy định mã HĐ RG-001 | | [`docs/database/database-guide.md`](docs/database/database-guide.md) | DB conventions + migration workflow + cheatsheet | -| [`docs/database/schema-diagram.md`](docs/database/schema-diagram.md) | ⭐ ERD + luồng DB + data flow 46 table (+ §11 PE module) | +| [`docs/database/schema-diagram.md`](docs/database/schema-diagram.md) | ⭐ ERD + luồng DB + data flow 51 table (+ §11 PE module + §12 Budget module) | | [`docs/flows/README.md`](docs/flows/README.md) | Index 6 flow (auth, permission, contract, form, SLA) | | [`docs/gotchas.md`](docs/gotchas.md) | ⭐ 26 bẫy đã gặp — đọc trước khi debug tương tự | | [`.claude/skills/`](.claude/skills/README.md) | 6 skill: contract-workflow, form-engine, permission-matrix, dependency-audit-erp, ef-core-migration, iis-deploy-runbook | diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md index 81d0416..b78f3a6 100644 --- a/docs/CLAUDE.md +++ b/docs/CLAUDE.md @@ -10,6 +10,7 @@ 3. Tự gen mã HĐ theo Quy định SOL-CCM-RG-001 4. Dashboard báo cáo HĐ theo NCC, dự án, trạng thái, giá trị 5. **Module Duyệt NCC (Phase 6)** — phiếu trình duyệt so sánh giá tiền-HĐ, 2 quy trình A/B, kế thừa HĐ 1-click khi DaDuyet +6. **Module Ngân sách (Phase 7)** — 4 bảng quản lý ngân sách dự án, workflow simple 3-step, link nullable Contract & PE để đối chiếu chi phí ## 2. Kiến trúc tổng thể @@ -59,13 +60,13 @@ SOLUTION_ERP/ │ ├── HANDOFF.md ⭐ brief 5 phút cho session tiếp │ ├── PROJECT-MAP.md bản đồ tổng quan │ ├── rules.md coding conventions -│ ├── architecture.md layered + PE module §9 +│ ├── architecture.md layered + PE §9 + Budget §10 │ ├── gotchas.md 38 pitfall đã gặp │ ├── forms-spec.md 8 form catalog + RG-001 │ ├── workflow-contract.md 9 phase HĐ + role matrix │ ├── database/ │ │ ├── database-guide.md conventions + migration workflow -│ │ └── schema-diagram.md ERD 47 bảng (+§11 PE) +│ │ └── schema-diagram.md ERD 51 bảng (+§11 PE +§12 Budget) │ ├── flows/ 6 sequence diagram (auth/permission/contract/form/sla + PE ref architecture) │ ├── guides/ setup, cicd, deploy, runbook, security │ ├── changelog/ @@ -106,7 +107,7 @@ SOLUTION_ERP/ - **NamGroup** (`D:\Dropbox\CONG_VIEC\NAMGROUP\SOURCECODE_CÔNG_TY\NAMGROUP\`) — template 2 FE + IIS deploy + permission matrix - **DH_Y_DUOC** (`D:\Dropbox\CONG_VIEC\DAI_Y_DUOC\DH_Y_DUOC_SOURCECODE\DH_Y_DUOC\`) — template backend hiện đại (Clean Arch + CQRS + EF migrations) -## 6. Roadmap (status 2026-04-24) +## 6. Roadmap (status 2026-04-28) | Phase | Focus | Trạng thái | |---|---|---| @@ -118,8 +119,10 @@ SOLUTION_ERP/ | **5 Production** | CI/CD Gitea Actions + 3 IIS site + Let's Encrypt + Security headers + Users CRUD | ✅ Done | | **Tier 3** | Versioned WF + 3-panel layout + 4-bảng + 4 catalogs + 16 demo users + Brand identity | ✅ Done | | **6 Module Duyệt NCC** | PE iter 1 (skeleton) + iter 2 (UX polish) + Domain rebrand `.solutions.com.vn` | ✅ Done | -| **7 PE feature gap** | Designer UI + Ý kiến 4 phòng ban + Export PDF + UAT thật + SMTP | 📝 WIP | -| **8+ Post-launch** | E-signature, Bravo/SAP, Mobile, AI OCR | 📝 Future | +| **7 Budget BE + 14 Solutions users** | Migration 14 — 4 bảng Budget + workflow simple + 11 endpoint + 14 user thật | ✅ Done (Session 4) | +| **8 Budget FE + PE/HD integration** | FE Budget pages + link select Budget vào PE/Contract form | 📝 Active (Session 5) | +| **PE feature gap** | Designer UI + Ý kiến 4 phòng ban + Export PDF + UAT thật + SMTP | 📝 Carry over | +| **9+ Post-launch** | E-signature, Bravo/SAP, Mobile, AI OCR | 📝 Future | Chi tiết atomic tasks: [`changelog/migration-todos.md`](changelog/migration-todos.md). Session logs: [`changelog/sessions/`](changelog/sessions/). diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index b0849f6..dbd6b4f 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -1,42 +1,48 @@ # HANDOFF — Brief 5 phút cho session tiếp theo -**Last updated:** 2026-04-24 chiều (Phase 6 — **PE polish iter 2 + domain rebrand hoàn tất, UAT-ready**) +**Last updated:** 2026-04-28 (Phase 7 — **Module Ngân sách (Budget) BE + 14 demo users Solutions thật**) ## TL;DR -**PE module UX polish gần complete.** Session 3 (24/04) apply 10 commit -fix tất cả UX friction user báo: -- Rename menu "Phương Án" → "Giải pháp" -- Menu tree inheritance Pe_*/PeWf_* (fix bug children không hiện) -- Accordion mutex 2 PE group + sidebar w-72 nowrap label -- NavLink active check query string (fix 2 leaf cùng highlight) -- PE detail flat layout: Panel 2 = 4 section (Thông tin/NCC/Hạng mục/**Bảng so sánh**), Panel 3 thêm Duyệt + Lịch sử thay đổi -- Upload file đính kèm per-NCC (SupplierAttachmentsCell) + Bảng so sánh tổng -- readOnly mode cho menu "Duyệt" (pendingMe=1) -- HĐ: move Lịch sử điều chỉnh Panel 2 → Panel 3 -- Demo email rebrand `@solutionerp.local → @solutions.com.vn` với backfill +**Session 4 (28/04)** thêm 2 milestone lớn: -**Domain migration (session 2):** 3 subdomain `.huypham.vn` → `.solutions.com.vn` -live E2E — `api/admin/eoffice.solutions.com.vn`. Cert Let's Encrypt + CORS + -FE bundle VITE_API_BASE_URL đều đã apply. +### A. Module Ngân sách (Budget) BE — migration 14, +4 bảng, +11 endpoint -**Tổng:** 47 DB tables, ~113 endpoints, 13 migrations, 33 gotchas, 20+ commit -session 3 push lên Gitea. +- 4 entity: `Budget` (Header) + `BudgetDetail` (flat row) + `BudgetApproval` (history) + `BudgetChangelog` (audit log). +- Enum `BudgetPhase` 5 state (DangSoanThao→ChoCCM→ChoCEO→DaDuyet + TuChoi). +- `BudgetPolicy.Default` hardcoded simple 3-step (Drafter→CCM→CEO) — chưa versioned (TODO khi user cần admin config UI). +- Mã `NS-YYYYMM-XXXX` Random.Shared (chưa atomic — TODO khi format chính thức). +- Link nullable: `Contract.BudgetId?` + `PE.BudgetId?` đã có FK + index, FE chưa wire form. +- Menu seed `Budgets` root + 3 leaf (Bg_List/Bg_Create/Bg_Pending) order=27 icon Wallet. +- Application: 11 CQRS handler ~340 LOC (Create/UpdateDraft/Transition/List/GetDetail/Delete + Detail CRUD auto-recompute TongNganSach + ListChangelogs). +- Api: `BudgetsController` 11 endpoint REST. +- **FE chưa làm — Priority 0 session 5.** -## ⚠️ CẢNH BÁO session tiếp (Session 4) +### B. 14 demo user Solutions thật -1. **Chưa xóa binding cũ `.huypham.vn`** — vẫn active fallback. Sau 1-2 ngày +- PRO 5 (TPB tra.bui + 4 NV) + CCM 7 (TPB ngocanh.huynh + 6 NV) + ISO 1 (chau.le) + CEO 1 (huy.duong). +- Pwd `User@123456`. Reconcile pattern (gotcha #38 4-field rename). +- Tổng 30 user (16 sample cũ giữ + 14 Solutions thật mới). + +**Tổng:** 51 DB tables, ~124 endpoints, 14 migrations, 38 gotchas, 5+ commit +session 4 push lên Gitea. + +## ⚠️ CẢNH BÁO session tiếp (Session 5) + +1. **FE Budget pages CHƯA LÀM** — BE đã sẵn sàng nhưng chưa có page nào. Pattern: copy từ PE 3-panel List + Create + Detail tabs (Thông tin / Hạng mục) + WorkflowPanel timeline. Mirror sang fe-user. Thêm route `/budgets`, `/budgets/new`, `/budgets/:id`. Menu resolver `Bg_*` → URL. +2. **PE/Contract → Budget integration CHƯA WIRE** — BE đã có `BudgetId?` nullable FK trên cả 2 entity, FE form chưa thêm field "Ngân sách" select. Cần filter Budget theo `Phase=DaDuyet && NamNganSach=current && ProjectId match`. Tab Hạng mục có thể bonus cột "So với ngân sách". +3. **Chưa xóa binding cũ `.huypham.vn`** — vẫn active fallback. Sau 1-2 ngày verify stable → `.\migrate-domains.ps1 -RemoveOld -SkipCert` trên VPS. -2. **win-acme scheduled task "unhealthy"** — cert auto-renew có thể fail +4. **win-acme scheduled task "unhealthy"** — cert auto-renew có thể fail khi gần 2026-06-18. Fix: mở `wacs.exe` interactive → Manage Renewals → recreate task. -3. **PE còn 3 task MISSING** cho feature-complete (xem STATUS §A): +5. **PE feature gap carry over** (xem STATUS §C): - PE Workflow admin designer UI `/system/pe-workflows/:typeCode` - - Auto-map PE Details → Contract 7 per-type Details khi gen HĐ - Section "Ý kiến 4 phòng ban" (Phê duyệt/CCM/MuaHàng/SM-PM) -4. **Login email mới** `admin@solutions.com.vn` / `Admin@123456` — old - `@solutionerp.local` đã bị rename 401. -5. **Chú ý G-084:** VPS shared với VietReport — mọi reverse proxy / backend + - Export phiếu PDF/Excel +6. **Login email** `admin@solutionerp.local` / `Admin@123456` — domain default + chưa đổi sang `@solutions.com.vn` (chỉ demo user và rebrand cũ trong BackfillDemoEmail). +7. **Chú ý G-084:** VPS shared với VietReport — mọi reverse proxy / backend service mới phải dùng `127.0.0.1` + bind loopback IPv4 explicit. ## ⭐ Skills (.claude/skills/) — PHẢI dùng khi task khớp @@ -76,7 +82,12 @@ session 3 push lên Gitea. | **Master expand 15 NCC + 8 Project** + backfill demo HĐ diverse | ✅ Done | | **Deps audit script** (`scripts/deps-audit.ps1`) | ✅ Done | | **Module Duyệt NCC (tiền-HĐ) E2E** — 10 bảng + 2 workflow + Kế thừa HĐ | ✅ Done | -| 6+ Post-launch (E-signature, Bravo/SAP, Mobile, AI) | 📝 Future | +| **PE polish iter 2** — flat layout + per-NCC attachments + readOnly Duyệt + email rebrand | ✅ Done | +| **Domain rebrand huypham.vn → solutions.com.vn** — 3 subdomain + cert + CORS + FE bundle | ✅ Done | +| **Module Ngân sách BE** — 4 bảng + 11 endpoint + workflow simple + 30 user | ✅ Done (FE TODO) | +| **PE Workflow designer UI + Ý kiến 4 phòng ban + Export PDF** | 📝 Pending session 5+ | +| **FE Budget pages + PE/Contract → Budget integration** | 📝 Priority 0 session 5 | +| 8+ Post-launch (E-signature, Bravo/SAP, Mobile, AI) | 📝 Future | ## Run nhanh @@ -117,25 +128,41 @@ Login: `admin@solutionerp.local` / `Admin@123456` ## Cần làm kế tiếp -### 🔥 Priority 0 — PE feature gap (session 4) +### 🔥 Priority 0 — Budget FE + PE/HD integration (session 5) -Xem **STATUS.md §🔥 In Progress** đầy đủ (nhóm A/B/C/D). 3 task MISSING cuối: +Xem **STATUS.md §🔥 In Progress** đầy đủ (nhóm A/B/C/D/E). Tóm tắt: -1. **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` — mirror pattern `WorkflowsPage.tsx` + `WorkflowDesigner.tsx`. BE cần `PeWorkflowAdminFeatures.cs` (GetOverview + CreateNewVersion) + `PeWorkflowsController.cs`. Framework backend đã sẵn (3 bảng `PurchaseEvaluationWorkflow*` + `FromDefinition` builder), chỉ thiếu wire UI. +**A. Budget FE pages — copy pattern PE:** +1. `fe-admin/src/types/budget.ts` (types + enums BudgetPhase + ApprovalDecision reuse) +2. `fe-admin/src/pages/budgets/BudgetsListPage.tsx` (3-panel `lg:grid-cols-[320px_1fr_360px]` — Panel 1 list + Panel 2 detail tabs + Panel 3 workflow timeline) +3. `fe-admin/src/pages/budgets/BudgetCreatePage.tsx` (form Header: tên/năm/dự án/phòng ban/người soạn) +4. `fe-admin/src/components/budgets/BudgetDetailTabs.tsx` (Thông tin / Hạng mục — flat row giống PE Details) +5. `fe-admin/src/components/budgets/BudgetWorkflowPanel.tsx` (Panel 3: timeline phase + ô comment + button Trình) +6. Mirror tất cả sang `fe-user/` +7. App.tsx routes `/budgets`, `/budgets/new`, `/budgets/:id` cả 2 app +8. Menu resolver `Bg_*` ở Layout: `Bg_List` → `/budgets`, `Bg_Pending` → `/budgets?phase=Pending`, `Bg_Create` → `/budgets/new` + +**B. PE/Contract → Budget integration:** +1. **PE form** thêm field `Ngân sách` select Budget (filter `Phase=DaDuyet && NamNganSach=current && ProjectId=peProjectId`). Lưu `PE.BudgetId`. +2. **Contract form** tương tự — link sang Budget cho đối chiếu chi phí. +3. PE Detail tab có thể thêm cột "So với ngân sách" — compute từ `BudgetDetail` tương ứng (match GroupCode + ItemCode) nếu có Budget link. + +**C. PE feature gap (carry over từ session 3):** +1. **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` — mirror pattern `WorkflowsPage.tsx` + `WorkflowDesigner.tsx`. BE cần `PeWorkflowAdminFeatures.cs` + `PeWorkflowsController.cs`. Framework backend đã sẵn (3 bảng `PurchaseEvaluationWorkflow*` + `FromDefinition`), chỉ thiếu wire UI. 2. **Ý kiến 4 phòng ban** (Phê duyệt / P.CCM / P.MuaHàng / SM-PM) — Excel form có, entity chưa map. Cần design: 4 text field + signoff date, hoặc dùng Approvals với role-kind. 3. **Export phiếu PDF/Excel** — tái dùng `IDocumentConverter` + template `PE-TrinhDuyet.docx`. -4. **Payment terms tách field** từ JSON blob → 6 field riêng (optional UX polish). -5. **Auto-map PE Details → Contract Details** khi gen HĐ (optional nâng cấp). -**Đã xong trong session 3 (check STATUS Recently Done):** -- ~~PE Attachments upload~~ ✅ (per-NCC + Bảng so sánh tổng) -- ~~Menu tree inheritance Pe_*/PeWf_*~~ ✅ -- ~~Accordion mutex + sidebar width + label nowrap~~ ✅ -- ~~NavLink query active check~~ ✅ -- ~~PE detail flat layout + readOnly mode~~ ✅ -- ~~HĐ move Lịch sử điều chỉnh → Panel 3~~ ✅ -- ~~Menu rename Phương Án → Giải pháp~~ ✅ -- ~~Demo email rebrand solutionerp.local → solutions.com.vn~~ ✅ +**D. Optional polish:** +- Budget MaNganSach atomic sequence (hiện Random.Shared, format chốt sau) +- Budget versioned workflow (admin config qua UI — hiện hardcoded `BudgetPolicy.Default`) +- Payment terms PE tách field +- Auto-map PE Details → Contract Details khi gen HĐ +- Matrix Quotes bulk paste từ Excel + +**Đã xong trong session 4 (check STATUS Recently Done):** +- ~~Module Ngân sách BE — 4 bảng + 11 endpoint + workflow simple~~ ✅ +- ~~14 demo user Solutions thật (PRO 5 + CCM 7 + ISO 1 + CEO 1)~~ ✅ +- ~~Docs cleanup + tái cấu trúc MD~~ ✅ ### A. Hard blockers (chờ user / ops) @@ -195,7 +222,7 @@ Trigger: user nói "audit skill" hoặc tự chạy đầu Phase mới. ## Lưu ý kỹ thuật quan trọng -**Đọc [`gotchas.md`](gotchas.md) (26 bẫy) trước khi:** +**Đọc [`gotchas.md`](gotchas.md) (38 bẫy) trước khi:** - Thêm package mới → .NET 10 compat (MediatR 14 fail → dùng 12.4.1) - Debug TS enum error → dùng const-object pattern (`erasableSyntaxOnly`) @@ -363,18 +390,23 @@ Remote: https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp.git ``` admin@solutionerp.local / Admin@123456 ← Admin (QTV) -Demo users (User@123456): - bod.huynh@solutionerp.local Tổng GĐ (BOD) - bod.le@solutionerp.local Phó GĐ NĐUQ - pm.nguyen@solutionerp.local GĐ Dự án FLOCK 01 (PM) - ccm.tran@solutionerp.local TPB Kiểm soát chi phí (CCM + TPB) - pro.pham@solutionerp.local TPB Cung ứng (PRO + TPB) - fin.do@solutionerp.local TPB Tài chính (FIN + TPB) - act.vu@solutionerp.local Kế toán trưởng (ACT + TPB) - equ.bui@solutionerp.local TPB Thiết bị (EQU + TPB) - hra.dang@solutionerp.local TPB HRA (HRA + TPB) +Demo users — 30 user (User@123456): + + ── 16 sample @solutionerp.local (giữ cho test legacy) ── + bod.huynh, bod.le Tổng GĐ + Phó GĐ NĐUQ + pm.nguyen GĐ Dự án FLOCK 01 (PM) + ccm.tran, pro.pham, fin.do TPB CCM/PRO/FIN + act.vu, equ.bui, hra.dang Kế toán trưởng / TPB EQU / TPB HRA qs.hoang, qs.ngo QS công trường (NV.PB) - nv.cao, nv.dinh NV Cung ứng/Tài chính (NV.PB) + nv.cao, nv.dinh, nv.truong NV Cung ứng/Tài chính/CCM (NV.PB) + bod.tran, pm.le Bonus NĐUQ + PM thứ 2 + + ── 14 Solutions thật @solutions.com.vn (session 4) ── + PRO 5: tra.bui (TPB) + phuong.nguyen, binh.lethanh, danh.huynh, dat.tran (NV) + CCM 7: ngocanh.huynh (TPB) + ha.dao, cuong.do, long.le, ha.nguyen, + dung.nguyen, anh.nguyen (NV) + ISO 1: chau.le + CEO 1: huy.duong ⚠ Rotate ALL passwords trước UAT thật ``` diff --git a/docs/STATUS.md b/docs/STATUS.md index 80a5796..eea85b9 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -2,9 +2,9 @@ > **Update rule:** trước khi bắt đầu 1 task → ghi row vào `🔥 In Progress`. Xong → chuyển sang `✅ Recently Done`. -**Last updated:** 2026-04-24 chiều (Phase 6 — **PE polish iter 2: rename/attachments/readOnly/comparison-table + email rebrand**) +**Last updated:** 2026-04-28 (Phase 7 — **Module Ngân sách (Budget) BE + 14 demo users Solutions**) -## 📍 Phase hiện tại: **Module Duyệt NCC — UX polish hoàn thiện, UAT-ready** — 47 DB tables, ~113 endpoints (+3 PE attachments), 13 migrations. Tất cả tính năng session 3 yêu cầu đã apply prod. PE module live đầy đủ: Domain rebrand + layout 4-section + upload file per-NCC + bảng so sánh tổng + readOnly menu Duyệt + accordion mutex + NavLink query match + Lịch sử điều chỉnh HĐ move sang Panel 3 + email @solutions.com.vn. +## 📍 Phase hiện tại: **Module Ngân sách BE deployed** — 51 DB tables (+4 Budget), 14 migrations (+14 `AddBudgets`), ~124 endpoints (+11 Budget). PE module ổn định, Budget BE live (CQRS + Controller + Migration + Menu seed), FE Budget pages chưa làm. 30 demo users (16 sample + 14 Solutions thật: 5 PRO + 7 CCM + 1 ISO + 1 CEO). ### 🌐 Production URLs @@ -14,33 +14,57 @@ - https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp — Gitea repo + Actions - Default admin: `admin@solutionerp.local` / `Admin@123456` ⚠️ **RE-ROTATE sau login đầu** -## 🔥 In Progress — Còn lại cho session 4 +## 🔥 In Progress — Còn lại cho session 5 -### A. PE feature gap (3 task chưa làm) +### A. Budget — FE pages (BE đã xong) -- [ ] **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` — framework BE đã sẵn (3 bảng + `FromDefinition` builder + menu leaves). Chỉ thiếu: - - BE `PeWorkflowAdminFeatures.cs` + `PeWorkflowsController.cs` (mirror Contract version) - - FE `PeWorkflowsPage.tsx` + `PeWorkflowDesigner.tsx` (copy `WorkflowsPage.tsx` + `WorkflowDesigner.tsx`) -- [ ] **Section "Ý kiến 4 phòng ban"** (Phê duyệt/P.CCM/P.MuaHàng/SM-PM) ở tab Thông tin — Excel form có, entity chưa map. Design: 4 text field + signoff date, hoặc dùng Approvals với role-kind. -- [ ] **Export phiếu PDF/Excel** — tái dùng `IDocumentConverter` + template `PE-TrinhDuyet.docx`. +- [ ] **FE Budget pages** — copy pattern PE: + - `fe-admin/src/types/budget.ts` (types + enums) + - `fe-admin/src/pages/budgets/BudgetsListPage.tsx` (3-panel List + Detail tabs) + - `fe-admin/src/pages/budgets/BudgetCreatePage.tsx` (form Header) + - `fe-admin/src/components/budgets/BudgetDetailTabs.tsx` (Thông tin / Hạng mục) + - `fe-admin/src/components/budgets/BudgetWorkflowPanel.tsx` (Panel 3 timeline + transition) + - Mirror fe-user + - App.tsx routes `/budgets`, `/budgets/new`, `/budgets/:id` + - Menu resolver `Bg_*` → `/budgets[?phase=Pending]` -### B. Optional polish +### B. PE/Contract → Budget integration -- [ ] **Auto-map PE Details → Contract 7 per-type Details** khi gen HĐ — hiện copy header + GiaTri only. -- [ ] **Payment terms tách field** từ JSON blob → 6 field riêng (Tạm ứng/TT tạm/Quyết toán/Bảo hành/Hạn mức/Đánh giá) theo Excel section D. -- [ ] **Matrix Quotes bulk paste** từ Excel column giá. -- [ ] **fe-user Inbox** thêm section "Phiếu Duyệt NCC chờ tôi" (hoặc `/pe-inbox` riêng). -- [ ] Edge case: reject E2E, xóa phiếu khi có Contract kế thừa, admin tạo WF v02 sau khi có phiếu pin v01. +- [ ] **PE form** thêm field **"Ngân sách"** select Budget của Project (filter Phase=DaDuyet, NamNganSach=current). +- [ ] **Contract form** tương tự — link sang Budget cho đối chiếu chi phí. +- [ ] PE Detail tab thêm cột "So với ngân sách" (compute từ BudgetDetail tương ứng nếu có). -### C. Deploy / Ops chưa xong +### C. PE feature gap (carry over từ session 3) -- [ ] **Remove binding cũ `.huypham.vn`** sau 1-2 ngày verify stable: `ssh vietreport-vps ; cd C:\solution-erp\scripts ; .\migrate-domains.ps1 -RemoveOld -SkipCert` -- [ ] **win-acme scheduled task "unhealthy"** — auto-renew có thể fail trước cert expire 2026-06-18. Fix: `wacs.exe` interactive → Manage Renewals → recreate task. +- [ ] **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` +- [ ] **Section "Ý kiến 4 phòng ban"** (Phê duyệt/CCM/MuaHàng/SM-PM) +- [ ] **Export phiếu PDF/Excel** — tái dùng `IDocumentConverter` + +### D. Optional polish + +- [ ] Budget MaNganSach atomic sequence (hiện `NS-YYYYMM-XXXX` Random.Shared, chốt format chính thức sau) +- [ ] Budget versioned workflow (admin config qua UI — hiện hardcoded `BudgetPolicy.Default`) +- [ ] Payment terms tách field (PE) +- [ ] Auto-map PE Details → Contract Details khi gen HĐ +- [ ] Matrix Quotes bulk paste từ Excel +- [ ] fe-user Inbox thêm section "Phiếu Duyệt NCC chờ tôi" + +### E. Deploy / Ops chưa xong + +- [ ] **Remove binding cũ `.huypham.vn`** sau verify: `ssh vietreport-vps ; cd C:\solution-erp\scripts ; .\migrate-domains.ps1 -RemoveOld -SkipCert` +- [ ] **win-acme scheduled task "unhealthy"** — auto-renew fix trước 2026-06-18. +- [ ] UAT thật 1 tuần với 2-3 user (16 demo + 14 Solutions = 30 user) +- [ ] SMTP config → Email outbox +- [ ] Rotate creds (admin + 30 demo + SA + vrapp + JWT) +- [ ] Schedule SQL backup Task Scheduler ## ✅ Recently Done (newest on top) | Ngày | Ai | Task | Commit | |---|---|---|---| +| 2026-04-28 | Claude | **Module Ngân sách (Budget) BE — 4 bảng + workflow simple 3-step** — Migration 14 `AddBudgets`. Domain: `Budget` (Header — MaNganSach `NS-YYYYMM-XXXX`, NamNganSach, ProjectId/DepartmentId, DrafterUserId, TongNganSach auto-sum, SlaDeadline) + `BudgetDetail` (flat row pattern: GroupCode/Name + ItemCode + NoiDung + DonViTinh + KhoiLuong/DonGia/ThanhTien) + `BudgetApproval` (workflow history reuse `ApprovalDecision`) + `BudgetChangelog` (`BudgetEntityType` Header/Detail/Workflow). Enum `BudgetPhase` 5 state (DangSoanThao→ChoCCM→ChoCEO→DaDuyet + TuChoi). `BudgetPolicy.Default` hardcoded 3-step (Drafter→CCM→CEO). Application: 11 CQRS handler (~340 LOC: Create/UpdateDraft/Transition/List/GetDetail/Delete + Detail CRUD auto-recompute TongNganSach + ListChangelogs). Api: `BudgetsController` 11 endpoint. Link: Contract.BudgetId? + PE.BudgetId? nullable FK + index. Menu seed `Budgets` root + 3 leaf (Bg_List/Create/Pending) order=27 icon Wallet. **FE chưa làm** (next session). | `a05c57b` | +| 2026-04-28 | Claude | **14 demo users Solutions company thật** — PRO 5 (TPB tra.bui + 4 NV: phuong/binh/danh/dat) + CCM 7 (TPB ngocanh.huynh + 6 NV: ha.dao/cuong.do/long.le/ha.nguyen/dung.nguyen/anh.nguyen) + ISO 1 (chau.le) + CEO 1 (huy.duong). Pattern reconcile per-user try-catch (gotcha #38 4-field rename). Pwd `User@123456`. Tổng 30 user (16 sample cũ + 14 Solutions thật). Test login E2E pass. | `8097892` | +| 2026-04-28 | Claude | **Docs cleanup + chốt session 3** — Tái cấu trúc MD: archive raw dump (forms-spec-raw, workflow-raw) → `_archive/`, compact `migration-todos.md` collapse Phase 0-5+Tier3 cũ, update `CLAUDE.md` modules table + skills 6 (3 domain + 3 ops), `flows/` thêm PE ref architecture, audit `gotchas.md` (38 pitfall — thêm #34 NavLink query string + #35 menu inheritance + #36 Vite env rebuild + #37 mutex accordion family + #38 Identity 4-field rename). Session log `2026-04-23-2200-roles-demo-pending-cleanup.md` + `2026-04-24-chot-session-3-pe-polish.md`. | `309dcd9` · `e71e0eb` · `e65578a` | | 2026-04-24 | Claude | **PE polish — Demo seed + MaPhieu atomic + Pe_* perm defaults** — Migration 13 `AddPurchaseEvaluationCodeSequences` (Prefix PK, mirror ContractCodeSequences). `IPurchaseEvaluationCodeGenerator` + impl SERIALIZABLE — format `PE/{YYYY}/{A\|B}/{Seq:D3}`. Replace Random.Shared trong CreatePEHandler. `SeedDemoPurchaseEvaluationsAsync` 4 phiếu varied (A-001 DangSoanThao, A-002 ChoCEODuyetNCC + 9 quotes, A-003 DaDuyet PaymentTerms JSON, B-001 ChoDuAn 5-step). `SeedPurchaseEvaluationPermissionDefaultsAsync` 7 role × 9 menu key — Drafter/DeptManager/Procurement Create+Update, các role duyệt R+U, DeptManager thêm Delete. | `c48ac21` | | 2026-04-24 | Claude | **Rebrand 3 domain huypham.vn → solutions.com.vn E2E** — 18 file repo (FE env + scripts + CI/CD + docs + skill + code comments). Viết `scripts/migrate-domains.ps1` (ASCII-only gotcha #30) chạy trên VPS: 3 HTTP binding mới + 3 cert Let's Encrypt (HTTP-01 via SelfHosting) + auto HTTPS 443 + redirect. CI/CD auto-deploy commit `66c1a5c+b93dacf`: appsettings.Production.json CORS mới + FE bundle `VITE_API_BASE_URL=api.solutions.com.vn`. E2E verified: `/api/purchase-evaluations` 401, CORS preflight OK, FE dist có domain mới. URL cũ fallback. Claude SSH tự chạy (không cần user RDP). | `66c1a5c` · `b93dacf` | | 2026-04-23 | Claude | **SeedDemoUsersAsync robust reconcile + 16 demo users** — Reconcile pattern (per-user try-catch, fix drift dept/position/role nếu user existing). 13 → 16 demo (+bod.tran NĐUQ thứ 2, +pm.le PM thứ 2, +nv.truong NV CCM). Detailed log created/fixed/failed counts. Resolves prod issue: chỉ thấy admin user vì old skip-if-exists fail silent. | `a667665` | @@ -93,7 +117,7 @@ | 2026-04-21 | Claude | **Phase 1 foundation** + Docs addition | `702411f` + `49a5f57` | | 2026-04-21 | Claude | **Phase 0** | `25dad7f` | -Session logs: [P0](changelog/sessions/2026-04-21-1045-phase0-scaffold.md) · [P1f](changelog/sessions/2026-04-21-1100-phase1-foundation.md) · [P1.2](changelog/sessions/2026-04-21-1130-phase1-cruds-permission.md) · [P2](changelog/sessions/2026-04-21-1200-phase2-form-engine.md) · [P3](changelog/sessions/2026-04-21-1330-phase3-workflow.md) · [P4](changelog/sessions/2026-04-21-1430-phase4-report.md) · [P5prep](changelog/sessions/2026-04-21-1530-phase5-prep.md) · [Tier 3](changelog/sessions/2026-04-22-0300-tier3-feature-complete.md) · [Skill gov](changelog/sessions/2026-04-23-0900-skill-governance.md) · [Toolkit+4-bảng+Roles VN](changelog/sessions/2026-04-23-1500-toolkit-data-roles.md) · [**Roles+Demo+Pending**](changelog/sessions/2026-04-23-2200-roles-demo-pending-cleanup.md) +Session logs: [P0](changelog/sessions/2026-04-21-1045-phase0-scaffold.md) · [P1f](changelog/sessions/2026-04-21-1100-phase1-foundation.md) · [P1.2](changelog/sessions/2026-04-21-1130-phase1-cruds-permission.md) · [P2](changelog/sessions/2026-04-21-1200-phase2-form-engine.md) · [P3](changelog/sessions/2026-04-21-1330-phase3-workflow.md) · [P4](changelog/sessions/2026-04-21-1430-phase4-report.md) · [P5prep](changelog/sessions/2026-04-21-1530-phase5-prep.md) · [Tier 3](changelog/sessions/2026-04-22-0300-tier3-feature-complete.md) · [Skill gov](changelog/sessions/2026-04-23-0900-skill-governance.md) · [Toolkit+4-bảng+Roles VN](changelog/sessions/2026-04-23-1500-toolkit-data-roles.md) · [Roles+Demo+Pending](changelog/sessions/2026-04-23-2200-roles-demo-pending-cleanup.md) · [PE polish iter 2 + rebrand](changelog/sessions/2026-04-24-chot-session-3-pe-polish.md) · [**Budget BE + 14 Solutions users**](changelog/sessions/2026-04-28-chot-session-4-budget.md) **Docs entry points:** @@ -101,7 +125,7 @@ Session logs: [P0](changelog/sessions/2026-04-21-1045-phase0-scaffold.md) · [P1 - [`workflow-contract.md`](workflow-contract.md) · [`forms-spec.md`](forms-spec.md) - [`database/database-guide.md`](database/database-guide.md) · [`database/schema-diagram.md`](database/schema-diagram.md) - [`flows/`](flows/) (7 file) · [`guides/`](guides/) (4 file) · [`gotchas.md`](gotchas.md) -- [`changelog/migration-todos.md`](changelog/migration-todos.md) · [`changelog/sessions/`](changelog/sessions/) (14 file) +- [`changelog/migration-todos.md`](changelog/migration-todos.md) · [`changelog/sessions/`](changelog/sessions/) (16 file) - [`.claude/skills/README.md`](../.claude/skills/README.md) — 6 skill (3 domain + 3 ops) · audit định kỳ 1/tháng (cron `solution-erp-skill-audit-monthly` next 2026-05-01) ## 🎯 Next up @@ -138,19 +162,19 @@ Session logs: [P0](changelog/sessions/2026-04-21-1045-phase0-scaffold.md) · [P1 ## 📊 Thông số cumulative -| | P0 | P1f | P1.2 | P2 | P3 | P4 | P5prep | Tier3 | +Toolkit | +RolesPg+Demo | **+PE module** | -|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:| -| BE LOC | 0 | ~400 | ~1500 | ~1900 | ~2700 | ~3100 | ~3300 | ~4800 | ~7800 | ~8800 | **~11100** | -| DB tables | 0 | 7 | 12 | 14 | 19 | 19 | 19 | 24 | 36 | 36 | **46** (+10 PE) | -| API endpoints | 0 | 4 | 20 | 23 | 31 | 33 | 35 | ~50 | ~80 | ~93 | **~110** (+17 PE) | -| Migrations | 0 | 1 | 3 | 4 | 5 | 5 | 5 | 8 | 11 | 11 | **12** | -| FE pages | 0 | 2 | 6 | 7 | 14 | 16 | 16 | ~20 | ~22 | ~23 | **~26** (+3 PE pages × 2 app) | -| FE components | — | — | — | — | — | — | — | many | many+ | +EditRowDialog (refactor ActionBtns) | -| Scripts PS | 0 | 0 | 0 | 1 | 1 | 1 | 3 | 4 | 4 | **5** (+deps-audit.ps1) | -| CI/CD workflow | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | -| Docs | 10 | 13 | 14 | 24 | 26 | 30 | 35 | ~40 | ~42 | **~44** (+session log) | -| Demo data | 0 | 0 | seed empty | 0 | 0 | 0 | 0 | 0 | 5+3 | **15+8+7+13+4** (NCC/Project/HĐ/User/Catalogs) | -| Commits | 1 | 2 | 3 | 5 | 6 | 7 | 8 | ~25 | ~47 | **~52** | +| | P0 | P1f | P1.2 | P2 | P3 | P4 | P5prep | Tier3 | +Toolkit | +RolesPg+Demo | +PE module | +PE polish | **+Budget+30 users** | +|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:| +| BE LOC | 0 | ~400 | ~1500 | ~1900 | ~2700 | ~3100 | ~3300 | ~4800 | ~7800 | ~8800 | ~11100 | ~11400 | **~11750** (+340 Budget) | +| DB tables | 0 | 7 | 12 | 14 | 19 | 19 | 19 | 24 | 36 | 36 | 46 | 47 (+CodeSeq) | **51** (+4 Budget) | +| API endpoints | 0 | 4 | 20 | 23 | 31 | 33 | 35 | ~50 | ~80 | ~93 | ~110 | ~113 | **~124** (+11 Budget) | +| Migrations | 0 | 1 | 3 | 4 | 5 | 5 | 5 | 8 | 11 | 11 | 12 | 13 | **14** (`AddBudgets`) | +| FE pages | 0 | 2 | 6 | 7 | 14 | 16 | 16 | ~20 | ~22 | ~23 | ~26 | ~26 | ~26 (Budget FE TODO) | +| FE components | — | — | — | — | — | — | — | many | many+ | +EditRowDialog | +PE 5-tab | +Compare section | (Budget FE TODO) | +| Scripts PS | 0 | 0 | 0 | 1 | 1 | 1 | 3 | 4 | 4 | 5 | 5 | **6** (+migrate-domains.ps1) | 6 | +| CI/CD workflow | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | +| Docs | 10 | 13 | 14 | 24 | 26 | 30 | 35 | ~40 | ~42 | ~44 | ~46 | ~48 | **~50** (+session log + chốt) | +| Demo data | 0 | 0 | empty | 0 | 0 | 0 | 0 | 0 | 5+3 | 15+8+7+13+4 | +PE 4 phiếu | +rebrand email | **30 user** (16 sample + 14 Solutions thật) | +| Commits | 1 | 2 | 3 | 5 | 6 | 7 | 8 | ~25 | ~47 | ~52 | ~63 | ~70 | **~75** | ## 🚨 Blockers / risks diff --git a/docs/architecture.md b/docs/architecture.md index d455455..f763d88 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -267,7 +267,49 @@ PurchaseEvaluation (Header) ─< PurchaseEvaluationSupplier (N:M × Supplier) Chi tiết: [`database/schema-diagram.md §11`](database/schema-diagram.md). -## 10. Liên quan +## 10. Budget (Phase 7 — Module Ngân sách) + +Module quản lý ngân sách dự án: header + chi tiết hạng mục + workflow simple 3-step + audit log. Liên kết nullable cả Contract và PurchaseEvaluation để đối chiếu chi phí. + +``` +Budget (Header) ─< BudgetDetail (flat row hạng mục) + ─< BudgetApproval (workflow history) + ─< BudgetChangelog (audit log) + ─> Project (FK Restrict) + ─> Department? (FK Restrict) + ─> User Drafter (FK Restrict) + +Contract.BudgetId? ──────────► Budget (link đối chiếu chi phí HĐ) +PurchaseEvaluation.BudgetId? ─► Budget (link đối chiếu chi phí tiền-HĐ) +``` + +**Phase enum** (`BudgetPhase` 5-state): + +``` +DangSoanThao(1) ──Trình──► ChoCCM(2) ──Duyệt──► ChoCEO(3) ──Duyệt──► DaDuyet(4) + ▲ │ │ + └──Reject(99)───────────┴─────────────────────┘ +``` + +**Workflow simple hardcoded** (`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 / AuthorizedSigner: ChoCEO → DaDuyet (Duyệt) hoặc → DangSoanThao (Trả về) + +**Mã ngân sách** `NS-{YYYYMM}-{Random:4d}` — hiện Random.Shared, sẽ chuyển atomic SERIALIZABLE khi format chốt chính thức (mirror Contract/PE pattern). + +**Auto-recompute** `TongNganSach`: +- Sau Add/Update/Delete BudgetDetail → handler tự sum `Sum(d.ThanhTien)` lại Header. +- Tránh state drift, đơn giản hơn trigger DB. + +**Integration roadmap**: +- PE form select Budget (filter `Phase=DaDuyet && NamNganSach=current && ProjectId match`) +- Contract form tương tự +- Tab Hạng mục PE/HD compute "So với ngân sách" (match GroupCode + ItemCode) + +Chi tiết: [`database/schema-diagram.md §12`](database/schema-diagram.md). + +## 11. Liên quan - [`rules.md`](rules.md) — coding conventions - [`database/database-guide.md`](database/database-guide.md) — DB schema chi tiết diff --git a/docs/changelog/migration-todos.md b/docs/changelog/migration-todos.md index 236b450..00585d1 100644 --- a/docs/changelog/migration-todos.md +++ b/docs/changelog/migration-todos.md @@ -1,7 +1,7 @@ # Migration To-dos — Atomic Roadmap -> Tick `[x]` khi xong. Phase 0-5 + Tier 3 đã DONE — collapsed. Detail xem session -> logs trong `docs/changelog/sessions/`. Active work: Phase 6 (đã ✅) + Phase 7 (WIP). +> Tick `[x]` khi xong. Phase 0-5 + Tier 3 + Phase 6 đã DONE — collapsed. Detail xem session +> logs trong `docs/changelog/sessions/`. Active work: Phase 7 partial (Budget BE done, FE WIP) + Phase 8 (Budget refinement). ## ✅ Phase 0-5 + Tier 3 — Done (2026-04-21..22) @@ -57,9 +57,9 @@ Session log: `2026-04-24-chot-session-3-pe-polish.md`. Sub: `api.solutions.com.vn` · `admin.solutions.com.vn` · `eoffice.solutions.com.vn`. Old `.huypham.vn` vẫn fallback (chưa remove). -## 📝 Phase 7 — PE feature gap + ops (Session 4) +## 📝 Phase 7 — PE feature gap + Budget BE (Session 4 partial done) -### A. PE feature gap (3 task MISSING) +### A. PE feature gap (3 task MISSING — carry over session 5) - [ ] **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` - BE `Application/PurchaseEvaluations/PeWorkflowAdminFeatures.cs` (mirror `WorkflowAdminFeatures.cs`) @@ -83,15 +83,53 @@ Sub: `api.solutions.com.vn` · `admin.solutions.com.vn` · `eoffice.solutions.co - [ ] Remove binding cũ `.huypham.vn` sau verify stable: `ssh vietreport-vps ; cd C:\solution-erp\scripts ; .\migrate-domains.ps1 -RemoveOld -SkipCert` - [ ] win-acme scheduled task fix unhealthy (cert expire 2026-06-18) -- [ ] UAT thật 1 tuần với 2-3 user +- [ ] UAT thật 1 tuần với 2-3 user (30 demo user — 16 sample + 14 Solutions thật) - [ ] SMTP config → Email outbox -- [ ] Rotate credentials (admin + 16 demo + SA + vrapp + JWT) +- [ ] Rotate credentials (admin + 30 demo + SA + vrapp + JWT) - [ ] Schedule SQL backup Task Scheduler -### Pending migrations +### D. Module Ngân sách (Budget) — Session 4 ✅ partial done + +- [x] **Migration 14** `AddBudgets` — 4 bảng (Budgets/BudgetDetails/BudgetApprovals/BudgetChangelogs) + index BudgetId nullable trên Contract & PurchaseEvaluation +- [x] Domain — `Budget` (Header) + `BudgetDetail` (flat row) + `BudgetApproval` + `BudgetChangelog` + enum `BudgetPhase` 5-state + `BudgetEntityType` Header/Detail/Workflow +- [x] `BudgetPolicy.Default` hardcoded simple 3-step (Drafter→CCM→CEO + Reject từ ChoCCM/ChoCEO về DangSoanThao) +- [x] Application CQRS ~340 LOC — Create + UpdateDraft + Transition + List + GetDetail + Delete (only DangSoanThao/TuChoi) + Detail CRUD (auto-recompute TongNganSach) + ListChangelogs +- [x] `BudgetsController` 11 endpoint REST +- [x] Menu seed `Budgets` root + 3 leaf (Bg_List/Bg_Create/Bg_Pending) order=27 icon Wallet +- [x] **14 demo user Solutions thật** — PRO 5 + CCM 7 + ISO 1 + CEO 1 (pwd `User@123456`) + +Session log: `2026-04-28-chot-session-4-budget.md`. + +### E. Pending migrations - [ ] `AddPePaymentTermFields` (nếu chốt UX tách field) - [ ] `AddPeDepartmentOpinions` (nếu chọn Option A header columns) +- [ ] `AddBudgetCodeSequences` (nếu chốt format MaNganSach atomic — hiện Random.Shared) +- [ ] `AddBudgetVersionedWorkflow` (nếu user cần admin config UI thay vì hardcoded `BudgetPolicy.Default`) + +## 📝 Phase 8 — Budget FE + integration (Session 5 active) + +### A. FE Budget pages — copy pattern PE + +- [ ] `fe-admin/src/types/budget.ts` (types + enum BudgetPhase + ApprovalDecision reuse) +- [ ] `fe-admin/src/pages/budgets/BudgetsListPage.tsx` (3-panel `[320px_1fr_360px]`) +- [ ] `fe-admin/src/pages/budgets/BudgetCreatePage.tsx` (form Header) +- [ ] `fe-admin/src/components/budgets/BudgetDetailTabs.tsx` (Thông tin / Hạng mục) +- [ ] `fe-admin/src/components/budgets/BudgetWorkflowPanel.tsx` (Panel 3 timeline + transition + comment) +- [ ] Mirror tất cả sang `fe-user/` +- [ ] App.tsx routes `/budgets`, `/budgets/new`, `/budgets/:id` cả 2 app +- [ ] Menu resolver `Bg_*` (Bg_List → `/budgets`, Bg_Pending → `/budgets?phase=Pending`, Bg_Create → `/budgets/new`) + +### B. 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ự — link sang Budget cho đối chiếu chi phí +- [ ] PE Detail tab thêm cột "So với ngân sách" — compute từ BudgetDetail tương ứng (match GroupCode + ItemCode) + +### C. Budget refinement (when needed) + +- [ ] Budget MaNganSach atomic sequence — chốt format chính thức rồi thêm `AddBudgetCodeSequences` migration + `IBudgetCodeGenerator` SERIALIZABLE pattern (mirror Contract/PE) +- [ ] Budget versioned workflow — admin config UI nếu Solutions cần custom step approver beyond default 3-step ## 🔁 Skill governance (recurring) @@ -104,7 +142,7 @@ Quy tắc: `docs/rules.md §9`. Audit định kỳ mỗi đầu tháng — workf Cron task `solution-erp-skill-audit-monthly` fire 9:00 AM ngày 1 mỗi tháng. -## 📦 Post-launch (Phase 8+ — future) +## 📦 Post-launch (Phase 9+ — future) - [ ] **Email outbox** (MailKit + SMTP) — blocked chờ SMTP config - [ ] E-signature integration (VNPT CA hoặc FPT CA) diff --git a/docs/changelog/sessions/2026-04-28-chot-session-4-budget.md b/docs/changelog/sessions/2026-04-28-chot-session-4-budget.md new file mode 100644 index 0000000..1f0423e --- /dev/null +++ b/docs/changelog/sessions/2026-04-28-chot-session-4-budget.md @@ -0,0 +1,260 @@ +# 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 email** — `admin@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) +``` diff --git a/docs/database/schema-diagram.md b/docs/database/schema-diagram.md index 9acc7f6..03aed0c 100644 --- a/docs/database/schema-diagram.md +++ b/docs/database/schema-diagram.md @@ -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