feat: update version to 0.7.9 and enhance project documentation
Some checks failed
Deploy Development / deploy (push) Successful in 35s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 5s
Test Suite / playwright-tests (push) Failing after 1m54s

- Incremented application version to 0.7.9 and updated database schema version to 20260427030.
- Revised project status documentation to reflect recent milestones and changes, including detailed logs of implemented features and next steps.
- Enhanced API specifications for exercises, including support for exercise variants and improved query parameters.
- Updated frontend routing to streamline exercise variant management within the ExerciseFormPage.
- Implemented role-based media upload limits and refined search/filter specifications for better user experience.
This commit is contained in:
Lars 2026-04-28 16:18:25 +02:00
parent d5fbc2cd5c
commit 7134fd1a25
11 changed files with 281 additions and 191 deletions

View File

@ -1,55 +1,53 @@
# Shinkan Jinkendo - Projekt-Status
**Stand:** 2026-04-27
**Version:** 0.4.0
**Version (Code):** 0.7.9 (`backend/version.py`, APP_VERSION)
**DB-Schema-Version:** `20260427030`
**Branch:** develop
**Letzter Commit:** e8eba57
---
## Executive Summary
**Aktueller Meilenstein:** MediaWiki Import - Skills Complete
**Aktueller Meilenstein:** Übungsvarianten Ende-zu-Ende (API, DB 030, Planung, UI) sowie Listen-Suche ohne Full-Page-Reload
**Letzte Änderungen:**
- ✅ Migration 022: Skills-Schema komplett (skill_main_categories, focus_areas, level_definitions)
- ✅ Migration 023: 69 Skills importiert mit vollständiger Kategorisierung
- ✅ Duplikat-Bereinigung und Fokusbereich-Zuordnung (karate/universal)
- ✅ Scripts erstellt (parse_matrix.py, generate_migration_023_direct.py)
**Letzte dokumentierte Änderungen (April 2026):**
**Nächste Schritte:**
1. Test: Übungs-Import mit neuen Skills
2. Optional: Level-Definitionen (1-5) aus Matrix extrahieren
3. Admin-UI für Skill-Kategorien (CRUD)
4. Deployment nach Prod vorbereiten
- ✅ Migration **030**: `training_unit_exercises.exercise_variant_id` (FK zu `exercise_variants`, ON DELETE SET NULL).
- ✅ **GET `/api/exercises?include_variants=true`** für Trainingsplanung und Übersichten.
- ✅ Varianten-**CRUD** + **Reorder**; Validierung in der Trainingsplanung (Variante gehört zur Übung).
- ✅ **Übungsliste**: Filter-Chips, Modal, `listFetching` statt Full-Page-Spinner, `<datalist>`-Titel aus Treffern.
- ✅ **Medien-Upload**: rollenbasierte Limits (Standard 50 MB, Admin bis 1024 MB, Env-Vars).
- ✅ **RichTextEditor**: Selection-Restore, Listen-Styling im Editor.
**Referenz:** Ausführliche technische Liste → [`library/FEATURES_DELIVERED_2026-Q2.md`](library/FEATURES_DELIVERED_2026-Q2.md)
**Nächste Schritte (Auszug):**
1. Prod-Deployment der Migrationen **020030** und Smoke-Tests.
2. Optional: Server-Autocomplete für Suche; Progressions-Serien als Blöcke (siehe Feature-Doc).
---
## Deployed Migrations (Dev: 023, Prod: TBD)
## Deployed Migrations (Dev / Zielstand)
| Migration | Beschreibung | Dev | Prod |
|-----------|--------------|-----|------|
| 001-017 | Initial Schema + Exercise System | ✅ | ✅ |
| 001017 | Initial Schema + Exercise System | ✅ | ✅ |
| 018 | Wiki Import Tracking | ✅ | ✅ |
| 019 | Exercises Optional Fields | ✅ | ✅ |
| 020 | Exercise Skills UNIQUE Constraint | ✅ | 🔲 |
| 021 | ~~Import Skills from Matrix~~ (DEPRECATED) | ⚠️ | ❌ |
| **022** | **Skills Schema Complete** | ✅ | 🔲 |
| **023** | **Skills Complete Import (69 Skills)** | ✅ | 🔲 |
| 022 | Skills Schema Complete | ✅ | 🔲 |
| 023 | Skills Complete Import (69 Skills) | ✅ | 🔲 |
| 028029 | exercise_media / skills Stufen | ✅ | 🔲 |
| **030** | **training_unit_exercises.exercise_variant_id** | ✅ | 🔲 |
---
## Aktuelle Datenbank-Stats (Dev)
## Aktuelle Datenbank-Stats (Dev, Richtwerte)
```
Skills: 69 (32 KARATE + 37 ALLGEMEINE)
Skill Main Categories: 2 (KARATE Fähigkeiten, ALLGEMEINE sportliche Fähigkeiten)
Skill Categories: 9 (Kihon, Kumite, Kata, Selbstverteidigung, Koordination, ...)
Übungen (MediaWiki): 221 (importiert, mit Skill-Zuordnungen)
Focus Areas: 5
Style Directions: 15
Target Groups: 12
```
Die exakten Zahlen hängen von der Umgebung ab (siehe Admin/DB). Die Skills/Übungen-Importe aus früheren Meilensteinen bleiben die Datenbasis.
---
@ -58,72 +56,48 @@ Target Groups: 12
### ✅ Deployed Features (Dev)
**Kern-System:**
- [x] Auth & Profile Management
- [x] Organisation (Clubs, Divisions, Groups)
- [x] Kataloge (Focus Areas, Styles, Target Groups - M:N)
- [x] Kataloge (Focus Areas, Styles, Target Groups M:N)
**Übungen:**
- [x] CRUD (Create, Read, Update, Delete)
- [x] M:N Beziehungen (Focus Areas, Styles, Target Groups, Skills)
- [x] Varianten & Medien
- [x] Suche & Filter (erweitert)
- [x] **Varianten** (CRUD, Reorder, Voraussetzung) + Anzeige im Detail
- [x] Medien (Upload/Embed, rollenabhängige Größenlimits)
- [x] Suche & Filter (Multi-Filter, Chips, Fokus beim Suchen)
- [x] Exercise Blocks (Bausteine)
- [x] Saved Searches
- [x] Saved Searches (wo implementiert)
**Trainingsplanung:**
- [x] Training Units / Einbinden von Übungen
- [x] **Optionale Zuordnung einer Übungsvariante** pro Eintrag (`exercise_variant_id`)
- [ ] Kalender-View / erweiterte Roadmap (Backlog)
**MediaWiki Import:**
- [x] Import-Tracking (wiki_import_log, wiki_import_references)
- [x] Übungs-Import via API (221 Übungen)
- [x] Skills via Migration 023 (69 Skills mit Kategorisierung)
- [x] Duplikat-Erkennung
- [x] Reimport-Flag
- [x] Import-Tracking, Übungs-Import, Skills-Migration (siehe ältere Session-Docs)
**Skills-System:**
- [x] Hierarchisches Schema (Haupt-/Unterkategorien)
- [x] Fokusbereich-Zuordnung (karate/universal)
- [x] Exercise-Skill Assignments mit Levels (1-5)
- [x] Level-Definitionen-Schema (noch nicht gefüllt)
- [x] Hierarchisches Schema, Fokusbereich-Zuordnung, Exercise-Skill mit Levels
**Admin-UI:**
- [x] Focus Areas, Styles, Target Groups CRUD
- [x] Hierarchie-View (Tree)
- [x] M:N Zuordnungen (Checkbox-Matrix)
- [x] MediaWiki Import-UI
- [x] Import-Log-Ansicht
### 🔲 In Arbeit
- [x] Katalog-CRUD, Matrix/Import je nach Rolle
**Skills:**
- [ ] Admin-UI für Skill-Kategorien (CRUD)
- [ ] Level-Definitionen aus Matrix extrahieren (optional)
- [ ] Skills-Beschreibungen aus Wiki importieren
- [ ] Skill-Filter in Übungssuche
### 🔲 In Arbeit / Backlog
**Training Planning:**
- [ ] Training Units (CRUD)
- [ ] Exercise Assignment zu Units
- [ ] Kalender-View
**Frontend:**
- [ ] Responsive Design (Mobile)
- [ ] Dark Mode
- [ ] Offline-Modus (PWA)
- [ ] Admin-UI für Skill-Kategorien (CRUD) falls noch offen
- [ ] Responsive Design / Dark Mode / PWA
- [ ] KI-Suche (`ai_search`) über reine Volltextsuche hinaus
### 📋 Geplant (Backlog)
**KI-Features:**
- [ ] Trainingsplan-Generator (basierend auf Fähigkeiten-Level)
- [ ] Übungs-Empfehlungen
- [ ] Reifegradmodelle (automatische Bewertung)
**Import/Export:**
- [ ] Trainingsmethoden-Import aus Wiki
- [ ] Bulk-Export (Excel/PDF)
- [ ] Import aus anderen Systemen
**Kollaboration:**
- [ ] Übungs-Review-Workflow
- [ ] Kommentare & Bewertungen
- [ ] Teilen & Favoriten
- Trainingsplan-Generator, Bulk-Export, Review-Workflow (unverändert strategisch geplant)
---
@ -131,64 +105,27 @@ Target Groups: 12
| Bereich | Issue | Priorität |
|---------|-------|-----------|
| Skills | Migration 021 löschen (faulty) | Niedrig |
| Import | Reimport-Flag-Bug (wird manchmal als false gespeichert) | Mittel |
| Import | DNS-Fehler sporadisch (temporär, retry hilft) | Niedrig |
| DB | 9 Duplikate in DB bereinigen (aus Migration 021) | Niedrig |
| Skills | Migration 021 bereinigen (falls noch referenziert) | Niedrig |
| Import | Reimport-Flag / DNS je nach Prod-Realität prüfen | Mittel |
---
## Lessons Learned (Session 2026-04-27)
## Lessons Learned (Auszug)
**✅ Funktioniert gut:**
- Direkte SQL-Generierung aus Matrix (ohne CSV-Zwischenschritt)
- UTF-8 Encoding explizit setzen (sys.stdout.reconfigure)
- Duplikat-Bereinigung nach fachlicher Logik (nicht automatisch)
- Verifikation-Queries direkt in Migration einbauen
**❌ Vermeiden:**
- CSV als Zwischenschritt (Encoding-Probleme)
- Automatisches Parsing ohne manuelle Duplikat-Prüfung
- Fehlende Schema-Erweiterung vor Daten-Import
- Unvollständige "Schnellschuss"-Migrationen (wie 021)
**📚 Best Practices:**
- Schema VOR Daten importieren
- Cleanup VOR Insert (DELETE old data)
- Verifikation NACH Insert (count, Verteilung)
- Produktionsreifer Import: Vollständig oder gar nicht
- **Listen-UX:** Bedingtes Rendern der **gesamten Seite** bei `loading` zerstört Fokus und Scroll separates `listFetching` für die Trefferliste.
- **Upload-Limits:** Vergleich immer in **MB** vor Umrechnung in Bytes; Admin-Limit nie unter Nutzer-Limit.
---
## Deployment-Status
### Dev-System (192.168.2.49:8098/3098)
### Dev
```
Branch: develop
Migrations: 023 (latest)
Skills: 69 ✅
Übungen: 221 ✅
Status: Stabil, bereit für Testing
```
Branch `develop`; Migrations bis mindestens **030** auf dem aktuellen Entwicklungsstand; Details in `backend/version.py`.
### Prod-System (TBD)
### Prod
```
Branch: main
Migrations: 019 (veraltet)
Skills: 0
Übungen: 0
Status: Wartet auf Migration 020-023 Deployment
```
**Deployment-Plan:**
1. ✅ Dev-Testing abgeschlossen (Migration 022+023)
2. 🔲 Test: Übungs-Import mit neuen Skills
3. 🔲 Code-Review + QA
4. 🔲 Prod-Deployment (Migration 020-023)
5. 🔲 Daten-Import auf Prod (Übungen + Skills)
6. 🔲 Smoke-Tests auf Prod
Deployment der oben genannten Migrationen und Datenabgleich nach internem Prozess.
---
@ -196,23 +133,23 @@ Status: Wartet auf Migration 020-023 Deployment
| Dokument | Pfad | Stand | Status |
|----------|------|-------|--------|
| Database Schema | `technical/DATABASE_SCHEMA.md` | 2026-04-27 | ✅ Aktuell |
| Domain Model | `functional/DOMAIN_MODEL.md` | 2026-04-27 | ✅ Aktuell |
| MediaWiki Import Spec | `technical/MEDIAWIKI_IMPORT_SPEC.md` | 2026-04-27 | ✅ Aktuell |
| Session Handover | `.claude/handover/session-2026-04-27-skills-complete.md` | 2026-04-27 | ✅ Komplett |
| API Reference | `technical/EXERCISES_API_SPEC.md` | 2026-04-24 | ⚠️ Veraltet |
| Frontend Routing | `technical/EXERCISES_FRONTEND_ROUTING.md` | 2026-04-23 | ⚠️ Veraltet |
| Lieferliste Q2 2026 | `library/FEATURES_DELIVERED_2026-Q2.md` | 2026-04-27 | ✅ Neu |
| Anforderungen (Index) | `functional/SHINKAN_REQUIREMENTS.md` | 2026-04-27 | ✅ Neu |
| Database Schema | `technical/DATABASE_SCHEMA.md` | 2026-04-27 | ✅ Aktualisiert (030) |
| Domain Model | `functional/DOMAIN_MODEL.md` | 2026-04-27 | ✅ Referenz |
| API Übungen | `technical/EXERCISES_API_SPEC.md` | 2026-04-27 | ✅ Aktualisiert (v1.3) |
| Frontend Routing | `technical/EXERCISES_FRONTEND_ROUTING.md` | 2026-04-27 | ✅ Aktualisiert |
| Search & Filter | `technical/SEARCH_FILTER_SPEC.md` | 2026-04-27 | ✅ Aktualisiert (Liste UX) |
| Media Upload | `technical/MEDIA_UPLOAD_SPEC.md` | 2026-04-27 | ✅ Aktualisiert (Limits) |
| Projektstatus | `PROJECT_STATUS.md` | 2026-04-27 | ✅ Diese Datei |
---
## Team & Kontakte
**Entwicklung:** Claude Code
**Product Owner:** Lars
**Git Repository:** http://192.168.2.144:3000/Lars/shinkan-jinkendo
**Wiki (Datenquelle):** https://karatetrainer.net
---
**Letzte Aktualisierung:** 2026-04-27
**Nächstes Review:** Nach Prod-Deployment

