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

136 lines
No EOL
5 KiB
Markdown

# 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/`:
```bash
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/`:
```bash
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:
```svelte
{#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/`