6.6 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Bibdle is a daily Bible verse guessing game built with SvelteKit 5. Players read a verse and try to guess which book of the Bible it comes from. The game provides feedback hints (Testament match, Section match, Adjacent book, etc.) similar to Wordle-style games. Progress is stored locally in the browser and a new verse is generated daily.
You are able to use the Svelte MCP server, where you have access to comprehensive Svelte 5 and SvelteKit documentation. Here's how to use the available tools effectively:
(Make sure you use the Svelte agent to execute these commands)
Available MCP Tools:
1. list-sections
Use this FIRST to discover all available documentation sections. Returns a structured list with titles, use_cases, and paths. When asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections.
2. get-documentation
Retrieves full documentation content for specific sections. Accepts single or multiple sections. After calling the list-sections tool, you MUST analyze the returned documentation sections (especially the use_cases field) and then use the get-documentation tool to fetch ALL documentation sections that are relevant for the user's task.
3. svelte-autofixer
Analyzes Svelte code and returns issues and suggestions. You MUST use this tool whenever writing Svelte code before sending it to the user. Keep calling it until no issues or suggestions are returned.
Tech Stack
- Framework: SvelteKit 5 with Svelte 5 (uses runes:
$state,$derived,$effect,$props) - Styling: Tailwind CSS 4
- Database: SQLite with Drizzle ORM
- Auth: Session-based authentication using Bun's built-in cryptographically secure functions
- Deployment: Node.js adapter for production builds
- ML:
@xenova/transformersfor verse embeddings (initialized in server hook) (currently disabled, was a test for a cancelled project)
Development Commands
# Start development server
bun run dev
# Type checking
bun run check
bun run check:watch
# Run tests
bun test
bun test --watch
bun test tests/timezone-handling.test.ts # Run a single test file
# Build for production
bun run build
# Preview production build
bun run preview
# Database operations
bun run db:push # Push schema changes directly (avoid in prod)
bun run db:generate # Generate migrations
bun run db:migrate # Run migrations
bun run db:studio # Open Drizzle Studio GUI
Critical: Date/Time Handling
NEVER use server time or UTC time for user-facing date calculations.
- Get today's date client-side:
new Date().toLocaleDateString("en-CA")→YYYY-MM-DD - Pass the date to the server as a query param or POST body (
localDate) - Server-side date arithmetic must use UTC methods on the client-provided date string:
new Date(dateStr + 'T00:00:00Z')+setUTCDate/getUTCDate src/routes/+page.tshasssr = falseso the load runs client-side with the true local date
Architecture
Database Schema (src/lib/server/db/schema.ts)
- user:
id,firstName,lastName,email(unique),passwordHash,appleId(unique),isPrivate - session:
id(SHA-256 hash of token),userId(FK),expiresAt - daily_verses: Cached daily verses with book ID, verse text, reference, and date
- dailyCompletions: Game results per user/date with guess count, grade, book; unique on
(userId, date)
Sessions expire after 30 days and auto-renew when < 15 days remain.
Bible Data (src/lib/types/bible.ts)
The bibleBooks array contains all 66 Bible books with metadata:
- Testament (old/new), Section (Law, History, Wisdom, Prophets, Gospels, Epistles, Apocalyptic)
- Order (1-66, used for adjacency detection), Popularity (2-10, affects grading)
Daily Verse System (src/routes/+page.server.ts)
getTodayVerse() checks the database for today's date, fetches from bible-api.com if missing (random verse + 2 consecutive), caches permanently, and returns verse with book metadata.
Game Logic (src/routes/+page.svelte)
State Management:
guessesarray stored in localStorage keyed by date:bibdle-guesses-${date}- Each guess tracks: book, testamentMatch, sectionMatch, adjacent
isWonderived from whether any guess matches the correct book
Grading System:
performanceScore = max(0, 10 - numGuesses)
difficulty = 14 - popularity
totalScore = performanceScore + difficulty * 0.8
// S: 14+, A: 11+, B: 8+, C: 5+, C-: <5
Hint System:
- ✅ Exact match | 🟩 Section match | 🟧 Testament match | ‼️ Adjacent book | 🟥 No match
Authentication System (src/lib/server/auth.ts)
- Token generation: base64-encoded random bytes; stored as SHA-256 hash in DB
- Cookie name:
auth-session - Anonymous users: identified by a client-generated ID; stats migrate on sign-up via
migrateAnonymousStats() - Apple Sign-In supported via
appleIdfield
Stats & Streak (src/routes/stats/)
- Stats page requires auth; returns
requiresAuth: trueif unauthenticated - Streak calculated client-side by calling
GET /api/streak?userId=X&localDate=Y - Streak walk-back: counts consecutive days backwards from
localDatethrough completed dates - Minimum displayed streak is 2 (single-day streaks suppressed)
API Endpoints
POST /api/daily-verse— Fetch verse for a specific datePOST /api/submit-completion— Submit game result with statsGET /api/streak?userId=X&localDate=Y— Current streak for userGET /api/streak-percentile— Streak percentile ranking
Key Files
src/routes/+page.svelte— Main game UI and client-side logicsrc/routes/+page.server.ts/+page.ts— Server load (verse) + client load (ssr: false)src/routes/stats/+page.svelte/+page.server.ts— Stats UI and server calculationssrc/lib/server/auth.ts— Session management, password hashing, anonymous migrationsrc/lib/server/bible-api.ts— External API integrationsrc/lib/server/bible.ts— Bible book utility functionssrc/lib/types/bible.ts— Bible books data and TypeScript typessrc/lib/server/db/schema.ts— Drizzle ORM schemasrc/hooks.server.ts— Session validation hook; initializes ML embeddingstests/— Bun test suites (timezone, game, bible, stats, share, auth migration)
Environment Variables
Required in .env:
DATABASE_URL— Path to SQLite database file (e.g.,./local.db)
Deployment
Uses @sveltejs/adapter-node. See bibdle.service and bibdle.socket for systemd configuration.