docs/database/database-guide.md: - Conventions (naming, data types, audit fields, soft delete) - Schema hien tai (Identity tables sau migration Init) + seed 12 role + admin - Schema planned: Phase 1 dot 2 (Supplier/Project/Department + Permission Matrix) - Schema planned: Phase 3 (Contract + Approval + Comment + Attachment + Template + Clause + CodeSequence) - Mermaid ERD cho tung phase - Migration workflow (create/apply/revert) - Index strategy + unique indexes - Backup/restore SQL - Common pitfalls + SQL cheatsheet docs/flows/ — 6 flow documentation: - README.md: index - auth-flow.md: login/refresh/me/logout (IMPLEMENTED, sequence + edge cases + security checklist) - permission-flow.md: Phase 1 dot 2 - Role x MenuKey x CRUD resolution + FE guard + BE policy - contract-creation-flow.md: Phase 2 - Drafter flow chon template -> fill -> preview -> save draft - contract-approval-flow.md: Phase 3 - state machine 9 phase chi tiet + reject flow + timeline UI - form-render-flow.md: Phase 2 - OpenXml + ClosedXML + LibreOffice PDF convert - sla-expiry-flow.md: Phase 3 - BackgroundService auto-approve qua SLA + warning notify Update references: - CLAUDE.md (root): them 2 row Tai lieu quan trong - docs/CLAUDE.md: update project layout voi flows/ + database/ - docs/STATUS.md: log docs addition - docs/changelog/migration-todos.md: tick Phase 0 docs items Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.6 KiB
9.6 KiB
Migration To-dos — Atomic Roadmap
Mỗi item là 1 task atomic (~2-8h work). Tick
[x]khi xong. Link session log nếu có.
Phase 0 — Draft Scaffold (T1)
- Tạo cấu trúc thư mục
SOLUTION_ERP/ - Scaffold .NET 10 solution
SolutionErp.slnx - Scaffold 4 project:
SolutionErp.{Domain, Application, Infrastructure, Api} - Wire Clean Arch references (Api → App/Infra, Infra → App, App → Domain)
- Install NuGet base: MediatR, FluentValidation, AutoMapper, EF Core SqlServer, Identity, JWT, Swagger, Serilog
- Scaffold 2 React + Vite apps
fe-admin+fe-uservới TS template - Config vite.config.ts: port, strictPort, proxy
/api, alias@ - Pin Node
>=20trong package.json +.nvmrccho CI - Parse 8 form →
docs/forms-spec.md - Parse quy trình →
docs/workflow-contract.md - Viết
docs/{CLAUDE,STATUS,PROJECT-MAP}.md - Viết
docs/database/database-guide.md(conventions + schema + ERD + migration workflow) - Viết
docs/flows/— README + 6 flow doc (auth, permission, contract-create, contract-approve, form-render, sla-expiry) - Viết
.gitignore,README.md,global.json,docker-compose.yml - Tạo placeholder skill folders:
contract-workflow,form-engine,permission-matrix git init+ commit đầu (25dad7f)- Push Gitea remote (chờ URL từ user)
Phase 1 — Alpha Core (T2-4)
Foundation (đã xong Session 2)
Domain/Common/BaseEntity.cs(Id Guid, CreatedAt, UpdatedAt, CreatedBy, UpdatedBy)Domain/Common/AuditableEntity.cs(IsDeleted, DeletedAt, DeletedBy)Domain/Contracts/Enums:ContractType,ContractPhase(9 state),ApprovalDecisionDomain/Identity/User.cs(IdentityUser + FullName + RefreshToken + IsActive)Domain/Identity/Role.cs(IdentityRole + Description)Domain/Identity/AppRoles.cs— 12 role constantsApplication/Common/Interfaces/: IApplicationDbContext, ICurrentUser, IDateTime, IJwtTokenServiceApplication/Common/Exceptions/*Application/Common/Behaviors/ValidationBehavior.csApplication/DependencyInjection.cs— MediatR + FluentValidationInfrastructure/Persistence/ApplicationDbContext.cs : IdentityDbContextInfrastructure/Persistence/Interceptors/AuditingInterceptor.csInfrastructure/Persistence/DbInitializer.cs— seed 12 role + adminInfrastructure/Persistence/DesignTimeDbContextFactory.csInfrastructure/Identity/{JwtSettings, JwtTokenService}.csInfrastructure/Services/DateTimeService.csInfrastructure/DependencyInjection.csApi/Services/CurrentUserService.csApi/Middleware/GlobalExceptionMiddleware.csApi/Controllers/AuthController.cs(login, refresh, me, logout)Api/Program.cs(Serilog, JWT, CORS, Swagger, middleware)Api/appsettings.{json, Development.json}+launchSettings.json(port 5443)- Migration 1
Init+ apply toSolutionErp_DevLocalDB - FE: Vite config (Tailwind 4 + proxy + alias)
- FE:
src/{index.css, lib/api.ts, lib/cn.ts, types/auth.ts}cho 2 app - FE:
src/contexts/AuthContext.tsx,components/{ProtectedRoute, Layout}.tsx - FE:
components/ui/{Button, Input, Label}.tsx - FE:
pages/LoginPage.tsx,pages/DashboardPage.tsx(admin) +pages/InboxPage.tsx(user) - FE:
App.tsxvới Router + AuthProvider + Toaster - FE:
main.tsxvới QueryClient (TanStack Query) - E2E verified: login qua Vite proxy cả 2 app → JWT + user info
Phase 1 đợt 2 — CRUD master + Permission Matrix (sắp tới)
Domain/Entities/Supplier(Code, Name, TaxCode, Phone, Email, Address, Type enum: NCC/NTP/TĐ/ĐVDV)Domain/Entities/Project(Code, Name, StartDate, EndDate, ManagerUserId)Domain/Entities/Department(Code, Name, ManagerUserId)- EF
IEntityTypeConfiguration<T>cho mỗi entity - CQRS CRUD: Create/Update/Delete/GetById/List (với paging) cho 3 entity
Api/Controllers/{SuppliersController, ProjectsController, DepartmentsController}- Migration 2:
AddMasterData Domain/Entities/MenuItem(Key PascalCase, Label, ParentKey, Order, Icon)Domain/Entities/Permission(RoleId, MenuKey, CanRead/Create/Update/Delete)- Seed default menu tree + permission admin có full access
Application/Permissions/Queries/GetMyMenuTreeQuery— resolve per-user, cacheApi/Controllers/{MenusController, RolesController, PermissionsController}- Migration 3:
AddPermissions Domain/Entities/Contractskeleton (Id, Type, SupplierId, ProjectId, Phase=DangChon, DraftData JSON)- Contract CRUD draft only (không workflow Phase 3)
- FE:
<PermissionGuard menuKey="Suppliers" action="Update">+usePermission()hook - FE Admin: 3 trang CRUD Supplier/Project/Department với table + modal + search/sort
- FE Admin: Permission Matrix grid page (role × menu × CRUD checkbox)
- FE User: trang "HĐ của tôi" list + filter
- Route guard theo role admin-only
- Update
SolutionErp.slnxnếu thêm project mới
Exit criteria Phase 1
- Admin login → tạo NCC/Project → tạo role "Nhân viên CCM" → gán permission menu "Contracts.Read"
- User CCM login → thấy menu Contracts, không thấy menu Admin
- Tạo Contract draft → list hiển thị, không bị 403 sai
Phase 2 — Form Engine (T5-6)
- Khảo sát: OpenXml vs Aspose.Words — chọn 1 (Aspose có license phí; OpenXml free nhưng verbose)
- Convert 3 file
.doc→.docx(COM automation PowerShell hoặc LibreOffice headless) - Parse chi tiết field của 5 template HĐ — mỗi form thành JSON spec
Domain/Entities/ContractTemplate(Id, FormCode, Name, TemplateFile path, FieldSpec JSON)Application/Forms/Services/IFormRenderer— input: template + data dict → output: byte[] (.docx)- Implement
DocxRenderer(OpenXml-based replace placeholder) - Implement
XlsxRenderercho FO-002.07 (dùng EPPlus/ClosedXML) Api/Controllers/FormsController— GET /templates, POST /render- FE user: form builder — chọn template → dynamic form → preview → export
- FE admin: upload template mới, edit field mapping
- Lưu
ContractClause(FO-002.04) dạng rich text, admin edit qua TipTap/TinyMCE - Import/export template (để backup)
- Test: 1 HĐ Giao khoán filled → export .docx mở bằng Word y hệt mẫu
Phase 3 — Workflow State Machine (T7-9)
Domain/Entities/ContractApproval+ContractComment+ContractAttachmentDomain/Entities/Contractupdate: thêmPhase,SlaDeadline,BypassProcurementAndCCMDomain/Services/IContractWorkflowService.TransitionAsync(...)— state guard + role guard + side effectsInfrastructure/Services/ContractCodeGenerator(implement RG-001) với locking cho seqInfrastructure/HostedServices/SlaExpiryJob— check mỗi 15min, auto-approve quá hạnInfrastructure/Services/NotificationService— email (MailKit) + in-app (SignalR optional)- MediatR behavior:
AuditBehavior— log mọi command - API:
POST /api/contracts/{id}/transitionsbody:{targetPhase, comment} - FE user Inbox: list "HĐ chờ tôi xử lý" (query by current phase + user role)
- FE Contract detail page: timeline 9 phase, approval panel, comment thread
- Upload attachment (scan có chữ ký đối tác)
- Notification UI: badge count, dropdown, click → detail
- E2E test: happy path end-to-end 1 HĐ qua 9 phase
- E2E test: reject → quay về DangSoanThao
- E2E test: SLA expired → auto-approve + log
Phase 4 — Reporting + Polish (T10-11)
- Dashboard admin: số HĐ theo phase, top NCC, top dự án, tổng giá trị theo tháng
- Excel export theo bộ lọc (dùng EPPlus)
- Report: HĐ quá hạn SLA bao nhiêu lần theo phase/role
- UX polish: skeleton loader, empty state, error boundary có recovery button
- Accessibility: keyboard nav, focus trap modal, aria labels
- Dark mode (optional, nếu rảnh)
- Performance: index DB cho query hot (SupplierId, ProjectId, Phase)
- Tài liệu user guide: quy trình tạo HĐ + duyệt
- UAT với 5-10 HĐ dữ liệu thật từ bộ phận Cung ứng
Phase 5 — Production (T12-13)
docs/guides/cicd.md— CI/CD runbook- Gitea Actions workflow
.gitea/workflows/deploy.yml— build .NET + 2 FE, deploy IIS qua SSH/WinRM - Pin Node 20.x trong workflow, test CI sớm (không để surprise cuối dự án)
scripts/deploy-iis.ps1— stop app pool, xcopy, start app pool- Windows Server setup: IIS + URL Rewrite + ARR (reverse proxy FE → IIS)
- SQL Server prod: backup plan daily + weekly full
- HTTPS certificate (Let's Encrypt qua win-acme hoặc mua cert)
appsettings.Production.json+ user secrets- Security audit: owasp top 10 check
- Rate limiting middleware (AspNetCoreRateLimit hoặc built-in)
- Health check endpoint
/healthcho IIS probe - Error tracking: Serilog → file rolling daily, retention 30 ngày
- Runbook: restart app, rollback migration, restore backup
- UAT production 1 tuần với 2-3 user thật
- Go-live checklist: backup, rollback plan, on-call contact
Post-launch (Phase 6+ — future)
- E-signature integration (VNPT CA hoặc FPT CA)
- Tích hợp Bravo / SAP ERP import NCC
- Mobile app (React Native?) cho BOD duyệt ngoài giờ
- AI: gợi ý điền form dựa HĐ cũ, OCR scan HĐ đối tác
- Multi-tenant nếu có công ty thứ 2