# 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/transformers` for verse embeddings (initialized in server hook) (currently disabled, was a test for a cancelled project) ## Development Commands ```bash # 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.ts` has `ssr = false` so 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:** - `guesses` array stored in localStorage keyed by date: `bibdle-guesses-${date}` - Each guess tracks: book, testamentMatch, sectionMatch, adjacent - `isWon` derived from whether any guess matches the correct book **Grading System:** ```javascript 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 `appleId` field ### Stats & Streak (`src/routes/stats/`) - Stats page requires auth; returns `requiresAuth: true` if unauthenticated - Streak calculated client-side by calling `GET /api/streak?userId=X&localDate=Y` - Streak walk-back: counts consecutive days backwards from `localDate` through completed dates - Minimum displayed streak is 2 (single-day streaks suppressed) ## API Endpoints - `POST /api/daily-verse` — Fetch verse for a specific date - `POST /api/submit-completion` — Submit game result with stats - `GET /api/streak?userId=X&localDate=Y` — Current streak for user - `GET /api/streak-percentile` — Streak percentile ranking ## Key Files - `src/routes/+page.svelte` — Main game UI and client-side logic - `src/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 calculations - `src/lib/server/auth.ts` — Session management, password hashing, anonymous migration - `src/lib/server/bible-api.ts` — External API integration - `src/lib/server/bible.ts` — Bible book utility functions - `src/lib/types/bible.ts` — Bible books data and TypeScript types - `src/lib/server/db/schema.ts` — Drizzle ORM schema - `src/hooks.server.ts` — Session validation hook; initializes ML embeddings - `tests/` — 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.