stammtisch-hersbruck/CLAUDE.md
Daniel Michelberger 132ce04e0c fix: pb_migrations nicht mounten — Deployment startete ohne Collections
Der in 22cd427 ergänzte Bind-Mount ./pb_migrations:/pb/pb_migrations
überdeckt das Verzeichnis aus dem Image. Auf einem Deployment-Host, neben
dessen compose-Datei kein ausgechecktes Repo liegt, legt Docker dort ein
leeres Verzeichnis an: PocketBase findet keine Migration und startet mit
einer Datenbank ohne Collections. Genau das ist auf der neu deployten
Instanz passiert — users war da (legt PocketBase selbst an), events, teams,
riders, runs und times fehlten.

Reproduziert und beide Richtungen verifiziert: mit leerem Mount 404 auf
allen fünf Collections, ohne Mount kommen alle sechs aus dem Image.

Die Migrationen kommen damit wieder ausschließlich über COPY ins Image. Der
Preis ist der Weg zurück: Im Admin-UI erzeugte Migrationen liegen nur im
Container und müssen mit "docker compose cp" ins Repo geholt werden. Das
steht jetzt in backend/README.md und CLAUDE.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 14:06:30 +02:00

5.2 KiB

CLAUDE.md

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

Project Overview

stammtisch-hersbruck.de is a SvelteKit 5 application using Svelte 5's new runes syntax ($state, $props, etc.) with PocketBase as the backend. The app manages events, runs, riders, times and teams for a motorsport/cycling event organization.

The repository is a monorepo: the SvelteKit app lives in frontend/, the PocketBase instance in backend/.

Development Commands

Alle Frontend-Befehle laufen aus frontend/:

cd frontend

# Start development server (runs on http://stammtisch-hersbruck.de.localhost:31337)
npm run dev

# Build for production
npm run build

# Preview production build
npm run preview

# Type-check Svelte files
npm run check

# Type-check with watch mode
npm run check:watch

# Generate TypeScript types from PocketBase schema
npm run generate-pocketbase-types

Backend (PocketBase) aus backend/:

cd backend

# PocketBase lokal starten (Admin-UI auf http://127.0.0.1:8090/_/)
docker compose up -d --build

# Stoppen
docker compose down

Architecture

Backend Integration (PocketBase)

  • API Base URL: konfigurierbar über PUBLIC_PB_URL in frontend/.env. Default ist die produktive Instanz https://api.stammtisch-hersbruck.de; für das lokale Backend aus backend/ auf http://127.0.0.1:8090 umstellen.
  • Schema: versioniert als Migration in backend/pb_migrations/, kommt per COPY ins Image (kein Bind-Mount — der würde das Image-Verzeichnis überdecken). Im Admin-UI erzeugte Migrationen liegen deshalb zunächst nur im Container und müssen mit docker compose cp ins Repo geholt werden; siehe backend/README.md.
  • Type-safe client: The PocketBase client is typed using auto-generated types in frontend/src/lib/types.d.ts
  • Collections: users, teams, events, runs, riders, times
  • Authentication: Handled through src/lib/stores/pocketbase.svelte.ts with the AuthStore class
  • File handling: Use getFileURL(record, file, options) helper for PocketBase file URLs

State Management Pattern

The app uses Svelte 5 runes for state management with a custom store pattern:

  1. Global stores in src/lib/stores/:

    • pocketbase.svelte.ts: PocketBase client, auth, and collection operations
    • app.svelte.ts: Global app state (theme, navigation, confirm dialogs, hotkeys)
    • teams.svelte.ts: Example of collection-specific store pattern
  2. Collection store pattern:

    • Each collection has a context-based store (see teams.svelte.ts as template)
    • Use setTeamContext() in parent and getTeamContext() in children
    • Stores provide: records, refresh(), create(), edit(), remove()
    • The collections helper in pocketbase.svelte.ts provides reusable CRUD operations
  3. Auth flow:

    • Auth state lives in auth store from pocketbase.svelte.ts
    • Cookie-based persistence available via auth.cookie flag
    • Auth store syncs with PocketBase authStore.onChange()

UI Components

  • UI Library: Using shadcn-svelte components (bits-ui based)
  • Component path alias: @/components/ui/* maps to $lib/components/ui/*
  • Styling: Tailwind CSS 4.x with custom configuration
  • Dark mode: Handled by mode-watcher package, toggle with toggleMode()
  • Tooltips: Global tooltip action available from app.svelte.ts using tippy.js

Important Patterns

Svelte 5 Runes: This project uses Svelte 5 syntax exclusively:

  • $state() for reactive state (not let with $:)
  • $props() for component props
  • $derived() for computed values
  • {@render children?.()} for slot content

Type Generation: After modifying PocketBase schema, run npm run generate-pocketbase-types to update TypeScript types.

Async Data Loading: Root layout (src/routes/+layout.svelte) shows pattern:

{#await load()}
  <!-- loading state -->
{:then _}
  <!-- main content -->
{/await}

Confirm Dialogs: Use app.confirm.request() for user confirmations (see events.svelte.ts remove pattern).

Hotkeys: Use app.hotkey(event, condition, callback) which auto-ignores input fields and contenteditable elements.

Project Configuration

  • Repo-Struktur: Monorepo mit frontend/ (SvelteKit) und backend/ (PocketBase). Ein einziges Git-Repo im Root.
  • Dev server port: 31337 (strict mode, custom domain: stammtisch-hersbruck.de.localhost)
  • Path alias: @/* resolves to ./src/lib/* (configured in frontend/svelte.config.js)
  • Adapter: @sveltejs/adapter-auto (auto-detects deployment platform)

File Structure Notes

  • Routes are in src/routes/ following SvelteKit conventions
  • Reusable components in src/lib/components/
  • Stores use .svelte.ts extension for Svelte 5 runes
  • Static assets in static/
  • components.json configures shadcn-svelte CLI

When Working with This Codebase

  • Always use Svelte 5 runes syntax, never legacy Svelte syntax
  • Use the official Svelte MCP server to validate Svelte code
  • Collection stores should follow the pattern in teams.svelte.ts
  • PocketBase operations go through the collections helper for consistency
  • UI components should use the shadcn-svelte imports from @/components/ui/