Full redesign of the Quiz template (same templateType: "quiz" key —
it's a plain text column, not a SQL enum, so no migration needed):
15-level money ladder with two guaranteed checkpoints (level 5, level
10), three classic lifelines (50:50, помощь зала, звонок другу — all
simulated client-side, weighted by difficulty band), a "Забрать"
walk-away option, and questions organized into 7 categories x 5
difficulty bands.
Ships with a 105-question bank of real, fact-checked trivia (history,
geography, science, literature, film/music, sport, general knowledge)
per the explicit "don't invent anything, use facts" requirement —
deliberately sticks to foundational/uncontestable facts rather than
"current record holder" style trivia that goes stale. A game session
draws one random unused question per level from that level's band
pool, so repeated playthroughs don't see the same 15 questions.
Checkpoint math verified against the classic rule (wrong answer keeps
the highest checkpoint reached, not partial credit) via a standalone
script before wiring it into the scene. Progress save/resume, the
builder form (added category+band fields), and the AI-generation
prompt (now requires real verifiable facts, structurally constrained
to the 7-category enum) all updated to match the new shape.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QcXH24ky6zjk2UyK5oZUPH
Every page here is personalized (session, coin balance, owned games) —
no intermediate proxy should ever cache one. Traced a report of a
stale UI (missing header content that had already shipped) to caching
somewhere between the app and the client — nginx isn't even on this
VM, the user's reverse proxy (Nginx Proxy Manager) lives on a separate
one I can't inspect. Rather than debug an opaque hop I don't control,
close it from this side: explicit no-store on every HTML/API response
except /_next/static, which keeps its normal long-lived immutable
caching since those filenames are content-hashed by the build.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QcXH24ky6zjk2UyK5oZUPH
Header nav was splitting into three lines on mobile (logo / nav /
logout floating right with a big gap) — applied the same order-last
wrap pattern already proven in top-tickets/project-claude, so nav
drops to its own scrollable row instead.
Bigger feature: player progress now survives closing the tab, for all
three templates, not just Clicker. Each Phaser scene reports its state
through the same registry-callback pattern already used for onFinish
(onProgress), and reads an initialState to resume instead of always
starting fresh. Autosave fires every 10 minutes for free; an instant
manual save costs coins.
New coin economy (src/lib/wallet/): a wallet + transaction ledger per
user, atomic grant/spend via db.transaction() so two concurrent spends
against a low balance can't both succeed (verified with a real race
test — exactly one wins, balance never goes negative). New accounts
get a 20-coin signup bonus so manual save is testable before any real
payment method exists.
Real-money purchases are scaffolded but deliberately not wired to a
provider yet — user hasn't picked one. /api/wallet/purchase creates a
pending order and returns a clean "not configured" error, same shape
as the AI/LDAP not-configured responses elsewhere in this project. The
payment abstraction (src/lib/payments/provider.ts) is the one seam a
real adapter needs to fill in later.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QcXH24ky6zjk2UyK5oZUPH
Without it, COPY . . in the Dockerfile overwrote the container's npm-ci
node_modules with the host's — a native-binary mismatch that surfaced
as a missing libnode.so.115 during the build-time page-data pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QcXH24ky6zjk2UyK5oZUPH
A self-hosted, Roblox-flavored game platform: browse/play published
browser games, build them by hand or by describing them to an LLM.
Fully independent from top-tickets — separate repo, DB, port (8082).
- Auth: email+password accounts (argon2, httpOnly session cookies),
no admin/agent split — every account can create and play.
- Three game templates (quiz, clicker, maze), each a zod schema paired
with a Phaser 4 Scene that renders purely from a validated instance
of that schema — manual and AI-generated games hit the same
renderer, so a saved game is always guaranteed to load and run. The
maze schema BFS-validates that the exit is reachable from the start.
- Manual constructor: per-template builder forms, draft/publish/edit/
delete, a launcher grid of published games, a full-bleed play page.
- AI generation: Anthropic API key configured under Settings → AI
(encrypted at rest, validated with a live call before saving, same
shape as top-tickets' mailbox/LDAP settings). Generation uses the
SDK's zodOutputFormat/messages.parse to force schema-shaped JSON
output, with one retry feeding back the validation error. Output
always prefills the manual builder for review — never auto-published
blind. Clean, distinct error message when no key is configured yet
(no silent fallback exists here, so it doesn't pretend one does).
- Docker Compose on port 8082 (bakes in the busy_timeout=30000 SQLite
pragma from day one — top-tickets hit this build-time race twice).
Deferred: more templates/genres, drag-and-drop level editor, likes/
leaderboards, AI-generated sprite assets, multiplayer, moderation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QcXH24ky6zjk2UyK5oZUPH