Backend production infra:
- Packages: Serilog.Sinks.File, HealthChecks.EntityFrameworkCore (RateLimiting built-in .NET 10)
- appsettings.Production.json MOI: placeholder __SET_VIA_SECRETS__, AllowedOrigins, Serilog File sink rolling daily retention 30d, RateLimit config
- appsettings.json + Development.json: them Serilog WriteTo Console
- Program.cs REWRITE:
- Serilog ReadFrom.Configuration (prod file / dev console)
- Rate limiter: policy auth-login 5/min/IP (AuthController.Login) + GlobalLimiter 300/min/IP
- Health checks: /health/live liveness (empty predicate) + /health/ready DB probe (AddDbContextCheck)
- HSTS production 1 year
- CORS origins from config AllowedOrigins (default dev 2 localhost)
- AuthController.Login gắn [EnableRateLimiting("auth-login")]
Deploy scripts:
- scripts/deploy-iis.ps1: stop pool → backup current → clean+extract artifact → start pool → health check loop 30s timeout → rollback instruction if fail
- scripts/backup-sql.ps1: BACKUP DATABASE voi INIT+COMPRESSION+CHECKSUM + retention 30d auto cleanup
- .gitea/workflows/deploy.yml MOI: 4 job build BE (Windows) + build 2 FE (Ubuntu, pin .nvmrc 20) + deploy-iis qua WinRM PSSession (secrets IIS_HOST/USER/PASSWORD/JWT_SECRET/DB_CONNECTION)
Docs guides MOI (4 file):
- deployment-iis.md: prereqs (IIS features, Hosting Bundle, SQL, WinRM) + setup lan dau (app pool, 3 site, HTTPS win-acme, user-secrets) + deploy hang ngay (CI/CD + manual) + rollback + monitoring + troubleshooting + SPA web.config sample
- cicd.md: pipeline overview 4 job, secrets setup, runner Windows+Ubuntu, branch strategy, build optimizations, common CI/CD issues
- security-checklist.md: OWASP top 10 2021 mapping voi status + pre go-live checklist + incident response
- runbook.md: daily ops (health/logs), restart/rollback, DB backup/restore/migration revert, user management (reset password, unlock, disable), monitoring (CPU/disk/connection pool), deployment checklist, common gotcha
Frontend refresh token (ca 2 app fe-admin + fe-user):
- lib/api.ts REWRITE: them REFRESH_KEY, axios response interceptor 401 → POST /auth/refresh → retry request goc. Queue pattern cho nhieu request song song chi 1 refresh call chay. Skip retry /auth/login + /auth/refresh tranh infinite loop. _retry flag tren original config.
- contexts/AuthContext.tsx: luu+xoa REFRESH_KEY trong login/logout
E2E verified:
- GET /health/live → 200 Healthy
- GET /health/ready → 200 Healthy (DB probe)
- Rate limit flood 7 POST /auth/login → #1-5 HTTP 400 (cred sai) + #6-7 HTTP 429 Too Many Requests ✅
- TS check fe-admin + fe-user → pass
- dotnet build → 0 errors
Docs updates:
- docs/STATUS.md: Phase 5 prep done, next Phase 5 deploy production + Phase 5.1 security hardening, cumulative stats 8 commits
- docs/HANDOFF.md: phase table them Phase 5 prep row, file tree update voi guides + scripts + workflows, git state commit 8
- docs/changelog/migration-todos.md: tick Phase 5 prep items (12 items done) + Phase 5 deploy items remaining + Phase 5.1 security hardening list
- docs/changelog/sessions/2026-04-21-1530-phase5-prep.md: session log chi tiet
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.4 KiB
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
# 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 genMaHopDongRG-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.ymlCI/CD build + deploy IISscripts/deploy-iis.ps1stop 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
.docqua Word COMDisplayAlerts=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 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)