Layout-Fix Satz-Zeile (mobil), README knapp/oeffentlich, Roadmap aktualisiert
Image bauen und in die Registry schieben / build (push) Successful in 6s

- ex-grid: minmax(min(460px,100%),1fr) -> keine 460px-Mindestspalte auf dem
  Handy mehr; Block und X-Button nicht mehr abgeschnitten
- Satz-Zeile: Aktionen (Reset/X) rechtsbuendig per flexiblem Spacer; auf
  sehr schmalen Handys kompaktere Felder (72px)
- README: gekuerzt, bodenstaendiger Ton, interne CI/CD-/Infra-Notizen raus
- ROADMAP: Umgesetztes markiert, veraltete Punkte entfernt, gestrafft
- Tests: 169 Checks gruen (39+18+52+32+28)
This commit is contained in:
AI-Agent committed 2026-10-05 11:24:51 +00:00
1 parent 1759da8437
commit 7c5045cec8
4 files changed
+92 -136

No files matched your search

+37 -87
View File
@@ -1,135 +1,85 @@
# REKORD # REKORD
**Rekord & Record: dein Training, festgehalten.** Selbstgehosteter Trainings-Tracker für Gym, Laufen und Radfahren. Läuft im
Browser, speichert auf deinem Server, gehört dir.
Ein leichtgewichtiger, selbst gehosteter Trainings-Tracker fürs Gym, Laufen Eine SQLite-Datei als Zustand, ein Python-Backend aus der Standardbibliothek,
und Radfahren. Läuft in jedem modernen Browser, speichert auf deiner Platte ein HTML/CSS/JS-Frontend ohne Framework. Kein Cloud-Konto, keine Telemetrie.
und wertet deine Fitnessdaten nicht aus. Kein Abo, kein Konto bei einem
Anbieter, keine Datenkraken.
## Warum REKORD? ## Was es kann
- **Kein Vendor Lock-in.** Alles läuft bei dir: Backend auf deinem Server,
Zustand in einer portablen SQLite-Datei. Export jederzeit als JSON oder
CSV, Import genauso. Zieh um oder hör auf - deine Daten gehören dir.
- **Leichtgewichtig.** Python-Standardbibliothek + SQLite im Backend, ein
HTML-, ein CSS-, ein JS-File im Frontend. Kein Framework, kein
Build-Schritt, keine Node-Installation. Läuft auf einem Mini-PC, einem
alten Laptop oder in einem Container.
- **Browserbasiert.** Keine App, kein Store, keine Installation. Aufschlagen,
loslegen - auf jedem Gerät mit Browser.
- **Cross-Device Sync.** Der Zustand liegt serverseitig. Öffne die App am
Handy, am Laptop oder am Desktop-Rechner - es ist derselbe Stand. Mehrere
Benutzer mit eigenen Konten und getrennten Daten sind eingebaut.
- **UX zuerst.** Sätze eintragen mit einer Box (Zahl + Einheit in einem
Feld), Set-Kette durch Abhaken, "Alles zurücksetzen", Verlauf inline
bearbeiten, Wochenübersicht, Statistik mit Differenz zur ersten Messung.
Der Tracker reibt sich nicht in den Weg zwischen dich und die Übung.
- **Dein Take aufs Aufzeichnen.** Die App zeichnet auf - Gewichte, Reps,
Cardio-Felder - und zeigt die Entwicklung über die Zeit. Sie verkauft
nichts, personalisiert nichts und schickt nichts nach Hause.
- **Open Source.** AGPL-3.0. Nachvollziehbar, erweiterbar, auditierbar.
## Features im Überblick
**Training erfassen** **Training erfassen**
- Gym mit Push/Pull/Legs (frei konfigurierbar) plus Laufen und Radfahren - Gym mit Push/Pull/Legs (frei konfigurierbar), dazu Laufen und Radfahren
- Eingabe als eine Box: Zahl links, Einheit fest rechts (kg, reps, km, min, - Eingabe als eine Box: Zahl links, Einheit fest rechts (kg, reps, km, min,
min/km, bpm, m) min/km, bpm, m)
- Set-Abhaken als "Set n [ ]": der ganze Button ist klickbar, das Set hakt - Sätze abhaken als "Set n [ ]"; der ganze Button ist klickbar, die Kette
eine Kette ab - ohne Lücken hakt ohne Lücken ab
- Reset-Satz und "Alles zurücksetzen" laden das letzte abgeschlossene - "Reset-Satz" und "Alles zurücksetzen" holen das letzte abgeschlossene
Training Training; optional startet eine Session direkt mit dem letzten Workout
- Vorbefüllung beim Start (optional): "Letztes Training vorbefüllen" oder oder mit den Plan-Gewichten
"Plan-Gewichte vorbefüllen" (startKg aus der Config, auch ohne Verlauf)
- Übungen per Drag & Drop sortieren, Übungen aus anderen Tagen spontan - Übungen per Drag & Drop sortieren, Übungen aus anderen Tagen spontan
hinzufügen hinzufügen
- Fragezeichen pro Übung: Erklärung plus die passende Maschine - Fragezeichen pro Übung: kurze Erklärung (herstellerunabhängig)
**Sessions & Verlauf** **Verlauf & Statistik**
- "Session starten" / "Session abschließen", mehrere Sessions am Tag - "Session starten" / "Session abschließen", mehrere Sessions am Tag
- Keine Geister: erst abgeschlossene Sessions erscheinen im Verlauf - Verlauf als Liste oder Wochenübersicht; inline bearbeitbar und löschbar
- Verlauf als Liste oder Wochenübersicht, inline bearbeitbar (Datum, Zeiten, - Statistik: bestes Gewicht je Trainingstag, Differenz zur ersten Messung
Abhak-Status, Werte) und löschbar
- Statistik: bestes Gewicht je Trainingstag mit Balken, Differenz zur ersten
Messung
**Ansicht & Einstellungen** **Ansicht & Einstellungen**
- Deutsch und Englisch (Server-Standard und pro Benutzer) - Deutsch und Englisch
- Farbthema: Dunkel, System (folgt dem Gerät), Hell - plus OLED-Dark-Schalter - Themes: Dunkel, System, Hell - plus OLED-Dark-Schalter
- Akzentfarbe aus zehn Farben (inklusive Weiß) - Akzentfarbe aus zehn Farben, Gewichtseinheit kg/lb, Start-Ansicht wählbar
- Gewichtseinheit kg oder lb, Start-Ansicht wählbar - Einstellungen liegen serverseitig, gelten auf allen Geräten
- Einstellungen serverseitig, gelten auf allen Geräten
**Mehrbenutzer** **Mehrbenutzer**
- Eigene Konten mit Kennwort (gehasht), Daten strikt getrennt - Konten mit Kennwort (gehasht), Daten getrennt pro Benutzer
- Der erste Benutzer ist Administrator und verwaltet Konten und Kennwörter - Der erste Benutzer ist Administrator und verwaltet Konten und Kennwörter
- Einmaliger Einrichtungs-Wizard beim ersten Start (Sprache, Modus,
Darstellung)
**Daten** **Daten**
- Export/Import als JSON und CSV (Backup, Umzug, Tabellen-Auswertung) - Export/Import als JSON und CSV (Backup, Umzug, Tabellen-Auswertung)
- Workouts über eine kleine API abrufbar (`/api/workouts`) - Workouts über eine kleine API (`/api/workouts`)
- Demo-Daten (`demo-data.json`) zum direkten Ausprobieren - Demo-Verlauf (`demo-data.json`) zum Ausprobieren
## Schnellstart ## Starten
Python (nur Standardbibliothek, kein `pip install`): Python (nur Standardbibliothek):
```bash ```bash
python3 server.py 8080 python3 server.py 8080
``` ```
Oder mit Docker: Oder Docker:
```bash ```bash
docker compose up -d docker compose up -d
``` ```
Danach im Browser: `http://<host>:8080/` Danach im Browser: `http://<host>:8080/`. Beim ersten Start führt ein kurzer
Wizard durch Sprache, Einzel- oder Mehrbenutzermodus und Darstellung.
Beim ersten Start führt dich ein kurzer Wizard durch Sprache, Einzel- oder ## Plan anpassen
Mehrbenutzermodus und Darstellung - danach ist die App einsatzbereit.
## Den Übungsplan anpassen Übungen, Sätze, Gewichte und Erklärungen stehen in `config.json` - ohne
Code-Eingriff. Schema: [TECH.md](TECH.md).
Alle Übungen, Sätze, Gewichte, Maschinen und Erklärungen stehen in ## Daten
`config.json` - ohne Code-Eingriff. Das komplette Schema steht in der
[technischen Dokumentation](TECH.md).
## Automatischer Build (CI/CD)
Ein Push auf `main` baut automatisch ein Docker-Image und legt es in der
Gitea-Registry ab (`git.somantis.net/j4stmarkus/trainingsplan`). Dafür läuft
ein Gitea-Actions-Runner auf dem Server; die Workflow-Datei liegt unter
`.gitea/workflows/build-image.yml`. Die CasaOS-Installation
(`docker-compose.casaos.yml`) bezieht die App aus diesem Registry-Image.
Fürs lokale Entwickeln bleibt `docker-compose.yml` mit `build: .` bestehen.
## Daten & Privatsphäre
- Alles liegt in `data/state.db` (SQLite) - backupbar, überlebt Neustart und - Alles liegt in `data/state.db` (SQLite) - backupbar, überlebt Neustart und
Container-Rebuild Container-Rebuild
- Datenverzeichnis frei wählbar (`TRAINING_STATE_DIR`) - Datenverzeichnis per `TRAINING_STATE_DIR` frei wählbar
- Keine externen Dienste, keine Telemetrie, keine Analyse deiner Daten - Keine externen Dienste, keine Telemetrie
## Roadmap ## Mehr
Die geplante Weiterentwicklung (Übungskatalog in der App bearbeiten, - [TECH.md](TECH.md) - Architektur, API, Datenmodell
herstellerunabhängige Info-Texte mit Bildern/Schritten, Plugin-System mit - [DESIGN.md](DESIGN.md) - Design-Sprache (Tokens, Komponenten, Anti-Patterns)
Ollama/Cloud-Coach, Wearable-Import, CLI-Harness) steht in - [ROADMAP.md](ROADMAP.md) - geplante Erweiterungen
[ROADMAP.md](ROADMAP.md).
## Design
Die verbindliche Design-Sprache (Tokens, Komponenten, Zustaende, Anti-
Patterns) steht in [DESIGN.md](DESIGN.md) - wiederverwendbar für weitere
Projekte.
## Lizenz ## Lizenz
+46 -47
View File
@@ -1,63 +1,62 @@
# REKORD - Roadmap # REKORD - Roadmap
Interne Roadmap. Prioritaeten: P1 = naechste Iterationen, P2 = bald, P3 = Was geplant ist, und was schon steht. Priorität: P1 = als Nächstes, P2 = bald,
spaeter. Status: Idee / Geplant / In Arbeit / Fertig. P3 = später. Status: Fertig / Teilweise / Geplant.
Zielrichtung: breiteres Feature-Set, einfachere Erweiterung des Leitplanken bleiben: config-getrieben, leichtgewichtig, Daten lokal, keine
Uebungs-/Maschinen-Katalogs, herstellerunabhaengige Inhalte, sanfte Telemetrie.
Integration (Plugins, lokale Modelle) statt Monolithen. Architektur-Leitplanken
bleiben: Config-getrieben, leichtgewichtig, Daten lokal, keine Telemetrie.
--- ## Umgesetzt
## Phase 1 - Inhalte & Bedienbarkeit - Config-getriebener Plan (`config.json`), SQLite-Zustand serverseitig
- Gym (Push/Pull/Legs), Laufen, Radfahren; Cardio-Felder aus der Config
- Set-Kette, Reset-Satz, "Alles zurücksetzen", Vorbefüllung (letztes Workout
oder Plan-Gewichte)
- Übungen per Drag & Drop sortieren, Übungen aus anderen Tagen hinzufügen
- Verlauf als Liste und Wochenübersicht, Inline-Bearbeitung, Löschen
- Statistik: bestes Gewicht je Tag, Differenz zur ersten Messung
- Mehrbenutzer mit Admin, Kennwort ändern/zurücksetzen, Server-Reset
- Einrichtungs-Wizard (Sprache, Darstellung, Modus)
- i18n de/en, Themes dunkel/system/hell + OLED, zehn Akzentfarben
- Export/Import JSON/CSV, Workouts-API, Demo-Daten
- Übungs-Infos herstellerunabhängig; mobile-taugliche Satz-Zeile
| Prioritaet | Thema | Status | Notiz | ## Offen
### Inhalte & Bedienbarkeit
| Prio | Thema | Status | Notiz |
|---|---|---|---| |---|---|---|---|
| P1 | **Uebungen/Maschinen in der App bearbeiten** | Idee | Heute aendert man `config.json` von Hand. Ziel: Uebungen, Tage, Maschinen und Info-Texte direkt in der App anlegen/bearbeiten (persistiert neben der Config), damit ein Nicht-Programmierer den Plan ohne Dateieditor pflegt. | | P1 | Übungen/Maschinen in der App bearbeiten | Geplant | Statt `config.json` von Hand: Übungen, Tage und Info-Texte direkt in der App pflegen. |
| P1 | **Info-Texte erweitern** | Idee | Neben dem Freitext: optionale Bilder (URL oder Upload), Schritte als Checkliste, ein "wertvoller Link" (z.B. zu einer neutralen Anatomie-/Form-Quelle). Wichtig: **nicht hersteller-spezifisch** - die Technogym-Referenzen aus der Config sind nur Platzhalter; der Katalog soll generisch sein. | | P1 | Info-Texte erweitern | Geplant | Optional Bilder, Schritte als Checkliste, ein Link (neutral, nicht herstellerspezifisch). |
| P1 | **Uebungsvarianten & Maschinen-Tags** | Idee | Eine Uebung mit mehreren Varianten (KH, Maschine, Kabel) und deren Verfuegbarkeit; beim Training schnell zwischen den Geräten wechseln, die im Studio stehen. | | P1 | Übungsvarianten & Maschinen-Tags | Geplant | Eine Übung mit Varianten (KH, Maschine, Kabel) und schnellem Wechsel im Training. |
| P1 | **Set-Vorlagen pro Uebung** | Idee | Im Plan definierte Satz-Vorlagen (Anzahl, Ziel-Reps, Pause) als Startpunkt - schon teilweise da ("Plan-Gewichte vorbefuellen"), aber noch nicht pro Satz steuerbar. | | P2 | Set-Vorlagen pro Übung | Teilweise | Plan-Gewichte vorbefüllen gibt es; noch nicht pro Satz steuerbar (Ziel-Reps, Pause). |
| P2 | **Gewichtseinheiten pro Uebung** | Idee | z.B. Bodyweight (kein kg), Bandwiderstand, Maschinen-Gewicht inkl. Hebel - neben dem globalen kg/lb. | | P2 | Einheiten pro Übung | Geplant | Bodyweight, Band, Maschinen-Gewicht - neben dem globalen kg/lb. |
## Phase 2 - Integration & Automation ### Integration
| Prioritaet | Thema | Status | Notiz | | Prio | Thema | Status | Notiz |
|---|---|---|---| |---|---|---|---|
| P1 | **Plugin-System** | Idee | Kleine Plugins (JS im Browser und/oder Server-Skripte) mit klaren Hooks: nach Session-Speichern, beim Export, beim Anzeigen einer Uebung, beim Abschluss. Registrierung in der Config. So bleiben Erweiterungen ausserhalb des Kerns. | | P1 | Plugin-System | Geplant | Kleine Plugins mit Hooks (nach Session-Speichern, beim Export, beim Anzeigen). |
| P1 | **Ollama/Cloud-Coach** | Idee | Plugin, das Form-Tipps/Zusammenfassungen per API generiert - **local-first** (Ollama), Cloud nur mit expliziter Zustimmung und eigener Wahl des Anbieters/Keys. Keine Daten gehen ohne Erlaubnis nach aussen. | | P1 | Ollama/Cloud-Coach | Geplant | Form-Tipps/Zusammenfassungen per API - local-first (Ollama), Cloud nur auf Wunsch. |
| P2 | **Webhooks bei Events** | Idee | Nach "Session abgeschlossen", "Benutzer angelegt" etc. - fuer eigene Automation (Backup, Benachrichtigungen, Hausautomation). | | P2 | Webhooks bei Events | Geplant | Nach "Session abgeschlossen" o.ä. für eigene Automation. |
| P2 | **API-Keys pro Benutzer** | Idee | Neben den Login-Tokens: eigene read/write Keys pro Benutzer fuer Scripts, ohne das Konto freizugeben. | | P2 | API-Keys pro Benutzer | Geplant | Read/write Keys für Scripts, ohne das Konto freizugeben. |
| P2 | **Effizienter Harness (CLI)** | Idee | Kleines Kommandozeilen-/Script-Interface (`rekord`-CLI oder Python-Client) gegen die API: Workouts eintragen/abrufen, Statistiken ziehen - fuer Cron-Jobs, TUI, Automation. | | P2 | CLI-Harness | Geplant | Kleines Kommandozeilen-Interface gegen die API (Cron, TUI). |
| P3 | **Wearable-Import** | Idee | Garmin/Apple/Fitbit/Samsung-Health-Exporte (CSV/JSON) als Plugin importieren; Puls etc. an Cardio-Sessions anhaengen. Kein Live-Sync in Phase 1. | | P3 | Wearable-Import | Geplant | Garmin/Apple/Fitbit/Samsung-Exporte (CSV/JSON) als Plugin. |
## Phase 3 - Analyse & UX ### Analyse & UX
| Prioritaet | Thema | Status | Notiz | | Prio | Thema | Status | Notiz |
|---|---|---|---| |---|---|---|---|
| P1 | **Volumen & 1RM-Schaetzung** | Idee | Trainingsvolumen (kg × Reps) je Uebung/Tag, 1RM-Schaetzung (z.B. Epley) als zusaetzliche Statistik-Kennzahl. | | P1 | Volumen & 1RM-Schätzung | Geplant | kg × Reps je Übung/Tag, 1RM-Schätzung als zusätzliche Kennzahl. |
| P2 | **Wochenvergleich & Trends** | Idee | Statistik ueber Wochen hinweg (nicht nur "Differenz zur ersten Messung"): gleitende Durchschnitte, PR-Markierungen, Verlaufs-Graph (ohne externe Chart-Lib, wenn moeglich). | | P2 | Wochenvergleich & Trends | Geplant | Gleitende Durchschnitte, PR-Markierungen, Verlauf ohne Chart-Lib. |
| P2 | **PWA / Offline** | Idee | Als installierbare App (Service Worker, App-Icon) - nicht kritisch, da serverseitig, aber schoener auf dem Handy. | | P2 | PWA / Offline | Geplant | Installierbar auf dem Handy (Service Worker, Icon). |
| P2 | **Sessions am selben Tag bessern** | Idee | Mehrere Sessions pro Tag sind drin; UX fuer "morgens laufen, abends Gym" vereinfachen (schneller Aktivitaets-/Tag-Wechsel). | | P2 | Mehrere Sessions am Tag | Teilweise | Funktioniert; Aktivitäts-/Tag-Wechsel im UI vereinfachen. |
## Phase 4 - Qualitaet & Betrieb ### Qualität
| Prioritaet | Thema | Status | Notiz | | Prio | Thema | Status | Notiz |
|---|---|---|---| |---|---|---|---|
| P2 | **Barrierefreiheit (a11y)** | Idee | Tastatur-Navigation, Kontraste, Screenreader-Labels systematisch pruefen. | | P2 | Barrierefreiheit | Teilweise | Fokus, Kontraste, Labels gepflegt; systematischer Test offen. |
| P2 | **Backup/Retention** | Idee | Automatische Export-Erinnerung oder in-App-Backup-Timer; Dokumentation fuer Rotation. | | P2 | Backup/Erinnerung | Geplant | Export gibt es; automatische Backup-Erinnerung offen. |
| P3 | **Mehrsprachigkeit ausbauen** | Idee | i18n-Architektur ist da (de/en); weitere Sprachen als Community-Beitrag. | | P3 | Weitere Sprachen | Geplant | i18n-Architektur (de/en) steht; weitere Sprachen als Beitrag. |
| P3 | **Mehr-Server / Replikation** | Idee | Datenhaltung bleibt SQLite; falls noetig: Import/Export als Synchronisationsweg dokumentieren statt Live-Replikation. |
---
## Konzepte in einem Satz
- **Content in der App statt in der Datei** - der Uebungskatalog wird Teil des
Produkts, nicht des Repos.
- **Herstellerunabhaengig** - Maschinen-Referenzen sind Hinweise, keine
Abhaengigkeit; Links/Medien sind optional und austauschbar.
- **Plugins statt Kern-Zerfaserung** - alles, was nicht jeder braucht
(Coach, Sync, Import), wird Plugin.
- **Local-first** - lokale Modelle (Ollama) sind der Default, Cloud nur auf
ausdruecklichen Wunsch.
+1
View File
@@ -931,6 +931,7 @@ function buildSetRow(a, model, ex, entry, i) {
row.appendChild(rBox); row.appendChild(rBox);
entry.wInput = wBox.querySelector("input"); entry.wInput = wBox.querySelector("input");
entry.rInput = rBox.querySelector("input"); entry.rInput = rBox.querySelector("input");
row.appendChild(el("span", "set-gap"));
const reset = el("button", "icon-btn", ""); const reset = el("button", "icon-btn", "");
reset.type = "button"; reset.type = "button";
+8 -2
View File
@@ -405,7 +405,7 @@ h3 { font-size: 15px; font-weight: 700; }
.ex-grid { .ex-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(460px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(min(460px, 100%), 1fr));
gap: 14px; gap: 14px;
align-items: start; align-items: start;
} }
@@ -438,12 +438,18 @@ h3 { font-size: 15px; font-weight: 700; }
.set-row { .set-row {
display: grid; display: grid;
grid-template-columns: auto auto auto auto auto; grid-template-columns: auto auto auto 1fr auto auto;
gap: 6px; gap: 6px;
align-items: center; align-items: center;
padding: 6px 8px; padding: 6px 8px;
} }
.set-gap { min-width: 0; }
@media (max-width: 480px) {
.field-box { width: 72px; }
}
.set-rows { overflow: hidden; } .set-rows { overflow: hidden; }
.set-row.is-done { background: var(--bg-subtle); } .set-row.is-done { background: var(--bg-subtle); }