94 lines
3.9 KiB
Markdown
Executable File
94 lines
3.9 KiB
Markdown
Executable File
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
# Krafttrainer
|
||
|
||
Einzelnutzer-Webapplikation zur Verwaltung und Protokollierung von Kraftübungen.
|
||
|
||
## Tech Stack
|
||
|
||
- **Backend:** Go 1.22+ mit `net/http` stdlib Router, SQLite (`go-sqlite3`), `golang-migrate`
|
||
- **Frontend:** React 19, Vite 8, TypeScript (strict), Tailwind CSS 4 (`@tailwindcss/vite`), Zustand, Recharts
|
||
- **Paketmanager:** pnpm (Version in `packageManager` field fixiert)
|
||
- **Produktion:** Single Binary via `embed` (Frontend in `backend/static/` eingebettet)
|
||
|
||
## Build & Run
|
||
|
||
```bash
|
||
make dev-backend # Go-Server auf :8090
|
||
make dev-frontend # Vite Dev-Server auf :5173 (Proxy → :8090)
|
||
make build # Single Binary ./krafttrainer (Frontend-Build + Go-Build mit CGO_ENABLED=1)
|
||
make clean # Binary + Dist-Ordner entfernen
|
||
```
|
||
|
||
Frontend TypeScript-Typecheck (ohne Build):
|
||
```bash
|
||
cd frontend && pnpm exec tsc --noEmit
|
||
```
|
||
|
||
Es gibt keine automatisierten Tests (weder Go-Tests noch Frontend-Tests).
|
||
|
||
## Deployment
|
||
|
||
- Läuft auf `192.168.1.118:8090` als systemd-Service (`krafttrainer.service`)
|
||
- User: `christoph`, Binary: `/home/christoph/krafttrainer/krafttrainer`
|
||
- DB: `/home/christoph/krafttrainer/krafttrainer.db`
|
||
- Deploy: `scp krafttrainer christoph@192.168.1.118:~/krafttrainer/`, dann `sudo systemctl restart krafttrainer`
|
||
|
||
## Architektur
|
||
|
||
### Backend-Flow
|
||
|
||
`Handler → Store → DB`. Jeder Handler folgt exakt diesem Muster:
|
||
1. `decodeJSON()` mit `DisallowUnknownFields()`
|
||
2. `model.Validate()` aufrufen
|
||
3. Store-Methode aufrufen
|
||
4. Fehler differenzieren und `writeJSON()` / `writeError()` aufrufen
|
||
|
||
Store-Methoden geben nach Mutationen immer **frisch aus der DB gelesene Objekte** zurück (kein Rekonstruieren aus Input).
|
||
|
||
### Fehlerbehandlung (Backend)
|
||
|
||
- Store-Fehler → 500 (generisch, kein DB-Leak)
|
||
- Validierungsfehler → 400
|
||
- Nicht gefunden (`sql.ErrNoRows`) → 404
|
||
- UNIQUE-Verletzung → 409
|
||
|
||
Sentinel-Strings im Error-Message für Handler-Differenzierung: `"UNIQUE_VIOLATION:"`, `"SESSION_CLOSED"`. Diese werden mit `strings.Contains()` geprüft — kein custom error type.
|
||
|
||
### Routing
|
||
|
||
Go 1.22+ Pattern-Matching im stdlib ServeMux mit `{id}`-Platzhaltern. Middleware-Chain: `Recoverer → RequestLogger → CORS`. SPA-Fallback in `main.go`: prüft zuerst ob statische Datei existiert, serviert sonst `index.html`.
|
||
|
||
### Frontend-Stores (Zustand)
|
||
|
||
Stores sind **flach und unabhängig** — keine direkte Store-zu-Store-Kommunikation. Feedback läuft ausschließlich über `useToastStore.getState().addToast()`. `activeSessionStore` verwaltet einen Timer-Interval manuell (kein React-Effect-Cleanup — beim `stopTimer()` explizit clearen).
|
||
|
||
Alle HTTP-Aufrufe gehen über `src/api/client.ts`. `ApiError` (extends Error) hat `status`-Property für HTTP-Statuscodes.
|
||
|
||
### Datenbank
|
||
|
||
- SQLite mit WAL-Mode und Foreign Keys (via Connection-String-Parameter in `store.go`)
|
||
- Migrations auto-run beim Start via embedded FS (`backend/migrations/embed.go`)
|
||
- `exercise_name` in `session_logs` **denormalisiert** gespeichert (damit gelöschte Übungen historische Daten nicht verwaisen lassen)
|
||
- UNIQUE-Constraint auf `(session_id, exercise_id, set_number)`
|
||
- Soft-Delete bei Übungen via `deleted_at` Timestamp
|
||
|
||
## Konventionen
|
||
|
||
- **API Prefix:** Alle Endpoints unter `/api/v1`. Fehler als `{ "error": "..." }`.
|
||
- **Gewichte:** Immer in kg. Feldnamen mit `_kg` Suffix (`weight_kg`, `weight_step_kg`).
|
||
- **UI-Sprache:** Deutsch.
|
||
- **Dark Mode:** Default. `bg-gray-950` Body, `bg-gray-900` Cards, `blue-500` Primary.
|
||
- **Touch-Targets:** min 44×44px.
|
||
|
||
## Vollständige Spezifikation
|
||
|
||
Siehe `PRD.md` im übergeordneten Verzeichnis (`03_Projekte/fitness-pad/PRD.md`) für:
|
||
- Vollständiges SQLite-Schema (Abschnitt 4.1)
|
||
- Alle Go-Structs und TypeScript-Typen (Abschnitt 4.2–4.3)
|
||
- Komplette API-Spezifikation mit Request/Response-Beispielen (Abschnitt 5)
|
||
- Validierungsregeln (Abschnitt 6)
|
||
- Frontend-Spezifikation und Komponentenverhalten (Abschnitt 7)
|