Portal Spec (Living)
Operating Links (Implementation-Ready)
- Project OS: 05_PROJECT_OPERATING_SYSTEM.md
- Engineering Rules: 06_ENGINEERING_RULES.md
- Execution Playbook: 07_EXECUTION_PLAYBOOK.md
- Task Packet Template: TASK_PACKET_TEMPLATE.md
References
- Quyết định kiến trúc & System Model: 01_DECISION_LOG.md, 03_SYSTEM_MODEL.md
- Danh sách routes Portal hiện có: ui_route_catalog.md
- Dòng chảy dữ liệu (UI → API): API_TRACEABILITY.md
Delivery Rule for Any Portal Change
- Chọn
Feature Keytrong matrix. - Tạo task packet và khai báo route/API impacted.
- Implement theo permission-aware UI.
- Cập nhật
specs/portal.md,FEATURE_STATUS_MATRIX.md. - Regenerate
_generated/ui_route_catalog.md.
1. UX / UI Principles
- Cấu trúc layout React/Vite (đang ở
apps/v2-portal): Layout chung với Menu trái (theo module) + Topbar (account, active workspace, notification). - Dashboard overview load dữ liệu tuỳ chỉnh (Role-based widgets).
- Forms: Thống nhất dùng Ant Design
Form, Validation tích hợp chung với DTO constraints của Backend.
2. Authentication & Workspace Selection
- Role Model: (Xem JWT Context trong DEC-001).
- Auth Flow: Khi session timeout, UI force redirect
/login. - Zalo Login: Dùng
ZaloPortalLoginDto(no tenant required). Xem DEC-002. - Workspace Navigation & Route Access Matrix (Trạng thái UI):
- State A (Unauthenticated): User không có JWT → Chỉ được phép truy cập
/login. Các route khác redirect về login. - State B (Authenticated +
tenantIdnull): Mới login xong, chưa đứng trên context tenant nào → UI bắt buộc khóa và ép user vào/workspace(hoặc/admin/*nếu user làSYSTEM_ADMIN). Cố tình vào linkcataloglập tức redirect về workspace. - State C (Authenticated +
tenantIdset): Được truy cập full module routes. Dữ liệu module fetch với token đã ngậm tenant. - Luồng Switch: Sau khi user chọn/switch tại
/workspace, Backend trả token mới chứatenantId, Axios interceptor cập nhật tự động Header, và giao diện auto-refresh data theo Tenant mới.
- State A (Unauthenticated): User không có JWT → Chỉ được phép truy cập
3. RBAC (Phân quyền trên UI)
- Tham chiếu:
../_generated/permission_manifest.md - Frontend maintain Hook
usePermissions():- Nếu thiếu quyền View (e.g.
CAT_VIEW), Menu Item bị ẩn, Route redirect 403. - Nếu có View nhưng thiếu Manage (
CAT_MANAGE), UI disable các button Tạo/Sửa/Xoá (trạng thái Read-only).
- Nếu thiếu quyền View (e.g.
4. Portal Page Registry
Quy tắc: Thống kê toàn bộ các trang (pages) của Portal. Mỗi trang phải chỉ đích danh Module (CKB) mà nó phụ thuộc, các quyền Permissions cần thiết, và Endpoint gọi tới.
PAGE: Workspace Selection
Module Ref: TENANTCode Truth: v2-portal/src/pages/Workspace.tsxPermissions Req: TENANT_VIEW (or Authenticated) Associated API: GET /v2/iam/tenants, POST /v2/iam/auth/switch-tenantDelta / Gaps: None (Synced)
PAGE: Product Management
Module Ref: CATALOGCode Truth: v2-portal/src/pages/ProductList.tsxPermissions Req: CAT_VIEW, CAT_MANAGEAssociated API: GET /v2/catalog/productsDelta / Gaps: None (Synced)
PAGE: Order Management
Module Ref: ORDERCode Truth: v2-portal/src/pages/OrderList.tsxPermissions Req: ORDER_VIEW, ORDER_MANAGEAssociated API: GET /v2/ecommerce/ordersDelta / Gaps: None (Synced)
PAGE: Inventory Dashboard
Module Ref: INVENTORYCode Truth: v2-portal/src/pages/InventoryDashboard.tsxPermissions Req: INV_VIEWAssociated API: /v2/supply-chain/inventoryDelta / Gaps: None (Synced)
PAGE: Purchase Orders
Module Ref: PROCUREMENTCode Truth: v2-portal/src/pages/PurchaseOrderList.tsxPermissions Req: PROC_VIEWAssociated API: /v2/supply-chain/procurementDelta / Gaps: None (Synced)
PAGE: Customers & Partners
Module Ref: PARTNER / CRMCode Truth: v2-portal/src/pages/CustomerList.tsxPermissions Req: CRM_VIEWAssociated API: GET /v2/crm/partnersDelta / Gaps: None (Synced)
PAGE: Vouchers
Module Ref: VOUCHERCode Truth: v2-portal/src/pages/VoucherList.tsxPermissions Req: VOUCHER_VIEWAssociated API: GET /v2/marketing/vouchersDelta / Gaps: None (Synced)
PAGE: System Admin Plugins
Module Ref: PLUGIN, ADMINCode Truth: v2-portal/src/pages/PluginStore.tsxPermissions Req: SYSTEM_ADMINAssociated API: GET /v2/admin/plugins/*Delta / Gaps: None (Synced)
(Các màn hình khác sẽ được điền dần vào registry này khi bắt đầu implement hoặc audit mock UI).