stammtisch-hersbruck/CLAUDE.md
Daniel Michelberger 1061a8b9ad chore: Repo-Struktur mit frontend/ und backend/ aufsetzen
Die SvelteKit-App liegt unter frontend/, das Backend unter backend/ als
eigenständige PocketBase-Instanz mit Dockerfile, docker-compose und
versioniertem Schema.

- PocketBase-URL über PUBLIC_PB_URL konfigurierbar, Default bleibt die
  produktive Instanz https://api.stammtisch-hersbruck.de
- Schema als Snapshot-Migration der sechs fachlichen Collections
  (users, teams, events, runs, riders, times), abgezogen von der
  produktiven Instanz. Verifiziert: ein Erststart gegen leere pb_data
  legt alle sechs an, Felder und API-Rules stimmen überein.
- pb_data und pb_migrations als Bind-Mounts, damit Daten persistieren und
  im Admin-UI erzeugte Migrationen im Repo landen
- Veraltete Dokumentation entfernt: pocketbase_schema.json nannte
  Collections (stages, results, organizers), die es nicht gibt

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

5 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/. Änderungen im Admin-UI erzeugen dort neue Dateien, die committet werden müssen.
  • 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/