fooder-app/CLAUDE.md
2026-04-02 15:21:05 +02:00

2.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

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:

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.