Files
solution-erp/CLAUDE.md
pqhuy1987 17f697aa94 [CLAUDE] Docs: chốt Session 19 — PE Section 5 V2 dynamic + Mig 26
Chunk D Docs cho Session 19 (PE Section 5 dynamic theo
ApprovalWorkflowLevel):

- docs/STATUS.md — Recently Done row Session 19 chi tiết + header
  narrative 25→26 mig + 58→59 tables + 5 spec Q&A + 4 chunk per-commit
- docs/HANDOFF.md — TL;DR Session 19 đầy đủ (polish 3 button +
  Chunk A/B/C summary + Stats Δ) + 7 cảnh báo Session 20+. Giữ TL;DR
  S18 nguyên văn theo §6.5 (KHÔNG cắt narrative)
- docs/changelog/migration-todos.md — Phase 9 Session 19 done block
  với 5 commit + Stats final + Defer Session 20+ (8 task pending)
- docs/changelog/sessions/2026-05-09-0400-pe-section-5-v2-dynamic-mig26.md
  — Session log mới, full Q&A + Chunks + Bug fix + Stats cumulative
- CLAUDE.md (root) — count 25→26 mig + 58→59 tables + Mig 26 description

KHÔNG đụng (per §6.5 không cố sửa khi không cần):
- rules.md / architecture.md / PROJECT-MAP.md / workflow-contract.md /
  forms-spec.md / database-guide.md
- Skills (6) — drift defer cron audit 2026-06-01
- schema-diagram.md §16 PE Level Opinions V2 — defer cùng §17-21 cron
  audit 2026-06-01

