All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 2m33s
- Session log 2026-04-22-0300 (A→K): attachment, SignalR, form builder, PDF, dynamic + versioned workflow, nested menu, 3-panel permissions, seed master, brand identity, content polish, Gitea fix - STATUS: Tier 3 feature-complete snapshot + cumulative stats (24 tables, ~50 endpoints, 8 migrations); next-up = UAT + Email SMTP (blocked) + rotate creds + SQL backup schedule - HANDOFF: rewrite brief cho session mới — phase 5 prod done, Tier 3 đóng gói, quick sanity-check 2 app, versioned workflow quick ref, file active hiện trạng, git state - migration-todos: tick Tier 3 items (attachment/realtime/form builder/ PDF/dynamic+versioned workflow/nested menu) + thêm iter-3 versioned workflow section + post-launch list - schema-diagram: +5 table (Notifications, WorkflowTypeAssignments, WorkflowDefinitions, WorkflowSteps, WorkflowStepApprovers); indexes mới, cardinality FK restrict cho pinned policy, truy vấn tiêu biểu - workflow-contract: +section 7bis resolution order, 7ter admin designer flow, updated data model + code pointers Tier 3 - PROJECT-MAP: module map post-Tier-3 (3 box mới Notification/ Attachment/Branding + Infra/DevOps box), API namespace đầy đủ, architectural wins 5 điểm - contract-workflow skill: versioned workflow section, policy resolution code snippet, admin designer flow, code pointers Tier 3, tier 4+ backlog - gotchas +7 bẫy mới (#26-32): SignalR WebSocket headers, interceptor 2-phase pattern, LibreOffice mirror 404, PS 5.1 UTF-16 GITHUB_PATH, PS 5.1 diacritics parse, Dialog size TS, NavLink end query-params Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
132 lines
13 KiB
Markdown
132 lines
13 KiB
Markdown
# 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-22 03:00 (post-Tier-3-feature-complete + versioned workflow)
|
||
|
||
## 📍 Phase hiện tại: **Tier 3 feature-complete** — Prod live, tất cả module lớn xong. 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 đóng gói xong, chờ UAT để quyết Tier 4)_
|
||
|
||
## ✅ Recently Done (newest on top)
|
||
|
||
| Ngày | Ai | Task | Commit |
|
||
|---|---|---|---|
|
||
| 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)
|
||
|
||
**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/) (8 file)
|
||
|
||
## 🎯 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`
|