claude.md
This commit is contained in:
parent
d0430adbc2
commit
85552e0f3f
1 changed files with 71 additions and 0 deletions
71
CLAUDE.md
Normal file
71
CLAUDE.md
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
# 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.
|
||||
Loading…
Reference in a new issue