Files
solution-erp/docs/STATUS.md
pqhuy1987 d43d2c0024
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 2m46s
[CLAUDE] Docs: chốt session 2026-04-23 — skill governance + cron audit
- Session log 2026-04-23-0900-skill-governance.md (A→E):
  khảo sát alirezarezvani/claude-skills + quyết định không bulk-clone,
  3 skill ops mới (dependency-audit-erp, ef-core-migration,
  iis-deploy-runbook), rules §9 + audit cadence cron 1/tháng,
  touch-points 6 file index
- STATUS: Recently Done 2 row mới (b904a25 governance + 661f859
  3 skill), header phase = "Tier 3 + skill governance",
  session log count → 12 file, link skills README.md
- HANDOFF: Last updated → 2026-04-23 09:30, TL;DR mention skill
  governance setup, table phase tier thêm row Skill governance ,
  Skills callout "PHẢI dùng khi task khớp" + audit cron next 2026-05-01,
  git state cập nhật 3 commit gần nhất

Cron task verified live qua list_scheduled_tasks: nextRunAt =
2026-05-01T02:05:48.000Z (jitter 348s).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 00:30:37 +07:00

135 lines
14 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.

# STATUS — Snapshot hiện tại
> **Update rule:** trước khi bắt đầu 1 task → ghi row vào `🔥 In Progress`. Xong → chuyển sang `✅ Recently Done`.
**Last updated:** 2026-04-23 09:30 (post-skill-governance + cron audit định kỳ)
## 📍 Phase hiện tại: **Tier 3 feature-complete + skill governance** — Prod live, 6 skill project-level + audit cron 1/tháng. Còn: UAT thật + Email outbox (chờ SMTP) + rotate creds.
### 🌐 Production URLs
- https://api.huypham.vn — API (Let's Encrypt, auto-renew via win-acme)
- https://admin.huypham.vn — Admin FE (HTTP→HTTPS auto-redirect)
- https://user.huypham.vn — User FE (HTTP→HTTPS auto-redirect)
- https://git.baocaogiaoduc.vn/vietreport-admin/solution-erp — Gitea repo + Actions
- Default admin: `admin@solutionerp.local` / `Admin@123456` ⚠️ **RE-ROTATE sau login đầu**
## 🔥 In Progress
_(không có — Tier 3 + skill governance đóng gói xong, chờ UAT + chờ cron audit fire 2026-05-01)_
## ✅ Recently Done (newest on top)
| Ngày | Ai | Task | Commit |
|---|---|---|---|
| 2026-04-23 | Claude | **Skill governance + audit định kỳ**`docs/rules.md §9` mới (6 skill bảng, nguyên tắc tạo project-specific, format SKILL.md bắt buộc, workflow audit 7 bước, 4 anti-patterns). Cron task `solution-erp-skill-audit-monthly` fire 9:00 AM ngày 1 mỗi tháng (next 2026-05-01) — self-contained prompt cold-start, auto-refresh stale nhỏ + đề xuất add/archive cho human approve, log vào `docs/changelog/skill-audit-{YYYY-MM}.md`, ABORT nếu repo dirty. Touch-points: CLAUDE.md callout + HANDOFF A1 + migration-todos checkbox + skill scope commit | `b904a25` |
| 2026-04-23 | Claude | **3 skill ops project-specific** — Khảo sát alirezarezvani/claude-skills, quyết định KHÔNG bulk-clone (skill global đã cover phần generic, repo còn lại doc-dump không có when-to-use). Viết 3 skill mới encode SOLUTION_ERP-only: `dependency-audit-erp` (npm/dotnet CVE scan respect MediatR 12.4.1 + Swashbuckle 6.9.0 pin), `ef-core-migration` (8 migration history + 3-file rule + DesignTimeDbContextFactory + 6 pitfalls cụ thể), `iis-deploy-runbook` (3 IIS site + win-acme + NSSM gitea-runner + LibreOffice + debug playbook 500/502/SignalR). Total skill project-level = 6 (3 domain + 3 ops) | `661f859` |
| 2026-04-22 | Claude | **PermissionsPage 3-panel layout** — Grid `lg:grid-cols-[280px_1fr_300px]`: Panel 1 Role list click-to-select (active ring-brand), Panel 2 Menu×CRUD matrix sticky thead + search + column bulk-toggle + brand-tinted hover, Panel 3 Granted progress bar + CRUD breakdown color badges (slate/emerald/amber/red) + Tip | `91b2da1` |
| 2026-04-22 | Claude | **Admin Workflows tabs → sidebar menu items** — Seed 7 `Wf_<Code>` leaf dưới group `Workflows`. Layout resolvePath `Wf_<Code>``/system/workflows/<code>`. WorkflowsPage bỏ tab bar, URL param drives type selection. Landing 7-card grid khi click top-level `Quy trình HĐ`. Inheritance: `Workflows.Read` perm → tất cả 7 leaves auto-visible. | `f216169` |
| 2026-04-22 | Claude | **Versioned workflow per ContractType** — 3 entity mới: WorkflowDefinition (Code+Version+IsActive+ContractType), WorkflowStep (Order+Phase+Name+SlaDays), WorkflowStepApprover (Role/User + AssignmentValue). Contract.WorkflowDefinitionId nullable FK pin tại create. Migration `AddVersionedWorkflows`. Seed v01 per 7 ContractType. `WorkflowPolicyRegistry.FromDefinition()` build runtime policy từ DB. ContractWorkflowService load pinned definition. Admin `/system/workflows/:typeCode` Designer modal (create new version, clone, add/remove step, +Role/+User approvers). POST /api/workflows auto-increment Version + deactivate old. Invariant: HĐ cũ pin v01 giữ nguyên khi v02 active. E2E verified: QT-MB-v02 active, HĐ cũ vẫn chạy v01. | `e7e5f2d` + `355bbe3` |
| 2026-04-21 | Claude | **Nested sidebar menu fe-user** — 7 ContractType × 3 actions (Danh sách/Thao tác/Duyệt), nested 3-level. Admin hide `Ct_*`. Layout recursive MenuNodeRenderer. MyContracts + Inbox filter `?type=X` | `5e0f380` + `48e91fe` |
| 2026-04-21 | Claude | **Seed master data + MyDashboard widgets** — DbInitializer seed 9 departments (PM/QS/CCM/PRO/FIN/ACT/EQU/HRA/BOD) + 5 demo suppliers + 3 demo projects idempotent. MyDashboard endpoint role-aware: DraftsInProgress / PendingMyApproval / DueSoon / Overdue / DraftsTotalValue. FE "Của tôi" row 4 card hover-interactive, admin auto-hide nếu = 0 | `6197c84` |
| 2026-04-21 | Claude | **Dynamic workflow policy per ContractType** — Domain WorkflowPolicy record + registry (Standard 8-phase cho Thầu phụ/Giao khoán/NCC; SkipCcm 7-phase cho Dịch vụ/Mua bán/Nguyên tắc). ContractWorkflowService dùng policy.ForContract(c). FE xóa NEXT_PHASES hardcoded, dùng contract.workflow.nextPhases BE trả. WorkflowSummaryCard timeline visual. Gotcha #21 resolved | `cae4d84` |
| 2026-04-21 | Claude | **PDF export + .doc/.xls auto-convert + DynamicForm** — LibreOffice 25.8.6 VPS, IDocumentConverter shell soffice `--convert-to pdf/docx/xlsx` timeout+temp isolation. Admin upload .doc auto-convert .docx. DynamicForm parse FieldSpec JSON render inputs (text/textarea/number/date/currency/select). Form↔JSON toggle. E2E verified PDF 488KB/126 pages | `e459097` + `6bbd894` |
| 2026-04-21 | Claude | **Form template builder CRUD** — Admin tự upload `.docx/.xlsx` qua UI (không cần dev). BE multipart + FormCode regex unique + FieldSpec JSON validation + soft delete via IsActive. FE FormsPage upload dialog + row actions render/edit/delete. E2E verified | `166d26c` |
| 2026-04-21 | Claude | **Fix Gitea 500 sau Install Web-WebSockets** — appcmd unlock section webSocket. Gotcha #25 | `c52186b` |
| 2026-04-21 | Claude | **SignalR realtime notifications E2E** — 3-project clean-arch: IRealtimeNotifier (App) + SignalRNotifier (Api) + NotificationPushInterceptor (Infra SaveChanges hook). Hub `/hubs/notifications` JWT `?access_token=` query (WebSocket headers limit). FE singleton lib/realtime.ts auto-reconnect + toast + query invalidation. IIS WebSocket module enabled | `ea9ab5e` |
| 2026-04-21 | Claude | **Attachment upload E2E** — IFileStorage + LocalFileStorage (path-traversal guard) + CQRS Upload/Download/Delete + 3 endpoint (multipart, stream, DELETE) + FE ContractAttachmentsSection drag-drop + purpose selector + icon-per-MIME + auth-blob download + confirm delete. Wired 2 ContractDetailPage | `c8d0070` + `dc3f09b` |
| 2026-04-21 | Claude | **Content polish** — typography 14px + leading 1.55 + tracking-tight + PageHeader border-b + Button shadow+active + Input inset shadow + DataTable rounded-xl UPPERCASE header brand hover | `346bd5d` |
| 2026-04-21 | Claude | **Brand identity từ Solutions logo** — pixel-sampled #1F7DC1 → palette brand-50..900 + accent red + Be Vietnam Pro (Vietnamese-first) + favicon 'S' crop + apple-touch-icon + login gradient brand | `4abb559` + `bf1fbe3` |
| 2026-04-21 | Claude | **Fix login Network Error** — SPA web.config HTTP→HTTPS redirect rule (CORS chỉ https) | `397eb36` |
| 2026-04-21 | Claude | **Notifications module E2E** — Domain entity + EF migration + Infra service + CQRS + API controller + FE bells wire real endpoint + ContractWorkflowService emit notification cho Drafter khi phase transition | `49c0ddc` |
| 2026-04-21 | Claude | **PermissionsPage iter 1** — search, stats badge, bulk column toggle, empty state | `6c0e206` |
| 2026-04-21 | Claude | **ERP shell** — TopBar + NotificationBell + UserMenu (avatar + role badges). Layout `[sidebar] [topbar + content]` | `2b6f91c` |
| 2026-04-21 | Claude | **Tier 1 UI polish** — SlaTimer (inline + full variant, 5 chỗ), Inbox stat cards, DataTable skeleton rows, EmptyState | `290936a`..`2e43799` |
| 2026-04-21 | Claude | **CI/CD deploy xanh E2E** — self-hosted Windows runner, single job build+deploy, fresh node_modules (Vite 8 rolldown binding), appsettings từ secrets, /health/live 200 sau deploy | `b40da1e` |
| 2026-04-21 | Claude | **VPS prod setup** — SQL DB (SQLEXPRESS), IIS sites (SolutionErp-Api/Admin/User), win-acme 3 Let's Encrypt + auto-renew, shared gitea-runner với VIETREPORT | `169e268`..`519ba85` |
| 2026-04-21 | Claude | **IDOR + SLA Job + Admin warning** — ContractsController filter theo role. SlaExpiryJob BackgroundService 15min auto-approve Decision=AutoApprove. DbInitializer warn khi admin vẫn default | `fba0754` |
| 2026-04-21 | Claude | **Phase 5.1 Security + Users Mgmt** — Security headers + Identity lockout + LoginHandler check + Users CQRS + UsersController + FE `/system/users` | `11e61c9` |
| 2026-04-21 | Claude | **Phase 5 Prep** — BE rate limit + health check + Serilog file + HSTS + scripts deploy-iis/backup-sql + .gitea/workflows/deploy.yml + 4 guides + FE refresh token queue pattern | `46a2cab` |
| 2026-04-21 | Claude | **Phase 4 Report MVP** — Dashboard KPI + Excel export + rules.md + architecture.md + schema-diagram.md + gotchas 26 pitfalls | `fe7ad8e` |
| 2026-04-21 | Claude | **Phase 3 Workflow MVP** — 9 phase state machine + gen mã HĐ RG-001 | `7e957a7` |
| 2026-04-21 | Claude | **Phase 2 Form Engine MVP** | `5113e4c` |
| 2026-04-21 | Claude | **Phase 1.2** — CRUD Master + Permission Matrix | `54d6c9b` |
| 2026-04-21 | Claude | **Phase 1 foundation** + Docs addition | `702411f` + `49a5f57` |
| 2026-04-21 | Claude | **Phase 0** | `25dad7f` |
Session logs: [P0](changelog/sessions/2026-04-21-1045-phase0-scaffold.md) · [P1f](changelog/sessions/2026-04-21-1100-phase1-foundation.md) · [P1.2](changelog/sessions/2026-04-21-1130-phase1-cruds-permission.md) · [P2](changelog/sessions/2026-04-21-1200-phase2-form-engine.md) · [P3](changelog/sessions/2026-04-21-1330-phase3-workflow.md) · [P4](changelog/sessions/2026-04-21-1430-phase4-report.md) · [P5prep](changelog/sessions/2026-04-21-1530-phase5-prep.md) · [Tier 3](changelog/sessions/2026-04-22-0300-tier3-feature-complete.md) · [**Skill gov**](changelog/sessions/2026-04-23-0900-skill-governance.md)
**Docs entry points:**
- [`rules.md`](rules.md) · [`architecture.md`](architecture.md) · [`HANDOFF.md`](HANDOFF.md)
- [`workflow-contract.md`](workflow-contract.md) · [`forms-spec.md`](forms-spec.md)
- [`database/database-guide.md`](database/database-guide.md) · [`database/schema-diagram.md`](database/schema-diagram.md)
- [`flows/`](flows/) (7 file) · [`guides/`](guides/) (4 file) · [`gotchas.md`](gotchas.md)
- [`changelog/migration-todos.md`](changelog/migration-todos.md) · [`changelog/sessions/`](changelog/sessions/) (12 file)
- [`.claude/skills/README.md`](../.claude/skills/README.md) — 6 skill (3 domain + 3 ops) · audit định kỳ 1/tháng (cron `solution-erp-skill-audit-monthly`)
## 🎯 Next up
### Hard blockers (chờ user / ops)
- [ ] **UAT 1 tuần 2-3 user thật** — hard requirement từ roadmap Phase 5
- [ ] **Email outbox** — MailKit + SMTP (BLOCKED chờ user cấp SMTP host/user/pass)
- [ ] **Rotate credentials** — SA, vrapp, JWT secret, runner token (đã post chat)
- [ ] **SQL backup daily** — Task Scheduler (script `scripts/backup-sql.ps1` đã có, chưa schedule)
### Optional polish (khi rảnh / UAT phát sinh)
- [ ] Roles CRUD — admin tạo custom role ngoài 12 hardcoded (schema sẵn, chỉ cần CQRS + FE)
- [ ] User-level approver targeting runtime — data model đã có (`WorkflowStepApprover.Kind=User`), chỉ cần wire User-kind vào `ContractWorkflowService.TransitionAsync` guard
- [ ] PermissionsPage: grant `Workflows.Read` cho non-admin role → menu Wf_* visible
- [ ] Warning notification khi còn 20% SLA (`SlaWarningSent` flag đã có, chỉ thiếu job emit)
- [ ] E2E test reject → quay về DangSoanThao (multi-role)
- [ ] Dependencies scan CI (`dotnet list package --vulnerable`, `npm audit`)
### Tier 3 ERP roadmap ✓ (close)
- [x] Attachment upload BE + FE ✓
- [x] SignalR real-time push ✓
- [x] Form template builder CRUD + DynamicForm ✓
- [x] PDF export qua LibreOffice headless ✓
- [x] .doc/.xls → .docx/.xlsx auto-conversion ✓
- [x] Dynamic workflow policy per ContractType ✓
- [x] **Versioned workflow (WorkflowDefinition pinned per Contract)**
- [x] **Admin workflow designer UI (per-type, per-step approvers)**
- [x] **Nested sidebar menu per ContractType (fe-user) + menu split admin/user**
- [x] **PermissionsPage 3-panel layout**
- [ ] Email outbox for Notification (blocked — SMTP config)
## 📊 Thông số cumulative
| | P0 | P1f | P1.2 | P2 | P3 | P4 | P5prep | **Tier3** |
|---|---:|---:|---:|---:|---:|---:|---:|---:|
| BE LOC | 0 | ~400 | ~1500 | ~1900 | ~2700 | ~3100 | ~3300 | **~4800** |
| DB tables | 0 | 7 | 12 | 14 | 19 | 19 | 19 | **24** (+Notifications, +WorkflowTypeAssignments, +WorkflowDefinitions, +WorkflowSteps, +WorkflowStepApprovers) |
| API endpoints | 0 | 4 | 20 | 23 | 31 | 33 | 35 | **~50** (+notifications, +attachments, +forms CRUD, +pdf export, +workflows admin, +my-dashboard) |
| Migrations | 0 | 1 | 3 | 4 | 5 | 5 | 5 | **8** (+AddNotifications, +AddWorkflowTypeAssignments, +AddVersionedWorkflows) |
| FE pages | 0 | 2 | 6 | 7 | 14 | 16 | 16 | **~20** (admin Users/Workflows per-type + user nested menu) |
| Scripts PS | 0 | 0 | 0 | 1 | 1 | 1 | 3 | **4** (+install-libreoffice) |
| CI/CD workflow | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| Docs | 10 | 13 | 14 | 24 | 26 | 30 | 35 | **~40** (+session log + updated MDs) |
| Commits | 1 | 2 | 3 | 5 | 6 | 7 | 8 | **~25** |
## 🚨 Blockers / risks
- ⚠️ **Email SMTP chưa có** — blocker cho notification outbound
- ⚠️ **UAT real user chưa chạy** — risk phát sinh bug edge-case quan trọng
- ⚠️ **Credentials leaked trong chat** — cần rotate trước go-live thật
- ⚠️ **SQL backup không auto** — risk data loss nếu VPS crash
- ⚠️ **Permission `Workflows.Read` cho non-admin** — cần grant để họ thấy menu Wf_* (hiện chỉ admin thấy)
- ⚠️ **User-kind approver chưa enable runtime** — designer cho chọn User nhưng guard fall back DeptManager
## Credentials + URLs
```
admin@solutionerp.local / Admin@123456
```
- API prod: https://api.huypham.vn — Health `/health/live` + `/health/ready`
- API dev: http://localhost:5443 — Swagger `/swagger`
- Admin FE prod: https://admin.huypham.vn · dev `http://localhost:8082`
- User FE prod: https://user.huypham.vn · dev `http://localhost:8080`
- SQL prod: `.\SQLEXPRESS` / `SolutionErp` / `vrapp`
- SQL dev: `(localdb)\MSSQLLocalDB` / `SolutionErp_Dev`