Backend Forms:
- Domain/Forms: ContractTemplate (FormCode, Name, ContractType, FileName, StoragePath, Format, FieldSpec JSON, IsActive) + ContractClause
- EF config voi unique FormCode + query filter IsDeleted
- DbSets + IApplicationDbContext update
- Migration AddForms (bang 14 total)
- Packages: DocumentFormat.OpenXml 3.x + ClosedXML 0.105+
- Application/Forms:
- IFormRenderer interface + RenderResult record
- FormFeatures.cs: List/Get/Render CQRS
- IWebHostEnvironmentLocator (abstract IWebHostEnvironment)
- Infrastructure/Forms:
- DocxRenderer: OpenXml-based placeholder {{field}} replace, handle split runs (gom text tat ca <w:t> trong paragraph, replace, gan lai text dau + clear rest)
- XlsxRenderer: ClosedXML cell value replace
- FormRenderer router theo format docx/xlsx
- Api:
- FormsController: GET /templates (filter type, onlyActive), GET /templates/{id}, POST /templates/{id}/render (return file)
- WebHostEnvironmentLocator impl
- DbInitializer SeedContractTemplatesAsync: seed 8 template metadata, IsActive=true chi khi file ton tai
Templates vat ly:
- Copy 5 .docx/.xlsx tu FORM/ sang wwwroot/templates/
- 3 .doc (FO-002.02/03/06) chua convert: IsActive=false (Word COM bi stuck luc test, can retry voi DisplayAlerts=0 hoac LibreOffice)
- scripts/convert-doc-to-docx.ps1 (Word COM automation)
Frontend fe-admin:
- types/forms.ts: ContractTemplate + ContractTypeLabel
- pages/forms/FormsPage.tsx: list templates + Render dialog (paste JSON data → download .docx/.xlsx)
- Route /forms them vao App.tsx
Bug fix:
- SpaceProcessingModeValues namespace: wrap EnumValue<> full path
- SaveAs2($path, 16) thay vi SaveAs([ref], [ref]) — PowerShell type issue
- Word COM stuck: kill process, skip .doc cho MVP
Docs (theo yeu cau user):
- docs/gotchas.md MOI: 17 pitfalls nhom theo tech stack / EF Core / OpenXml / JSON / dev workflow
- .claude/skills/form-engine/SKILL.md: placeholder → full spec (algorithm + code pointers + API + limitations)
- .claude/skills/permission-matrix/SKILL.md: placeholder → full spec (BE policy + FE guard + seed + pitfalls)
- docs/HANDOFF.md MOI: brief 5 phut cho session sau (run quickstart + where we are + next steps + file tree + gotchas ref)
- docs/STATUS.md: update cumulative stats + next up Phase 3
- docs/changelog/migration-todos.md: tick Phase 2 iteration 1 items + add iteration 2 list
- docs/changelog/sessions/2026-04-21-1200-phase2-form-engine.md: session log
- CLAUDE.md root: them reference den gotchas + HANDOFF
E2E verified:
- GET /api/forms/templates (onlyActive=false) → 8 templates
- POST /api/forms/templates/{FO-002.05}/render voi data dict → HTTP 200 + file .docx 482KB (Microsoft Word 2007+ OK)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.2 KiB
4.2 KiB
CLAUDE.md — AI Agent Context
Full content:
docs/CLAUDE.md
SOLUTION_ERP — Hệ thống Quản lý Hợp đồng Nhà cung cấp / Thầu phụ / Tổ đội 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 — 4 file đọc trước tiên
1. docs/STATUS.md ← Snapshot HIỆN TẠI (phase nào, việc gì đang làm)
2. docs/PROJECT-MAP.md ← Bản đồ toàn cảnh (nên đọc đầu dự án)
3. docs/changelog/migration-todos.md ← Atomic tasks theo từng phase
4. docs/workflow-contract.md ← ⭐ State machine 9 phase — ảnh hưởng mọi thiết kế
⚡ 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
IApplicationDbContextinterface (Application layer) - Auth: JWT Bearer + ASP.NET Identity
- DB: SQL Server (LocalDB dev / SQL Server prod), EF Core 10 Code-First migrations
- Error handling:
GlobalExceptionMiddlewaremap 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
>=20trongengines; CI pin20.xqua.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, ...)
- 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
Commit convention
[CLAUDE] <scope>: <imperative message>
Scope: Contract · Form · Workflow · Supplier · Auth · Admin · Api · App · Domain · Infra · FE-Admin · FE-User · Docs · CICD · Scripts
📖 Tài liệu quan trọng
| File | Nội dung |
|---|---|
docs/STATUS.md |
🔥 Current state — đọc đầu tiên |
docs/PROJECT-MAP.md |
Bản đồ tổng quan |
docs/changelog/migration-todos.md |
Roadmap 5 phase + atomic tasks |
docs/CLAUDE.md |
Full context — tech stack, architecture |
docs/workflow-contract.md |
State machine 9 phase + role matrix |
docs/forms-spec.md |
Catalog 8 form + quy định mã HĐ |
docs/database/database-guide.md |
DB conventions + schema hiện tại + planned + ERD |
docs/flows/README.md |
Index 6 flow (auth, permission, contract create/approve, form render, SLA) |
docs/gotchas.md |
⭐ 17 bẫy đã gặp — đọc trước khi debug tương tự |
docs/HANDOFF.md |
Brief 5 phút: session trước làm gì + P1 tasks tiếp |
⚠️ Kết thúc session
- Update
docs/STATUS.md(In Progress→Recently Done) - Tick checklist tương ứng trong
docs/changelog/migration-todos.md - Tạo session log
docs/changelog/sessions/YYYY-MM-DD-HHMM-{topic}.mdnếu đáng ghi - Commit
[CLAUDE] <scope>: <message> - ⚠️ Update
SolutionErp.slnxnếu có.cs/.csprojmới
Bỏ qua nếu chỉ trả lời câu hỏi, không sửa file nào.