- platforms table gets url_alias_param column (configurable per platform)
- Admin game form has new "Username URL Param" field — leave blank if platform
doesn't support it, or set to e.g. "username" if it does
- Platform cards now use onclick openPlatform() instead of plain href:
copies player's saved alias to clipboard on every click, and if
url_alias_param is set appends ?param=alias to the launch URL
- Toast notification confirms "Alias copied — paste into login"
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Players now paste the URL of their post instead of just clicking a
platform button. The server fetches the URL and looks for the player's
referral code in the page content. If found, the share is auto-approved
and tokens are awarded immediately. If not (login wall, private page,
code missing), it falls into the pending queue with a reason so admins
can click the link directly for manual review.
- api/referrals.php: replace submit_share with URL-accepting version;
add scrapeForReferralCode() (SSRF-guarded cURL, 8s timeout, 512KB cap)
and inferPlatformFromUrl() helpers
- db/schema.sql: add share_url, auto_verified, verify_result columns
- index.php: replace platform buttons with URL input form; show auto-
verify result inline; shares list shows URL and auto-verify badge
- admin/index.php: share cards show clickable URL, auto-check result
label, and auto-verified tag
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two concurrent loadAdminReferrals() calls shared the same DOM container,
so whichever fetch resolved last would overwrite the other's result.
Added a request ID counter (_refListReqId) so stale responses are
discarded rather than applied.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- api/backup.php: list/create/download/delete backups; streams zip directly
for downloads; 7-backup rolling prune on each create
- Each backup is a single zip containing all of public_html + a full
mysqldump of tomt_ttg_db
- Cron at 2 AM daily via /usr/local/bin/ttg-backup.sh (already installed)
- Admin UI: 💾 Backups nav item under System section; shows backup list
with date/size, Download + Delete per row; Create Backup Now button
with live status; auto-loads when section is opened
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New section below pending purchases/cashouts: one square card per
active platform showing net credit balance, completed purchase count,
and sent cashout count. Loads on page load alongside other dashboard
data. Credits turn yellow below 100 and red at/below 0 with a warning.
Clicking a card jumps to Game Management and opens that platform's
credit modal.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a pending purchase is resolved as completed:
- Inserts a debit row into platform_credits for the matching platform
(joins token_purchases.platform_id slug → platforms.id)
- Debit notes include purchase #, player name, username, token count, amount, method
- Total shown in credit modal now subtracts debits from credits (net balance)
Credit history table updates:
- CREDIT/DEBIT type badges, debit rows tinted red with − prefix
- Debit rows show "Purchase #X ↗" button that closes modal, jumps to
the Purchases section (all tab), and highlights that purchase row
- Edit/delete buttons hidden on auto-generated debit rows
Also fixes: resolve_purchase was echoing $sent (undefined variable bug)
Also fixes: purchaseCard div now has id="pr-N" so jump-highlight works
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
saveCreditEntry and deleteCreditEntry were using apiFetch() which routes
to /api/admin.php, but credits_create/update/delete only exist in
/api/platforms.php — causing the Unknown action error on every save.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- resetGameForm() now called every time Game Management section is opened,
preventing stuck edit state (disabled slug, wrong form title)
- Added prominent Add New Game button at top of section (master admin only)
- DOMContentLoaded init ensures form state is correct on page load
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DB: added is_deleted, deleted_at columns to platforms table
- Soft delete: archive button moves games to archived section instead of hard delete
- Archived section: master admin can restore (reactivates) or permanently delete
- Slug reuse: creating a game with an archived slug reactivates the old record
- New game form: master admin always sees add form + agent info; other admins hidden
- Edit: non-master admins have form card revealed on edit
- Delete/Add buttons: only visible to master admin
- api/platforms.php: public and admin_list queries exclude archived games
- api/admin.php: platforms_archived, platforms_restore, platforms_purge actions added
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: saves went through admin.php which still used old console_url column
and had broken response using undefined $sent variable (always returned error).
- api/admin.php: platforms_create/update/delete fully rewritten with all agent
fields, master-admin gating, and correct json_encode responses
- api/admin.php: update now sets updated_at=NOW() on save
- admin/index.php: game cards show last-edited date (✏️ from updated_at)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Agent Info: master admin sees full edit form; other admins see view-only panel with Copy and Open URL buttons
- Credit Accounting: master admin can manage entries; other admins see total only (Manage Credits button hidden)
- API: credits_create/update/delete require master admin; platform update strips agent fields for non-master
- Players: suspend/delete buttons disabled when viewing master admin account (UI + JS guards)
- URL fields (Agent Link, Games Link): open-in-new-tab arrow button added in both edit and view modes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DB: added sub_agent_login, sub_agent_password, cashier_login, cashier_password to platforms table
- API: create/update handle all 4 new fields
- Admin: Sub-Account and Cashier sections added inside Agent Info box; game list cards display all new fields
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DB: renamed console_url to agent_link, added agent_login, agent_password, games_link, agent_guide to platforms table
- api/platforms.php: create/update now handles all 5 agent fields (admin-only)
- admin/index.php: game form has new Agent Info section (purple, admin-only styling); game list cards show all agent fields inline; JS saveGame/editGame/resetGameForm updated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>