# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Rhema Wave Technologies User Portal — a SvelteKit web app managing affirmations (audio content tied to solfeggio frequencies), user accounts, license keys, and authentication. ## Tech Stack - **Framework:** SvelteKit 2.x with Svelte 5 (runes API: `$props()`, `$state()`, `$derived()`, `$effect()`) - **Language:** TypeScript (strict mode) - **Styling:** Tailwind CSS 4.x (Vite plugin, not PostCSS) - **Database:** PostgreSQL via Prisma 7.x (driver adapter with `pg` pool) - **Auth:** `better-auth` with email/password + Google OAuth - **Rich Text:** TipTap 3.x - **Runtime:** Node.js 22, deployed via `@sveltejs/adapter-node` ## Common Commands ```bash npm run dev # Start dev server npm run build # Production build npm run check # Type-check (svelte-kit sync + svelte-check) npm run lint # Prettier check + ESLint npm run format # Auto-format with Prettier npm run test # Run all tests once (vitest --run) npm run test:unit # Run tests in watch mode (vitest) npx vitest run src/path/to/file.spec.ts # Run a single test file npm run migrate -- --name # Create a new Prisma migration npm run deploy # Apply pending Prisma migrations ``` ## Architecture ### Routing & Auth Guard - `src/routes/(protected)/` — route group requiring authentication. The `+layout.server.ts` in this group checks `locals.user` against the DB and throws 403 if missing. - `src/routes/account/setup/` — intentionally outside `(protected)` so logged-in users without a profile can complete setup. - `src/hooks.server.ts` — runs `auth.api.getSession()` on every request, injecting `session` and `user` into `event.locals`. ### Server/Client Split - Auth config: `src/lib/auth.ts` (server) / `src/lib/auth-client.ts` (client) - DB access: `src/lib/db.ts` (server-only) — creates a `pg` pool with optional SSL via `DO_CA_CERTIFICATE` env var for DigitalOcean managed DB. - Prisma generated client outputs to `src/lib/generated/prisma/` (gitignored). ### Key Patterns - **Svelte 5 runes throughout** — use `$props()`, `$state()`, `$derived()`, `$effect()` (not Svelte 4 reactivity). - **SvelteKit form actions** for mutations (create/edit affirmations, registration, account setup). - **Reusable forms** — `AffirmationForm.svelte` is shared between create and edit via an `action` prop. - **API routes** at `src/routes/api/v1/` (affirmations, license keys). ### Database Schema Core models: `User`, `Profile` (1:1 with User), `Address` (belongs to Profile), `Session`, `Account` (OAuth), `UserRole`, `Affirmation`, `SolfeggioFrequency`, `AffirmationCategory`, `LicenseKey`. Schema lives in `prisma/schema.prisma`. ## Testing Vitest 4.x with two project configurations in `vite.config.ts`: - **`client`** — browser tests (Playwright/Chromium) matching `*.svelte.{test,spec}.{js,ts}` - **`server`** — Node environment tests matching `*.{test,spec}.{js,ts}` (excludes `.svelte.*`) Global config: `expect: { requireAssertions: true }`. ## Code Style - **Prettier:** tabs, single quotes, no trailing commas, semicolons, 100 char width - **ESLint:** flat config with typescript-eslint + eslint-plugin-svelte - Svelte files parsed with `prettier-plugin-svelte`; class sorting via `prettier-plugin-tailwindcss` ## Deployment - Containerized via Dockerfile (multi-stage, Node 22 Alpine) - CI/CD: GitHub Actions on push to `main` → Podman build → deploy with `--network=host` - Hosted on DigitalOcean (managed PostgreSQL with SSL, self-hosted runner) - Production `.env` mounted from `/mnt/volume_nyc3_01/Portal/.env` ## Environment Variables Required: `DATABASE_URL`, `BETTER_AUTH_SECRET`, `BETTER_AUTH_URL`, `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`. Optional: `DO_CA_CERTIFICATE` (path to CA cert for managed DB SSL).