Path filter docs-only → CI sẽ skip deploy (gotcha #41).
2026-05-09 11:11:09 +07:00

146 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CLAUDE.md — AI Agent Context
> **Full content:** [`docs/CLAUDE.md`](docs/CLAUDE.md)
---
**SOLUTION_ERP** — Hệ thống Quản lý Hợp đồng Nhà cung cấp / Thầu phụ / Tổ đội + **Phiếu Duyệt NCC tiền-HĐ** cho Công ty TNHH Xây dựng Solutions.
Kiến trúc: **.NET 10 Clean Architecture + 2 React FE (admin + user) + SQL Server + IIS**.
## 🚀 BẮT ĐẦU SESSION — 5 file đọc trước tiên
```
1. docs/STATUS.md ← Snapshot HIỆN TẠI (phase nào, việc gì đang làm — PE module CÒN CHỈNH NHIỀU)
2. docs/HANDOFF.md ← Brief 5 phút: session trước làm gì + cảnh báo session tiếp
3. docs/PROJECT-MAP.md ← Bản đồ toàn cảnh
4. docs/changelog/migration-todos.md ← Atomic tasks theo phase (Phase 7 PE refinement mới)
5. docs/workflow-contract.md ← ⭐ State machine 9 phase HĐ — base pattern cho PE workflow
```
## ⚡ Quick Rules
### Backend — `.NET 10` Clean Architecture
- Solution: `SolutionErp.slnx` ở root, projects ở `src/Backend/`
- **4 layer:** `Api → Application ← Domain` + `Infrastructure → Application`
- Pattern: **CQRS + MediatR**, **FluentValidation**, **AutoMapper**
- Repository qua `IApplicationDbContext` interface (Application layer)
- Auth: **JWT Bearer + ASP.NET Identity**
- DB: **SQL Server** (LocalDB dev / SQL Server prod), **EF Core 10 Code-First migrations**
- Error handling: `GlobalExceptionMiddleware` map exception → HTTP status
- Commit scope tech stack: `Api` · `App` · `Domain` · `Infra`
### Frontend — 2 app React 18 + Vite + TS + shadcn/ui + TanStack Query
- `fe-admin/` (port **8082**) · `fe-user/` (port **8080**)
- Vite proxy `/api → http://localhost:5443` (SolutionErp.Api)
- **Named export**, không default export (trừ `App`)
- shadcn/ui copy-paste, **duplicate giữa 2 app là CÓ CHỦ ĐÍCH** (mỗi app UX riêng)
- Auth context: `solution-erp-admin-token` / `solution-erp-user-token``localStorage`
- TanStack Query cho data fetching
- **Node pin `>=20`** trong `engines`; CI pin `20.x` qua `.nvmrc` (bài học NamGroup — KHÔNG dùng Node latest trên CI)
- UI **100% tiếng Việt**
### Database conventions
- Schema: `dbo` (single schema)
- Table: **PascalCase tiếng Anh** (Contracts, Suppliers, Projects, ContractApprovals, PurchaseEvaluations, ...)
- PK: `Id` (Guid), FK: `{Entity}Id`
- Audit fields: `CreatedAt`, `UpdatedAt`, `CreatedBy`, `UpdatedBy` (`BaseEntity`)
- Soft delete: `IsDeleted`, `DeletedAt`, `DeletedBy` (`AuditableEntity`)
- Migrations: `dotnet ef migrations add <Name> --project src/Backend/SolutionErp.Infrastructure --startup-project src/Backend/SolutionErp.Api`
- **Hiện có 26 migration → 59 bảng** (Phase 9+ Session 19 — Mig 26 `AddPeLevelOpinionsForV2`: bảng mới `PurchaseEvaluationLevelOpinions` UNIQUE composite (PEId, LevelId), FK Cascade Pe + Restrict Level. Section 5 "Ý kiến cấp duyệt" V2 dynamic theo workflow đã pin: forEach Step (Phòng) → forEach Level (Cấp) → forEach NV → 1 OpinionBox. Service `ApproveV2Async` UPSERT auto khi NV duyệt — Q1=1B (sync gắn với Duyệt, KHÔNG form input rời). SignedByUserId track signer thật, FE banner "Admin duyệt thay" khi !== ApproverUserId. Comment empty → "(duyệt — không ý kiến)" placeholder. Phiếu V1 legacy fallback Mig 15 4 box readOnly (data history). Mig 25 `AddIsUserSelectableToApprovalWorkflows`: ALTER `ApprovalWorkflows` +`IsUserSelectable bit` (admin pin/unpin workflow nào cho user pick lúc create phiếu, multi-select độc lập IsActive). Backfill `WHERE IsActive=1 SET 1` giữ behavior cũ. Designer +badge "Cho user chọn" + button Ghim/Bỏ ghim. Workspace filter dropdown chỉ workflows `IsUserSelectable=true`. Mig 22-24 V2 schema (Session 17): `ApprovalWorkflows`/Steps/Levels — Quy trình > Bước (Phòng) > Cấp (N NV cụ thể qua ApproverUserId, OR-of-N cùng cấp). PE.ApprovalWorkflowId pin V2. PE.CurrentApprovalLevelOrder track. State machine 5 trạng thái: Nháp / Đã gửi duyệt / Trả lại (Phase riêng TraLai=98) / Từ chối / Đã duyệt. PE Service V2 wire match `actor.Id == ApproverUserId`. Contract V2 chưa wire (Mig 27/28 defer Session 20+). 81 test pass. Mig 21 V1 flat workflow vẫn live cho phiếu cũ.)
### 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, 13, 15 | Feature-complete — chỉ Export PDF còn pending (không quan trọng) |
| Budget (Ngân sách dự án) | `Domain/Budgets/` | 14 | **Feature-complete** — BE + FE 3-panel + integration với PE/HD |
| Master (Supplier/Project/Department) | `Domain/Master/` | 2, 10 | 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 |
| **Tests** | `tests/SolutionErp.{Domain,Infrastructure}.Tests/` | — | **81 test pass** (58 Domain + 23 Infra: 17 codegen + 6 PE WF) — CI gate + path filter docs-only skip |
### Commit convention
```
[CLAUDE] <scope>: <imperative message>
```
**Scope:** `Contract` · `PurchaseEvaluation` · `Budget` · `Form` · `Workflow` · `Supplier` · `Auth` · `Admin` · `Api` · `App` · `Domain` · `Infra` · `FE-Admin` · `FE-User` · `Tests` · `Docs` · `CICD` · `Scripts` · `Skill`
## 🧪 Tests (Phase 9 — Session 9 +6)
```
tests/
├── SolutionErp.Domain.Tests/ (54 test - Phase 1: WorkflowPolicy / PEPolicy / BudgetPolicy)
└── SolutionErp.Infrastructure.Tests/ (17 + 6 + 6 = 29 test)
├── Common/ (SqliteDbFixture + TestApplicationDbContext + IdentityFixture S9)
├── Services/ (17 codegen + 6 PE 2-stage approval S9)
└── Application/ (6 test - PeWorkflowDefinition versioning)
```
**81 unit test pass** / ~3s (58 Domain + 23 Infra: 17 codegen + 6 PE WF versioning). +4 TraLai entry-point tests Session 17 (Standard_TraLai_To_DangGopY + BothPolicies_TraLai_To_ChoPurchasing + NextPhasesFrom_TraLai). Mig 21 drop 19 legacy N-stage/2-stage tests. CI gate + path filter live.
```bash
dotnet test SolutionErp.slnx # chạy cả 2 test project
```
**Quy tắc timing test:** feature mới = test-after (UAT ổn → viết). Bug fix = test-before BẮT BUỘC (reproduce → fix). Critical algorithm (codegen/guard/financial/security) = test-before merge. Spec change = update test cũ + code chung commit. Skip: DTO mapping, CRUD master, FE snapshot. Detail `docs/rules.md §7`.
### CI/CD pipeline (3 fix lớn 29/04)
- ✅ Manual checkout bypass github.com (fix gotcha #39 TCP timeout)
- ✅ Path filter docs-only skip — `paths-ignore` (gotcha #41)
- ⏸️ npm cache (gotcha #40 — failed, rolled back)
**Tốc độ:** code commit ~3 phút / docs-only commit **0s** (skip).
## 🛠️ Skills (.claude/skills/) — 6 skill PHẢI dùng khi task khớp
| Domain (3) | Ops (3) |
|---|---|
| `contract-workflow` — state machine + versioned WF | `dependency-audit-erp` — npm/dotnet CVE scan |
| `form-engine` — render docx/xlsx + PDF | `ef-core-migration` — EF migration + 3-file rule |
| `permission-matrix` — role × menu × CRUD | `iis-deploy-runbook` — 3 site IIS + win-acme + runner |
**Audit định kỳ:** đầu mỗi tháng — combined skill + doc drift audit theo `docs/rules.md §6.4 + §9.4`. Cron `solution-erp-skill-audit-monthly` fire 9:00 ngày 1. Lần kế: **2026-05-01**.
Quy tắc:
- KHÔNG bulk-clone repo skill 3rd party. Chỉ thêm skill PROJECT-SPECIFIC. Xem `docs/rules.md §9` đầy đủ.
- KHÔNG rewrite toàn bộ MD định kỳ. Chỉ compact + patch drift. Xem `docs/rules.md §6.4` đầy đủ.
## 📖 Tài liệu quan trọng
| File | Nội dung |
|---|---|
| [`docs/STATUS.md`](docs/STATUS.md) | **🔥 Current state** — đọc đầu tiên |
| [`docs/HANDOFF.md`](docs/HANDOFF.md) | Brief 5 phút: session trước làm gì + next tasks |
| [`docs/rules.md`](docs/rules.md) | ⭐ Coding conventions (BE Clean Arch, FE React, DB, Git, Docs) |
| [`docs/architecture.md`](docs/architecture.md) | ⭐ Layered architecture + request lifecycle + deployment |
| [`docs/PROJECT-MAP.md`](docs/PROJECT-MAP.md) | Bản đồ tổng quan |
| [`docs/changelog/migration-todos.md`](docs/changelog/migration-todos.md) | Roadmap 5 phase + atomic tasks |
| [`docs/CLAUDE.md`](docs/CLAUDE.md) | Full context — tech stack chi tiết |
| [`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 52 table (+ §11 PE module + §12 Budget module + §13 PEDeptOpinions) |
| [`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 |
| [`docs/guides/vps-setup.md`](docs/guides/vps-setup.md) | ⭐ Master runbook deploy VPS shared với VIETREPORT |
## ⚠️ Kết thúc session
1. Update `docs/STATUS.md` (`In Progress``Recently Done`)
2. Tick checklist tương ứng trong `docs/changelog/migration-todos.md`
3. Tạo session log `docs/changelog/sessions/YYYY-MM-DD-HHMM-{topic}.md` nếu đáng ghi
4. Commit `[CLAUDE] <scope>: <message>`
5. ⚠️ **Update `SolutionErp.slnx`** nếu có `.cs/.csproj` mới
> Bỏ qua nếu chỉ trả lời câu hỏi, không sửa file nào.