Files
solution-erp/docs/HANDOFF.md
pqhuy1987 5113e4c771 [CLAUDE] Phase2: Form Engine MVP + docs (gotchas, skill, handoff)
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>
2026-04-21 12:01:11 +07:00

156 lines
6.3 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.

# HANDOFF — Brief 5 phút cho session tiếp theo
**Last updated:** 2026-04-21 12:00 (cuối Phase 2 MVP)
## Ở đâu rồi?
| Phase | Trạng thái |
|---|---|
| 0 Draft | ✅ Done |
| 1 Alpha Core foundation | ✅ Done |
| 1 Alpha Core đợt 2 (CRUD + Permission) | ✅ Done |
| **2 Form Engine MVP** | ✅ Done |
| 2 Form Engine iteration 2 | 📝 Optional |
| 3 Workflow (9 phase state machine) | 📋 Next |
| 4 Report + Polish | 📋 Queue |
| 5 Production (CI/CD IIS) | 📋 Queue |
## Run nhanh
```powershell
# Terminal 1 — API (auto seed 8 template lần đầu)
dotnet run --project src\Backend\SolutionErp.Api
# Terminal 2 — Admin FE
cd fe-admin && npm run dev # → http://localhost:8082
# Terminal 3 — User FE
cd fe-user && npm run dev # → http://localhost:8080
```
Login: `admin@solutionerp.local` / `Admin@123456`
Điểm cần test ngay:
- `/forms` → render FO-002.05 → download .docx (Phase 2 MVP)
- `/system/permissions` → chọn role → tick matrix
- `/master/suppliers|projects|departments` → CRUD
## Cần làm kế tiếp (ưu tiên)
### A. Phase 3 — Workflow (item lớn, ~3 tuần work)
**Đọc trước:**
1. [`workflow-contract.md`](workflow-contract.md) — spec 9 phase + role matrix
2. [`flows/contract-approval-flow.md`](flows/contract-approval-flow.md) — sequence diagram
3. [`flows/sla-expiry-flow.md`](flows/sla-expiry-flow.md) — BackgroundService auto-approve
4. [`forms-spec.md#RG-001`](forms-spec.md) — format mã HĐ
**Deliverable chính:**
- Entity: `Contract` (Phase, SlaDeadline, BypassProcurementAndCCM, DraftData) + `ContractApproval` + `ContractComment` + `ContractAttachment`
- `IContractWorkflowService.TransitionAsync()` — state guard (9 phase adjacency) + role guard
- `IContractCodeGenerator` (implement RG-001) với transaction SERIALIZABLE + `ContractCodeSequences` table
- `SlaExpiryJob` BackgroundService — auto-approve HĐ quá hạn mỗi 15 phút
- `INotificationService` — email (MailKit) + in-app
- API `POST /api/contracts/{id}/transitions`
- FE `/inbox` (list HĐ chờ tôi xử lý theo role × phase)
- FE `/contracts/{id}` detail — timeline 9 phase, approval panel, comment thread, attachment upload
### B. Phase 2 iteration 2 (nếu user muốn polish Form Engine)
- Convert 3 file `.doc` (retry Word COM với timeout OR LibreOffice)
- Field spec JSON → dynamic form builder
- `{{#loop}}...{{/loop}}` support
- PDF convert
- FE upload template UI
### C. Quick wins (không block phase)
- FE Users management + Roles CRUD (test permission với non-admin role)
- fe-user sync menu động (đang hardcode)
## Lưu ý kỹ thuật quan trọng
**Đọc [`gotchas.md`](gotchas.md) trước khi:**
- Thêm package mới → check compat với .NET 10 (MediatR 14 fail → dùng 12)
- Debug 404 API → kiểm Program.cs có persist không (Dropbox issue)
- Expression tree error → tách switch ra ngoài LINQ
- TS enum error → dùng const-object pattern (`erasableSyntaxOnly`)
- Word COM stuck → kill + fallback LibreOffice
- Migration lỗi → check 3 file đầy đủ (Designer + Migration + Snapshot)
## File đang active
```
SOLUTION_ERP/
├── src/Backend/ (Clean Arch, 4 project, .NET 10)
│ ├── SolutionErp.Domain/
│ │ ├── Common/ BaseEntity, AuditableEntity
│ │ ├── Contracts/ ContractType, ContractPhase, ApprovalDecision
│ │ ├── Forms/ ContractTemplate, ContractClause ← Phase 2
│ │ ├── Identity/ User, Role, MenuItem, Permission, AppRoles, MenuKeys
│ │ └── Master/ Supplier, Project, Department, SupplierType
│ ├── SolutionErp.Application/
│ │ ├── Auth/ Login, Refresh, Me
│ │ ├── Common/ Exceptions, Behaviors, Interfaces, Models
│ │ ├── Forms/ FormFeatures (List/Get/Render) ← Phase 2
│ │ ├── Master/ Suppliers, Projects, Departments CQRS
│ │ └── Permissions/ GetMyMenuTree, matrix upsert
│ ├── SolutionErp.Infrastructure/
│ │ ├── Forms/ DocxRenderer, XlsxRenderer, FormRenderer ← Phase 2
│ │ ├── Identity/ JwtSettings, JwtTokenService
│ │ ├── Persistence/ DbContext, DbInitializer, Interceptors, Migrations (4)
│ │ └── Services/ DateTimeService
│ └── SolutionErp.Api/
│ ├── Authorization/ MenuPermissionHandler + Requirement
│ ├── Controllers/ Auth, Suppliers, Projects, Departments, Menus, Roles, Permissions, Forms
│ ├── Middleware/ GlobalExceptionMiddleware
│ ├── Services/ CurrentUserService, WebHostEnvironmentLocator
│ └── wwwroot/templates/ 5 file .docx/.xlsx ← Phase 2
├── fe-admin/ (7 page)
│ └── src/pages/
│ ├── LoginPage
│ ├── DashboardPage
│ ├── master/SuppliersPage, ProjectsPage, DepartmentsPage
│ ├── system/PermissionsPage
│ └── forms/FormsPage ← Phase 2
├── fe-user/ (2 page — Login + Inbox placeholder)
├── docs/ (24 file — STATUS, PROJECT-MAP, workflow, forms-spec, database-guide, 6 flow, gotchas, 4 session log, 1 handoff)
└── .claude/skills/ (3 skill — contract-workflow placeholder, form-engine + permission-matrix full spec)
```
## Git state
```
49a5f57..(sẽ là commit 5) — Phase 2 MVP
54d6c9b — Phase 1.2 CRUD + Permission
49a5f57 — Docs database-guide + flows
702411f — Phase 1 foundation
25dad7f — Phase 0 scaffold
Branch: main
Remote: chưa (Gitea URL chờ user)
```
## Credentials + URLs
```
admin@solutionerp.local / Admin@123456
```
- API: http://localhost:5443 (swagger `/swagger`)
- Admin FE: http://localhost:8082
- User FE: http://localhost:8080
- SQL LocalDB: `(localdb)\MSSQLLocalDB` / Database=`SolutionErp_Dev`
## Đánh giá nhanh
**Tốt:**
- Build pass 100% cả BE + FE
- E2E test: login + CRUD + render template đều pass
- Docs đầy đủ: 24 file, có session log mỗi chunk, gotchas library tích lũy
**Rủi ro:**
- fe-user còn thô — Phase 3 phải build inbox
- Form render chỉ MVP — loop table + PDF chưa có
- Permission matrix chưa test thực với non-admin user