Vị trí trong hệ thống
Siêu Đại Lý là tầng cao nhất trong chuỗi phân phối. Mọi đại lý đều được tạo ra và quản lý bởi siêu đại lý.
- Tạo / Suspend / Terminate agent
- Move shop giữa các agent
- Move player giữa các shop
- Cấp credits cho agent
- Cấu hình game provider per-agent
- Xem toàn bộ sub-hierarchy
- Chỉ shops của mình
- Players trong shops của mình
- Không thể tạo agent khác
- Không move shop sang SA khác
- Không biết credit balance của SA
Login qua
Endpoint riêng — tách biệt với /agent-auth
So sánh với Agent Portal
Superagent Portal kế thừa toàn bộ tính năng của Agent Portal và bổ sung thêm khả năng quản lý đa cấp.
| Tính năng | Agent Portal | Superagent Portal | Ghi chú |
|---|---|---|---|
| Dashboard & Analytics | ✔ | ✔ | Cùng DashboardPage, nhưng SA thấy summary toàn hierarchy |
| Quản lý Shops | ✔ (shops của mình) | ✔ (tất cả shops) | SA thấy shops của MỌI agent con |
| Quản lý Players | ✔ (players của mình) | ✔ (tất cả players) | SA thấy players trong mọi shop |
| Tạo Agent mới | ✗ | ✔ +SA | createManagedAgent() |
| Suspend / Terminate Agent | ✗ | ✔ +SA | 3 trạng thái: active → suspended → terminated |
| Move Shop sang Agent khác | ✗ | ✔ +SA | moveManagedShop(shopId, targetAgentId) |
| Move Player sang Shop khác | ✗ | ✔ +SA | moveManagedPlayer(playerId, targetShopId) |
| Cấp Credits cho Agent | ✗ | ✔ +SA | SuperAgentAgentCreditTrigger |
| Cấp Credits cho Shop | ✔ | ✔ | SellCreditsCashToAgentTrigger (dùng chung) |
| Cấu hình Game Provider per-Agent | ✗ | ✔ +SA | putManagedAgentGameMappings() |
| Sửa Cost Rate của Agent | ✗ | ✔ +SA | updateManagedAgentRate() |
| Xem Hierarchy Tree | ~ (1 cấp: shops) | ✔ (2 cấp: agents+shops) | SA: HierarchyMiniTree · Agent: AgentHierarchyMiniTree |
| Transactions History | ✔ | ✔ | AgentTransactionsPage dùng chung |
| Credit Purchase | ✔ | ✔ | PurchaseCheckoutPage đã bỏ — mua qua CreditPurchaseModal dùng chung |
| Broadcast / Popup | ✔ | ✔ | SendBroadcastPage, SendShopPopupPage dùng chung |
| PWA Service Worker | ✗ | ✔ +SA | Workbox, StaleWhileRevalidate, precache |
Quản lý Đại Lý
SuperAgentManagementPage.tsx — trang trung tâm với 3 tab: agents | shops | players. Route /agents, /shops, /players dùng cùng component với prop section.
Form modal thu thập đầy đủ thông tin và gửi lên POST /super-agent/agents.
- Tối thiểu 8 ký tự (PASSWORD_MIN = 8)
- Phải có ít nhất 1 chữ HOA
- Phải có ít nhất 1 chữ thường
- Phải có ít nhất 1 chữ số
- Giá trị nhập vào: 0 – 100 (phần trăm)
- Chuyển đổi: toRate(percent) → 0–1
- Khi edit: phải lớn hơn SA's own cost rate
- can_create_shop_popup — Agent có thể gửi popup/broadcast cho shops/players
- can_manage_shop_popup_permission — Agent có thể bật/tắt quyền popup cho từng shop
- default_shop_can_create_player_popup — Mặc định shop mới được tạo bởi agent này sẽ có quyền gửi popup cho players
Trong tab shops, mỗi row có nút "Move". SA chọn agent đích (target agent ≠ current agent), confirm → moveManagedShop(shopId, targetAgentId).
Trong tab players, mỗi row có nút "Move". SA chọn shop đích (target shop ≠ current shop), confirm → moveManagedPlayer(playerId, targetShopId).
- Search theo name / email / phone
- useMemo: filteredAgents
- Search theo name / email / phone
- Filter theo agent (dropdown)
- useMemo: filteredShops
- Search theo username / email / phone
- Filter theo shop (dropdown)
- useMemo: filteredPlayers
Chi tiết Đại Lý — ManagedAgentDetailPage
Route /agents/:agentId. Trang có 4 tab: Info · Games · Shops · Players. Tab được quản lý qua URL search param ?tab=....
- Tên, email, status badge (active/suspended/terminated)
- Credit balance của agent (agent.credit_balance)
- Nút Suspend / Unsuspend / Terminate
- SuperAgentAgentCreditTrigger — phân phối credits
- Sửa Cost Rate inline (edit → nhập → save)
- Guard: cost rate mới phải lớn hơn SA's own rate
- Fetch fetchManagedAgentGameMappings(agentId)
- Fetch fetchPublicGameProviders()
- parentGamePool: tập game SA đang có (filter)
- 2 mode: All (kế thừa pool SA) hoặc Selected
- Checkbox list — chọn game providers cụ thể
- Save → putManagedAgentGameMappings(agentId, ids[])
- Empty array = "all" (kế thừa SA pool)
- Stat: Total shops / Active shops
- Table: shop name, email, status
- Filter: chỉ hiện shops của agent này (s.agent?.id === agentId)
- Stat: Total players / Active players
- Table: username/email/phone, shop, status
- Filter: p.agent_id === agentId
Cấu hình Game Provider per-Agent
SA có thể giới hạn hoặc mở rộng game providers mà mỗi agent có quyền sử dụng. Logic kế thừa và override từ SA pool xuống agent pool.
parentGamePool[]
cho từng Agent
kế thừa toàn bộ SA
trong agent pool
Phân phối Credits
SA phân phối credits xuống agent — một cơ chế hoàn toàn mới so với Agent Portal (chỉ cấp credits xuống shop).
Component SuperAgentAgentCreditTrigger.tsx trong components/credits/. Xuất hiện trong ManagedAgentDetailPage tab Info, bên cạnh các nút govern agent.
- Click "Credit" button → open modal
- Load SA's own balance (fetchDashboard())
- Hiển thị tên agent + cost rate hiện tại
- Nhập amount (credits)
- Preview: credits → cash equivalent
- Submit → distributeCreditsToManagedAgent()
- Close → callback onSuccess()
Visibility đa cấp — HierarchyMiniTree
Component HierarchyMiniTree.tsx trong components/dashboard/. Hiển thị 2 cấp: SA → Agents → Shops. Khác với Agent Portal chỉ thấy 1 cấp (Agent → Shops).
- Expandable tree — root SA node expand/collapse
- Mỗi Agent có thể expand/collapse riêng để xem shops
- StatusDot per-node (green=active, amber=suspended, gray=terminated)
- Shops hiển thị dạng card grid (1-3 cols tùy viewport)
- Mỗi shop card có link đến /agents/{id}
- Date range filter (from/to) — thống kê theo kỳ
- Summary row: total deposits, withdrawals, new users, total users
- Stats per-shop: deposits, withdrawals, new users, total users
- API: fetchSuperAgentShopHierarchyStats({from, to})
- Default range: 30 ngày gần nhất
PWA Capability — Service Worker
Superagent Portal là repo duy nhất trong ecosystem có Service Worker — hướng tới khả năng dùng trên mobile và hoạt động khi mạng không ổn định.
precacheAndRoute(self.__WB_MANIFEST) — cache toàn bộ assets tĩnh (JS, CSS, fonts) tại install time. Tự động cập nhật khi build mới.
createHandlerBoundToURL('/index.html') — intercept navigate requests, trả về index.html cho React Router handle client-side.
StaleWhileRevalidate strategy cho .png files. Cache tên "images", max 100 entries. Hiển thị ảnh cached ngay, revalidate ngầm.
clientsClaim() — SA mới được activate ngay sau install, không cần chờ tab đóng/mở. Đảm bảo cập nhật nhanh.
SA portal có Service Worker gợi ý dùng trên mobile (tablet/phone) — phù hợp với vai trò "regional manager" di động, cần truy cập mọi lúc mọi nơi.
Sử dụng workbox-core, workbox-routing, workbox-strategies, workbox-expiration, workbox-precaching.
Routes của Superagent Portal
Cấu trúc React Router v6 — tất cả routes đều được bọc trong ProtectedRoute (trừ /login).
| Path | Component | Độc quyền SA? | Mô tả |
|---|---|---|---|
| /dashboard | DashboardPage | Dashboard với HierarchyMiniTree (2 cấp) | |
| /agents | SuperAgentManagementPage (section="agents") | SA Only | Danh sách agents + tạo mới + govern |
| /agents/:agentId | ManagedAgentDetailPage | SA Only | Chi tiết agent: Info/Games/Shops/Players |
| /shops | SuperAgentManagementPage (section="shops") | Tất cả shops + filter theo agent + move | |
| /players | SuperAgentManagementPage (section="players") | Tất cả players + filter theo shop + move | |
| /transactions | AgentTransactionsPage | Lịch sử giao dịch (dùng chung) | |
| /purchase/checkout | PurchaseCheckoutPage đã bỏ — mua qua CreditPurchaseModal | Mua credits (dùng chung) | |
| /payment/return | AgentPaymentReturnPage | Kết quả thanh toán (dùng chung) | |
| /login | LoginPage | Gọi POST /super-agent-auth/login |
Technical Stack & Architecture
- @kioskgaming/page-loading — PageLoadingIndicator variant="page" và variant="inline"
- @kioskgaming/ui — shared UI components
API Endpoints tổng hợp
Tất cả endpoints dưới prefix /super-agent/ và /super-agent-auth/.
| Method | Endpoint | Function | Mục đích |
|---|---|---|---|
| POST | /super-agent-auth/login | loginWithEmailPassword() | Đăng nhập SA |
| GET | /super-agent/agents | fetchManagedAgents() | Danh sách agents con |
| POST | /super-agent/agents | createManagedAgent() | Tạo agent mới |
| PUT | /super-agent/agents/{id}/suspend | suspendManagedAgent() | Suspend agent |
| PUT | /super-agent/agents/{id}/unsuspend | unsuspendManagedAgent() | Unsuspend agent |
| POST | /super-agent/agents/{id}/terminate | terminateManagedAgent() | Terminate agent (không đảo ngược) |
| PUT | /super-agent/agents/{id}/rate | updateManagedAgentRate() | Sửa cost rate của agent |
| POST | /super-agent/agents/{id}/credits | distributeCreditsToManagedAgent() | Cấp credits cho agent |
| GET | /super-agent/agents/{id}/game-mappings | fetchManagedAgentGameMappings() | Game mappings của agent |
| PUT | /super-agent/agents/{id}/game-mappings | putManagedAgentGameMappings() | Cập nhật game access |
| GET | /super-agent/shops | fetchManagedShops() | Tất cả shops |
| PUT | /super-agent/shops/{id}/move | moveManagedShop() | Move shop sang agent khác |
| GET | /super-agent/players | fetchManagedPlayers() | Tất cả players |
| PUT | /super-agent/players/{id}/move | moveManagedPlayer() | Move player sang shop khác |
| GET | /super-agent/shop-hierarchy-stats | fetchSuperAgentShopHierarchyStats() | Stats hierarchy (deposits, withdrawals, users) |