From e71e0eba65aed2e0678f865ede04802f10abd784 Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Sat, 25 Apr 2026 14:17:53 +0700 Subject: [PATCH] =?UTF-8?q?[CLAUDE]=20Docs:=20tai=20cau=20truc=20cleanup?= =?UTF-8?q?=20=E2=80=94=20archive=20raw,=20compact=20migration-todos,=20up?= =?UTF-8?q?date=20CLAUDE+flows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User request: 'review cap nhat va tai cau truc lai MD sao cho phu hop voi hien tai, cac phan thua va da dieu chinh co the bo ra luon hoac cap nhat lai'. Cleanup highlights: 1. Archive 2 file Phase 0 raw dump → docs/_archive/ (forms-spec-raw 657 line + workflow-raw 62 line). Update link reference 2 file goc. 2. Compact migration-todos.md 386 → 114 line (-71%). Collapse Phase 0-5 + Tier 3 + Sessions detailed thanh 1 bang summary. Detail xem session logs. Phase 6 iter 1+2 + Phase 7 active checklist. 3. Compact STATUS.md In Progress: bo ~17 row ✅ done (giu chỉ 5+ task pending: 3 PE feature gap + 4 optional polish + 2 Ops). Recently Done table giu day du history. 4. Update flows/README — tat ca 6 flow ✅ Implemented + them PE row reference architecture.md §9. 5. Update docs/CLAUDE.md — project layout co PurchaseEvaluations, _archive, skills 6 (3 dom + 3 ops). Roadmap them Phase 6 ✅ + Phase 7 WIP. Lien he them prod URL solutions.com.vn + SSH config + login admin. 6. Skill ef-core-migration: 13 migration label. Net delta: -800 line docs (chu yeu archive + collapse migration-todos). --- docs/CLAUDE.md | 87 +++--- docs/STATUS.md | 57 +--- docs/{ => _archive}/forms-spec-raw.md | 0 docs/{ => _archive}/workflow-raw.md | 0 docs/changelog/migration-todos.md | 422 +++++--------------------- docs/flows/README.md | 11 +- docs/workflow-contract.md | 2 +- 7 files changed, 146 insertions(+), 433 deletions(-) rename docs/{ => _archive}/forms-spec-raw.md (100%) rename docs/{ => _archive}/workflow-raw.md (100%) diff --git a/docs/CLAUDE.md b/docs/CLAUDE.md index fb1dba1..81d0416 100644 --- a/docs/CLAUDE.md +++ b/docs/CLAUDE.md @@ -2,13 +2,14 @@ ## 1. Giới thiệu -**SOLUTION_ERP** là hệ thống quản lý Hợp đồng Nhà cung cấp / Thầu phụ / Tổ đội / Dịch vụ cho **Công ty TNHH Xây dựng Solutions**, thay thế quy trình giấy / Word+Excel hiện tại. +**SOLUTION_ERP** là hệ thống quản lý Hợp đồng Nhà cung cấp / Thầu phụ / Tổ đội / Dịch vụ + **Phiếu Duyệt NCC tiền-HĐ** cho **Công ty TNHH Xây dựng Solutions**, thay thế quy trình giấy / Word+Excel hiện tại. **Scope chính:** 1. Số hóa 8 form hợp đồng (template engine điền field → export .docx/.xlsx) -2. Workflow 9 phase trình ký (state machine + role guard + SLA auto-approve) +2. Workflow 9 phase trình ký HĐ (state machine + role guard + SLA auto-approve + versioned WF per ContractType) 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 ## 2. Kiến trúc tổng thể @@ -46,39 +47,35 @@ ``` SOLUTION_ERP/ ├── src/Backend/ -│ ├── SolutionErp.Domain/ Entities, ValueObjects, Enums, DomainEvents +│ ├── SolutionErp.Domain/ Entities + Enums (Contracts/, PurchaseEvaluations/, Forms/, Identity/, Master/, Notifications/) │ ├── SolutionErp.Application/ CQRS handlers, DTOs, Validators, Mappings, Interfaces -│ ├── SolutionErp.Infrastructure/ EF DbContext, Identity, Repositories, External +│ ├── SolutionErp.Infrastructure/ EF DbContext, Identity, Repositories, External services │ └── SolutionErp.Api/ Controllers, Middleware, Program.cs, appsettings -├── fe-admin/ (admin UI — CRUD master data, approve, dashboards) -│ └── src/ -├── fe-user/ (user UI — soạn thảo HĐ, comment, upload) -│ └── src/ +├── fe-admin/ (admin UI — CRUD master, approve, dashboards, workflow designer, permission matrix) +├── fe-user/ (user UI — soạn HĐ + duyệt phiếu PE + inbox) ├── docs/ │ ├── CLAUDE.md (file này) -│ ├── STATUS.md -│ ├── PROJECT-MAP.md -│ ├── forms-spec.md ⭐ 8 form catalog + RG-001 code format -│ ├── workflow-contract.md ⭐ 9 phase state machine + role matrix +│ ├── STATUS.md ⭐ snapshot hiện tại + Recently Done +│ ├── 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 +│ ├── 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, schema hiện tại + planned, ERD, migration workflow -│ ├── flows/ ⭐ Sequence/state diagram mỗi feature -│ │ ├── README.md (index) -│ │ ├── auth-flow.md ✅ implemented -│ │ ├── permission-flow.md 📝 Phase 1 đợt 2 -│ │ ├── contract-creation-flow.md 📝 Phase 2 -│ │ ├── contract-approval-flow.md 📝 Phase 3 -│ │ ├── form-render-flow.md 📝 Phase 2 -│ │ └── sla-expiry-flow.md 📝 Phase 3 -│ ├── guides/ setup, cicd, code-rules... -│ └── changelog/ -│ ├── migration-todos.md Roadmap 5 phase -│ └── sessions/ YYYY-MM-DD session logs +│ │ ├── database-guide.md conventions + migration workflow +│ │ └── schema-diagram.md ERD 47 bảng (+§11 PE) +│ ├── flows/ 6 sequence diagram (auth/permission/contract/form/sla + PE ref architecture) +│ ├── guides/ setup, cicd, deploy, runbook, security +│ ├── changelog/ +│ │ ├── migration-todos.md roadmap compact (Phase 0-5+Tier3 collapsed) +│ │ └── sessions/ session logs YYYY-MM-DD +│ └── _archive/ raw dump Phase 0 (forms-spec-raw, workflow-raw) ├── .claude/skills/ 6 skill: 3 domain (contract-workflow, form-engine, permission-matrix) + 3 ops (dependency-audit-erp, ef-core-migration, iis-deploy-runbook) -├── scripts/ parse_forms.py, parse_workflow.py, seed, deploy +├── scripts/ deploy, migrate-domains, backup, deps-audit ├── SolutionErp.slnx Solution file ├── global.json .NET 10 SDK pin -├── docker-compose.yml SQL Server cho dev └── CLAUDE.md Pointer → docs/CLAUDE.md ``` @@ -109,18 +106,23 @@ 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 5 phase (summary) +## 6. Roadmap (status 2026-04-24) -| Phase | Tuần | Focus | Exit criteria | -|---|---|---|---| -| **0 Draft** | T1 | Scaffold, parse FORM + QUY_TRINH | Build pass, docs đủ | -| **1 Alpha Core** | T2-4 | Auth + Permission + CRUD Supplier/Project/Contract | Admin tạo HĐ draft + gán role | -| **2 Form Engine** | T5-6 | Template engine 8 form, export .docx/.xlsx | Export 1 HĐ giống mẫu 100% | -| **3 Workflow** | T7-9 | State machine 9 phase + SLA + notify | HĐ đi hết quy trình → có mã số | -| **4 Report + Polish** | T10-11 | Dashboard, Excel export, UX pass | UAT 5-10 HĐ thật | -| **5 Production** | T12-13 | CI/CD IIS, security, runbook, UAT | Go-live | +| Phase | Focus | Trạng thái | +|---|---|---| +| **0 Draft** | Scaffold, parse FORM + QUY_TRINH | ✅ Done | +| **1 Alpha Core** | Auth + Permission + CRUD master + Contract draft | ✅ Done | +| **2 Form Engine** | OpenXml + ClosedXML + LibreOffice PDF + DynamicForm | ✅ Done | +| **3 Workflow** | 9 phase state machine + RG-001 code gen + SLA job + attachments + SignalR | ✅ Done | +| **4 Reporting** | Dashboard KPI + Excel export + MyDashboard role-aware | ✅ Done | +| **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 | -Chi tiết atomic tasks ở [`changelog/migration-todos.md`](changelog/migration-todos.md). +Chi tiết atomic tasks: [`changelog/migration-todos.md`](changelog/migration-todos.md). +Session logs: [`changelog/sessions/`](changelog/sessions/). ## 7. Quy ước code @@ -142,7 +144,14 @@ Chi tiết atomic tasks ở [`changelog/migration-todos.md`](changelog/migration - SQL injection: EF Core parameterized (không raw SQL trừ khi cần) - Audit log: mọi write → `AuditLog` table -## 9. Liên hệ +## 9. Liên hệ + Production -- **Dev:** pqhuy1987@gmail.com (solo) +- **Dev:** pqhuy1987@gmail.com (solo + Claude) +- **Prod login:** `admin@solutions.com.vn` / `Admin@123456` ⚠️ rotate sau login đầu +- **3 domain prod:** + - https://api.solutions.com.vn — API + - https://admin.solutions.com.vn — Admin FE + - https://eoffice.solutions.com.vn — User FE +- **Gitea remote:** https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp +- **SSH VPS:** `ssh vietreport-vps` (config sẵn `~/.ssh/config` user=Administrator key=id_ed25519) - **Domain expert:** TBD (sẽ update sau UAT đầu tiên) diff --git a/docs/STATUS.md b/docs/STATUS.md index 730cf1b..80a5796 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -14,53 +14,28 @@ - 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 — PE module chưa xong (session tiếp xử lý) +## 🔥 In Progress — Còn lại cho session 4 -> **User feedback (2026-04-23 tối session 2):** "phần Duyệt NCC chưa xong đâu đấy nhé, còn chỉnh nhiều". +### A. PE feature gap (3 task chưa làm) -### A. Chức năng MISSING trong MVP (còn lại) +- [ ] **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`. -- [ ] **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` — framework versioned WF đã có (3 bảng + policy `FromDefinition`). Chỉ thiếu: - - BE `PeWorkflowAdminFeatures.cs` (mirror `WorkflowAdminFeatures.cs` — GetOverview + CreateNewVersion) - - `PeWorkflowsController.cs` — GET overview + POST create-version - - FE `PeWorkflowsPage.tsx` + `PeWorkflowDesigner.tsx` (mirror `WorkflowsPage.tsx` + `WorkflowDesigner.tsx`) - - Menu leaf `PeWf_*` đã seed rồi, resolver Layout.tsx đã map `/system/pe-workflows/:code` -- [x] ✅ **PE Attachments upload** (2026-04-24) — `PurchaseEvaluationAttachmentFeatures.cs` (Upload/Download/Delete) + 3 endpoint REST + `IFileStorage` reuse. FE column "File đính kèm" per-NCC (SupplierAttachmentsCell) + section "Bảng so sánh (file tổng)" (GeneralAttachmentsSection, `supplierRowId=null`). Enum purpose: QuoteDocument=1/RequirementSpec=2/DecisionExport=3/**ComparisonTable=4**/Other=99. 20MB MIME whitelist. -- [ ] **Auto-map PE Details → Contract 7 per-type Details khi gen HĐ** — hiện `CreateContractFromEvaluationCommand` chỉ copy header + GiaTri, KHÔNG copy Details. Cần mapping per ContractType (PE Detail schema flat ≠ 7 Contract Details schemas). -- [x] ✅ **Demo PE data seed** (2026-04-24) — 4 phiếu `[DEMO]` cover full state-space. -- [x] ✅ **MaPhieu atomic sequence** (2026-04-24) — Migration 13. Format `PE/{YYYY}/{A|B}/{Seq:D3}`. -- [ ] **Section "Ý kiến các phòng ban" (Phê duyệt/P.CCM/P.MuaHàng/SM-PM) ở tab Thông tin** — Excel form mẫu có, entity hiện chưa map. Cần thêm 4-8 text field + signoff date (hoặc dùng Approvals row như ContractApprovals). +### B. Optional polish -### B. UX / Polish cần chỉnh +- [ ] **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. -- [ ] **Payment terms chi tiết** — hiện JSON blob. UX tách 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** — click cell → popup: OK. Nhưng bulk paste column giá từ Excel chưa có (power user feature). -- [ ] **Export phiếu PDF/Excel** — user cần bản in ký. Tái dùng `IDocumentConverter` + template `PE-TrinhDuyet.docx`. -- [x] ✅ **Permission grant Pe_* cho non-admin role** (2026-04-24). -- [x] ✅ **Menu tree inheritance Pe_*/PeWf_*** (2026-04-24) — `GetMyMenuTreeQuery` extend 2 inherit root mới (PurchaseEvaluations + PeWorkflows). Fix bug: admin có perm nhưng menu children không hiện. -- [x] ✅ **Sidebar accordion mutex Pe_*** (2026-04-24) — extend `AccordionContextValue` + `expandedPeCode` + URL sync pathname. 2 PE group không expand cùng lúc; Ct_ + Pe_ độc lập gia đình. -- [x] ✅ **NavLink query active check** (2026-04-24) — `queryMatches` helper. 2 leaf cùng pathname `/purchase-evaluations` (Danh sách `?type=2` vs Duyệt `?type=2&pendingMe=1`) không còn cùng highlight. Áp dụng Ct_* + Pe_*. -- [x] ✅ **Sidebar width + label nowrap** (2026-04-24) — w-64 → w-72 (288px). Top-level group: `text-xs tracking-wider` → `text-[11px] tracking-wide whitespace-nowrap`. "QUY TRÌNH CHỌN THẦU PHỤ - NCC" fit single-line. -- [x] ✅ **PE detail flat layout** (2026-04-24) — Panel 2 bỏ 5 tabs, render flat 4 section (Thông tin / NCC tham gia / Hạng mục + Báo giá / **Bảng so sánh**). Panel 3 add Duyệt + Lịch sử sections dưới workflow timeline. -- [x] ✅ **PE readOnly mode menu Duyệt** (2026-04-24) — pendingMe=1 → hide toàn bộ action (Sửa/Xóa/Thêm/Edit inline/Upload/Delete attachment). Giữ download + comment khi transition. Chip "chế độ duyệt" ở header. -- [x] ✅ **Contract: move Lịch sử điều chỉnh Panel 2 → Panel 3** (2026-04-24) — Chi tiết HĐ full-width. Panel 3 bổ sung ContractChangelogsTab dưới Lịch sử duyệt. -- [x] ✅ **Menu rename "Phương Án" → "Giải pháp"** (2026-04-24) — DbInitializer labels + backfill UPDATE existing rows. Giữ nguyên enum value + menu key + typeCode + policy name (zero breaking change). -- [x] ✅ **Demo email @solutionerp.local → @solutions.com.vn** (2026-04-24) — AdminEmail const + 17 demo users rename trong source + BackfillUserEmailDomainAsync idempotent rename existing users (Email/NormalizedEmail/UserName/NormalizedUserName). Chạy trước SeedAdmin tránh duplicate. Password + role + refresh token giữ nguyên. -- [ ] **fe-user Inbox** — hiện chỉ HĐ. Cần thêm section "Phiếu Duyệt NCC chờ tôi" (hoặc route `/pe-inbox` riêng). +### C. Deploy / Ops chưa xong -### C. Edge case chưa test - -- [ ] Reject path E2E: DangSoanThao → ChoPurchasing → (CCM reject) → DangSoanThao — verify approval row vẫn log -- [ ] Xóa phiếu khi đã có Contract kế thừa (PE.ContractId set) — cascade delete child OK, Contract standalone không break, nhưng nên warning dialog -- [ ] Admin tạo PE workflow v02 sau khi có phiếu pin v01 — invariant "phiếu cũ giữ cũ" chưa test (pattern giống HĐ, nên pass) -- [ ] Change EvaluationType (A ↔ B) sau create — form hiện disable, đúng. User có đổi nhầm → phải xóa + tạo lại. - -### D. Deploy / Ops - -- [x] ✅ **Domain migration** *.huypham.vn → *.solutions.com.vn (2026-04-24) — SSH Claude vào VPS run `migrate-domains.ps1`: 3 HTTP binding + 3 cert Let's Encrypt + HTTPS binding. CORS BE + FE bundle VITE_API_BASE_URL đã rebuild. E2E verified 3 domain live + preflight OK. URL cũ vẫn active (fallback) — sẽ remove sau 1-2 ngày via `-RemoveOld`. -- [x] ✅ **CI/CD auto-deploy commit 3990066+ lên prod** — runner Running, PE endpoint 401 OK, CORS allow admin.solutions.com.vn. -- [ ] **win-acme scheduled task "unhealthy"** — auto-renew có thể fail. Fix: `wacs.exe` interactive → Manage Renewals → recreate task (hoặc ignore tới cert gần hết hạn 2026-06-18). -- [ ] **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` +- [ ] **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. ## ✅ Recently Done (newest on top) diff --git a/docs/forms-spec-raw.md b/docs/_archive/forms-spec-raw.md similarity index 100% rename from docs/forms-spec-raw.md rename to docs/_archive/forms-spec-raw.md diff --git a/docs/workflow-raw.md b/docs/_archive/workflow-raw.md similarity index 100% rename from docs/workflow-raw.md rename to docs/_archive/workflow-raw.md diff --git a/docs/changelog/migration-todos.md b/docs/changelog/migration-todos.md index aaf6e9b..236b450 100644 --- a/docs/changelog/migration-todos.md +++ b/docs/changelog/migration-todos.md @@ -1,384 +1,112 @@ # Migration To-dos — Atomic Roadmap -> Mỗi item là 1 task atomic (~2-8h work). Tick `[x]` khi xong. Link session log nếu có. +> 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). -## Phase 0 — Draft Scaffold (T1) +## ✅ Phase 0-5 + Tier 3 — Done (2026-04-21..22) -- [x] Tạo cấu trúc thư mục `SOLUTION_ERP/` -- [x] Scaffold .NET 10 solution `SolutionErp.slnx` -- [x] Scaffold 4 project: `SolutionErp.{Domain, Application, Infrastructure, Api}` -- [x] Wire Clean Arch references (Api → App/Infra, Infra → App, App → Domain) -- [x] Install NuGet base: MediatR, FluentValidation, AutoMapper, EF Core SqlServer, Identity, JWT, Swagger, Serilog -- [x] Scaffold 2 React + Vite apps `fe-admin` + `fe-user` với TS template -- [x] Config vite.config.ts: port, strictPort, proxy `/api`, alias `@` -- [x] Pin Node `>=20` trong package.json + `.nvmrc` cho CI -- [x] Parse 8 form → `docs/forms-spec.md` -- [x] Parse quy trình → `docs/workflow-contract.md` -- [x] Viết `docs/{CLAUDE,STATUS,PROJECT-MAP}.md` -- [x] Viết `docs/database/database-guide.md` (conventions + schema + ERD + migration workflow) -- [x] Viết `docs/flows/` — README + 6 flow doc (auth, permission, contract-create, contract-approve, form-render, sla-expiry) -- [x] Viết `.gitignore`, `README.md`, `global.json`, `docker-compose.yml` -- [x] Tạo placeholder skill folders: `contract-workflow`, `form-engine`, `permission-matrix` -- [x] `git init` + commit đầu (`25dad7f`) -- [ ] Push Gitea remote (chờ URL từ user) +| Phase | Focus | Trạng thái | +|---|---|---| +| 0 Draft | Scaffold .NET 10 + 2 Vite + parse FORM/QT + docs | ✅ | +| 1 Alpha Core | Auth + 12 role + Permission Matrix + 3 master CRUD + Contract draft | ✅ | +| 2 Form Engine | OpenXml + ClosedXML render + LibreOffice PDF + DynamicForm | ✅ | +| 3 Workflow | State machine 9 phase + RG-001 code gen + SLA job + attachments + SignalR realtime | ✅ | +| 4 Reporting | Dashboard KPI + Excel export + MyDashboard role-aware + brand identity #1F7DC1 | ✅ | +| 5 Production | CI/CD Gitea Actions + 3 IIS site + Let's Encrypt + Security headers + Users CRUD | ✅ | +| Tier 3 | Versioned workflow + 3-panel layout + 4-bảng overhaul + 4 master catalogs + 16 demo users + RolesPage CRUD + 7 demo HĐ varied | ✅ | -## Phase 1 — Alpha Core (T2-4) +Detail chi tiết: `docs/changelog/sessions/2026-04-21-*.md` + `2026-04-22-0300-tier3-feature-complete.md` + `2026-04-23-*.md`. -### Foundation (đã xong Session 2) +## ✅ Phase 6 — Module Duyệt NCC (tiền-HĐ) — Done -- [x] `Domain/Common/BaseEntity.cs` (Id Guid, CreatedAt, UpdatedAt, CreatedBy, UpdatedBy) -- [x] `Domain/Common/AuditableEntity.cs` (IsDeleted, DeletedAt, DeletedBy) -- [x] `Domain/Contracts/` Enums: `ContractType`, `ContractPhase` (9 state), `ApprovalDecision` -- [x] `Domain/Identity/User.cs` (IdentityUser + FullName + RefreshToken + IsActive) -- [x] `Domain/Identity/Role.cs` (IdentityRole + Description) -- [x] `Domain/Identity/AppRoles.cs` — 12 role constants -- [x] `Application/Common/Interfaces/`: IApplicationDbContext, ICurrentUser, IDateTime, IJwtTokenService -- [x] `Application/Common/Exceptions/*` -- [x] `Application/Common/Behaviors/ValidationBehavior.cs` -- [x] `Application/DependencyInjection.cs` — MediatR + FluentValidation -- [x] `Infrastructure/Persistence/ApplicationDbContext.cs : IdentityDbContext` -- [x] `Infrastructure/Persistence/Interceptors/AuditingInterceptor.cs` -- [x] `Infrastructure/Persistence/DbInitializer.cs` — seed 12 role + admin -- [x] `Infrastructure/Persistence/DesignTimeDbContextFactory.cs` -- [x] `Infrastructure/Identity/{JwtSettings, JwtTokenService}.cs` -- [x] `Infrastructure/Services/DateTimeService.cs` -- [x] `Infrastructure/DependencyInjection.cs` -- [x] `Api/Services/CurrentUserService.cs` -- [x] `Api/Middleware/GlobalExceptionMiddleware.cs` -- [x] `Api/Controllers/AuthController.cs` (login, refresh, me, logout) -- [x] `Api/Program.cs` (Serilog, JWT, CORS, Swagger, middleware) -- [x] `Api/appsettings.{json, Development.json}` + `launchSettings.json` (port 5443) -- [x] Migration 1 `Init` + apply to `SolutionErp_Dev` LocalDB -- [x] FE: Vite config (Tailwind 4 + proxy + alias) -- [x] FE: `src/{index.css, lib/api.ts, lib/cn.ts, types/auth.ts}` cho 2 app -- [x] FE: `src/contexts/AuthContext.tsx`, `components/{ProtectedRoute, Layout}.tsx` -- [x] FE: `components/ui/{Button, Input, Label}.tsx` -- [x] FE: `pages/LoginPage.tsx`, `pages/DashboardPage.tsx` (admin) + `pages/InboxPage.tsx` (user) -- [x] FE: `App.tsx` với Router + AuthProvider + Toaster -- [x] FE: `main.tsx` với QueryClient (TanStack Query) -- [x] E2E verified: login qua Vite proxy cả 2 app → JWT + user info +### Iter 1 (2026-04-23) -### Phase 1 đợt 2 — CRUD master + Permission Matrix +- [x] Migration 12 `AddPurchaseEvaluations` — 10 bảng (Header/Suppliers/Details/Quotes/Approvals/Changelogs/Attachments/WorkflowDefinitions/Steps/StepApprovers) +- [x] Domain — 2 enum (Type A/B, Phase 7-state) + Policy record + Registry + FromDefinition builder +- [x] Seed — 13 menu Pe_*/PeWf_* + 2 WorkflowDefinition v01 (QT-DN-A 3-step, QT-DN-B 5-step) +- [x] Application CQRS ~900 LOC — Create/Update/Transition/List/Inbox/Get/Delete + Supplier CRUD + Detail CRUD + Quote Upsert + SelectWinner + Changelog +- [x] PurchaseEvaluationWorkflowService — policy guard + approval + notification + changelog +- [x] PurchaseEvaluationsController — 17 endpoint REST +- [x] FE 2 app — Types + PurchaseEvaluationsListPage 3-panel + Create page + PeDetailTabs + PeWorkflowPanel + Menu resolver Pe_* +- [x] Kế thừa HĐ — `CreateContractFromEvaluationCommand` (guard DaDuyet + SelectedSupplier + !ContractId) → Contract draft. FE CreateContractDialog pick ContractType. +- [x] **Migration 13** `AddPurchaseEvaluationCodeSequences` — atomic MaPhieu sequence `PE/{YYYY}/{A|B}/{Seq:D3}` +- [x] Demo PE seed — 4 phiếu varied phase (A-001/A-002/A-003/B-001) + Pe_* permission defaults 7 role × 9 menu key -- [x] `Domain/Master/Supplier` (+ SupplierType enum 5 loại) / `Project` / `Department` (AuditableEntity) -- [x] EF `IEntityTypeConfiguration` cho mỗi entity (unique Code + query filter IsDeleted) -- [x] CQRS CRUD: Create/Update/Delete/GetById/List (PagedResult) cho 3 entity -- [x] `Api/Controllers/{SuppliersController, ProjectsController, DepartmentsController}` -- [x] Migration 2: `AddMasterData` -- [x] `Domain/Identity/MenuItem` (Key PK, Label, ParentKey, Order, Icon) + `MenuKeys` const class -- [x] `Domain/Identity/Permission` (RoleId, MenuKey, CanRead/Create/Update/Delete) -- [x] Seed default menu tree + admin full access trong DbInitializer (mở rộng Tier 3: 28 Ct_* + 7 Wf_*) -- [x] `Application/Permissions/Queries/GetMyMenuTreeQuery` — resolve per-user + inherit Contracts/Workflows root -- [x] `Api/Controllers/{MenusController, RolesController, PermissionsController}` -- [x] Migration 3: `AddPermissions` -- [x] Authorization handler `MenuPermissionHandler` + register policy `{menu}.{action}` -- [x] FE: `` + `usePermission()` hook -- [x] FE Admin: 3 trang CRUD Supplier/Project/Department với DataTable + Dialog + search/sort/paging -- [x] FE Admin: Permission Matrix grid page (role × menu × CRUD checkbox) — iter 1 + 3-panel iter 2 -- [x] FE Admin: Layout menu động từ `/api/menus/me` + recursive nested + filterForAdmin -- [x] FE User: trang "HĐ của tôi" list + filter `?type=X` — Tier 3 -- [x] FE Admin: Users management page (tạo user + gán role + reset password + unlock) -- [x] FE Admin: Roles CRUD `/system/roles` — admin thêm custom role ngoài 12 hardcoded (commit 072ad6d) -- [x] Route guard theo role admin-only — PermissionGuard ở button level +Session log: `2026-04-23-2300-purchase-evaluations.md` + `2026-04-24-1030-pe-polish-demo-maphieu-perms.md`. -### Exit criteria Phase 1 +### Iter 2 — UX polish (2026-04-24) -- [x] Admin login → tạo NCC/Project → gán permission menu -- [x] User non-admin login → thấy menu theo role, không bị 403 -- [x] Tạo Contract draft → list hiển thị, filter role-aware +- [x] Rename menu "Phương Án" → "Giải pháp" + backfill DB (zero breaking change) +- [x] Menu tree inheritance extend Pe_*/PeWf_* (`GetMyMenuTreeQuery` + 4 root) +- [x] Accordion mutex Pe_* groups + sidebar w-72 + label nowrap +- [x] NavLink active check query string (queryMatches helper) — fix 2 leaf cùng highlight +- [x] PE detail flat layout: Panel 2 = 4 section (Thông tin/NCC/Hạng mục/**Bảng so sánh**), Panel 3 += Approvals + Changelog +- [x] Upload file đính kèm per-NCC (SupplierAttachmentsCell) + Bảng so sánh tổng (GeneralAttachmentsSection, supplierRowId=null) + enum `ComparisonTable=4` +- [x] readOnly mode menu "Duyệt" (pendingMe=1) — hide Sửa/Xóa/Thêm/Edit/Upload/Delete, giữ download + transition + comment +- [x] Contract: move Lịch sử điều chỉnh Panel 2 → Panel 3 (Chi tiết HĐ full-width) +- [x] Demo email rebrand `@solutionerp.local` → `@solutions.com.vn` + `BackfillUserEmailDomainAsync` (idempotent rename 4 field Email/NormalizedEmail/UserName/NormalizedUserName) -## Phase 2 — Form Engine (T5-6) +Session log: `2026-04-24-chot-session-3-pe-polish.md`. -### MVP xong (Phase 2 iteration 1) +### ✅ Domain rebrand `.huypham.vn` → `.solutions.com.vn` (2026-04-24) -- [x] Khảo sát: chọn **OpenXml + ClosedXML** (free, không cần license) -- [x] `Domain/Forms/ContractTemplate` (Id, FormCode, Name, ContractType, FileName, StoragePath, Format, FieldSpec JSON, IsActive) -- [x] `Domain/Forms/ContractClause` skeleton -- [x] EF config + Migration `AddForms` -- [x] `Application/Forms/Services/IFormRenderer` interface -- [x] `Infrastructure/Forms/DocxRenderer` (OpenXml, handle placeholder split runs) -- [x] `Infrastructure/Forms/XlsxRenderer` (ClosedXML) -- [x] `Application/Forms/FormFeatures.cs` — List/Get/Render CQRS -- [x] `Api/Controllers/FormsController` — GET templates, GET single, POST render -- [x] Copy 5 .docx/.xlsx template → `wwwroot/templates/` -- [x] Seed 8 ContractTemplate rows (5 IsActive=true, 3 chờ convert) -- [x] FE admin: `FormsPage` — list + render dialog điền JSON + download -- [x] E2E verified: render FO-002.05 → file .docx 482KB mở được bằng Word +- [x] 18 file repo (FE env + scripts + CI/CD + docs + skill + code comments) +- [x] `scripts/migrate-domains.ps1` (ASCII-only #30) — 3 IIS binding + 3 cert Let's Encrypt + auto HTTPS + redirect +- [x] CI/CD auto rebuild BE CORS + FE bundle VITE_API_BASE_URL +- [x] E2E verified 3 domain live + preflight OK -### Iteration 2 (Tier 3 — đã làm) +Sub: `api.solutions.com.vn` · `admin.solutions.com.vn` · `eoffice.solutions.com.vn`. Old `.huypham.vn` vẫn fallback (chưa remove). -- [x] Convert `.doc` → `.docx` / `.xls` → `.xlsx` qua `IDocumentConverter` + LibreOffice headless (thay Word COM, auto-convert khi admin upload) -- [x] FE user: form builder dynamic — `DynamicForm` component render từ `FieldSpec` JSON (text/textarea/number/date/currency/select) -- [x] FE admin: upload template mới qua UI (POST multipart) + edit FieldSpec + delete (soft via IsActive) -- [x] PDF convert via LibreOffice headless (`soffice --headless --convert-to pdf`) — `LibreOfficeDocumentConverter` (timeout + per-request temp + isolated UserInstallation) -- [x] Format helpers: number → `VND`, date → `dd/MM/yyyy` (render layer) -- [ ] Support `{{#loop}}...{{/loop}}` block cho table lặp (hạng mục HĐ giao khoán, PO) — optional -- [ ] Lưu `ContractClause` (FO-002.04) dạng rich text + TipTap/TinyMCE editor — optional -- [ ] Import/export template (backup/restore) — optional -- [ ] Content preservation test (render → diff layout) — optional +## 📝 Phase 7 — PE feature gap + ops (Session 4) -## Phase 3 — Workflow State Machine (T7-9) +### A. PE feature gap (3 task MISSING) -### MVP xong (iteration 1) +- [ ] **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` + - BE `Application/PurchaseEvaluations/PeWorkflowAdminFeatures.cs` (mirror `WorkflowAdminFeatures.cs`) + - `Api/Controllers/PeWorkflowsController.cs` + - FE `fe-admin/src/pages/system/PeWorkflowsPage.tsx` + `PeWorkflowDesigner.tsx` + - Route `/system/pe-workflows/:typeCode` (menu PeWf_* + resolver đã sẵn) +- [ ] **Ý kiến 4 phòng ban** (Phê duyệt / P.CCM / P.MuaHàng / SM-PM) ở tab Thông tin + - Option A: 4 text field + signoff date + UserId vào header + - Option B: dùng `PurchaseEvaluationApprovals` với roleKind extra field + - UX: 4 box sign-off như Excel mẫu +- [ ] **Export phiếu PDF/Excel** — tái dùng `IDocumentConverter` + template `PE-TrinhDuyet.docx` -- [x] `Domain/Contracts/Contract` (Phase, SlaDeadline, BypassProcurementAndCCM, MaHopDong, DraftData, SlaWarningSent) -- [x] `Domain/Contracts/ContractApproval` (FromPhase, ToPhase, ApproverUserId, Decision, Comment) -- [x] `Domain/Contracts/ContractComment` + `ContractAttachment` (+ AttachmentPurpose enum) -- [x] `Domain/Contracts/ContractCodeSequence` (Prefix PK, LastSeq) -- [x] EF config + unique MaHopDong filtered + indexes Phase/Supplier/Project/SlaDeadline + cascade delete -- [x] DbSets (5) + `IApplicationDbContext` update -- [x] Migration `AddContractsWorkflow` -- [x] `Application/Contracts/Services/IContractWorkflowService` + `IContractCodeGenerator` -- [x] `Infrastructure/Services/ContractWorkflowService` — adjacency 9 phase + role guard + Admin bypass + system actor + bypass CCM (Chủ đầu tư) -- [x] `Infrastructure/Services/ContractCodeGenerator` — 7 format RG-001 + transaction SERIALIZABLE -- [x] CQRS: Create/UpdateDraft/Transition/AddComment/List/Inbox/GetDetail/Delete (8 feature) -- [x] `Api/Controllers/ContractsController` — 8 endpoint REST -- [x] FE admin: ContractsListPage + ContractDetailPage (timeline + action dialog) -- [x] FE user: InboxPage + ContractCreatePage + ContractDetailPage + MyContractsPage -- [x] PhaseBadge component + color map -- [x] E2E verified: tạo HĐ → chạy 9 phase → gen mã `FLOCK 01/HĐGK/SOL&PVL2026/01` +### B. Optional polish -### Iteration 2 (polish — Tier 3 + Notification) +- [ ] Auto-map PE Details → Contract per-type Details khi gen HĐ (phức tạp vì 7 schema khác nhau) +- [ ] Payment terms tách field từ JSON → 6 column (Tạm ứng/TT tạm/Quyết toán/Bảo hành/Hạn mức/Đánh giá) +- [ ] Matrix Quotes bulk paste từ Excel +- [ ] fe-user Inbox thêm section "Phiếu Duyệt NCC chờ tôi" -- [x] `Infrastructure/HostedServices/SlaExpiryJob` — check mỗi 15min, auto-approve quá hạn với Decision=AutoApprove (+30s delay startup) -- [x] E2E test với non-admin user (Drafter role) — IDOR filter verified -- [x] Admin password warning log khi vẫn dùng default -- [x] `Infrastructure/Services/NotificationService` — in-app + emit (email đợi SMTP) -- [x] SignalR hub cho real-time notification badge — `/hubs/notifications` + interceptor auto-push -- [x] Upload attachment endpoint (multipart) + FE drag-drop UI (`wwwroot/uploads/contracts/{id}/`) — IFileStorage + path-traversal guard -- [x] Filter Inbox theo type ở FE (`?type=X`) -- [x] Render HĐ template docx/xlsx → PDF export (LibreOffice) -- [ ] Warning notification khi còn 20% SLA — `SlaWarningSent` flag đã có -- [ ] MediatR `AuditBehavior` — log mọi command (ngoài ContractApprovals) -- [ ] RowVersion optimistic concurrency (2 user race → 409) -- [ ] Render HĐ docx lúc tạo (merge TemplateId + DraftData + ContractClause appendix) -- [ ] E2E test: reject → quay về DangSoanThao với multi-role -- [ ] Email notification (MailKit + SMTP) — blocked chờ user config +### C. Ops -### Iteration 3 (Versioned workflow — Tier 3) +- [ ] 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 +- [ ] SMTP config → Email outbox +- [ ] Rotate credentials (admin + 16 demo + SA + vrapp + JWT) +- [ ] Schedule SQL backup Task Scheduler -- [x] `Domain/Contracts/WorkflowDefinition` (Code + Version + IsActive + ContractType + Description) -- [x] `Domain/Contracts/WorkflowStep` (Order + Phase + Name + SlaDays) -- [x] `Domain/Contracts/WorkflowStepApprover` (Kind: Role|User + AssignmentValue) -- [x] `Contract.WorkflowDefinitionId` nullable FK pin tại create time -- [x] Migration `AddVersionedWorkflows` + seed v01 cho 7 ContractType -- [x] `WorkflowPolicyRegistry.FromDefinition()` — runtime policy build từ DB -- [x] `ContractWorkflowService` — load pinned def → FromDefinition → guard -- [x] `WorkflowAdminFeatures` — GetOverview + CreateNewVersion (auto-increment Version + deactivate old) -- [x] FE admin `/system/workflows/:typeCode` — DefinitionCard + history + Designer modal -- [x] Designer: Steps repeatable, per-step phase/name/SLA, +Role / +User approver select -- [x] Clone-from-version button cho starting point -- [x] Invariants: UNIQUE (Code, Version), 1 IsActive per ContractType, no cascade FK -- [x] E2E: create QT-MB-v02 → v01 archived → HĐ mới pin v02 → HĐ cũ pin v01 giữ nguyên -- [ ] Runtime enable User-kind approver trong TransitionAsync guard (data model ready) +### Pending migrations -## Phase 4 — Reporting + Polish (T10-11) +- [ ] `AddPePaymentTermFields` (nếu chốt UX tách field) +- [ ] `AddPeDepartmentOpinions` (nếu chọn Option A header columns) -### MVP xong (iteration 1) +## 🔁 Skill governance (recurring) -- [x] Dashboard admin: 5 KPI (total/active/overdue/published this month/total value) + by phase + top 5 NCC + top 5 dự án + 12 tháng -- [x] Excel export HĐ theo filter (phase/supplier/project/date range) qua ClosedXML -- [x] BE `GetDashboardStatsQuery` + `ExportContractsToExcelCommand` + ReportsController -- [x] FE `DashboardPage` rewrite với `BarChart` tự build (Tailwind only, không thư viện ngoài) -- [x] FE `ReportsPage` filter + export -- [x] Docs consolidation: `rules.md` + `architecture.md` + `database/schema-diagram.md` + gotchas update +Quy tắc: `docs/rules.md §9`. Audit định kỳ mỗi đầu tháng — workflow §9.4. -### Iteration 2 (Tier 3 + optional) - -- [x] Dashboard user-specific (`MyDashboard` endpoint — DraftsInProgress / PendingMyApproval / DueSoon / Overdue / DraftsTotalValue) + FE "Của tôi" row 4 card -- [x] UX polish: skeleton loader DataTable, empty state có action, error boundary recovery -- [x] Content polish: typography 14px + leading 1.55 + tracking-tight + PageHeader + Button + Input + DataTable -- [x] Brand identity: #1F7DC1 palette + Be Vietnam Pro font + Solutions logo -- [ ] SLA overdue report (by role / phase, export Excel) -- [ ] Contract audit log export (từng HĐ ra PDF) -- [ ] Chart library recharts (nếu cần chart phức tạp) -- [ ] Accessibility: keyboard nav, focus trap modal, aria labels -- [ ] Dark mode -- [ ] Performance: explicit index DB cho query hot đã identify -- [ ] Tài liệu user guide: quy trình tạo HĐ + duyệt -- [ ] UAT với 5-10 HĐ dữ liệu thật từ bộ phận Cung ứng - -## Phase 5 — Production (T12-13) - -### Prep xong (code + scripts + docs) - -- [x] `docs/guides/cicd.md` — CI/CD runbook -- [x] Gitea Actions workflow `.gitea/workflows/deploy.yml` — build .NET + 2 FE, deploy IIS qua WinRM -- [x] Pin Node `.nvmrc` 20 (gotcha #5) -- [x] `scripts/deploy-iis.ps1` — stop pool → backup → xcopy → start → health check -- [x] `scripts/backup-sql.ps1` — daily BACKUP DATABASE + COMPRESSION + retention 30d -- [x] `appsettings.Production.json` template + user secrets pattern -- [x] Rate limiting (built-in .NET 10) — auth-login 5/min + global 300/min -- [x] Health check `/health/live` + `/health/ready` (DB probe) -- [x] Serilog File sink rolling daily retention 30d -- [x] HSTS production (1 year) -- [x] `docs/guides/deployment-iis.md` — setup lần đầu + troubleshooting -- [x] `docs/guides/security-checklist.md` — OWASP top 10 -- [x] `docs/guides/runbook.md` — operations (restart, rollback, restore) -- [x] FE refresh token auto interceptor (queue pattern cả 2 app) - -### Deploy thật - -- [x] Windows Server setup: IIS + URL Rewrite + ARR (reverse proxy FE → IIS) -- [x] SQL Server prod (SQLEXPRESS) + vrapp db_owner -- [x] HTTPS certificate (Let's Encrypt qua win-acme — 3 cert + auto-renew) -- [x] Gitea remote setup + push all commits -- [x] Set Gitea Actions secrets (JWT_SECRET, DB_CONNECTION — deploy local via runner) -- [x] Enable Gitea runner (Windows self-hosted, shared với VIETREPORT) -- [x] Test CI/CD workflow — xanh E2E, /health/live 200 sau deploy -- [ ] **UAT production 1 tuần với 2-3 user thật** ← hard blocker còn lại -- [ ] SQL Task Scheduler trigger backup-sql.ps1 (script có sẵn, chưa schedule) -- [ ] Go-live checklist: rotate creds + backup plan + on-call contact - -### Phase 5.1 Security hardening + Users Mgmt - -- [x] Security headers middleware (X-Content-Type-Options, X-Frame-Options, CSP, Referrer-Policy, Permissions-Policy) -- [x] Identity account lockout (5 fail → 15min, config-driven) -- [x] Password policy config-driven (default 8 dev, override `Identity:Password:RequiredLength` prod) -- [x] LoginCommand: check IsLockedOutAsync + AccessFailedAsync + reset on success -- [x] BE Users management: CQRS 8 feature + UsersController 7 endpoint (Users.Read/Create/Update policies) -- [x] FE admin `/system/users`: list + create + assign roles + reset password + unlock + toggle active -- [x] IDOR check ContractsController — user Drafter chỉ xem HĐ mình tạo hoặc role eligible phase (`ListContractsQueryHandler` + `GetContractQueryHandler`) -- [x] Admin mặc định warning log (`DbInitializer.WarnDefaultAdminPasswordAsync`) -- [ ] Dependencies scan vào CI (`dotnet list package --vulnerable --include-transitive`, `npm audit --audit-level=high`) -- [x] BE Roles CRUD (Create/UpdateLabels/Delete custom role) + FE `/system/roles` — Name FK không đổi, ShortName+Description editable (commit 072ad6d) - -## Skill governance (recurring) - -**Quy tắc:** xem `docs/rules.md §9`. Audit định kỳ mỗi đầu tháng — workflow §9.4. - -- [x] **Setup ban đầu** — 6 skill (3 domain + 3 ops), rules §9, HANDOFF section A1 ← `661f859`+ +- [x] **Setup ban đầu** — 6 skill (3 domain + 3 ops), rules §9 ← `661f859` - [ ] **Audit 2026-05-01** — log `docs/changelog/skill-audit-2026-05.md` - [ ] **Audit 2026-06-01** - [ ] **Audit 2026-07-01** -- [ ] (lập lại mỗi tháng đầu) -## Session 2026-04-23 (tối) — RolesPage + Demo data + Clear pending tasks +Cron task `solution-erp-skill-audit-monthly` fire 9:00 AM ngày 1 mỗi tháng. -- [x] **RolesPage CRUD** `/system/roles` — 12 hardcoded + custom (`072ad6d`) -- [x] **Seed 7 demo HĐ** varied phases + details + comments + approvals (`8bc9565`) -- [x] **User-kind approver runtime guard** trong TransitionAsync (`4edcd58`) -- [x] **Warning 20% SLA** notification trong SlaExpiryJob (`4edcd58`) -- [x] **Edit detail row inline** — 7 typed UpdateXxxDetail + EditRowDialog (`e53cd3a`) -- [x] **Deps audit helper** `scripts/deps-audit.ps1` (`e53cd3a`) -- [x] **Master expand** 5→15 NCC + 3→8 Project (per-Code idempotent) (`bcdc007`) -- [x] **Backfill demo HĐ** supplier+project diverse theo loại (`bcdc007`) - -## 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` -- [x] **SignalR realtime notifications** — 3-project clean-arch split + JWT `?access_token=` + auto-reconnect — `ea9ab5e` -- [x] **Form template builder CRUD** — Upload/Update/Delete + FieldSpec JSON editor — `166d26c` -- [x] **PDF export + DynamicForm + .doc auto-convert** — LibreOffice headless per-request temp — `6bbd894` + `e459097` -- [x] **Dynamic workflow policy** — Standard/SkipCcm registry theo ContractType — `cae4d84` -- [x] **Versioned workflow** — WorkflowDefinition + Steps + Approvers pinned per Contract — `e7e5f2d` -- [x] **Admin workflow designer** — per-type page + Designer modal + clone — `e7e5f2d` -- [x] **Nested sidebar menu fe-user** — 7 type × 3 action + admin/user split — `5e0f380` -- [x] **Workflows tabs → sidebar menu** — 7 Wf_ leaves + URL-driven — `f216169` -- [x] **PermissionsPage 3-panel layout** — Role list | Menu×CRUD | Granted stats — `91b2da1` -- [x] **Seed master data** — 9 dept + 5 supplier + 3 project + MyDashboard — `6197c84` -- [x] **Brand identity** — #1F7DC1 palette + Be Vietnam Pro + Solutions logo — `4abb559`..`bf1fbe3` - -## Phase 6 — Module Duyệt NCC (tiền-HĐ) ✅ Done - -- [x] **Migration 12 AddPurchaseEvaluations** — 10 bảng: PurchaseEvaluations + Suppliers + Details + Quotes + Approvals + Changelogs + Attachments + WorkflowDefinitions + WorkflowSteps + WorkflowStepApprovers -- [x] **Domain** — 2 enum (Type A/B, Phase 7 state) + Policy record + Registry + FromDefinition builder (mirror WorkflowPolicyRegistry HĐ) -- [x] **Seed** — 13 menu Pe_*/PeWf_* + 2 WorkflowDefinition v01 (QT-DN-A 3-step, QT-DN-B 5-step) -- [x] **Application CQRS** — ~900 dòng: Create/Update/Transition/List/Inbox/Get/Delete + Supplier CRUD + Detail CRUD + Quote Upsert + SelectWinner + Changelog -- [x] **PurchaseEvaluationWorkflowService** — policy-based guard + approval + notification + changelog -- [x] **PurchaseEvaluationsController** — 17 endpoint REST -- [x] **FE 2 app** — Types + PurchaseEvaluationsListPage 3-panel + PurchaseEvaluationCreatePage + PeDetailTabs (5 tab) + PeWorkflowPanel + Menu resolver Pe_* -- [x] **Kế thừa HĐ** — CreateContractFromEvaluationCommand guard DaDuyet + SelectedSupplier + !ContractId → gen Contract draft kế thừa Supplier/Project/GiaTri/DraftData. FE CreateContractDialog pick ContractType 7 loại. Link 2 chiều PE.ContractId. -- [ ] **PE Workflow admin designer UI** — `/system/pe-workflows/:typeCode` (framework đã sẵn, mirror `/system/workflows/:typeCode`) — optional -- [ ] **PE Attachments upload** (pattern reuse ContractAttachmentFeatures) — optional -- [ ] **Auto-map PE Details → Contract Details per-type** khi gen HĐ — phức tạp vì 7 ContractType schema khác nhau, user điền lại manual — optional - -## Phase 7 — PE refinement (session tiếp) - -**User feedback (2026-04-23 tối session 2):** "phần Duyệt NCC chưa xong đâu đấy nhé, còn chỉnh nhiều" - -### A. Chức năng MISSING trong MVP - -- [ ] **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` - - BE `Application/PurchaseEvaluations/PeWorkflowAdminFeatures.cs` — mirror `WorkflowAdminFeatures.cs` (GetOverview + CreateNewVersion) - - `Api/Controllers/PeWorkflowsController.cs` — GET overview + POST create-version (`[Authorize(Policy = "PeWorkflows.Create")]`) - - FE `fe-admin/src/pages/system/PeWorkflowsPage.tsx` — URL-driven, landing + per-type - - FE `fe-admin/src/components/workflow/PeWorkflowDesigner.tsx` — Steps + Approvers modal - - Route `/system/pe-workflows/:typeCode` trong App.tsx (menu `PeWf_*` + resolver đã sẵn) -- [ ] **PE Attachments upload** — pattern copy từ `ContractAttachmentFeatures.cs` - - BE `Application/PurchaseEvaluations/PurchaseEvaluationAttachmentFeatures.cs` (Upload/Download/Delete) - - 3 endpoint POST/GET/DELETE `/api/purchase-evaluations/{id}/attachments` - - FE `components/pe/PeAttachmentsSection.tsx` — drag-drop với purpose selector -- [ ] **Ý kiến 4 phòng ban** (Phê duyệt / P.CCM / P.MuaHàng / SM-PM từ Excel form) - - Option A: Thêm 4 text field (NhậnXétPheDuyet/CCM/MuaHang/SmPm) + 4 date field + 4 UserId vào `PurchaseEvaluations` header - - Option B: Dùng existing `PurchaseEvaluationApprovals` với roleKind extra field - - UX: tab Thông tin hiển thị 4 box sign-off như Excel -- [ ] **Payment terms tách field** từ JSON → 6 columns hoặc subtable - - Migration `AddPurchaseEvaluationPaymentTerms` — cột/bảng: TamUng%, ThanhToanTam%, QuyetToan%, BaoHanh%, HanMucCongNo, DanhGia - - FE form field-based (loại bỏ JSON textarea) -- [ ] **Auto-map PE Details → Contract Details khi gen HĐ** (optional — nâng cấp) - - 7 mapping function per ContractType (khó vì schema khác biệt) - - MVP: skip, user nhập manual -- [x] ✅ **Demo PE data seed** — `SeedDemoPurchaseEvaluationsAsync` (2026-04-24) - - A-001 DangSoanThao (Drafter mới mở, chưa có quotes) - - A-002 ChoCEODuyetNCC (winner đề xuất + 9 quotes 3×3 grid) - - A-003 DaDuyet (chưa tạo HĐ — showcase kế thừa button) + PaymentTerms JSON - - B-001 ChoDuAn (5-step giữa chừng) - - Idempotent: skip-if-`[DEMO]` exists -- [x] ✅ **MaPhieu format chính thức + atomic sequence** (2026-04-24) - - Format: `PE/{YYYY}/{TypeLetter}/{Seq:D3}` (TypeLetter = A | B) - - `PurchaseEvaluationCodeSequences` bảng mới (Prefix PK, mirror ContractCodeSequences) - - `IPurchaseEvaluationCodeGenerator` + impl SERIALIZABLE transaction - - Migration 13 `AddPurchaseEvaluationCodeSequences` (1 bảng) - - Wired vào CreatePurchaseEvaluationCommandHandler thay Random.Shared - -### B. UX / Polish - -- [ ] Matrix Quotes **bulk paste** từ Excel column giá → paste matrix row -- [ ] **Export phiếu PDF/Excel** — tái dùng `IDocumentConverter` + template `PE-TrinhDuyet.docx` upload qua FormsPage -- [x] ✅ **Permission grant Pe_* cho non-admin role** (2026-04-24) - - `SeedPurchaseEvaluationPermissionDefaultsAsync` — 7 role × 9 menu key - - Drafter/DeptManager/Procurement: R+C+U - - CostControl/PM/Director/AuthorizedSigner: R+U - - DeptManager thêm Delete (xóa nháp) - - Idempotent per-(roleId × menuKey), admin tinh chỉnh tiếp qua /system/permissions -- [ ] **fe-user Inbox** thêm section "Phiếu Duyệt NCC chờ tôi" (hoặc route `/pe-inbox`) -- [ ] **Sidebar accordion fe-user** extend cover `Pe_` (hiện chỉ track `Ct_`) -- [ ] **Dashboard** — thêm KPI "PE phiếu chờ tôi", "PE đã duyệt tháng này", "PE cần tạo HĐ" - -### C. Edge case + E2E test - -- [ ] Reject path E2E: DangSoanThao → ChoPurchasing → (CCM reject) → DangSoanThao -- [ ] Admin tạo PE workflow v02 sau khi có phiếu pin v01 — invariant test -- [ ] Xóa phiếu khi PE.ContractId set — warning dialog -- [ ] 2 admin đồng thời tạo v02 cho cùng type — race condition (atomic dealsactivate old) - -### D. Deploy - -- [ ] Verify commit `3990066` apply prod (runner status + `/api/purchase-evaluations` → 401 expected) - -## Post-launch (Phase 8+ — future) +## 📦 Post-launch (Phase 8+ — future) - [ ] **Email outbox** (MailKit + SMTP) — blocked chờ SMTP config -- [x] **Roles CRUD** — admin tạo custom role ngoài 12 hardcoded (commit 072ad6d) -- [ ] **User-kind approver runtime** — data model có, guard cần wire - [ ] E-signature integration (VNPT CA hoặc FPT CA) - [ ] Tích hợp Bravo / SAP ERP import NCC - [ ] Mobile app (React Native?) cho BOD duyệt ngoài giờ diff --git a/docs/flows/README.md b/docs/flows/README.md index d88f129..88435e7 100644 --- a/docs/flows/README.md +++ b/docs/flows/README.md @@ -7,11 +7,12 @@ | Flow | Phase | Trạng thái | Doc | |---|---|---|---| | **Authentication** — login, refresh, logout, /me | 1 | ✅ Implemented | [`auth-flow.md`](auth-flow.md) | -| **Permission resolution** — resolve menu + CRUD cho user | 1 đợt 2 | 📝 Planned | [`permission-flow.md`](permission-flow.md) | -| **Contract creation** — tạo HĐ draft + fill form template | 2 | 📝 Planned | [`contract-creation-flow.md`](contract-creation-flow.md) | -| **Contract approval** — state machine 9 phase | 3 | 📝 Planned | [`contract-approval-flow.md`](contract-approval-flow.md) | -| **Form render** — template engine xuất docx/xlsx | 2 | 📝 Planned | [`form-render-flow.md`](form-render-flow.md) | -| **SLA expiry auto-approve** — hosted service | 3 | 📝 Planned | [`sla-expiry-flow.md`](sla-expiry-flow.md) | +| **Permission resolution** — resolve menu + CRUD cho user (inherit Contracts/Workflows/PurchaseEvaluations/PeWorkflows roots) | 1 | ✅ Implemented | [`permission-flow.md`](permission-flow.md) | +| **Contract creation** — tạo HĐ draft + fill form template + 7 per-type Details | 2-3 | ✅ Implemented | [`contract-creation-flow.md`](contract-creation-flow.md) | +| **Contract approval** — state machine 9 phase + versioned workflow per ContractType | 3 | ✅ Implemented | [`contract-approval-flow.md`](contract-approval-flow.md) | +| **Form render** — template engine OpenXml/ClosedXML + LibreOffice PDF | 2 | ✅ Implemented | [`form-render-flow.md`](form-render-flow.md) | +| **SLA expiry auto-approve** — hosted service 15-min check + warning 20% | 3 | ✅ Implemented | [`sla-expiry-flow.md`](sla-expiry-flow.md) | +| **Purchase Evaluation** — phiếu duyệt NCC tiền-HĐ + kế thừa HĐ | 6 | ✅ Implemented (UX iter 2) | (xem `architecture.md §9` + `database/schema-diagram.md §11`) | ## Quy ước đọc diff --git a/docs/workflow-contract.md b/docs/workflow-contract.md index 93e13f6..256617d 100644 --- a/docs/workflow-contract.md +++ b/docs/workflow-contract.md @@ -1,7 +1,7 @@ # Workflow — Quy trình trình ký Hợp đồng TP/NCC/Tổ đội > **Nguồn:** `QUY_TRINH/QT TRINH KY HOP DONG TP-NCC.docx` -> **Raw dump:** [`workflow-raw.md`](workflow-raw.md) +> **Raw dump:** [`_archive/workflow-raw.md`](_archive/workflow-raw.md) — Phase 0 (archived) > **Phase 3 deliverable:** Implement state machine + role guard + SLA timer + notification ## 1. Phạm vi