View File

@ -456,6 +456,8 @@ skill_level_definitions (
- Abweichende Zielgruppen
- Eigener Medienbezug
**Umsetzung (Trainingsplanung):** Ein Eintrag in `training_unit_exercises` kann optional eine konkrete Varianten-ID (`exercise_variant_id`, Migration 030) tragen; Bindung wird gegen die gewählte Übung validiert. Varianten werden über die Übungs-API verwaltet (`technical/EXERCISES_API_SPEC.md`).
---
## Methodenbezug (§11.5)

View File

@ -0,0 +1,12 @@
# Shinkan Jinkendo Anforderungen (Index)
Ausführliche fachliche Inhalte:
| Dokument | Inhalt |
|----------|--------|
| [shinkan_anforderungsdokument_entwurf.md](./shinkan_anforderungsdokument_entwurf.md) | Gesamtentwurf Anforderungen |
| [DOMAIN_MODEL.md](./DOMAIN_MODEL.md) | Domänenmodell, Variantenlogik (Abschnitt 11.2) |
**Lieferstand & Umsetzung (Stand Code):** siehe [`../PROJECT_STATUS.md`](../PROJECT_STATUS.md) und [`../library/FEATURES_DELIVERED_2026-Q2.md`](../library/FEATURES_DELIVERED_2026-Q2.md).
`CLAUDE.md` (Repo-Root) verweist hierher als Einstieg.

View File

@ -0,0 +1,117 @@
# Gelieferte Features & technische Basis (April 2026)
**Stand:** 2026-04-27
**Referenz:** `backend/version.py`**APP_VERSION 0.7.9**, **DB_SCHEMA_VERSION 20260427030**
Dieses Dokument bündelt die in der Entwicklungsphase erreichten **lieferbaren** Funktionen und die zugehörigen **technischen Artefakte**. Detail-Spezifikationen bleiben in den verlinkten Pfaden unter `.claude/docs/technical/` und `.claude/docs/functional/`.
---
## 1. Datenbank-Migrationen (Auswahl)
| Migration | Inhalt |
|-----------|--------|
| **028** | `exercise_media` erweitert (Embed/Metadaten), `exercise_skills` Level-Felder (VARCHAR); Medien-API |
| **029** | Kanonische Fähigkeitsstufen (basisoptimierung), `model_levels`-Namen |
| **030** | `training_unit_exercises.exercise_variant_id` → FK `exercise_variants(id)` ON DELETE SET NULL |
---
## 2. Backend Übungen (`routers/exercises.py`)
### 2.1 Liste & Suche
- `GET /api/exercises` mit Filtern u. a.: Fokus, Stilrichtung, Trainingsstil, Zielgruppe, Fähigkeiten, **Skill-Stufe min/max**, `visibility_any`, `status_any`, `search`, **`ai_search`** (Platzhalter, derzeit gleiche Volltextlogik wie `search`).
- Optional: **`include_variants=true`** — liefert pro Übung ein kompaktes **`variants`**-JSON (id, variant_name, sequence_order) für Planung/UI.
### 2.2 Übungsvarianten (CRUD)
Implementiert gemäß **`EXERCISES_API_SPEC.md`** (Varianten-Abschnitt):
- `POST /api/exercises/{id}/variants`
- `PUT /api/exercises/{id}/variants/{variant_id}`
- `DELETE /api/exercises/{id}/variants/{variant_id}` (409, wenn andere Varianten diese als Voraussetzung nutzen)
- `PUT /api/exercises/{id}/variants/reorder``sequence_order` 1…n
Sortierung der Varianten im Detail: **`sequence_order`**, dann **`progression_level`**, dann **`id`**.
### 2.3 Medien-Upload Größenlimits
- Standard: **50 MB** pro Datei (`EXERCISE_MEDIA_MAX_UPLOAD_MB`, Default 50).
- **`admin`** / **`superadmin`**: **1024 MB** Default (`EXERCISE_MEDIA_ADMIN_MAX_UPLOAD_MB`), nie unter dem Nutzer-Limit (in MB verglichen).
Logik: `_upload_limit_bytes(session)` vor `read()`-Prüfung.
---
## 3. Backend Trainingsplanung (`routers/training_planning.py`)
- `training_unit_exercises`: Schreiben/Lesen von **`exercise_variant_id`**.
- Validierung: Variante muss zur gewählten **`exercise_id`** gehören.
- JOIN liefert u. a. **`exercise_variant_name`** beim Lesen einer Einheit.
---
## 4. Frontend Übungsliste (`ExercisesListPage.jsx`)
- **Filter-Modal** (Fokus, Stilrichtung, Trainingsstil, Zielgruppe, Fähigkeit + Stufen von/bis, Sichtbarkeit, Status).
- **Filter-Chips** unter der Suchleiste; Klick entfernt einen Filter; Badge am Filter-Button = Anzahl Chips.
- **Kein Vollbild-Spinner** bei jeder Suche: nur noch **`listFetching`** — Suchfelder bleiben im DOM (**Fokus/Cursor** bleiben erhalten); Liste zeigt optional „Aktualisiere Treffer…“.
- **`<datalist>`** mit Titeln der aktuellen Treffer; **`autoComplete="on"`** für Browser-Vorschläge.
- **`api.listExercises`**: Booleans (z. B. `include_variants`) werden als Query übergeben.
---
## 5. Frontend Übung bearbeiten (`ExerciseFormPage.jsx`)
- **Varianten-Editor**: eingeklappter Bereich (`<details>`), **eine Variante zur Zeit** über Dropdown oder „Neue Variante“; Felder über **`ExerciseVariantFields`**; Reihenfolge Nach oben/unten; Speichern/Löschen pro Variante.
- **Medien** wie zuvor (Formularteil).
Hinweis: Es gibt **keine** separaten Routen `/exercises/:id/variants/...` — Bearbeitung erfolgt unter **`/exercises/:id/edit`** (Routing-Doku ggf. anpassen).
---
## 6. Frontend Übung Detail (`ExerciseDetailPage.jsx`)
- Varianten-Abschnitt mit **Meta** (Dauer, Schwierigkeit, Material, Progressionsstufe) wo vorhanden.
---
## 7. Frontend Trainingsplanung (`TrainingPlanningPage.jsx`)
- `listExercises({ include_variants: true })`.
- Pro Zeile: Übung + **Variante** (optional), Dauer, Reihenfolge.
---
## 8. Rich-Text (`RichTextEditor.jsx` + CSS)
- **Selection Save/Restore** vor Toolbar-Klicks (`insertUnorderedList` / `insertOrderedList` zuverlässiger bei Mehrzeilen-Markierung).
- **`styleWithCSS` false** vor Formatbefehlen.
- **Listen-Styling** für `.rich-text-editor ul/ol/li` (Einzüge sichtbar).
---
## 9. Admin Matrix / Reifegrad (Kontext)
- Bereits dokumentiert in **`CHANGELOG`** / Module **`maturity_models`**: Matrix-Stack-Bundle Export/Import, Kontext-Bindings — siehe `version.py` und Admin-UI-Pfade.
---
## 10. Nächste sinnvolle Schritte (nicht Lieferstand)
- Progressions-Serien als **Blöcke** (angekündigt; Voraussetzung: `prerequisite_variant_id` / `progression_level` vorhanden).
- Serverseitige **Suchvorschläge** (Autocomplete-Endpoint), falls datalist nicht reicht.
- Optional: Streaming/chunked Upload für sehr große Videos (RAM-Thema).
---
## 11. Verweise
| Thema | Dokument |
|--------|----------|
| API Übungen | `technical/EXERCISES_API_SPEC.md` |
| Domänenmodell | `functional/DOMAIN_MODEL.md` |
| Datenbank Überblick | `technical/DATABASE_SCHEMA.md` |
| Upload formal | `technical/MEDIA_UPLOAD_SPEC.md` |
| Projektstatus-Kachel | `../PROJECT_STATUS.md` |

View File

@ -269,7 +269,10 @@ exercise_media (id, exercise_id, type, url, title, description, ...)
```sql
training_units (id, group_id, date, title, description, ...)
training_unit_exercises (training_unit_id, exercise_id, sort_order, ...)
training_unit_exercises (
training_unit_id, exercise_id, sort_order,
exercise_variant_id -- FK exercise_variants(id) ON DELETE SET NULL (Migration 030)
)
exercise_blocks (id, name, description, created_by, club_id, ...) -- Migration 017
```

View File

@ -1,9 +1,10 @@
# Exercises API Specification
**Version:** 1.2
**Datum:** 2026-04-24
**Status:** REVIEWED - Pending Implementation
**Version:** 1.3
**Datum:** 2026-04-27
**Status:** Teilweise implementiert (Liste mit Filtern + Varianten + Medienlimits siehe Code)
**Autor:** Claude Code
**Änderungen v1.3:** `GET /exercises` erweiterte Query-Parameter (`include_variants`, Multi-Filter, `ai_search`-Platzhalter); Dokumentation angepasst
**Änderungen v1.2:** KI-Assistenz Endpoints, Skill-Level-System (benannte Stufen), intensity als low/medium/high
**Änderungen v1.1:** Exercise Blocks Endpoints, Permissions dokumentiert, age_groups korrigiert
@ -66,33 +67,35 @@ Development: https://dev.shinkan.jinkendo.de/api
### `GET /exercises`
**Query Parameters:**
- `focus_area` (int, optional) - Focus Area ID
- `visibility` (enum, optional) - `private | club | official`
- `status` (enum, optional) - `draft | in_review | approved | archived`
- `skill_id` (int, optional) - Skill ID
- `search` (string, optional) - Volltext (title, summary, execution)
- `limit` (int, optional, default: 50, max: 100)
- `offset` (int, optional, default: 0)
**Query Parameters (Auswahl):**
| Parameter | Beschreibung |
|-----------|----------------|
| `focus_area_ids[]`, `focus_area` | Fokusbereiche (ODER über Liste oder Legacy Einzel-ID) |
| `visibility_any[]`, `visibility` | Sichtbarkeit(en) |
| `status_any[]`, `status` | Status |
| `skill_ids[]`, `skill_id` | Fähigkeit(en) |
| `skill_min_level`, `skill_max_level` | Stufe 15 auf Übung↔Skill-Zuordnung |
| `style_direction_ids[]`, `style_direction_id` | Stilrichtung(en) |
| `training_type_ids[]`, `training_type_id` | Trainingsstil(e) |
| `target_group_ids[]`, `target_group_id` | Zielgruppe(n) |
| `search`, `ai_search` | Volltext (aktuell gleiche Logik; `ai_search` Platzhalter für spätere KI-Suche) |
| `include_variants` | `true`: jedes Listenelement enthält optional kompaktes **`variants`** für UI/Planung |
| `limit` | Default 50, max 100 |
| `offset` | Default 0 |
**Response:** `200 OK`
Lightweight-Liste; bei `include_variants=true` zusätzlich z.B.:
```json
[
{
{
"id": 1,
"title": "Maai - Distanzübung",
"summary": "Distanzgefühl entwickeln...",
"focus_area": "karate",
"visibility": "club",
"status": "approved",
"created_by": 1,
"creator_name": "Lars",
"club_id": 1,
"club_name": "Dojo Berlin",
"created_at": "2026-04-20T10:00:00Z",
"updated_at": "2026-04-22T14:30:00Z"
}
]
"variants": [
{ "id": 10, "variant_name": "Basis", "sequence_order": 1 }
]
}
```
**Errors:**

View File

@ -1,9 +1,10 @@
# Frontend Routing & Navigation Specification
**Version:** 1.0
**Datum:** 2026-04-24
**Version:** 1.1
**Datum:** 2026-04-27
**Status:** DRAFT - Awaiting Review
**Autor:** Claude Code
**Änderungen v1.1:** Übungsvarianten-Bearbeitung nur unter `/exercises/:id/edit` (keine VariantFormPage-Routen)
---
@ -12,12 +13,10 @@
### 1.1 Route-Übersicht
```
/exercises → ExercisesListPage (Grid + Filter)
/exercises → ExercisesListPage (Grid + Filter + Chips)
/exercises/new → ExerciseFormPage (Create)
/exercises/{id} → ExerciseDetailPage (Accordion-Layout)
/exercises/{id}/edit → ExerciseFormPage (Edit)
/exercises/{id}/variants/new → VariantFormPage (Create)
/exercises/{id}/variants/{vid}/edit → VariantFormPage (Edit)
/exercises/{id}/edit → ExerciseFormPage (Edit inkl. Varianten-Editor inline)
/exercise-blocks → ExerciseBlocksListPage (Meine Blocks)
/exercise-blocks/new → ExerciseBlockFormPage (Create)
@ -75,8 +74,7 @@
**Pattern:**
```
Home → Übungen → [Übungsname] → Bearbeiten
Home → Übungen → [Übungsname] → Variante anlegen
Home → Übungen → [Übungsname] → Bearbeiten (Varianten im gleichen Formular)
```
**Implementation:**
@ -640,8 +638,7 @@ function App() {
<Route path="new" element={<ExerciseFormPage />} />
<Route path=":id" element={<ExerciseDetailPage />} />
<Route path=":id/edit" element={<ExerciseFormPage />} />
<Route path=":id/variants/new" element={<VariantFormPage />} />
<Route path=":id/variants/:variantId/edit" element={<VariantFormPage />} />
{/* Varianten: Bearbeitung inline in ExerciseFormPage, keine eigenen Routen */}
</Route>
{/* Exercise Blocks Routes */}

View File

@ -1,9 +1,10 @@
# Media Upload & Embed Specification
**Version:** 1.0
**Datum:** 2026-04-24
**Version:** 1.1
**Datum:** 2026-04-27
**Status:** DRAFT - Awaiting Review
**Autor:** Claude Code
**Änderungen v1.1:** Rollenbasierte Server-Limits (`EXERCISE_MEDIA_*_MB`)
---
@ -20,9 +21,10 @@
- Keine Abhängigkeit von Drittanbietern für Kern-Content
- Externe Plattformen für ergänzende Videos
**Limitierungen:**
- Max. 50 MB pro Datei
- Max. 10 Media-Items pro Übung (kombiniert Local + Embeds)
**Limitierungen (implementiert):**
- Max. Dateigröße: **50 MB** Standardnutzer (`EXERCISE_MEDIA_MAX_UPLOAD_MB`, Default 50).
- **`admin` / `superadmin`**: höheres Limit (**1024 MB** Default `EXERCISE_MEDIA_ADMIN_MAX_UPLOAD_MB`; nie unter dem Nutzer-Limit in MB).
- Max. 10 Media-Items pro Übung (kombiniert Local + Embeds) — siehe Backend-Validierung
- Erlaubte Formate: JPEG, PNG, GIF, MP4, PDF
---

View File

@ -1,9 +1,10 @@
# Search & Filter Specification
**Version:** 1.0
**Datum:** 2026-04-24
**Version:** 1.1
**Datum:** 2026-04-27
**Status:** DRAFT - Awaiting Review
**Autor:** Claude Code
**Änderungen v1.1:** Abschnitt 1.2 implementiertes Verhalten Übungsliste (Fokus, listFetching, Chips, datalist)
---
@ -18,6 +19,16 @@
**Kombination:** Alle Filter UND Keyword-Search kombinierbar
### 1.2 Übungsliste (Frontend, implementiert)
Auf **`ExercisesListPage`** gilt:
- Filter und Suche kombinieren sich; **Server-Request** bei geänderter Query (Debouncing möglich).
- **Kein Ersetzen der gesamten Seite** durch einen Ladezustand bei List-Refetch — nur die Liste zeigt einen **„Aktualisiere Treffer…“**-Zustand; Suchfelder bleiben montiert (**Fokus erhalten**).
- Erste Ladephase ohne Treffer: kompakter Spinner **unter** der Suchleiste.
- **`<datalist>`** (`list=` an Suchfeldern) mit Distinct-Titeln aus den aktuellen Treffern zur Auswahl.
- Zusätzliche Filter erscheinen als **Chips**; Zähler am Filter-Button = Anzahl aktiver Filter.
---
## 2. Volltext-Suche (PostgreSQL)

View File

@ -74,18 +74,16 @@ frontend/src/
└── library/ # Auto-generierte Docs
```
## Aktuelle Version: v0.1.0 (Initial Setup)
## Aktuelle Version
**Status:** Initial Setup in Arbeit
**Branch:** develop
**Nächster Schritt:** Basis-Migrationen + Core-Router
**Siehe:** `backend/version.py` (`APP_VERSION`, `DB_SCHEMA_VERSION`, `MODULE_VERSIONS`) und `.claude/docs/PROJECT_STATUS.md`.
### Updates (21.04.2026 - Initial Setup)
Kurz (Stand 2026-04-27): App **0.7.9**, DB-Schema-Version **20260427030**; Kern-Features: Übungen mit Varianten, Medien, Trainingsplanung mit optionaler Variantenwahl.
- **Repository:** Erstellt auf Gitea
- **Basis-Struktur:** Verzeichnisse angelegt
- **Von Mitai übernommen:** auth.py, db.py, db_init.py
- **Eigene Dateien:** version.py, CLAUDE.md
### Log (Auszug)
- 2026-04-27: Übungsvarianten API/UI, Migration 030, Listen-UX-Suche, Admin-Upload-Limits — siehe `PROJECT_STATUS.md` und `docs/library/FEATURES_DELIVERED_2026-Q2.md`.
- 2026-04-21: Repository- und Initial-Setup (Historie; Details in Git).
## Domänenmodell (MVP Core)

View File

@ -748,9 +748,17 @@ export async function deleteTrainerContext(id) {
// Training Planning
// ============================================================================
export async function listTrainingUnits(groupId, startDate, endDate) {
const query = new URLSearchParams({ group_id: groupId, start_date: startDate, end_date: endDate }).toString()
return request(`/api/training-units?${query}`)
/** Query-Parameter wie GET /api/training-units (group_id, start_date, end_date, status). */
export async function listTrainingUnits(filters = {}) {
const q = new URLSearchParams()
if (filters.group_id != null && filters.group_id !== '') {
q.set('group_id', String(filters.group_id))
}
if (filters.start_date) q.set('start_date', filters.start_date)
if (filters.end_date) q.set('end_date', filters.end_date)
if (filters.status) q.set('status', filters.status)
const qs = q.toString()
return request(`/api/training-units${qs ? `?${qs}` : ''}`)
}
export async function getTrainingUnit(id) {