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>
139 lines
No EOL
5.2 KiB
Markdown
139 lines
No EOL
5.2 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/`, 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:
|
|
```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/` |