From 7134fd1a25e1be55f7e2eefd3581b24f907685f5 Mon Sep 17 00:00:00 2001 From: Lars Date: Tue, 28 Apr 2026 16:18:25 +0200 Subject: [PATCH] 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. --- .claude/docs/PROJECT_STATUS.md | 197 ++++++------------ .claude/docs/functional/DOMAIN_MODEL.md | 2 + .../docs/functional/SHINKAN_REQUIREMENTS.md | 12 ++ .../library/FEATURES_DELIVERED_2026-Q2.md | 117 +++++++++++ .claude/docs/technical/DATABASE_SCHEMA.md | 5 +- .claude/docs/technical/EXERCISES_API_SPEC.md | 59 +++--- .../technical/EXERCISES_FRONTEND_ROUTING.md | 19 +- .claude/docs/technical/MEDIA_UPLOAD_SPEC.md | 14 +- .claude/docs/technical/SEARCH_FILTER_SPEC.md | 17 +- CLAUDE.md | 16 +- frontend/src/utils/api.js | 14 +- 11 files changed, 281 insertions(+), 191 deletions(-) create mode 100644 .claude/docs/functional/SHINKAN_REQUIREMENTS.md create mode 100644 .claude/docs/library/FEATURES_DELIVERED_2026-Q2.md diff --git a/.claude/docs/PROJECT_STATUS.md b/.claude/docs/PROJECT_STATUS.md index 12b7b3d..14091a3 100644 --- a/.claude/docs/PROJECT_STATUS.md +++ b/.claude/docs/PROJECT_STATUS.md @@ -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, ``-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 +**Wiki (Datenquelle):** https://karatetrainer.net --- **Letzte Aktualisierung:** 2026-04-27 -**Nächstes Review:** Nach Prod-Deployment diff --git a/.claude/docs/functional/DOMAIN_MODEL.md b/.claude/docs/functional/DOMAIN_MODEL.md index b5a17bc..898c5c6 100644 --- a/.claude/docs/functional/DOMAIN_MODEL.md +++ b/.claude/docs/functional/DOMAIN_MODEL.md @@ -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) diff --git a/.claude/docs/functional/SHINKAN_REQUIREMENTS.md b/.claude/docs/functional/SHINKAN_REQUIREMENTS.md new file mode 100644 index 0000000..591a9cf --- /dev/null +++ b/.claude/docs/functional/SHINKAN_REQUIREMENTS.md @@ -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. diff --git a/.claude/docs/library/FEATURES_DELIVERED_2026-Q2.md b/.claude/docs/library/FEATURES_DELIVERED_2026-Q2.md new file mode 100644 index 0000000..2e0b56c --- /dev/null +++ b/.claude/docs/library/FEATURES_DELIVERED_2026-Q2.md @@ -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…“. +- **``** 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 (`
`), **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` | diff --git a/.claude/docs/technical/DATABASE_SCHEMA.md b/.claude/docs/technical/DATABASE_SCHEMA.md index f87cfba..203ee19 100644 --- a/.claude/docs/technical/DATABASE_SCHEMA.md +++ b/.claude/docs/technical/DATABASE_SCHEMA.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 ``` diff --git a/.claude/docs/technical/EXERCISES_API_SPEC.md b/.claude/docs/technical/EXERCISES_API_SPEC.md index c6a6f35..24ac9f1 100644 --- a/.claude/docs/technical/EXERCISES_API_SPEC.md +++ b/.claude/docs/technical/EXERCISES_API_SPEC.md @@ -1,9 +1,10 @@ # Exercises API Specification -**Version:** 1.2 -**Datum:** 2026-04-24 -**Status:** REVIEWED - Pending Implementation -**Autor:** Claude Code +**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" - } -] +{ + "id": 1, + "title": "Maai - Distanzübung", + "variants": [ + { "id": 10, "variant_name": "Basis", "sequence_order": 1 } + ] +} ``` **Errors:** diff --git a/.claude/docs/technical/EXERCISES_FRONTEND_ROUTING.md b/.claude/docs/technical/EXERCISES_FRONTEND_ROUTING.md index 86b6efb..d8f8ddc 100644 --- a/.claude/docs/technical/EXERCISES_FRONTEND_ROUTING.md +++ b/.claude/docs/technical/EXERCISES_FRONTEND_ROUTING.md @@ -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 +**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() { } /> } /> } /> - } /> - } /> + {/* Varianten: Bearbeitung inline in ExerciseFormPage, keine eigenen Routen */} {/* Exercise Blocks Routes */} diff --git a/.claude/docs/technical/MEDIA_UPLOAD_SPEC.md b/.claude/docs/technical/MEDIA_UPLOAD_SPEC.md index c2ba1dd..15cba7d 100644 --- a/.claude/docs/technical/MEDIA_UPLOAD_SPEC.md +++ b/.claude/docs/technical/MEDIA_UPLOAD_SPEC.md @@ -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 +**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 --- diff --git a/.claude/docs/technical/SEARCH_FILTER_SPEC.md b/.claude/docs/technical/SEARCH_FILTER_SPEC.md index 7b92175..73829b6 100644 --- a/.claude/docs/technical/SEARCH_FILTER_SPEC.md +++ b/.claude/docs/technical/SEARCH_FILTER_SPEC.md @@ -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 +**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. +- **``** (`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) diff --git a/CLAUDE.md b/CLAUDE.md index ba9bc75..adef7a2 100644 --- a/CLAUDE.md +++ b/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) diff --git a/frontend/src/utils/api.js b/frontend/src/utils/api.js index 40bdf7a..061e1c1 100644 --- a/frontend/src/utils/api.js +++ b/frontend/src/utils/api.js @@ -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) {