Skip to content

Dashboard & access

The admin panel (apps/admin, port 3001) is where the operations team runs the platform. This page covers the landing dashboard and, more importantly, the access model that decides who can do what.

The dashboard

The home screen is an operational snapshot rather than a marketing page. It leads with the numbers that matter day to day — total players and recent signups, total wagered, house profit and edge, and active players in the last 24 hours — and surfaces a warning banner when withdrawals are waiting to be processed.

Below the stats sit quick links into the busy areas (players, games, withdrawals, bonuses, support, marketing), a live activity feed that polls for fresh signups, deposits, withdrawals, and big wins, and a short list of the top games by volume.

Access model

Access is enforced in layers, and understanding them explains why a page might load for one admin but not another.

  1. Middleware provides a cookie-presence fast path. Guests hitting any page outside /login, /unauthorized, /api/auth/*, and ops endpoints are redirected to /login before protected UI renders. /api/admin/* still returns JSON 401/403 from handlers rather than HTML redirects.
  2. Protected layout re-validates the admin against the database (active status, role) before mounting the sidebar chrome.
  3. Page guards (requireAdminPagePermission) still run on each protected page and redirect to /login or /unauthorized when the required permission is missing.
  4. Navigation is fetched after login from GET /api/admin/navigation and filtered server-side by DB-resolved permissions — guests never receive the section catalog.
  5. Every admin API call is wrapped so it checks the session, verifies the required permission (or authenticated-session-only for navigation), runs the handler, and writes an audit entry on a successful change. This is the layer that ultimately protects the data. Inactive admins receive 401 so the client clears the session and returns to /login.
  6. Hono support routes recognize principalKind: admin_panel with granular permissions. Staff-scoped endpoints (claim, staff feed, staff notifications, online status) reject admin-panel principals — adminUserId is never treated as a support_staff id.

The practical takeaway: middleware keeps guests off the panel, the layout/page guards authorize chrome and pages, and the API is the authoritative data gate.

Roles and permissions

Permissions are fine-grained slugs like players.view, players.edit, payments.manage, or bonuses.templates.manage. A role is a named bundle of those slugs, stored in the database.

One role is special: a seeded superadmin that is marked as a system role, carries every permission, and bypasses all checks. Beyond that, operators create custom roles and tick the permissions each one should have, grouped by domain. The superadmin flag can't be granted through the UI — it only exists on the seeded role.

A quick map of which permission opens which area:

AreaPermission to viewPermission to change
Dashboard activitydashboard.view
Playersplayers.viewplayers.edit
KYC documentsplayers.documents.viewplayers.documents.manage
Balance correctionsbalance.correction.manage
Segmentsplayers.viewplayers.edit
Games cataloggames.viewgames.manage
Bonus templatesbonuses.templates.viewbonuses.templates.manage
Loyalty programloyalty.viewloyalty.manage
Withdrawalsplayers.payments.viewpayments.manage
Marketing / UTMcms.manage
Cashbackcashback.viewcashback.manage
Questsquests.viewquests.manage
Wheelswheels.viewwheels.manage
Traffic qualifiercms.managecms.manage
Supportsupport.viewsupport.manage
Support staffsupport.staff.viewsupport.staff.manage
Adminsadmins.viewadmins.manage
Rolesroles.manage
Audit logadmins.logs.view

The permission catalog is broader than the panel currently uses — there are slugs reserved for limits, payment geo rules, and other features that may not have dedicated docs pages yet.

Admin accounts and the audit log

The Admins area manages the back-office accounts themselves. It has three tabs: a searchable list where you create admins and assign roles or reset passwords, a roles editor with the permission matrix described above, and an audit log.

The log is worth calling out. Because every mutating API call writes an entry, the log gives a chronological record of who did what — the actor, the action, the entity touched, and a timestamp — with sensitive fields like passwords redacted. It's the answer to "who changed this?"