mirror of
https://github.com/pupperpowell/bibdle.git
synced 2026-04-05 17:33:31 -04:00
no longer initializes embeddings model on startup
This commit is contained in:
111
CLAUDE.md
111
CLAUDE.md
@@ -27,19 +27,14 @@ After calling the list-sections tool, you MUST analyze the returned documentatio
|
||||
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.
|
||||
|
||||
### 4. playground-link
|
||||
|
||||
Generates a Svelte Playground link with the provided code.
|
||||
After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project.
|
||||
|
||||
## 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 @oslojs/crypto (SHA-256 hashed tokens)
|
||||
- **Auth**: Session-based authentication using Bun's built-in cryptographically secure functions
|
||||
- **Deployment**: Node.js adapter for production builds
|
||||
- **External API**: bible-api.com for fetching random verses
|
||||
- **ML**: `@xenova/transformers` for verse embeddings (initialized in server hook) (currently disabled, was a test for a cancelled project)
|
||||
|
||||
## Development Commands
|
||||
|
||||
@@ -51,6 +46,11 @@ bun run dev
|
||||
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
|
||||
|
||||
@@ -58,92 +58,99 @@ bun run build
|
||||
bun run preview
|
||||
|
||||
# Database operations
|
||||
bun run db:push # Push schema changes to database
|
||||
bun run db:generate # Generate migrations (DO NOT RUN)
|
||||
bun run db:migrate # Run migrations (DO NOT RUN)
|
||||
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**: User accounts with id and age
|
||||
- **session**: Auth sessions linked to users with expiration timestamps
|
||||
- **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 are automatically renewed when less than 15 days remain.
|
||||
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 - higher is more popular)
|
||||
- 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`)
|
||||
|
||||
The `getTodayVerse()` function:
|
||||
1. Checks database for existing verse for today's date
|
||||
2. If none exists, fetches from bible-api.com (random verse + 2 consecutive verses)
|
||||
3. Caches in database with UTC date key
|
||||
4. Returns verse with book metadata for the game
|
||||
`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 stores game state in localStorage keyed by date
|
||||
- `guesses` array stored in localStorage keyed by date: `bibdle-guesses-${date}`
|
||||
- Each guess tracks: book, testamentMatch, sectionMatch, adjacent
|
||||
- `isWon` is derived from whether any guess matches the correct book
|
||||
- `isWon` derived from whether any guess matches the correct book
|
||||
|
||||
**Grading System:**
|
||||
```javascript
|
||||
// Grade formula combines performance + difficulty
|
||||
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:**
|
||||
- ✅ Green checkmark: Exact match
|
||||
- 🟩 Green square: Section matches
|
||||
- 🟧 Orange square: Testament matches (shared results)
|
||||
- ‼️ Double exclamation: Adjacent book in Bible order
|
||||
- 🟥 Red square: No match
|
||||
- ✅ Exact match | 🟩 Section match | 🟧 Testament match | ‼️ Adjacent book | 🟥 No match
|
||||
|
||||
### Authentication System (`src/lib/server/auth.ts`)
|
||||
|
||||
- Token-based sessions with SHA-256 hashing
|
||||
- Cookies store session tokens, validated on each request
|
||||
- Hook in `src/hooks.server.ts` populates `event.locals.user` and `event.locals.session`
|
||||
- Note: Currently the schema includes user table but auth UI is not yet implemented
|
||||
- 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` - Server load function, fetches/caches daily verse
|
||||
- `src/lib/server/bible-api.ts` - External API integration for verse fetching
|
||||
- `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 definitions
|
||||
- `src/hooks.server.ts` - SvelteKit server hook for session validation
|
||||
- `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`)
|
||||
- `DATABASE_URL` — Path to SQLite database file (e.g., `./local.db`)
|
||||
|
||||
## Deployment
|
||||
|
||||
The project uses `@sveltejs/adapter-node` for deployment. The build output is a Node.js server that can be run with systemd or similar process managers. See `bibdle.service` and `bibdle.socket` for systemd configuration.
|
||||
|
||||
## Important Notes
|
||||
|
||||
- Uses Svelte 5 runes syntax (`$state`, `$derived`, `$effect`, `$props`) - not stores or reactive declarations
|
||||
- The schema includes authentication tables but the login/signup UI is not yet implemented
|
||||
- Daily verses are cached permanently in the database to ensure consistency
|
||||
- LocalStorage persists guesses per day using the key pattern `bibdle-guesses-${date}`
|
||||
- The game validates book IDs from the API against the hardcoded `bibleBooks` array
|
||||
Uses `@sveltejs/adapter-node`. See `bibdle.service` and `bibdle.socket` for systemd configuration.
|
||||
|
||||
Reference in New Issue
Block a user