Last updated: March 2026 ยท Everything you need to run the admin portal
What Is This System?
MySeatPack sells blind-box Lakers tickets. Customers pick 3โ5 possible games with odds (must total 100%), pay, and after the drop closes, each order is randomly assigned one game using the NIST Randomness Beacon โ a government quantum random number source. This makes the assignment verifiable and tamper-proof.
๐ Drop Packs
Standard packs with pre-set games and odds. Customers choose a tier (100/200/300 level) and quantity (1โ4 seats).
โ๏ธ Custom Packs
Customers build their own pack โ pick 3โ5 games, set their own odds. Same NIST assignment process.
๐ฏ Predict & Win
Free prediction game. Guess the combined final score. Closest wins $10 store credit. Leaderboard prize after 20 games.
๐ง Marketing
Email subscriber management with segmentation, tags, blast sending, and template library.
The Order Lifecycle
PendingโConfirmedโAssignedโDelivered
Pending: Order placed, awaiting your review and confirmation email send.
Confirmed: You clicked "Confirm Pack" โ customer received confirmation email with their game odds. Order is now eligible for NIST assignment.
Assigned: NIST Beacon ran, game was randomly selected. Customer got assignment email + 24hr buyback window opens.
Delivered: You manually clicked "Mark Delivered" with seat info โ customer got ticket delivery email.
Automatic vs Manual Actions
๐ค Automatic (cron every hour)
NIST assignment (if confirmed order past assignment time)
Buyback reminder email at 20hr mark
SeatGeek price scraper update
๐ Manual (you do these)
Confirm Pack โ sends confirmation email
Assign (NIST) โ force-run assignment now
Force (manual override) โ assign specific game
Mark Delivered โ enter seat info, sends ticket email
Mark Resolved / Issue Refund on buybacks
Buyback Policy
After assignment, customers have 24 hours to request a buyback for store credit. The percentage was shown on the pack page at purchase (typically 85%). At 20 hours, an automatic reminder email goes out. After 24 hours, the pack is considered kept and you deliver the ticket.
โ ๏ธ Always check the Buybacks tab after running assignments โ open buyback requests need to be resolved or refunded before you deliver tickets.
Emails โ What Gets Sent & When
Confirmation email: When you click "Confirm Pack" in admin
Assignment email: Automatically after NIST assigns a game (or when you click "Assign" manually)
Buyback reminder: Automatically at 20 hours after assignment
Ticket delivered email: When you click "Mark Delivered" and enter seat info
Marketing blasts: You send these manually from the Marketing tab
All transactional emails are sent via Google Apps Script (the Gmail account). Marketing blasts also go through Apps Script.
Admin Tabs Reference
What each tab does and what to watch for
๐ฆ Orders Tab
Main operations hub. Shows all orders with status badges. Click any row to expand and see full details + action buttons.
Action Buttons
โ Confirm Pack: Only active on Pending orders. Sends confirmation email to customer with their game odds breakdown.
โบ Resend Email: Active on Confirmed/Assigned. Re-sends the last email (confirmation or assignment).
โก Assign (NIST): Active on Confirmed orders. Hits NIST Beacon right now and assigns a game. Cannot be undone.
โ Mark Delivered: Active on Assigned orders. Opens prompts for Section, Row, Seat. Sends ticket delivery email.
๐ View Reveal: Opens the customer-facing reveal page for that order.
Force (Manual Override): Bypasses NIST โ select a game from dropdown and force-assign it. Cannot be undone. Use only when NIST is unavailable or for corrections.
๐จ Assign and Force actions CANNOT be undone. Double-check the order before clicking.
โฉ๏ธ Buybacks Tab
Shows all buyback requests submitted by customers through their reveal page. Open = needs action. Resolved = done.
โ Mark Resolved: Customer got their credit or you handled it. Closes the request.
๐ธ Issue Refund: Processes refund via Shopify. Also marks as resolved.
โ๏ธ Custom Packs Tab
Filtered view of orders where source=custom. Same action buttons as Orders tab. Custom packs need extra review since customers set their own game selections.
๐ฐ Revenue Tab
Summary stats (total revenue, pack count, assigned count, avg price) plus a full sortable table. Export to CSV button at top right.
๐ฏ Predict & Win Tab
Manage prediction challenges.
Create Challenge: Fill in the question, game name, game date, submission deadline, and win condition.
Pick Winner: Enter the winner's email after the game. System applies $10 credit.
Close: Stops accepting new entries without picking a winner.
View Entries: Select a challenge from the dropdown to see all entries and results.
๐ Seasonal Tab
Shows seasonal/drop pack orders pulled from the Google Sheet. Read-only view โ no action buttons. For reference only.
โญ Credits & Leaderboard Tab
View all store credits and the Predict & Win leaderboard.
Adjust Credit: Enter email + amount โ Add or Deduct. Used for manual credit grants or corrections.
Leaderboard: Auto-calculated from prediction entries. Top player after 20 challenges wins $150 credit.
๐ฃ Marketing Tab
Full subscriber management + email blast tool.
Subscriber list: Filter by source (Pack, Predict, Notify, Manual). Sort by email/source/date. Tag subscribers for segmentation.
Tags: Add inline by clicking "+" next to any subscriber. Bulk tag via checkboxes. Use for game-specific or interest targeting.
Send Blast: Write subject + body (or load a template), select audience filter, click Send. Sends via Apps Script/Gmail.
Templates: 9 pre-built HTML templates. Click to preview, "Use Template" loads it into the composer. Save your own custom templates.
Manual Add: Paste emails (comma or newline separated) to bulk-add subscribers.
Export: Downloads filtered list as CSV.
Complete Order Flow
Step by step from customer purchase to ticket in hand
Stores order data in KV storage (assign_[orderId]). Status = pending. Logs to Google Sheet.
3
Order appears in admin โ Orders tab
Shows as Pending. No email sent yet.
Step 2 โ You Confirm the Order
1
Click "โ Confirm Pack" in admin
Worker updates status to confirmed, calls Apps Script webhook.
2
Apps Script sends confirmation email
Branded HTML email with game options, odds breakdown, and assignment time. Goes to customer's email.
3
Order shows as Confirmed
Now eligible for NIST assignment at the scheduled time.
Step 3 โ NIST Assignment
1
Cron runs every hour (or you click "Assign")
Worker fetches NIST Beacon pulse for the assignment timestamp.
2
Last 8 hex chars of beacon โ number 1โ100
That number falls in one game's range. That game is assigned.
3
Assignment email sent automatically
Customer gets game name, date, tier, beacon proof, buyback info.
4
24-hour buyback window opens
Customer can request buyback via their reveal page. At 20hrs, reminder email auto-sends.
Step 4 โ Ticket Delivery
1
After 24hr buyback window closes (or customer confirms attending)
Transfer ticket on Ticketmaster to customer's account.
2
Click "โ Mark Delivered" in admin
Prompts for Section, Row, Seat(s). Enter the exact seat details.
3
Ticket delivery email sent
Customer gets seat details, game info, and instructions to open Ticketmaster app.
4
Order shows Delivered
Button changes to a green "โ Ticket Delivered" indicator. Done.
๐ก You can have multiple orders at different stages simultaneously. Check the admin daily around game time to make sure assigned orders don't expire without delivery.
Technical Reference
Architecture overview โ URLs, files, and what lives where
Orders are created as Draft Orders (not regular orders). Admin page is a custom Liquid page (msp-admin). The page loads the worker JS files as external scripts.
Shopify Liquid Pages
Page
Handle
What it does
Admin Portal
msp-admin
Full admin dashboard โ loads part2a/b/c JS from worker
Reveal Page
reveal
Customer-facing game reveal + buyback request
Predict & Win
predict-and-win
Customer prediction entry form
Custom Pack Builder
custom-pack
Customer-facing pack configurator
Admin Auth
Password: msp2026admin ยท Header: X-Admin-Key
Login function: window.mspAdminLogin() and window.doAdmLogin() (aliases)
โ ๏ธ The login div has id="admLogin" โ never assign window.admLogin as a function or it will collide with the DOM element and crash the script.
Debug Snapshot
Copy and paste this to Claude when you need help troubleshooting
When something breaks, copy the block below and paste it at the start of your message to Claude. It gives full context so we can debug faster without re-explaining everything.
## MySeatPack System Context
### Architecture
- **Storefront:** Shopify (myseatpack.com)
- **API + JS serving:** Cloudflare Worker (msp-custom-pack)
- **Worker URL:** https://msp-custom-pack.nameless-forest-4d91.workers.dev
- **Email + logging:** Google Apps Script (v6, deployed as Web App)
- **Order storage:** Cloudflare KV (TOKENS namespace)
### Admin Portal
- **URL:** https://myseatpack.com/pages/msp-admin
- **Liquid page handle:** msp-admin
- **Login function:** window.mspAdminLogin() / window.doAdmLogin()
- **Login div id:** admLogin (NOT used as window property โ DOM collision risk)
- **Admin key:** msp2026admin (header: X-Admin-Key)
### JS Files (served by Cloudflare Worker)
- **/admin-part2a.js** โ Login, Orders, Buybacks, Custom Packs, Revenue, Predict & Win, Seasonal, Credits/Leaderboard
- **/admin-part2b.js** โ Marketing subscriber list, tags, blast sending
- **/admin-part2c.js** โ Email templates (9 starters + custom save/load)
### Order Flow
Pending โ Confirmed (manual) โ Assigned (NIST cron or manual) โ Delivered (manual)
### Cron Jobs (hourly)
- processAssignments() โ NIST beacon assignment
- updateSeatGeekPrices() โ price scraper
- processBuybackReminders() โ 20hr buyback reminder email
### KV Key Patterns
- assign_[orderId] โ full order data
- buyback_[orderId] โ buyback requests
- public_assignments โ public reveal data
- seatgeek_prices โ cached prices
- shopify_access_token โ Shopify OAuth token
### Google Apps Script Webhooks
- Sheets: AKfycbwv3nWQS7KxuSGgPCxAkmbfT3vwTSUXPUGEhE2U6PJjGJkInYlEYwjY5kwjlKzGAbjDcw/exec
- Reveal: AKfycbxTPx7Ji4SoDZxdb_R-KTmCJWiA5EFE3Hy8gVg6E9DyCEj5xn1VdtlEQpC3Sp7NkZiX/exec
### Transactional Emails (via Apps Script)
- send_confirmation_email โ on Confirm Pack click
- send_assignment_email โ on NIST assignment
- send_buyback_reminder_email โ auto at 20hr after assignment
- send_ticket_delivered_email โ on Mark Delivered click
### Shopify
- Store: myseatpack.myshopify.com
- Orders created as Draft Orders
- API version: 2026-01
### Known Gotchas
1. window.admLogin collides with DOM element id="admLogin" โ never assign it as a function
2. Literal newlines inside JS strings crash the script โ always use \n escape sequences
3. Admin JS is served by the Worker, not a static file โ must edit worker.js and redeploy to change admin behavior
4. Apps Script must be re-deployed (new version) after any changes or old code runs
5. Login function defined at line ~14 of admin-part2a.js โ any syntax error anywhere in the file prevents login
---
**Issue I'm reporting:**
[DESCRIBE YOUR ISSUE HERE]
Common Issues & Fixes
๐ด Login not working / password not accepted
Almost always a JS syntax error in admin-part2a.js that crashes the script before the login function is defined. Open browser DevTools (F12) โ Console tab. Look for "Uncaught SyntaxError". Note the line number and fix that line in the worker.
๐ด Orders not loading / "Connection failed" toast
Worker API route failed. Check: (1) Worker is deployed and active in Cloudflare. (2) X-Admin-Key header matches the ADMIN_KEY env var. (3) KV namespace "TOKENS" is bound to the worker.
๐ด Emails not sending
Apps Script issue. Check: (1) Script is deployed as Web App with "Anyone" access. (2) Webhook URL in worker constants matches the deployed version URL. (3) Open Apps Script โ Executions tab to see errors.
๐ด NIST assignment not running automatically
Check: (1) Order status is "confirmed" (not pending). (2) Assignment time has passed. (3) Worker cron is configured in wrangler.toml or Cloudflare dashboard under Triggers. (4) NIST beacon URL is reachable (occasionally down briefly).
๐ด Changes to worker not taking effect
You must click "Deploy" in the Cloudflare editor after making changes โ saving the file is not enough. Also clear browser cache or hard-refresh (Ctrl+Shift+R) the admin page.
๐ด Marketing list not loading
Apps Script GET route for get_marketing_list may be timing out or returning an error. Check the mktDebug element in the Marketing tab (it shows the fetch status). Also verify the PRED_SHEET URL in the worker constants is the correct deployed Apps Script URL.
Code Backups
Full source backups for all 3 components โ update after every change
๐จ IMPORTANT โ TO ANYONE MAKING CHANGES: After deploying any update, paste the new code into the correct section below, update the date, and click Save. Cloudflare has NO auto-backup. This is the only copy.
File: Code.gs ยท Deployed at: Google Apps Script โ Deploy โ New Deployment (must redeploy after every change)
Last updated: March 5, 2026
Shopify pages: msp-admin (HTML shell) โ found at Shopify Admin โ Online Store โ Pages
Note: Shopify keeps its own version history, but paste the current version here too for easy reference.
๐ก Backups are saved in your browser's local storage. They persist between sessions on this device, but are not shared across devices. For extra safety, also keep a copy in a Google Doc or text file.