VIP Program¶
Purpose¶
The VIP Program screen manages VIP applications and the VIP tier catalog. Players apply for VIP via the player site; compliance + partnerships review applications here. The screen also exposes the per-tier perks (cashback %, dedicated host flag, withdrawal cap bumps).
Audience¶
VIP / partnerships, compliance (KYC tier prerequisite), risk (vetting application).
Path in admin-fe¶
| Screen | URL | Page |
|---|---|---|
| VIP applications list | /vip-program |
ebit-admin-fe/src/app/(dashboard)/vip-program/page.tsx |
| VIP application detail | /vip-program/[id] |
ebit-admin-fe/src/app/(dashboard)/vip-program/[id]/page.tsx |
Backing API endpoints¶
| Endpoint | Source |
|---|---|
GET /admin/vip-program/all (list applications) |
apps/api/src/vip-program/admin/vip-program-admin.controller.ts:30 |
GET /admin/vip-program/:id (one application) |
apps/api/src/vip-program/admin/vip-program-admin.controller.ts:36 |
PATCH /admin/vip-program/:id/status (approve / reject / pending) |
apps/api/src/vip-program/admin/vip-program-admin.controller.ts:42 |
DELETE /admin/vip-program/:id (drop application) |
apps/api/src/vip-program/admin/vip-program-admin.controller.ts:53 |
Frontend wiring: ebit-admin-fe/src/queries/vip-program/.
Key actions¶
| Action | Required permission | API call | DB tables touched | Audit-logged? |
|---|---|---|---|---|
| List VIP applications | vip.application.view |
GET /admin/vip-program/all |
VipApplication, User |
yes |
| View one application | vip.application.view |
GET /admin/vip-program/:id |
VipApplication, UserStats |
yes |
| Set status (approve / reject / hold) | vip.application.action |
PATCH /admin/vip-program/:id/status |
VipApplication.status, VipMember (on approve) |
yes |
| Delete application | vip.application.action |
DELETE /admin/vip-program/:id |
VipApplication |
yes |
The VIP tier catalog (VipLevel records — bronze / silver / gold / platinum / diamond, with cashback %, perks) is read by the player UI; the admin panel doesn't expose a tier-editor screen — schema changes go through engineering.
Filters and views¶
- Status —
PENDING/APPROVED/REJECTED/ON_HOLD. - Tier requested — bronze / silver / gold / platinum / diamond.
- Date range.
- Search by user — username / email.
- Sort —
createdAt,wageredUSD.
Common workflows¶
- Daily VIP application triage. Partnerships opens
/vip-program, filters PENDING. For each, opens detail. Reviews KYC level (must be ≥ 2), wager total, deposit total, country status. Approves viaPATCH .../status { status: APPROVED, tier: ... }. - Auto-tier from wagering. No automatic promotion in code. Operator sees a player has crossed wagering threshold for next tier; manually applies.
- Reject ineligible application. Player applied with KYC=0. Reject with reason note. Player gets in-app notification (rt service).
- Promote existing VIP to a higher tier. No "edit tier" endpoint. Operator deletes the existing VIP record, creates a new application at higher tier, approves. Or engineering does it via raw DB. Improvement tracked.
- De-VIP a player. Set status
REJECTED(effective revoke) orDELETEto drop the record. Player loses cashback % at next bet.
Edge cases / gotchas¶
- No tier-edit endpoint. Approving creates a
VipMemberat the requested tier; you cannot promote in place. Workaround above. - VIP perks (cashback %) ride on
VipLevel.cashbackPercent— bet-settle flow reads this. Editing the VipLevel catalog requires a deploy. - Approval does NOT bump withdraw limits automatically — those still come from KYC. VIP affects perks only (cashback, host).
- Application carries free-text reason for rejection / hold; player sees it in their account history.
- Application has no time-to-live. Stale PENDINGs accumulate. Operations should sweep weekly.
- Bot users cannot apply. Player-side endpoint blocks
User.isBot=true. - VIP host assignment is a flag on
VipMember, no per-host workload view in the admin UI.
Cross-links¶
- Per-user VIP status: user-profile.md → VIP tab
- Wager / deposit prerequisites: dashboard.md → users-stats
- KYC tier prerequisite: kyc-limits.md
- Player-side VIP application endpoint:
apps/api/src/vip-program/players/vip-program.controller.ts - Audit: admin-logs.md
- Permission keys:
libs/auth/src/permissions/const.ts:228-235
Sequence — approving a VIP application¶
sequenceDiagram
actor partner
participant admin-fe
participant api
participant pg as Postgres
partner->>admin-fe: open /vip-program, filter PENDING
admin-fe->>api: GET /admin/vip-program/all?status=PENDING
api->>api: PermissionGuard('vip.application.view')
api->>pg: SELECT VipApplication WHERE status=PENDING JOIN User
pg-->>api: rows
api-->>admin-fe: applications
partner->>admin-fe: open one, review KYC + wager, click Approve gold
admin-fe->>api: PATCH /admin/vip-program/:id/status { status: APPROVED, tier: gold }
api->>api: PermissionGuard('vip.application.action')
api->>pg: UPDATE VipApplication SET status=APPROVED
api->>pg: INSERT VipMember (userId, tier=gold, cashbackPercent from VipLevel)
api->>pg: INSERT AdminActionLog
api-->>admin-fe: 200 OK
admin-fe-->>partner: row removed from PENDING