no longer initializes embeddings model on startup

This commit is contained in:
George Powell
2026-02-28 02:48:46 -05:00
parent 1ae2b2ac6c
commit 6e74fffb65
12 changed files with 243 additions and 97 deletions

111
CLAUDE.md
View File

@@ -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.