Standout Builder Studio · planning Index / Operator Portal review Updated 16 Jun 2026

Operator Portal

The operator portal (apps/portal) is built and live on this branch. It is a standalone Cloudflare Worker that gives B2B operators a magic-link-authenticated window into the Standout game catalogue — with per-game factsheets, permissioned embedded demos, and a roadmap view.

GROUNDED · matches main

Feature set

Feature Detail
Magic-link login Operator enters their email; Resend delivers a one-time link. The Worker validates the token and issues a signed session cookie. No passwords, no OAuth app to configure.
Game catalogue A paginated table of all published games. Each row shows the game name, RTP, volatility, category, and a lock indicator for the operator's access grant. Rows link to the game factsheet.
Lock state per row Each game row reflects the operator's current grant state: unlocked (demo access granted), locked (catalogue-visible but not demoed), or hidden (not published to this operator). The lock state is set by admins via the admin page.
Roadmap A 6-month forward view of planned game releases and platform milestones, authored by the Standout team and published to operators.
Game factsheet Per-game page with maths summary (RTP, volatility, max win), media (screenshots, video placeholder), and materials (spec sheet, jurisdiction matrix). Placeholders are shown where content is not yet published.
Permissioned embedded demos If the operator has a demo grant for a game, the factsheet shows an embedded iframe of the live demo. The iframe URL is server-guarded — an unauthenticated or ungrant request returns 403. The admin page sets the demo URL and allocates per-operator demo access.
Admin page Accessible to any @vhslab.com email or any email on the admin allowlist. Allows publishing games (setting their portal-visible status), setting the demo URL, setting a launch partner flag and launch date, and allocating per-operator demo access by email.
Per-game chat (upcoming) A real-time chat panel on each factsheet connecting operators to the Standout team over Slack threads — see Portal ↔ Slack chat. Approved design, pending implementation.

Data model

The portal uses three D1 tables as its own overlay on top of the shared games table. The shared games table is the source of truth for game identity and metadata; the portal tables add operator-specific state.

Table Key columns Role
games slug, title, rtp, volatility, category Shared source of truth. Seeded from the operator screenshot catalogue. Read-only from the portal's perspective.
portal_games game_slug, published, demo_url, launch_partner, launch_date Portal-specific overlay. Controls whether a game is visible in the operator catalogue and what demo URL is served.
portal_grants email, game_slug, granted_at Per-operator demo access grants. One row per (email, game_slug) pair. Checked on every factsheet and demo iframe request.
portal_magic_links token, email, expires_at, used_at One-time login tokens. Tokens are single-use; used_at is set on redemption. Expired or already-used tokens return 401.
D1 binding
The portal Worker binds to D1 by name at deploy time — [[d1_databases]] in wrangler.toml with binding = "DB". No database_id is hard-coded; the binding is resolved by Cloudflare at deploy. The same D1 instance is shared with apps/web.

Authentication flow

  1. Operator visits the portal root. If no valid session cookie is present, the login form is shown.
  2. Operator submits their email. The Worker creates a portal_magic_links row with a random token and 15-minute expiry, then calls Resend to send the link.
  3. Operator clicks the link. The Worker looks up the token, checks it is not expired and not used, marks it used_at = now(), and issues a signed session cookie (HttpOnly, Secure, SameSite=Lax).
  4. Subsequent requests carry the cookie. The Worker calls verifySession() on every protected route; the email from the verified session is used to look up grants and admin status.

Admin access rule

A session is treated as admin if the verified email ends in @vhslab.com OR if the email is present in the hard-coded admin allowlist in the Worker. Admin sessions can access the /admin route; non-admin sessions receive 403.


Surfaces at a glance

Route Who can access What it shows
/ Any authenticated operator Game catalogue — published games with lock state per operator.
/roadmap Any authenticated operator 6-month forward view of planned releases and milestones.
/games/:slug Any authenticated operator Game factsheet — maths, media, materials, embedded demo if granted.
/admin Admin emails only (@vhslab.com or allowlist) Publish games, set demo URLs, set launch partner/date, allocate per-email demo access.
/api/portal/chat/ws Any authenticated operator (session cookie verified on upgrade) WebSocket endpoint — routes to the ChatRoom Durable Object for real-time chat. See Portal ↔ Slack chat. (Upcoming.)
/api/portal/slack/events Slack only (signature-verified, no session) Inbound Slack Events API webhook — receives team replies and routes to the correct Durable Object. (Upcoming.)