shinkan-jinkendo/backend/version.py
Lars 870a7611dc
Some checks failed
Deploy Development / deploy (push) Successful in 36s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Failing after 34s
feat: enhance governance visibility checks and update login rate limit
- Updated governance visibility logic in `assert_valid_governance_visibility` to enforce club membership checks for platform admins and ensure proper club existence validation.
- Increased login request limit from 5 to 30 per minute to improve user experience.
- Refactored exercise update logic to better handle visibility and club ID requirements, ensuring compliance with governance rules.
2026-05-05 21:57:55 +02:00

464 lines
21 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Shinkan Jinkendo Version Information
APP_VERSION = "0.8.25"
BUILD_DATE = "2026-05-05"
DB_SCHEMA_VERSION = "20260505041"
MODULE_VERSIONS = {
"auth": "1.2.1", # Login-Rate-Limit 30/minute pro IP (vorher 5/minute)
"profiles": "1.4.0", # GET /profiles/me: effective_club_id (TenantContext-Auflösung); TenantContext-Modul
"tenant_context": "1.0.0", # resolve/get_depends; library_content_visibility_sql
"clubs": "0.4.0", # public-directory, members/directory; Vereins-GUI verwendet Endpoints
"club_memberships": "1.0.0",
"club_join_requests": "1.0.0",
"admin_users": "1.0.0", # GET /api/admin/users
"groups": "0.1.0",
"skills": "0.1.0",
"methods": "0.1.0",
"exercises": "2.6.1", # PUT Übung: visibility club ohne club_id → effective_club_id / Body club_id; Governance für Plattform-Admins ohne Vereinsmitgliedschaft bei club
"training_units": "0.1.0",
"training_programs": "0.1.0",
"planning": "0.8.0", # TenantContext auf allen Planungs-Endpunkten; Vorlagen-Liste wie Übungen nach aktivem Verein
"import_wiki": "1.0.0",
"admin": "1.0.0",
"membership": "1.0.0",
"catalogs": "1.5.0", # Updated: Trainer Contexts API (Migration 012)
"maturity_models": "1.4.0", # matrix_stack_bundle: vollständiger Katalog+Modelle+Bindings Export/Import
}
CHANGELOG = [
{
"version": "0.8.25",
"date": "2026-05-05",
"changes": [
"Übungen PUT: bei visibility club wird club_id aus aktivem Verein oder Body gesetzt (verhindert club ohne club_id für Vereinsnutzer)",
"club_tenancy: governance visibility club für Plattform-Admins ohne Vereinsmitgliedschaft (nur Existenz clubs.id)",
"Login POST /api/auth/login: Rate-Limit 30/minute pro IP (vorher 5/minute)",
],
},
{
"version": "0.8.24",
"date": "2026-05-05",
"changes": [
"Übungen-Router: get/update/delete, Varianten, Medien — Depends(get_tenant_context); Upload-Limits via TenantContext; fehlenden DELETE decorator variants gefixt",
],
},
{
"version": "0.8.23",
"date": "2026-05-05",
"changes": [
"ACCESS_LAYER: library_content_visibility_sql + TenantContext an Übungen-Liste, Rahmenprogramme, Trainingsplanung",
"POST Übung/Vorlage/Rahmenprogramm: visibility club ohne club_id → effective_club_id; POST Übung mit assert_valid_governance_visibility",
],
},
{
"version": "0.8.22",
"date": "2026-05-05",
"changes": [
"ACCESS_LAYER Stufe B: Modul tenant_context (resolve_tenant_context, Depends(get_tenant_context)); GET /profiles/me liefert effective_club_id; veralteter X-Active-Club-Id wird dort verworfen (ignore), strikt auf anderen Endpoints via Depends",
"Arbeitspapier ACCESS_LAYER_ENDPOINT_AUDIT.md für Router-Inventar",
],
},
{
"version": "0.8.21",
"date": "2026-05-05",
"changes": [
"FastAPI: Router club_memberships und club_join_requests registriert (GET /api/clubs/{id}/members, join-requests u. a.) — behoben 404 auf Vereinsseite Tab Mitglieder",
],
},
{
"version": "0.8.20",
"date": "2026-05-05",
"changes": [
"Migration 041: wenn noch kein superadmin existiert, werden ältestes Profil mit role admin zu superadmin hochgestuft",
"Registrierung: erster Nutzer und ADMIN_BOOTSTRAP_EMAILS erhalten superadmin (vorher admin)",
],
},
{
"version": "0.8.19",
"date": "2026-05-05",
"changes": [
"Portal-Admin: GET /api/admin/users (alle Nutzer + Vereine); PUT /profiles/{id} mit role/tier (Super-Admin nur durch Super-Admin); Mitgliedschaft inaktiv in Übersicht",
"GUI Admin → Nutzer: Portal-Rolle/Tier, Verein zuweisen, Vereinsrollen bearbeiten",
],
},
{
"version": "0.8.18",
"date": "2026-05-05",
"changes": [
"DB 040 club_membership_requests; API Antrag/Abrufen/annehmen/ablehnen; öffentliches Vereinsverzeichnis; Mitglieder-Directory für Trainerwahl",
"GUI: Vereinsverwaltung Tab Mitglieder & Anträge; Registrierung/Einstellungen Vereinsantrag; Gruppenformular Haupt- und Co-Trainer",
"GET /profiles nur noch für Plattform-Admins",
],
},
{
"version": "0.8.17",
"date": "2026-05-05",
"changes": [
"Multi-Tenancy Phase 4: training_plan_templates + training_framework_programs Listen und Lesen nach visibility/club wie Übungen; Schreiben nur Ersteller oder Plattform-Admin; club_tenancy.assert_valid_governance_visibility",
],
},
{
"version": "0.8.16",
"date": "2026-05-05",
"changes": [
"API Vereinsmitglieder: GET/POST/GET-one/PUT/DELETE /api/clubs/{id}/members (Plattform- oder Vereinsadmin); Frontend api.js Hooks",
],
},
{
"version": "0.8.15",
"date": "2026-05-05",
"changes": [
"DB 039 Fix: Co-Trainer-Backfill über Subquery + CASE (kein jsonb_array_length/jsonb_array_elements auf Nicht-Arrays durch Planner/LATERAL-Reihenfolge)",
],
},
{
"version": "0.8.14",
"date": "2026-05-05",
"changes": [
"DB 039 Fix: Co-Trainer-Backfill nur wenn co_trainer_ids ein JSON-Array ist (vermeidet jsonb_array_length auf Nicht-Array)",
],
},
{
"version": "0.8.13",
"date": "2026-05-05",
"changes": [
"Fix: Startup unter Windows (cp1252) — Emoji/Sonderzeichen in print durch ASCII ([OK]/[FAIL]/[WARN]) ersetzt (main, run_migrations, db_init)",
],
},
{
"version": "0.8.12",
"date": "2026-05-05",
"changes": [
"DB 039: club_members, club_member_roles, clubs.primary_admin_profile_id, profiles.active_club_id + Backfill",
"Multi-Tenancy: Vereinslisten gefiltert, Vereinsanlage nur Plattform-Admin mit primary_admin_profile_id",
"Übungen: visibility club nur für Mitglieder des zugeordneten Vereins",
"GET /api/profiles/me: clubs[], ohne pin_hash; active_club_id setzen via PUT",
"Frontend: X-Active-Club-Id, Vereins-Umschalter, Vereinsseiten angepasst",
],
},
{
"version": "0.8.11",
"date": "2026-05-05",
"changes": [
"DB 038: training_units.lead_trainer_profile_id (Vertretung / Leitung pro Termin)",
"API GET /api/training-units: club_id, assigned_to_me, sort, limit; Co-Trainer in Sichtbarkeit; lead_trainer_name / effective_lead_trainer_profile_id",
"API PUT /api/training-units/{id}: lead_trainer_profile_id (Validierung über Gruppe)",
],
},
{
"version": "0.8.10",
"date": "2026-05-05",
"changes": [
"DB 037: Rahmen-Slot-Blueprints als training_units (framework_slot_id); migration training_framework_slot_exercises → Sektionen/Items; origin_framework_slot_id für Kopien",
"API: Rahmen-Slots mit sections/exercises aus Blueprint; Kalender list_training_units ohne Blueprints; POST /api/training-units/from-framework-slot",
],
},
{
"version": "0.8.9",
"date": "2026-05-05",
"changes": [
"DB 036: Rahmenprogramm Kontext (Fokusbereich, Stilrichtung, M:N Trainingsarten & Zielgruppen); nur Bibliothek — plan_mode/group_id/Slot-training_unit entfernt.",
"API: /api/training-framework-programs ohne concrete/library; Payload focus_area_id, style_direction_id, training_type_ids, target_group_ids",
],
},
{
"version": "0.8.8",
"date": "2026-05-05",
"changes": [
"DB 035: Trainingsrahmenprogramm (Rahmen, Ziele, Slots, Slot-Übungen); plan_mode concrete|library",
"DB 035: training_plan_templates.visibility + Backfill club (CURR-007/008)",
"API: CRUD /api/training-framework-programs (AuthZ wie Übungs-/Planungsbibliothek)",
],
},
{
"version": "0.8.7",
"date": "2026-04-30",
"changes": [
"DB 034: Progressionskanten mit optionalen Varianten-Endpunkten",
"API: POST …/edges/sequence (Reihe auf einmal); POST …/edges/delete-batch",
"Frontend Progressions-UI: Sequenz-Editor, Ketten-Ansicht, Variantenwahl",
],
},
{
"version": "0.8.6",
"date": "2026-04-30",
"changes": [
"DB 033: exercise_progression_edges.notes (Entwicklungsziel)",
"API: Kanten mit notes; JOIN Übungstitel in Listen; PUT Kanten-Notiz",
"Frontend: Progressionsgraphen-Tab unter Übungen + Bereich in Übung bearbeiten",
],
},
{
"version": "0.8.5",
"date": "2026-04-30",
"changes": [
"DB 032: exercise_progression_graphs + exercise_progression_edges (Übung→Übung, edge_type next_exercise)",
"API: CRUD Progressionsgraphen und Kanten unter /api/exercise-progression-graphs",
],
},
{
"version": "0.8.4",
"date": "2026-04-27",
"changes": [
"run_migrations: Warteschlange nach numerischem Präfix der Dateien (stabile Reihenfolge auch bei ungleich langen Zahlen wie 9 vs 10)",
],
},
{
"version": "0.8.3",
"date": "2026-04-28",
"changes": [
"Migrationen: Warteschlange aller fehlenden *.sql; idempotent über schema_migrations",
"Ausführung vorzugsweise psql -1 -f (eine Transaktion pro Datei); Fallback psycopg2 + sqlparse.split",
"requirements: sqlparse wenn kein psql im PATH",
],
},
{
"version": "0.8.2",
"date": "2026-04-28",
"changes": [
"main: run_migrations — Exit-Code auswerten; bei Fehler kein API-Start (verhindert Prod ohne Skill-Tabellen wie 022)",
"SKIP_DB_MIGRATE=1 optional für lokale Runs ohne Datenbank",
],
},
{
"version": "0.8.1",
"date": "2026-04-28",
"changes": [
"skills: JSONB keywords per psycopg2.extras.Json (verhindert 500 wenn keywords als Objekt/Array gesendet wird)",
"GET /api/health/ready: DB-Verbindung + Kern-Tabellen + schema_migrations_count (ohne Auth, für Prod-Debugging)",
],
},
{
"version": "0.8.0",
"date": "2026-04-28",
"changes": [
"DB 031: Trainingsvorlagen (Sektionen) + Struktur pro Einheit (Sektionen, Übungen/Notizen, Dauer)",
"API: /api/training-plan-templates CRUD; Trainingseinheiten mit sections[] + plan_template_id",
"Trainingsplanung UI: Abschnitte, Zwischen-Anmerkungen, Vorlagen auswählen / speichern",
],
},
{
"version": "0.7.9",
"date": "2026-04-27",
"changes": [
"Übungsvarianten: POST/PUT/DELETE /api/exercises/{id}/variants + reorder",
"Übung bearbeiten: voller Varianten-Editor (Speichern pro Variante, Reihenfolge, Voraussetzung)",
"Übung Ansehen: Varianten-Metadaten (Dauer, Schwierigkeit, Material, Progression)",
"GET /exercises Detail: Varianten-Sortierung sequence_order → progression_level",
],
},
{
"version": "0.7.8",
"date": "2026-04-27",
"changes": [
"DB 030: training_unit_exercises.exercise_variant_id (FK exercise_variants)",
"GET /exercises?include_variants=true liefert Varianten für Trainingsplanung",
"Trainingseinheiten: optional exercise_variant_id beim Anlegen/Aktualisieren",
],
},
{
"version": "0.7.7",
"date": "2026-04-27",
"changes": [
"DB 029: Fähigkeitsstufen Einheit (basisoptimierung), model_levels Namen 15",
"Übungen: GET /exercises Filter Stilrichtung, Trainingsstil, Zielgruppe, Fähigkeits-Stufe min/max, ai_search (Volltext-Platzhalter)",
"API: exercise_skills Level-Normalisierung bei Schreiben/Lesen; Wiki-Import Slugs statt Zahl in DB",
],
},
{
"version": "0.7.6",
"date": "2026-04-27",
"changes": [
"API: GET/POST /api/admin/matrix-stack (shinkan.matrix_stack.v1) Fähigkeitskatalog, Reifegradmodelle, Kontext-Bindings für Test→Prod",
"DB 028: exercise_media (Embed/Metadaten), exercise_skills VARCHAR-Level/Intensität; API: POST/PUT/DELETE Medien, /media Static; Übungen-Listen-Fokus",
],
},
{
"version": "0.7.5",
"date": "2026-04-27",
"changes": [
"Resolve/Export: Legacy M:N nur noch, wenn für den Fokus keine Kontext-Bindings existieren (korrekte Striktheit für Fokus+Trainingsstil / Teil-Kontexte)",
],
},
{
"version": "0.7.4",
"date": "2026-04-27",
"changes": [
"DB 027: Bindings Fokus+Trainingsstil ohne Stilrichtung",
"resolve: alle passenden Bindings nach Spezifität mergen",
"API: Export/Import JSON (Modell + aufgelöste Matrix)",
],
},
{
"version": "0.7.3",
"date": "2026-04-27",
"changes": [
"DB 026: maturity_model_context_bindings (Fokus / Stilrichtung / Trainingsstil)",
"API: resolve merged mehrere Modelle; CRUD Bindings; training_type_id Query",
"Admin-Tab Kontext-Zuordnung",
],
},
{
"version": "0.7.2",
"date": "2026-04-27",
"changes": [
"DB: Migration 025 maturity_model_focus_areas / _style_directions / _target_groups (M:N)",
"Bootstrap-Reifegradmodell für alle importierten Skills (Wiki), Stufen 15",
"API+UI: Kontext als Mehrfachauswahl; Matrix zeigt Haupt-/Untergruppe pro Fähigkeit",
],
},
{
"version": "0.7.1",
"date": "2026-04-27",
"changes": [
"DB: Migration 024 maturity_models, model_levels, model_skills, model_skill_levels",
"API: CRUD Reifegradmodelle, Matrix-Pflege, resolve-Kontext",
"Frontend: Admin Fähigkeitsmatrix (/admin/maturity-models)",
],
},
{
"version": "0.7.0",
"date": "2026-04-24",
"changes": [
"BREAKING: Exercises v2.0 - Clean-Room Rebuild (kein Legacy-Code)",
"DB: Migration 014 - Variant Progression + Search Vector + Legacy DROP (age_groups, focus_area, secondary_areas, training_character)",
"DB: Migration 016 - Saved Exercise Searches",
"DB: Migration 017 - Exercise Blocks + Template Blocks",
"Backend: exercises.py komplett neu nach EXERCISES_API_SPEC.md v1.2",
"Backend: Nur M:N Relations, keine JSONB-Kataloge mehr",
"Backend: enrich_exercise_detail() für vollständige Objekte",
"Backend: assign_exercise_relations() für M:N Management",
"API: GET /exercises - Volltext-Suche via tsvector",
"API: POST/PUT /exercises - M:N Relations (focus_areas_multi, training_styles_multi, etc.)",
"Issue #53 konform: Import = Feld-Zuordnung, keine fachliche Interpretation",
]
},
{
"version": "0.6.0",
"date": "2026-04-24",
"changes": [
"Feature: MediaWiki Import (SMW Direct API)",
"DB: Migration 018 - wiki_import_log + wiki_import_references",
"Backend: SmwClient (login, browse, ask, categorymembers)",
"Backend: SmwMapper (SMW Properties → exercises/skills/methods)",
"Backend: import_wiki Router (preview, execute, status, logs, discover)",
"Config: MEDIAWIKI_API_URL=https://karatetrainer.net/api.php",
]
},
{
"version": "0.5.0",
"date": "2026-04-23",
"changes": [
"Feature: Trainer-Kontext-System für fokussierte Ansichten",
"DB: Migration 012 - exercise_training_characters (M:N)",
"DB: Migration 012 - trainer_contexts (Trainer-Profil-System)",
"Backend: CRUD API für Trainer-Kontexte (/api/trainer-contexts)",
"Frontend: TrainerContextsPage für Verwaltung eigener Arbeitsbereiche",
"Architektur: Flat Catalogs + Smart Filtering für 1000+ Übungen",
"Architektur: NULL = 'für alles geeignet', M:N = spezifische Zuordnung",
]
},
{
"version": "0.4.0",
"date": "2026-04-23",
"changes": [
"BREAKING: Migration 010 - Umbenennung training_styles → style_directions",
"BREAKING: Migration 011 - Neue Dimension training_types (Breitensport/Leistungssport)",
"DB: Konsistente Terminologie - Stilrichtungen vs. Trainingsstile",
"DB: Neue Tabelle training_types mit Seed-Daten (Breitensport, Leistungssport, Wettkampf)",
"DB: Neue Junction-Tabelle exercise_training_types (M:N)",
"Architektur: Fokusbereich → Stilrichtung → Trainingsstil → Zielgruppe (alle M:N)",
"Backend: Alle SQL Queries aktualisiert auf neue Tabellennamen (style_directions, style_direction_target_groups)",
"Backend: API Parameter umbenannt (training_style_id → style_direction_id)",
"Backend: CRUD Endpoints für training_types hinzugefügt",
]
},
{
"version": "0.3.4",
"date": "2026-04-23",
"changes": [
"BREAKING: Migration 009 - Zielgruppen M:N Refactoring",
"DB: target_groups.training_style_id entfernt (jetzt global unabhängig)",
"DB: Neue Junction-Tabelle training_style_target_groups (M:N)",
"API: 5 neue Endpoints für M:N Management (GET/POST/PUT/DELETE + hierarchy)",
"API: GET /training-style-target-groups mit Enrichment (focus_area_name, training_style_name)",
"API: GET /training-styles/hierarchy für Tree-View (verschachtelte Struktur)",
"API: POST /training-style-target-groups mit Upsert-Logik",
"Backward-Compatible: exercise_target_groups weiterhin unterstützt",
"Architecture: Eine Zielgruppe kann mehreren Stilen zugeordnet werden",
]
},
{
"version": "0.3.3",
"date": "2026-04-23",
"changes": [
"Fix: Admin-Navigation - Redirect /admin → /admin/catalogs",
"Fix: Admin-Link funktioniert jetzt (vorher 404)"
]
},
{
"version": "0.3.2",
"date": "2026-04-23",
"changes": [
"Feature: Zielgruppen-Verwaltung komplett (Backend + Frontend)",
"API: GET/POST/PUT/DELETE /target-groups mit hierarchischem Kontext (focus_area → training_style → target_group)",
"Admin UI: Neuer Tab 'Zielgruppen' in Katalogverwaltung",
"UX: Create/Edit-Forms mit Training-Stil-Auswahl, Altersbereich (min/max)",
"UX: Hierarchie-Anzeige in Liste (Fokusbereich → Stil → Zielgruppe)",
"Protection: DELETE mit CASCADE-Schutz (Fehler wenn Übungen zugeordnet)",
]
},
{
"version": "0.3.1",
"date": "2026-04-23",
"changes": [
"Feature: Exercises-Router unterstützt M:N Zuordnungen",
"API: GET /exercises/{id} liefert focus_areas[], training_styles[], target_groups[], age_groups_catalog[]",
"API: POST/PUT /exercises akzeptiert focus_areas_multi[], training_styles_multi[], target_groups_multi[], age_groups_catalog[]",
"Pattern: DELETE+INSERT für M:N Updates (konsistent mit skills)",
"Backward-Compatible: Legacy FK-Felder (focus_area_id, training_style_id) bleiben erhalten",
]
},
{
"version": "0.3.0",
"date": "2026-04-23",
"changes": [
"BREAKING: M:N Beziehungen für Übungen (statt 1:1)",
"Migration 008: M:N Zuordnungstabellen (exercise_focus_areas, exercise_styles, exercise_target_groups, exercise_age_groups)",
"Feature: Hierarchische Katalog-Struktur (Fokusbereich → Stil → Zielgruppe)",
"Feature: Zielgruppen-Verwaltung (training_styles.focus_area_id Hierarchie)",
"Feature: Primary/Secondary Assignments (is_primary Flag)",
"Doku: DATABASE_SCHEMA.md + DOMAIN_MODEL.md kontinuierlich gepflegt",
"Architecture: Smart Cascade-Logik (RESTRICT, Rerouting, Move)",
]
},
{
"version": "0.2.0",
"date": "2026-04-23",
"changes": [
"Feature: Admin-verwaltbare Kataloge (Focus Areas, Training Styles, Training Characters, Skill Categories)",
"Feature: Trainer-Fokusbereich-Zuordnung für rollenbasierte Filterung",
"Migration 007: Katalog-Tabellen + Seed-Daten",
"Frontend: AdminCatalogsPage mit 5 Tabs (CRUD für alle Kataloge)",
"Frontend: ExercisesPage nutzt Katalog-Dropdowns (kein Hard-Coding mehr)",
"Frontend: Trainingsstil-Dropdown hinzugefügt (fehlte komplett)",
"Standardisierung: Alle Formulare mit Labels oben, volle Breite, linksbündig",
]
},
{
"version": "0.1.0",
"date": "2026-04-21",
"changes": [
"Initial MVP Setup",
"Feature: Übungsverwaltung (Kern-Modul)",
"Feature: Fähigkeiten- und Methodenkataloge",
"Feature: Trainingsplanung für Gruppen",
"Feature: Trainingsabschnitte mit Kombinations-Flag",
"Feature: MediaWiki-Import (einseitig)",
"Feature: Freigabelogik (privat/Verein/offiziell)",
"Infrastructure: Auth + Membership von Mitai übernommen",
]
}
]