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>
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_URLinfrontend/.env. Default ist die produktive Instanzhttps://api.stammtisch-hersbruck.de; für das lokale Backend ausbackend/aufhttp://127.0.0.1:8090umstellen. - Schema: versioniert als Migration in
backend/pb_migrations/, kommt perCOPYins 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 mitdocker compose cpins Repo geholt werden; siehebackend/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.tswith theAuthStoreclass - 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:
-
Global stores in
src/lib/stores/:pocketbase.svelte.ts: PocketBase client, auth, and collection operationsapp.svelte.ts: Global app state (theme, navigation, confirm dialogs, hotkeys)teams.svelte.ts: Example of collection-specific store pattern
-
Collection store pattern:
- Each collection has a context-based store (see
teams.svelte.tsas template) - Use
setTeamContext()in parent andgetTeamContext()in children - Stores provide:
records,refresh(),create(),edit(),remove() - The
collectionshelper inpocketbase.svelte.tsprovides reusable CRUD operations
- Each collection has a context-based store (see
-
Auth flow:
- Auth state lives in
authstore frompocketbase.svelte.ts - Cookie-based persistence available via
auth.cookieflag - Auth store syncs with PocketBase
authStore.onChange()
- Auth state lives in
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-watcherpackage, toggle withtoggleMode() - Tooltips: Global
tooltipaction available fromapp.svelte.tsusing tippy.js
Important Patterns
Svelte 5 Runes: This project uses Svelte 5 syntax exclusively:
$state()for reactive state (notletwith$:)$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) undbackend/(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.tsextension for Svelte 5 runes - Static assets in
static/ components.jsonconfigures 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
collectionshelper for consistency - UI components should use the shadcn-svelte imports from
@/components/ui/