Files
solution-erp/docs/changelog/migration-todos.md
pqhuy1987 b431c8f68d
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 3m7s
[CLAUDE] Docs: Chunk E7 — chốt session 9 Chunk E-bis complete
- STATUS: Recently Done +1 row session 9 (5 commit per-chunk + 83 test). Phase 9
  header update count 77→83. Section E (Chunk E-bis) tick toàn bộ done.
- HANDOFF: TL;DR session 9 + Cảnh báo session 10. Giữ session 8 narrative cũ.
- migration-todos: Phase 9 +1 section "Session 9 done" với 5 task tick. Pending
  Chunk E-bis tick chuyển done.
- CLAUDE.md (root + docs): test count 77 → 83 (54 Domain + 29 Infra:
  17 codegen + 6 PE WF Application + 6 PE 2-stage approval).
- Session log mới: 2026-05-04-1700-chot-session-9-chunk-e-bis-complete.md
  (full narrative + lessons + stats theo §6.5 KEEP rule).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 13:56:38 +07:00

266 lines
20 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.

# Migration To-dos — Atomic Roadmap
> Tick `[x]` khi xong. Phase 0-8 đã DONE — collapsed. Detail xem session
> logs trong `docs/changelog/sessions/`. Active work: Phase 9 (UAT + Ops + carry over PE PDF export + Tests Phase 3-5).
## ✅ Phase 0-5 + Tier 3 — Done (2026-04-21..22)
| Phase | Focus | Trạng thái |
|---|---|---|
| 0 Draft | Scaffold .NET 10 + 2 Vite + parse FORM/QT + docs | ✅ |
| 1 Alpha Core | Auth + 12 role + Permission Matrix + 3 master CRUD + Contract draft | ✅ |
| 2 Form Engine | OpenXml + ClosedXML render + LibreOffice PDF + DynamicForm | ✅ |
| 3 Workflow | State machine 9 phase + RG-001 code gen + SLA job + attachments + SignalR realtime | ✅ |
| 4 Reporting | Dashboard KPI + Excel export + MyDashboard role-aware + brand identity #1F7DC1 | ✅ |
| 5 Production | CI/CD Gitea Actions + 3 IIS site + Let's Encrypt + Security headers + Users CRUD | ✅ |
| Tier 3 | Versioned workflow + 3-panel layout + 4-bảng overhaul + 4 master catalogs + 16 demo users + RolesPage CRUD + 7 demo HĐ varied | ✅ |
Detail chi tiết: `docs/changelog/sessions/2026-04-21-*.md` + `2026-04-22-0300-tier3-feature-complete.md` + `2026-04-23-*.md`.
## ✅ Phase 6 — Module Duyệt NCC (tiền-HĐ) — Done
### Iter 1 (2026-04-23)
- [x] Migration 12 `AddPurchaseEvaluations` — 10 bảng (Header/Suppliers/Details/Quotes/Approvals/Changelogs/Attachments/WorkflowDefinitions/Steps/StepApprovers)
- [x] Domain — 2 enum (Type A/B, Phase 7-state) + Policy record + Registry + FromDefinition builder
- [x] Seed — 13 menu Pe_*/PeWf_* + 2 WorkflowDefinition v01 (QT-DN-A 3-step, QT-DN-B 5-step)
- [x] Application CQRS ~900 LOC — Create/Update/Transition/List/Inbox/Get/Delete + Supplier CRUD + Detail CRUD + Quote Upsert + SelectWinner + Changelog
- [x] PurchaseEvaluationWorkflowService — policy guard + approval + notification + changelog
- [x] PurchaseEvaluationsController — 17 endpoint REST
- [x] FE 2 app — Types + PurchaseEvaluationsListPage 3-panel + Create page + PeDetailTabs + PeWorkflowPanel + Menu resolver Pe_*
- [x] Kế thừa HĐ — `CreateContractFromEvaluationCommand` (guard DaDuyet + SelectedSupplier + !ContractId) → Contract draft. FE CreateContractDialog pick ContractType.
- [x] **Migration 13** `AddPurchaseEvaluationCodeSequences` — atomic MaPhieu sequence `PE/{YYYY}/{A|B}/{Seq:D3}`
- [x] Demo PE seed — 4 phiếu varied phase (A-001/A-002/A-003/B-001) + Pe_* permission defaults 7 role × 9 menu key
Session log: `2026-04-23-2300-purchase-evaluations.md` + `2026-04-24-1030-pe-polish-demo-maphieu-perms.md`.
### Iter 2 — UX polish (2026-04-24)
- [x] Rename menu "Phương Án" → "Giải pháp" + backfill DB (zero breaking change)
- [x] Menu tree inheritance extend Pe_*/PeWf_* (`GetMyMenuTreeQuery` + 4 root)
- [x] Accordion mutex Pe_* groups + sidebar w-72 + label nowrap
- [x] NavLink active check query string (queryMatches helper) — fix 2 leaf cùng highlight
- [x] PE detail flat layout: Panel 2 = 4 section (Thông tin/NCC/Hạng mục/**Bảng so sánh**), Panel 3 += Approvals + Changelog
- [x] Upload file đính kèm per-NCC (SupplierAttachmentsCell) + Bảng so sánh tổng (GeneralAttachmentsSection, supplierRowId=null) + enum `ComparisonTable=4`
- [x] readOnly mode menu "Duyệt" (pendingMe=1) — hide Sửa/Xóa/Thêm/Edit/Upload/Delete, giữ download + transition + comment
- [x] Contract: move Lịch sử điều chỉnh Panel 2 → Panel 3 (Chi tiết HĐ full-width)
- [x] Demo email rebrand `@solutionerp.local``@solutions.com.vn` + `BackfillUserEmailDomainAsync` (idempotent rename 4 field Email/NormalizedEmail/UserName/NormalizedUserName)
Session log: `2026-04-24-chot-session-3-pe-polish.md`.
### ✅ Domain rebrand `.huypham.vn` → `.solutions.com.vn` (2026-04-24)
- [x] 18 file repo (FE env + scripts + CI/CD + docs + skill + code comments)
- [x] `scripts/migrate-domains.ps1` (ASCII-only #30) — 3 IIS binding + 3 cert Let's Encrypt + auto HTTPS + redirect
- [x] CI/CD auto rebuild BE CORS + FE bundle VITE_API_BASE_URL
- [x] E2E verified 3 domain live + preflight OK
Sub: `api.solutions.com.vn` · `admin.solutions.com.vn` · `eoffice.solutions.com.vn`. Old `.huypham.vn` vẫn fallback (chưa remove — Phase 9 Ops).
## 📝 Phase 7 — PE feature gap + Budget BE (Session 4 partial done)
### A. PE feature gap (3 task — phần lớn đóng ở Phase 8 S5)
- [x] **PE Workflow admin designer UI** `/system/pe-workflows/:typeCode` — done S5 (`5d94bb4`)
- BE `Application/PurchaseEvaluations/PeWorkflowAdminFeatures.cs` (mirror `WorkflowAdminFeatures.cs`)
- `Api/Controllers/PeWorkflowsController.cs`
- FE `fe-admin/src/pages/system/PeWorkflowsPage.tsx` + `PeWorkflowDesigner.tsx`
- Route `/system/pe-workflows/:typeCode` (menu PeWf_* + resolver đã sẵn)
- [x] **Ý kiến 4 phòng ban** (Phê duyệt / P.CCM / P.MuaHàng / SM-PM) ở tab Thông tin — done S5 (`5d94bb4`, Migration 15)
- Option A: 4 text field + signoff date + UserId vào header
- Option B: dùng `PurchaseEvaluationApprovals` với roleKind extra field
- **Chốt:** dùng Migration 15 `AddPurchaseEvaluationDepartmentOpinions` (separate table UNIQUE PEId+Kind, 4 box sign-off 2x2 grid OpinionBox như Excel mẫu) — tốt hơn Option A/B vì audit qua Changelog + Upsert preserve chữ ký cũ khi text-only edit.
- [ ] **Export phiếu PDF/Excel** — tái dùng `IDocumentConverter` + template `PE-TrinhDuyet.docx` → carry over Phase 9 (user pending — không quan trọng lắm)
### B. Optional polish (carry over Phase 9 — làm khi UAT phát sinh)
- [ ] Auto-map PE Details → Contract per-type Details khi gen HĐ (phức tạp vì 7 schema khác nhau)
- [ ] Payment terms tách field từ JSON → 6 column (Tạm ứng/TT tạm/Quyết toán/Bảo hành/Hạn mức/Đánh giá)
- [ ] Matrix Quotes bulk paste từ Excel
- [ ] fe-user Inbox thêm section "Phiếu Duyệt NCC chờ tôi"
### C. Ops (carry over Phase 9 — Hard blockers)
- [ ] Remove binding cũ `.huypham.vn` sau verify stable: `ssh vietreport-vps ; cd C:\solution-erp\scripts ; .\migrate-domains.ps1 -RemoveOld -SkipCert`
- [ ] win-acme scheduled task fix unhealthy (cert expire 2026-06-18)
- [ ] UAT thật 1 tuần với 2-3 user (30 demo user — 16 sample + 14 Solutions thật)
- [ ] SMTP config → Email outbox
- [ ] Rotate credentials (admin + 30 demo + SA + vrapp + JWT)
- [ ] Schedule SQL backup Task Scheduler
### D. Module Ngân sách (Budget) — Session 4 ✅ partial done
- [x] **Migration 14** `AddBudgets` — 4 bảng (Budgets/BudgetDetails/BudgetApprovals/BudgetChangelogs) + index BudgetId nullable trên Contract & PurchaseEvaluation
- [x] Domain — `Budget` (Header) + `BudgetDetail` (flat row) + `BudgetApproval` + `BudgetChangelog` + enum `BudgetPhase` 5-state + `BudgetEntityType` Header/Detail/Workflow
- [x] `BudgetPolicy.Default` hardcoded simple 3-step (Drafter→CCM→CEO + Reject từ ChoCCM/ChoCEO về DangSoanThao)
- [x] Application CQRS ~340 LOC — Create + UpdateDraft + Transition + List + GetDetail + Delete (only DangSoanThao/TuChoi) + Detail CRUD (auto-recompute TongNganSach) + ListChangelogs
- [x] `BudgetsController` 11 endpoint REST
- [x] Menu seed `Budgets` root + 3 leaf (Bg_List/Bg_Create/Bg_Pending) order=27 icon Wallet
- [x] **14 demo user Solutions thật** — PRO 5 + CCM 7 + ISO 1 + CEO 1 (pwd `User@123456`). Reconcile pattern (gotcha #38 4-field rename). Tổng 30 user (16 sample cũ + 14 Solutions thật mới).
Session log: `2026-04-28-chot-session-4-budget.md`.
### E. Pending migrations
- [ ] `AddPePaymentTermFields` (nếu chốt UX tách field — JSON blob → 6 column)
- [x] **`AddPurchaseEvaluationDepartmentOpinions`** ✅ migration 15 (S5)
- [ ] `AddBudgetCodeSequences` (nếu chốt format MaNganSach atomic — hiện Random.Shared)
- [ ] `AddBudgetVersionedWorkflow` (nếu user cần admin config UI thay vì hardcoded `BudgetPolicy.Default`)
## ✅ Phase 8 — Budget FE + PE/HD integration (Session 5 done)
### A. FE Budget pages — done ✅
- [x] `fe-admin/src/types/budget.ts` (BudgetPhase 5-state enum + DTO types)
- [x] `fe-admin/src/pages/budgets/BudgetsListPage.tsx` (3-panel `[340px_1fr_360px]` + filter Phase/Năm + ?phase=Pending alias + readOnly mode + BudgetDetailPage fullpage mobile)
- [x] `fe-admin/src/pages/budgets/BudgetCreatePage.tsx` (form Header — Tên/Năm/Dự án/Phòng ban/Mô tả)
- [x] `fe-admin/src/components/budgets/BudgetDetailTabs.tsx` (Section Thông tin Header + Section Hạng mục table CRUD inline auto-compute ThanhTien=KL×ĐG)
- [x] `fe-admin/src/components/budgets/BudgetWorkflowPanel.tsx` (Panel 3 timeline activePhases + nextPhases buttons + Dialog comment + Approvals/Changelog)
- [x] Mirror tất cả sang `fe-user/`
- [x] App.tsx routes `/budgets`, `/budgets/new`, `/budgets/:id` cả 2 app
- [x] Menu resolver `Bg_*` (Bg_List → `/budgets`, Bg_Pending → `/budgets?phase=Pending`, Bg_Create → `/budgets/new`)
### B. PE/Contract → Budget integration — done ✅
- [x] **PE form** + Select "Ngân sách" filter Phase=DaDuyet, ProjectId match, BE validate
- [x] **Contract form** (Header + Edit) tương tự, EditForm read-only link card khi !isDraft
- [x] PE Detail Hạng mục thêm cột "NS link · Δ" — match per-row qua `groupCode|itemCode` + footer aggregate (xanh dưới / đỏ vượt / xám khớp)
- [x] PE Detail UI restructure 4 section đánh số match form spec PHIẾU TRÌNH KÝ
- [x] BE: BudgetSummaryDto shared + Create/Update PE+Contract commands + BudgetId? + GetQueries load Budget
- [x] CreateContractFromEvaluation carry forward pe.BudgetId → contract.BudgetId
### C. PE Workflow Designer admin UI — done ✅
- [x] BE `PeWorkflowAdminFeatures.cs` ~250 LOC mirror Contract pattern
- [x] BE `PeWorkflowsController` 2 endpoint reuse policy `Workflows.*`
- [x] FE `PeWorkflowsPage.tsx` ~500 LOC + designer dialog (clone/edit/+Role/+User)
- [x] App.tsx route `/system/pe-workflows/:typeCode`
### D. Ý kiến 4 phòng ban — done ✅
- [x] Migration 15 `AddPurchaseEvaluationDepartmentOpinions` (UNIQUE PEId+Kind)
- [x] Domain entity + enum `PeDepartmentKind` (PheDuyet/Ccm/MuaHang/SmPm)
- [x] BE Upsert (sign=true → set SignedAt+UserId, sign=false giữ chữ ký cũ) + Delete + 2 endpoint
- [x] FE Section "5. Ý kiến 4 phòng ban (sign-off)" 2x2 grid OpinionBox
### E. Tests Phase 1-2-3mini + CI optimize — done ✅
- [x] **Phase 1**`tests/SolutionErp.Domain.Tests/` (xUnit + FluentAssertions 7.2): 54 test policy state machine (Contract WF + PE WF + Budget) + Registry + FromDefinition versioned + UserKindApprover
- [x] **Phase 2**`tests/SolutionErp.Infrastructure.Tests/` (EF SQLite + TestApplicationDbContext override `nvarchar(max) → TEXT`): 17 test code generator format + sequence + year boundary + persistence verify
- [x] **Phase 3 mini**`tests/.../Application/PeWorkflowAdminTests.cs`: 6 test CreatePeWorkflowDefinitionCommand versioning (auto-increment + deactivate cũ + EvaluationType independence + steps/approvers persistence)
- [x] CI gate `.gitea/workflows/deploy.yml` — 2 step `dotnet test` trước build, fail → no deploy
- [x] **Total 77 test pass / ~3s**
- [x] **CI manual checkout bypass github.com** — fix gotcha #39 (act_runner TCP timeout 21s)
- [x] **CI path filter docs-only skip** — gotcha #41 (paths-ignore behavior)
- [ ] **Tests Phase 3 full** — Opinion Upsert + Budget link validation (cần Identity UserManager setup helper)
- [ ] **npm junction cache CI optimize** (rollback ở `a21790d` — gotcha #40 chưa debug)
## 📝 Phase 9 — UAT + Ops + carry over (Session 6+ active)
### ✅ Session 9 done (2026-05-04) — Chunk E-bis complete (FE 2-stage + HĐ/Budget mirror + 6 test)
User chỉ thị "làm hết cho xong tính năng luôn" sau Session 8 close bug fix anh Kiệt phía BE PE. Session 9 đóng toàn bộ pending Chunk E-bis (defer từ session 8).
- [x] **Chunk E2 — FE Workflow Panel PE** hiển thị progress 2-stage timeline per phase × dept (commit `f8eebd5`). Component `DeptApprovalsSection` group by phase × dept, highlight amber khi current phase có Review nhưng chưa Confirm, badge fuchsia "bypass" khi NV.CanBypassReview. Cả fe-admin + fe-user (rule §3.9).
- [x] **Chunk E3 — FE UserManager toggle CanBypassReview** (commit `4380bdc`). UserDto BE thêm field `CanBypassReview`. UsersPage column "Bypass" + button ShieldCheck (icon highlight fuchsia khi enabled). Endpoint backend đã có sẵn từ Session 8 Chunk E1. fe-user KHÔNG có UsersPage (admin-only).
- [x] **Chunk E4 — HĐ 2-stage logic mở rộng** (commit `b6f5a16`). ContractWorkflowService thêm `UserManager<User>` DI + mirror toàn bộ logic 2-stage từ PE service (sau policy guard, trước gen mã HĐ). ContractDepartmentApprovalFeatures.cs (List query mirror PE pattern). Endpoint `GET /contracts/{id}/department-approvals`. FE WorkflowHistoryPanel section "Tiến trình duyệt 2-cấp phòng ban" insert giữa WorkflowSummaryCard và Lịch sử duyệt.
- [x] **Chunk E5 — Budget 2-stage logic mở rộng** (commit `1fc439b`). TransitionBudgetCommandHandler thêm `INotificationService` + `IDateTime` DI + mirror 2-stage logic. BudgetDepartmentApprovalFeatures.cs + endpoint. FE BudgetWorkflowPanel section "Tiến trình duyệt 2-cấp phòng ban". Note: low-priority cho Budget (ít user duyệt budget per dept) nhưng giữ consistent UX 3 module.
- [x] **Chunk E6 — 6 test 2-stage + IdentityFixture helper** (commit `8353fe8`). IdentityFixture (Common/) setup ServiceProvider với Identity stack đầy đủ — DbContext SQLite shared connection + AddIdentityCore<User> + AddRoles<Role> + AddEntityFrameworkStores. Single shared scope cho fixture lifetime đảm bảo DbContext + UserManager đồng instance. Helper `CreateUserAsync(email, name, deptId, roles, canBypassReview)` reusable. 6 test PeTwoStageApprovalTests: NV_Review_Blocks_Phase_Transition (đóng bug anh Kiệt — test chính xác) / TPB_Confirm_After_NV_Review_Allows_Transition / NV_With_BypassReview_Allows_Transition_With_IsBypassed_True / Admin_Skips_TwoStage_Logic_Entirely / Reject_Sets_RejectedFromPhase_And_Forces_DangSoanThao / Resume_After_Reject_Jumps_Back_To_RejectedPhase. Tests Contract + Budget 2-stage skipped — logic identical PE, ROI thấp; pattern reusable nếu UAT phát hiện regression riêng. **Total 77→83 test pass**.
Stats sau session 9:
- BE LOC: ~13750 → ~14400 (+650, gồm Contract + Budget 2-stage logic + 2 List feature + Test fixture)
- API endpoints: ~131 → ~133 (+2 List dept-approvals HĐ/Budget)
- Tests: 77 → **83** (+6 PE 2-stage)
- Schema không đổi (Migration 16 đã có sẵn từ session 8)
- 5 commit per-chunk pushed → 1 CI run trigger qua HEAD = `8353fe8`
Pending còn lại Phase 9: chỉ Hard blockers Ops (UAT thật / SMTP / Rotate creds / SQL backup). Feature 2-stage đầy đủ.
### ✅ Session 8 done (2026-05-04) — Migration 16: 2-stage dept approval + smart reject + lock edit
**Bối cảnh:** Anh Kiệt (FDC) báo bug PE workflow: NV.PRO tạo phiếu → duyệt được hết phase. Phân quyền sai vì policy chỉ check role, không check Stage 2-cấp.
**3 ràng buộc gộp 1 migration:**
- [x] **Lock edit khi Phase != DangSoanThao** — 17 handler thêm guard (Contract Detail × 15 qua helper `EnsureContractType`, PE Detail × 5 qua helper mới `PurchaseEvaluationDraftGuard`, Budget Detail × 3 inline). KHÔNG lock Comment + Attachment + Opinion (workflow design intent).
- [x] **Smart reject + Resume**`Decision=Reject``entity.RejectedFromPhase = currentPhase` + force `targetPhase=DangSoanThao`. Resume: `Drafter trình từ DangSoanThao + RejectedFromPhase != null → jump tới phase đã reject + clear field`. Bypass policy guard ở resume.
- [x] **2-stage dept approval (PE only v1)** — User.DepartmentId != null + role guard:
- DeptManager (TPB) → Stage=Confirm trực tiếp
- User.CanBypassReview=true → Stage=Confirm + IsBypassed=true
- Else (NV) → Stage=Review only, BLOCK transition cho đến khi TPB confirm
- Schema: 3 bảng `*DepartmentApprovals` UNIQUE (TargetId, Phase, Dept, Stage)
- [x] **Migration 16** `AddTwoStageDeptApprovalAndSmartReject` — 4 ALTER + 3 CREATE TABLE + 12 indexes + FK Cascade
- [x] **Endpoint mới**: `GET /api/purchase-evaluations/{id}/department-approvals` (List), `PATCH /api/users/{id}/bypass-review` (toggle)
- [x] **Notify TPB cùng dept** khi NV review (best effort, fail non-critical)
- [x] **Verify**: Build pass + 77 test pass + Migration applied LocalDB OK + schema verified qua sqlcmd
- [x] 5 commit per-chunk: `5fe61cc` (A) · `14f3c9f` (B) · `9747f8c` (C) · `a532ba6` (D) · current (E1)
Session log: `2026-05-04-1230-chot-session-8-2-stage-dept-approval.md`.
**Pending Chunk E-bis** ✅ TẤT CẢ DONE ở Session 9 (xem section trên):
- [x] FE Workflow Panel hiển thị progress 2-stage timeline (E2 — PE) + HĐ (E4) + Budget (E5)
- [x] FE UserManager toggle `CanBypassReview` checkbox (E3)
- [x] HĐ 2-stage mở rộng (E4)
- [x] Budget 2-stage mở rộng (E5)
- [x] Tests 2-stage logic Service-layer (E6 — 6 test PE + IdentityFixture)
### ✅ Session 6 done (2026-04-30 — pure docs work)
- [x] **MD audit + compact** — STATUS -27%, HANDOFF -32%, migration-todos -35%, archive 51 row Phase 0-7 cũ
- [x] **3 skill refresh**`form-engine` Phase 2 MVP → Tier 3 feature-complete, `permission-matrix` 12 menu → ~60 + inheritance roots, `ef-core-migration` 24 DbSet → 52 bảng
- [x] **Rule mới rules.md §7** — Khi nào viết test (timing rule 5-row table)
- [x] **Rule mới rules.md §6.4** — Audit + compact MD định kỳ (cadence + checklist + anti-pattern)
- [x] **rules.md §9.4** — Mở rộng skill audit cross-ref §6.4
### A. Hard blockers (chờ user / ops)
- [ ] UAT thật 1 tuần với 2-3 user (30 demo: 16 sample + 14 Solutions thật)
- [ ] SMTP config → Email outbox (BLOCKED chờ user cấp host/user/pass)
- [ ] Rotate credentials (admin + 30 demo + SA + vrapp + JWT secret + Gitea runner token)
- [ ] Schedule SQL backup daily Task Scheduler
### B. PE feature gap còn lại
- [ ] Export phiếu PDF/Excel — `IDocumentConverter` + template `PE-TrinhDuyet.docx` (user pending — không quan trọng lắm)
### C. Optional polish (làm khi UAT phát sinh)
- [ ] Budget MaNganSach atomic sequence + migration `AddBudgetCodeSequences`
- [ ] Budget versioned workflow + migration `AddBudgetVersionedWorkflow`
- [ ] Payment terms PE tách field (JSON → 6 column)
- [ ] Auto-map PE Details → Contract Details khi gen HĐ
- [ ] Matrix Quotes bulk paste từ Excel
- [ ] fe-user Inbox thêm section "Phiếu Duyệt NCC chờ tôi"
### D. Tests Phase 3-5 (làm khi gặp bug recurring để justify ROI)
- [ ] **Phase 3** — Application handler tests (CQRS + EF InMemory) ~15 test
- [ ] **Phase 4** — API smoke tests (WebApplicationFactory) ~7 test
- [ ] **Phase 5** — FE Vitest cho lib utility (queryMatches, fmtMoney) ~10 test
### E. Ops chưa xong
- [ ] Remove binding cũ `.huypham.vn` sau verify stable
- [ ] win-acme scheduled task fix unhealthy (cert expire 2026-06-18)
## 🔁 Skill governance (recurring)
Quy tắc: `docs/rules.md §9`. Audit định kỳ mỗi đầu tháng — workflow §9.4.
- [x] **Setup ban đầu** — 6 skill (3 domain + 3 ops), rules §9 ← `661f859`
- [ ] **Audit 2026-05-01** — log `docs/changelog/skill-audit-2026-05.md`
- [ ] **Audit 2026-06-01**
- [ ] **Audit 2026-07-01**
Cron task `solution-erp-skill-audit-monthly` fire 9:00 AM ngày 1 mỗi tháng.
## 📦 Post-launch (Phase 10+ — future)
- [ ] **Email outbox** (MailKit + SMTP) — blocked chờ SMTP config
- [ ] 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