feat: update version to 0.7.9 and enhance project documentation
- 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:
parent
d5fbc2cd5c
commit
7134fd1a25
|
|
@ -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 **020–030** 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 | ✅ | ✅ |
|
||||
| 001–017 | 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) | ✅ | 🔲 |
|
||||
| 028–029 | 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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
12
.claude/docs/functional/SHINKAN_REQUIREMENTS.md
Normal file
12
.claude/docs/functional/SHINKAN_REQUIREMENTS.md
Normal 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.
|
||||
117
.claude/docs/library/FEATURES_DELIVERED_2026-Q2.md
Normal file
117
.claude/docs/library/FEATURES_DELIVERED_2026-Q2.md
Normal 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 (basis–optimierung), `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` |
|
||||
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -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 1–5 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:**
|
||||
|
|
|
|||
|
|
@ -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 */}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
16
CLAUDE.md
16
CLAUDE.md
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user