mirror of
https://github.com/pupperpowell/bibdle.git
synced 2026-04-05 17:33:31 -04:00
157 lines
6.6 KiB
Markdown
157 lines
6.6 KiB
Markdown
# 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.
|