# 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-21 15:30 (post-prod-deploy) ## 📍 Phase hiện tại: **Đã go-live prod** — 3 domain HTTPS live, CI/CD xanh, Notifications module + ERP shell ### 🌐 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ó — chờ UAT + quyết Tier 3 tiếp theo)_ ## ✅ Recently Done (newest on top) | Ngày | Ai | Task | Commit | |---|---|---|---| | 2026-04-21 | Claude | **SignalR realtime notifications E2E** — Clean-arch split (IRealtimeNotifier Application + SignalRNotifier Api + NotificationPushInterceptor Infrastructure). Hub `/hubs/notifications` JWT via `?access_token=` query (WebSocket headers limit). Interceptor SavedChangesAsync auto-push → zero caller changes. FE singleton connection với auto-reconnect + toast trên push + query invalidation. IIS WebSocket module enabled. Hub verified: negotiate 200 với JWT (WebSockets/SSE/LongPolling transports), 401 không auth | `ea9ab5e` | | 2026-04-21 | Claude | **Attachment upload E2E** — IFileStorage abstraction + LocalFileStorage (path-traversal guard) + CQRS Upload/Download/Delete + 3 controller endpoints (multipart, File stream, DELETE) + FE ContractAttachmentsSection (drag-drop + purpose selector + icon-per-MIME + auth-blob download + confirm delete) + wired vào cả 2 ContractDetailPage. Unblock E2E workflow (scan HĐ ký/đóng dấu) | `c8d0070` + `dc3f09b` | | 2026-04-21 | Claude | **Content polish** — typography (14px + leading 1.55 + tracking-tight, heading weights) + PageHeader (text-[22px] + border-b) + Button (shadow + active-press + ring-2) + Input/Select/Textarea (inset shadow + border/ring focus) + DataTable (rounded-xl + UPPERCASE tracking header + brand hover) | `346bd5d` | | 2026-04-21 | Claude | **Brand identity từ Solutions logo** — pixel-sampled #1F7DC1 → full palette brand-50..900 + accent red + Be Vietnam Pro font (Vietnamese-first) + favicon chữ 'S' crop từ logo.png + apple-touch-icon + login page gradient brand + ERP subtitle | `4abb559` + `bf1fbe3` | | 2026-04-21 | Claude | **Fix login Network Error** — SPA web.config thêm HTTP→HTTPS redirect rule (CORS chỉ allow https origin, user gõ bare domain bị block) | `397eb36` | | 2026-04-21 | Claude | **Notifications module E2E** — Domain entity + EF migration + Infra service + CQRS (List/UnreadCount/MarkRead/MarkAllRead) + API controller + FE bells wire real endpoint + ContractWorkflowService emit notification cho Drafter khi phase transition. Foundation sẵn cho SignalR/email outbox | `49c0ddc` | | 2026-04-21 | Claude | **PermissionsPage improved** — search, stats badge, bulk column toggle, empty state icon | `6c0e206` | | 2026-04-21 | Claude | **ERP shell**: TopBar + NotificationBell + UserMenu (avatar + role badges). Layout tách `[sidebar] [topbar + content]` — foundation cho multi-module ERP | `2b6f91c` | | 2026-04-21 | Claude | **Tier 1 UI polish** — SlaTimer (inline + full variant, 5 chỗ), Inbox stat cards, DataTable skeleton rows, EmptyState component + MyContracts CTA | `290936a`..`2e43799` | | 2026-04-21 | Claude | **CI/CD deploy xanh E2E** — self-hosted Windows runner, single job build+deploy local, npm install fresh node_modules (Vite 8 rolldown binding), appsettings rendered 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 certs + auto-renew, shared gitea-runner với VIETREPORT | `169e268`..`519ba85` | | 2026-04-21 | Claude | **IDOR + SLA Job + Admin warning** — ContractsController List/GetDetail filter theo role (non-admin chỉ thấy HĐ mình là Drafter hoặc role eligible phase). SlaExpiryJob BackgroundService auto-approve quá hạn mỗi 15min với Decision=AutoApprove. DbInitializer warn log khi admin vẫn dùng password 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 + Docs Consolidation** — Dashboard KPI + Excel export + rules.md + architecture.md + schema-diagram.md + gotchas update 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 | **Docs addition** | `49a5f57` | | 2026-04-21 | Claude | **Phase 1 foundation** | `702411f` | | 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) **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/) (7 file) ## 🎯 Next up ### Phase 5 (prod go-live) - [x] Gitea remote + push all commits - [x] Gitea Actions runner (self-hosted Windows, shared VIETREPORT runner) - [x] Secrets Gitea (JWT_SECRET, DB_CONNECTION — IIS_* deprecated sau rewrite workflow) - [x] CI/CD workflow xanh end-to-end - [x] Windows Server setup IIS (SolutionErp-Api/Admin/User) - [x] HTTPS cert (win-acme 3 Let's Encrypt + auto-renew) - [x] SQL Server prod (SQLEXPRESS) + vrapp db_owner - [x] Smoke test E2E: /health/ready Healthy, login JWT thật, FE live - [ ] **UAT 1 tuần 2-3 user thật** ← next - [ ] SQL backup Task Scheduler (script đã có, chưa schedule) - [ ] Rotate credentials (SA, vrapp, JWT, runner token) — 1 số đã post chat ### Tier 3 ERP roadmap còn (lớn, để dành session sau) - [x] Attachment upload BE endpoint + FE drag-drop ✓ - [x] SignalR real-time push (auto-push interceptor + client auto-reconnect) ✓ - [ ] Form template builder UI (field spec JSON editor, upload .docx/.xlsx admin) - [ ] PDF export (LibreOffice headless pipeline hoặc QuestPDF re-render) - [ ] Email outbox cho Notification (MailKit, SMTP config) - [ ] .doc → .docx conversion UI/pipeline (3 file pending) ### Phase 5.1 Security — hầu như xong - [x] Security headers middleware (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, CSP) - [x] Identity account lockout (5 fail → 15min, config-driven) - [x] Password policy config-driven - [x] LoginHandler check lockout + AccessFailedAsync + reset on success - [x] BE Users management + FE admin UsersPage - [x] IDOR check ContractsController (non-admin chỉ thấy HĐ mình/role eligible) - [x] Admin password warning log startup - [x] SLA Expiry BackgroundService auto-approve - [ ] Dependencies scan CI (`dotnet list package --vulnerable` + `npm audit`) - [ ] Roles CRUD — optional ### Polish iterations **Phase 2 iter 2:** convert .doc, field spec JSON + form builder, {{#loop}}, PDF convert **Phase 3 iter 2:** SLA job auto-approve, email/in-app notify, attachment upload, RowVersion **Phase 4 iter 2:** SLA overdue report, PDF HĐ export, dashboard user-specific ### Quick wins - FE Users management + Roles CRUD (test permission non-admin) - Filter Inbox theo phase FE - Test refresh token flow manual (logout/login flow) ## 📊 Thông số cumulative | | P0 | P1f | P1.2 | P2 | P3 | P4 | **P5 prep** | |---|---:|---:|---:|---:|---:|---:|---:| | BE LOC | 0 | ~400 | ~1500 | ~1900 | ~2700 | ~3100 | **~3300** | | DB tables | 0 | 7 | 12 | 14 | 19 | 19 | 19 | | API endpoints | 0 | 4 | 20 | 23 | 31 | 33 | **35** (+health) | | Migrations | 0 | 1 | 3 | 4 | 5 | 5 | 5 | | FE pages | 0 | 2 | 6 | 7 | 14 | 16 | 16 | | Scripts PS | 0 | 0 | 0 | 1 (convert-doc) | 1 | 1 | **3** (+deploy-iis, backup-sql) | | CI/CD workflow | 0 | 0 | 0 | 0 | 0 | 0 | **1** | | Docs | 10 | 13 | 14 | 24 | 26 | 30 | **35** (+4 guides + session log) | | Commits | 1 | 2 | 3 | 5 | 6 | 7 | **8** (sắp) | ## 🚨 Blockers / risks - ⏳ **Gitea remote URL** — ĐANG CẦN để push + setup CI/CD - ⚠️ **Phase 5.1 security hardening** chưa làm (headers, account lockout, IDOR check) - ⚠️ **3 file .doc chưa convert** (Phase 2 carryover) - ⚠️ **SLA không tự auto-approve** (Phase 3.2) - ⚠️ **Email/in-app notification** chưa có - ⚠️ **FE Users management chưa có** — khó test permission non-admin - ⚠️ **Rate limit global 300/min/IP** — OK cho dev, cần tăng cho prod nếu nhiều user ## Credentials + URLs ``` admin@solutionerp.local / Admin@123456 ``` - API: http://localhost:5443 — Swagger `/swagger` (dev only) — Health `/health/live` + `/health/ready` - Admin FE: http://localhost:8082 — `/dashboard`, `/contracts`, `/reports`, `/master/*`, `/forms`, `/system/permissions` - User FE: http://localhost:8080 — `/inbox`, `/contracts/new`, `/my-contracts`