# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands ```bash npm run dev # Start Vite dev server (port 5173) npm run build # Build production bundle npm run preview # Preview production build npm run check # Svelte type checker npm run check:watch # Type checker in watch mode ``` Docker: ```bash docker-compose up # Dev server with hot reload (port 5173) ``` There are no test commands — this project has no test suite. ## Architecture **Fooder** is a Svelte 5 + SvelteKit PWA for tracking food/calories and macronutrients. It's a fully client-side SPA (static adapter, SSR disabled) that communicates with a backend API at `/api`. ### Routing SvelteKit file-based routing with two route groups: - `(auth)/` — public login/register pages - `(app)/` — protected pages guarded by auth check in `src/routes/(app)/+layout.svelte` Main routes: `/diary/[date]` (primary view), `/diary/[date]/add-entry`, `/diary/[date]/edit-entry/[entry_id]`, `/presets`, `/products/new`. ### State Management Three layers: 1. **Auth** (`$lib/auth/store.svelte.ts`) — Svelte 5 runes-based store holding `accessToken`, `user`, and refresh token (localStorage). 2. **Server data** — TanStack Svelte Query with 30s stale time. Cache keys follow `['diary', date]`, `['products']`, etc. 3. **Offline** (`$lib/offline/`) — Network status in `network.svelte.ts`; IndexedDB (via `idb`) in `db.ts` for persistent cache and mutation queue. ### Offline-First Pattern When offline, mutating functions in `$lib/offline/mutations.ts`: 1. Generate a temporary entry with a negative ID as an optimistic placeholder 2. Update the TanStack Query in-memory cache immediately 3. Persist the change to IndexedDB (survives reload) 4. Enqueue the real API call in an IndexedDB mutation queue On reconnect, `$lib/offline/sync.ts` replays the queue FIFO. Sync stops on first failure to preserve consistency; malformed requests are dropped to unblock the queue. ### API Layer `$lib/api/client.ts` is the core fetch wrapper. It handles: - JWT access token injection and automatic refresh with deduplication (prevents simultaneous refresh races) - Offline detection: write mutations are queued via the offline system instead of failing - Auth endpoints (`/token/*`) are never queued — they require a live response ### Key Technologies | Purpose | Library | |---------|---------| | Framework | Svelte 5 (Runes: `$state`, `$derived`, `$props`, `$effect`) | | Meta-framework | SvelteKit 2 | | Server data cache | TanStack Svelte Query | | Styling | Tailwind CSS v4 | | Offline persistence | idb (IndexedDB wrapper) | | PWA | vite-plugin-pwa (NetworkFirst for `/api/*`) | ### Svelte 5 Runes This project uses Svelte 5 runes syntax throughout — no legacy `writable`/`readable` stores. Use `$state`, `$derived`, `$props`, and `$effect` for all reactive patterns.