# Session 2026-04-21 15:00 — Prod go-live + ERP shell + Notifications module

**Focus:** Đưa SOLUTION_ERP lên production thật (3 domain HTTPS), cải thiện UX
foundation để sau này scale thành ERP đầy đủ (HR, Accounting, Inventory...),
và build Notifications module E2E.

## Outcomes

### 1. Production go-live E2E (3 domain HTTPS)

- VPS: Windows Server chia sẻ với VIETREPORT (`103.124.94.38`), IIS + SQLEXPRESS
- Sites tạo: `SolutionErp-Api`, `SolutionErp-Admin`, `SolutionErp-User`
- Win-acme issue 3 Let's Encrypt cert + auto-renew 9h daily scheduled task
- Gitea runner `vps-vietreport-runner` (shared) pickup SOLUTION_ERP tasks
- CI/CD workflow rewrite: single `windows-latest` self-hosted job, deploy local
  (không WinRM vì runner trên cùng VPS với IIS)
- JWT_SECRET generate + push qua Gitea API (64-char hex)
- DbInitializer auto-migrate khi API start → migration `AddNotifications` chạy
  tự động lần deploy sau

### 2. ERP shell (scale foundation)

- `TopBar` component — title placeholder + NotificationBell + UserMenu (avatar
  initials + role badges + logout). Thay cho bottom-of-sidebar layout cũ.
- `NotificationBell` — unread badge, 30s refetch, click mark-read, 'Đọc hết'
  bulk action. Foundation sẵn cho SignalR/email sau này.
- Layout giờ `[sidebar] [topbar + content]` grid — sau này thêm module HR, KT…
  chỉ cần thêm vào menu tree, không đụng layout.

### 3. Tier 1 UI polish

- `SlaTimer` (inline + full variant, 5 chỗ: 3 list + 2 detail)
  - Inline: countdown text có màu (emerald/amber/red) + pulsing dot khi quá hạn
  - Full: progress bar + deadline timestamp
- Inbox stat cards (total / sắp hạn / quá hạn / tổng giá trị) — derived client-side
- `DataTable` skeleton rows khi loading (thay "Đang tải…" text)
- `EmptyState` component (icon + title + description + CTA) + MyContracts empty với "Tạo HĐ mới" button

### 4. PermissionsPage improvement

- Search menu theo tên/key
- Stats badge: granted / total quyền theo role
- Bulk column toggle (tick/bỏ toàn cột CRUD)
- EmptyState khi chưa chọn role

### 5. Notifications module E2E

**Domain:**
- `Notification` entity (UserId, Type, Title, Description, Href, RefId, ReadAt)
- `NotificationType` enum (stable ints): ContractPhaseTransition, ContractCommentAdded,
  SlaWarning, SlaOverdue, ContractPublished, ContractRejected, Generic

**Infrastructure:**
- `NotificationConfiguration` (bảng Notifications, index `(UserId, ReadAt)`)
- `NotificationService` — ghi DbContext, KHÔNG SaveChanges (caller quyết định
  unit-of-work — đảm bảo atomic với domain mutation)
- Migration `AddNotifications`

**Application:**
- `INotificationService` (Notify / NotifyMany)
- CQRS: `ListMyNotificationsQuery`, `GetMyUnreadCountQuery`, `MarkNotificationReadCommand`,
  `MarkAllNotificationsReadCommand`

**Api:**
- `NotificationsController` — GET /api/notifications + unread-count + POST {id}/read + read-all

**Integration:**
- `ContractWorkflowService.TransitionAsync` emit notification cho Drafter (skip
  nếu actor chính là Drafter). Title + type map theo phase đích:
  - `DaPhatHanh` → `ContractPublished`
  - `TuChoi` → `ContractRejected`
  - Khác → `ContractPhaseTransition`

**FE:**
- Both NotificationBell (admin + user) dùng `/api/notifications` thật
  (thay derived-from-inbox mock)

### 6. Login bug fix — "Network Error"

- Root cause: SPA web.config thiếu HTTP→HTTPS redirect rule. User gõ bare
  `admin.huypham.vn` → load HTTP → `Origin: http://...` → CORS chỉ allow HTTPS → browser block.
- Fix: thêm rule `HTTP to HTTPS` (301) vào SPA web.config trước SPA Routes rule.
  Vừa deploy SCP lên VPS trực tiếp, vừa update `setup-iis-sites.ps1` cho deploy sau.

## Commits (chronological)

```
169e268  Scripts: rewrite 4 deploy PS1 ASCII-only (PS 5.1 compat)
4545276  Scripts: fix setup-ssl.ps1 --installationsiteid flag
ccfcfb4  CICD: rewrite workflow for local deploy on self-hosted runner
5df883d  CICD: re-trigger after runner PATH fix
57a0275  CICD: use powershell (5.1) instead of pwsh (7)
10ae519  CICD: re-trigger after task 32 stuck (runner restart race)
519ba85  CICD: npm install (not ci) — Vite 8 rolldown native binding
5709092  CICD: fresh node_modules per build
b40da1e  CICD: read appsettings template from source workspace
290936a  CICD + FE: deploy pool-state guard + SlaTimer component
0e5b5cd  FE-User: stat cards trên Inbox
c1c2361  FE: DataTable skeleton rows khi loading
2e43799  FE: EmptyState component + MyContracts CTA empty state
2b6f91c  FE: TopBar + NotificationBell + UserMenu — ERP shell foundation
6c0e206  FE-Admin: PermissionsPage improved
49c0ddc  App+Domain+Infra+Api+FE: Notifications module end-to-end
397eb36  Scripts: SPA web.config thêm HTTP→HTTPS redirect
```

## Next session priority

1. **UAT 1 tuần với 2-3 user thật** — hard requirement từ roadmap
2. Chọn Tier 3 tiếp: Form template builder (admin tự upload template + field spec JSON)
   vs PDF export (LibreOffice/QuestPDF) vs SignalR real-time push
3. SQL backup Task Scheduler schedule hàng ngày
4. Rotate credentials đã post chat (SA, vrapp, JWT)
