# HANDOFF — Brief 5 phút cho session tiếp theo **Last updated:** 2026-04-21 15:30 (cuối Phase 5 Prep) ## Ở đâ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 MVP (9 phase + code gen) | ✅ Done | | 3 Workflow iteration 2 (SLA + notify + attachment) | 📝 Optional | | 4 Report MVP (Dashboard + Excel) | ✅ Done | | 4 Report iteration 2 | 📝 Optional | | **5 Prep (infra + scripts + guides + refresh token)** | ✅ Done | | 5 Deploy production (cần Gitea URL) | 📋 Next | | 5.1 Security hardening (headers, lockout, IDOR) | 📋 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 (Phase 4 MVP): - **Admin `/dashboard`** → 5 KPI card + By Phase bar + Monthly chart + Top NCC/dự án - **Admin `/reports`** → filter phase/date → Export Excel .xlsx 10 cột có formula SUM - **fe-user `/contracts/new`** → tạo HĐ draft (Phase 2 DangSoanThao, SLA +7d) - **fe-user `/inbox`** → xem HĐ chờ role mình xử lý - **`/contracts/{id}`** → click "Duyệt → tiếp" chạy state machine. Phase 8 gen `MaHopDong` RG-001 - **`/forms`** → render template .docx - **`/system/permissions`** → ma trận Role × MenuKey - **`/master/suppliers|projects|departments`** → CRUD ## Cần làm kế tiếp (ưu tiên) ### A. Phase 5 — Production (tuần 12-13, item lớn nhất còn lại) **Đọc trước:** `docs/changelog/migration-todos.md` section Phase 5. - [ ] `.gitea/workflows/deploy.yml` CI/CD build + deploy IIS - [ ] `scripts/deploy-iis.ps1` stop app pool → xcopy → start - [ ] Windows Server IIS + URL Rewrite + ARR (reverse proxy FE → .NET) - [ ] HTTPS cert via win-acme hoặc mua - [ ] `appsettings.Production.json` + user secrets + JWT secret rotation - [ ] Rate limiting middleware (auth endpoint 5 req/min/IP) - [ ] Security audit OWASP top 10 - [ ] Health check endpoint `/health` - [ ] Serilog → file rolling daily retention 30d - [ ] SQL backup: daily full + 15min log - [ ] Runbook: restart, rollback migration, restore backup - [ ] UAT production 1 tuần với 2-3 user thật - [ ] Go-live checklist ### B. Polish iterations (optional — khi rảnh) **Phase 2 iter 2:** convert 3 .doc qua Word COM `DisplayAlerts=0` hoặc LibreOffice, field spec JSON + form builder FE dynamic, `{{#loop}}` block support, PDF convert, FE upload template multipart. **Phase 3 iter 2:** `SlaExpiryJob` BackgroundService auto-approve, email (MailKit) + in-app (SignalR) notify, upload attachment endpoint + FE multipart (`wwwroot/uploads/contracts/{id}/`), RowVersion concurrency, render HĐ docx khi tạo (merge TemplateId + DraftData + ContractClause). **Phase 4 iter 2:** SLA overdue report by role/phase, PDF HĐ export (LibreOffice), dashboard user-specific (role tôi). ### C. Phase 2 iteration 2 (form engine polish) - Convert 3 file `.doc` qua Word COM `DisplayAlerts=0` + timeout, hoặc LibreOffice - Field spec JSON per template + dynamic form builder FE - `{{#loop}}...{{/loop}}` block support cho table lặp - PDF convert via LibreOffice headless - Admin upload template UI (multipart) ### D. Quick wins (không block phase) - FE Users management + Roles CRUD (test permission với non-admin user thật) - Filter Inbox theo phase FE - Refresh token auto (FE axios interceptor retry 401) ## 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 + **Contract, ContractApproval, ContractComment, ContractAttachment, ContractCodeSequence** ← Phase 3 │ │ ├── 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 │ │ ├── Contracts/ ContractFeatures (8 CQRS), IContractWorkflowService, IContractCodeGenerator, DTOs ← Phase 3 │ │ ├── Forms/ FormFeatures (List/Get/Render) ← Phase 2 │ │ ├── Master/ Suppliers, Projects, Departments CQRS │ │ ├── Permissions/ GetMyMenuTree, matrix upsert │ │ └── Reports/ **DashboardStats, ExportContractsToExcel, IContractExcelExporter** ← Phase 4 │ ├── SolutionErp.Infrastructure/ │ │ ├── Forms/ DocxRenderer, XlsxRenderer, FormRenderer ← Phase 2 │ │ ├── Identity/ JwtSettings, JwtTokenService │ │ ├── Persistence/ DbContext, DbInitializer, Interceptors, Migrations (**5**) │ │ ├── Reports/ **ContractExcelExporter** ← Phase 4 │ │ └── Services/ DateTimeService, ContractWorkflowService, ContractCodeGenerator ← Phase 3 │ └── SolutionErp.Api/ │ ├── Authorization/ MenuPermissionHandler + Requirement │ ├── Controllers/ Auth, Suppliers, Projects, Departments, Menus, Roles, Permissions, Forms, Contracts, **Reports** (10 controller) │ ├── Middleware/ GlobalExceptionMiddleware │ ├── Services/ CurrentUserService, WebHostEnvironmentLocator │ └── wwwroot/templates/ 5 file .docx/.xlsx ← Phase 2 ├── fe-admin/ (11 page) │ └── src/pages/ │ ├── LoginPage │ ├── DashboardPage ← Phase 4 rewrite (KPI cards + BarChart) │ ├── master/SuppliersPage, ProjectsPage, DepartmentsPage │ ├── system/PermissionsPage │ ├── forms/FormsPage ← Phase 2 │ ├── contracts/ContractsListPage, ContractDetailPage ← Phase 3 │ └── ReportsPage ← Phase 4 ├── fe-user/ (5 page) │ └── src/pages/ │ ├── LoginPage │ ├── InboxPage ← Phase 3 │ └── contracts/ContractCreatePage, ContractDetailPage, MyContractsPage ← Phase 3 ├── docs/ (35 file) │ ├── STATUS.md, HANDOFF.md, rules.md, architecture.md │ ├── CLAUDE.md, PROJECT-MAP.md │ ├── workflow-contract.md, forms-spec.md │ ├── database/{database-guide, schema-diagram}.md │ ├── flows/ (7 file — README + 6 flow) │ ├── guides/ (4 file) — deployment-iis, cicd, security-checklist, runbook ← Phase 5 prep │ ├── changelog/migration-todos.md + sessions/ (7 session log) │ └── gotchas.md ├── scripts/ (5 file PS + py) │ ├── parse_forms.py, parse_workflow.py (Phase 0) │ ├── convert-doc-to-docx.ps1 (Phase 2) │ └── deploy-iis.ps1, backup-sql.ps1 ← Phase 5 prep ├── .gitea/workflows/deploy.yml ← Phase 5 prep CI/CD template └── .claude/skills/ (3 skill — all full spec) ``` ## Git state ``` (sẽ là commit 8) — Phase 5 Prep (infra + scripts + guides + refresh token) fe7ad8e — Phase 4 Report MVP + docs consolidation 7e957a7 — Phase 3 Workflow MVP 5113e4c — Phase 2 Form Engine 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 CẦN NGAY để Phase 5 go-live) ``` ## 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 full 9-phase workflow end-to-end — mã HĐ gen đúng format RG-001 - Docs đầy đủ: 26 file, session log mỗi chunk, gotchas tích lũy 17 pitfall - Cả 2 FE đều có Contract detail page + timeline + comment thread + state machine action **Rủi ro còn:** - SLA chỉ set deadline — không có job auto-approve (Phase 3.2) - Không có notification (email + in-app) — user phải F5 inbox - Form render chỉ MVP — loop table + PDF chưa có - Permission matrix chưa test thực với non-admin user - 3 file .doc chưa convert (carryover Phase 2) - Không có upload attachment endpoint (chỉ có entity + DTO)