Files
krafttrainer/CLAUDE.md
Christoph K. 833ad04a6f Add delete session functionality
- DELETE /api/v1/sessions/{id}: only closed sessions, user-scoped
- Returns 404 if not found/wrong user, 409 if session still open
- Deletes session_logs first, then session (no CASCADE)
- Frontend: trash button per session in SessionList (closed sessions only)
- Confirm dialog before delete, toast feedback, list reloads after

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 20:50:48 +01:00

95 lines
4.1 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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"`, `"SESSION_OPEN"`, `"SESSION_NOT_FOUND"`. 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
- Hard-Delete bei Sessions: löscht zuerst explizit `session_logs`, dann `sessions` (kein ON DELETE CASCADE)
## 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.24.3)
- Komplette API-Spezifikation mit Request/Response-Beispielen (Abschnitt 5)
- Validierungsregeln (Abschnitt 6)
- Frontend-Spezifikation und Komponentenverhalten (Abschnitt 7)