2026-04-21 14:26:12 +02:00
# Shinkan Jinkendo Version Information
2026-05-11 08:25:00 +02:00
APP_VERSION = " 0.8.76 "
feat(compliance): P-06 Upload-Einwilligungsdialog v1-conservative
Implementiert server-seitige Rechteerklärungspflicht für alle Medien-Uploads
und Sichtbarkeits-Promotions (konservative Erstannahme: alle Uploads).
Backend:
- backend/media_rights.py (NEU): Kernmodul — validate_rights_declaration,
check_rights_coverage, assert_rights_for_promotion, assert_rights_for_exercise_link,
write_rights_declaration, update_rights_quick_fields
- backend/migrations/048_media_rights_declarations.sql (NEU): Tabelle
media_asset_rights_declarations (Append-only Audit-Log), Felder
rights_status/rights_visibility_level in media_assets
- backend/routers/media_assets.py: P-06-Pflichtprüfung in PATCH (single + bulk),
POST /api/media-assets/{id}/rights-declarations (Re-Deklaration),
GET /api/admin/media-rights/legacy-summary|legacy-assets (Admin-Endpoints)
- backend/routers/exercises.py: P-06-Felder in upload_exercise_media,
assert_rights_for_exercise_link in attach_exercise_media_from_asset
- backend/main.py: admin_rights_router registriert
Frontend:
- frontend/src/components/RightsDeclarationDialog.jsx (NEU): 9-Felder-Dialog
(konservativ: immer alle Fragen), Client-Validierung, VORLÄUFIG-Hinweis
- frontend/src/pages/MediaLibraryPage.jsx: Dialog-Intercept vor Upload,
Altbestand-Indikator (legacy_unreviewed)
- frontend/src/utils/api.js: P-06-Felder in bulkUploadMediaAssets weitergeleitet
Tests:
- backend/tests/test_media_rights_declaration.py (NEU): 28 Unit-/Integrationstests
- backend/tests/test_media_assets_archive.py: P-06 fetchone-Slots + Mock ergänzt
- backend/tests/test_media_assets_copyright_promotion.py: check_rights_coverage gemockt
- tests/dev-smoke-test.spec.js: 5 P-06 E2E-Tests ergänzt
Dokumentation:
- docs/compliance-implementation.md: P-06-Abschnitt
- docs/compliance-package-register.md: Status ⚠️ teilweise umgesetzt (KRIT-04 offen)
- docs/compliance-roadmap.md: P-06 im Freigaben-Log
Offen: KRIT-04 (rechtliche Finalisierung Einwilligungsformulierung) — technisch
vollständig, Rechtstext VORLÄUFIG.
version: 0.8.75
module: media_rights 1.0.0, media_assets 1.13.0, exercises 2.20.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 08:12:44 +02:00
BUILD_DATE = " 2026-05-11 "
DB_SCHEMA_VERSION = " 20260511048 "
2026-04-21 14:26:12 +02:00
MODULE_VERSIONS = {
2026-05-10 21:29:21 +02:00
" legal_documents " : " 1.2.0 " , # jsPDF-Download auf LegalPage (oeffentlich) + Admin; Abschnitts-Sortierung/-Einfuegen
2026-05-10 08:26:15 +02:00
" auth " : " 1.2.3 " , # P-05b: reset-password min_length=8 via Pydantic PasswordResetConfirm
2026-05-06 13:52:24 +02:00
" profiles " : " 1.7.0 " , # exercise_list_prefs JSONB (Standard Übungsfilter); Patch via ProfileUpdate + Json()
2026-05-08 10:45:58 +02:00
" tenant_context " : " 1.0.5 " , # Plattform-Admin: effective_club ohne Header aus Profil active_club_id wenn Verein existiert
2026-05-05 22:05:10 +02:00
" clubs " : " 0.4.1 " , # Alle geschützten Endpoints Depends(get_tenant_context); profile_id/role aus TenantContext
" club_memberships " : " 1.0.1 " , # Depends(get_tenant_context)
" club_join_requests " : " 1.0.1 " , # Depends(get_tenant_context)
2026-05-05 21:05:52 +02:00
" admin_users " : " 1.0.0 " , # GET /api/admin/users
2026-05-07 12:36:46 +02:00
" platform_media_storage " : " 1.0.0 " , # GET/PUT /api/admin/platform-media-storage (Superadmin-Pfad unter MEDIA_ROOT)
feat(compliance): P-06 Upload-Einwilligungsdialog v1-conservative
Implementiert server-seitige Rechteerklärungspflicht für alle Medien-Uploads
und Sichtbarkeits-Promotions (konservative Erstannahme: alle Uploads).
Backend:
- backend/media_rights.py (NEU): Kernmodul — validate_rights_declaration,
check_rights_coverage, assert_rights_for_promotion, assert_rights_for_exercise_link,
write_rights_declaration, update_rights_quick_fields
- backend/migrations/048_media_rights_declarations.sql (NEU): Tabelle
media_asset_rights_declarations (Append-only Audit-Log), Felder
rights_status/rights_visibility_level in media_assets
- backend/routers/media_assets.py: P-06-Pflichtprüfung in PATCH (single + bulk),
POST /api/media-assets/{id}/rights-declarations (Re-Deklaration),
GET /api/admin/media-rights/legacy-summary|legacy-assets (Admin-Endpoints)
- backend/routers/exercises.py: P-06-Felder in upload_exercise_media,
assert_rights_for_exercise_link in attach_exercise_media_from_asset
- backend/main.py: admin_rights_router registriert
Frontend:
- frontend/src/components/RightsDeclarationDialog.jsx (NEU): 9-Felder-Dialog
(konservativ: immer alle Fragen), Client-Validierung, VORLÄUFIG-Hinweis
- frontend/src/pages/MediaLibraryPage.jsx: Dialog-Intercept vor Upload,
Altbestand-Indikator (legacy_unreviewed)
- frontend/src/utils/api.js: P-06-Felder in bulkUploadMediaAssets weitergeleitet
Tests:
- backend/tests/test_media_rights_declaration.py (NEU): 28 Unit-/Integrationstests
- backend/tests/test_media_assets_archive.py: P-06 fetchone-Slots + Mock ergänzt
- backend/tests/test_media_assets_copyright_promotion.py: check_rights_coverage gemockt
- tests/dev-smoke-test.spec.js: 5 P-06 E2E-Tests ergänzt
Dokumentation:
- docs/compliance-implementation.md: P-06-Abschnitt
- docs/compliance-package-register.md: Status ⚠️ teilweise umgesetzt (KRIT-04 offen)
- docs/compliance-roadmap.md: P-06 im Freigaben-Log
Offen: KRIT-04 (rechtliche Finalisierung Einwilligungsformulierung) — technisch
vollständig, Rechtstext VORLÄUFIG.
version: 0.8.75
module: media_rights 1.0.0, media_assets 1.13.0, exercises 2.20.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 08:12:44 +02:00
" media_rights " : " 1.0.0 " , # P-06: zentrales Policy-Modul (validate, coverage, write declaration)
" media_assets " : " 1.13.0 " , # P-06: Rechte-Erklaerung bei Upload/Promotion; Re-Deklarations-Endpoint; Admin-Legacy-Summary
2026-04-21 14:26:12 +02:00
" groups " : " 0.1.0 " ,
" skills " : " 0.1.0 " ,
" methods " : " 0.1.0 " ,
feat(compliance): P-06 Upload-Einwilligungsdialog v1-conservative
Implementiert server-seitige Rechteerklärungspflicht für alle Medien-Uploads
und Sichtbarkeits-Promotions (konservative Erstannahme: alle Uploads).
Backend:
- backend/media_rights.py (NEU): Kernmodul — validate_rights_declaration,
check_rights_coverage, assert_rights_for_promotion, assert_rights_for_exercise_link,
write_rights_declaration, update_rights_quick_fields
- backend/migrations/048_media_rights_declarations.sql (NEU): Tabelle
media_asset_rights_declarations (Append-only Audit-Log), Felder
rights_status/rights_visibility_level in media_assets
- backend/routers/media_assets.py: P-06-Pflichtprüfung in PATCH (single + bulk),
POST /api/media-assets/{id}/rights-declarations (Re-Deklaration),
GET /api/admin/media-rights/legacy-summary|legacy-assets (Admin-Endpoints)
- backend/routers/exercises.py: P-06-Felder in upload_exercise_media,
assert_rights_for_exercise_link in attach_exercise_media_from_asset
- backend/main.py: admin_rights_router registriert
Frontend:
- frontend/src/components/RightsDeclarationDialog.jsx (NEU): 9-Felder-Dialog
(konservativ: immer alle Fragen), Client-Validierung, VORLÄUFIG-Hinweis
- frontend/src/pages/MediaLibraryPage.jsx: Dialog-Intercept vor Upload,
Altbestand-Indikator (legacy_unreviewed)
- frontend/src/utils/api.js: P-06-Felder in bulkUploadMediaAssets weitergeleitet
Tests:
- backend/tests/test_media_rights_declaration.py (NEU): 28 Unit-/Integrationstests
- backend/tests/test_media_assets_archive.py: P-06 fetchone-Slots + Mock ergänzt
- backend/tests/test_media_assets_copyright_promotion.py: check_rights_coverage gemockt
- tests/dev-smoke-test.spec.js: 5 P-06 E2E-Tests ergänzt
Dokumentation:
- docs/compliance-implementation.md: P-06-Abschnitt
- docs/compliance-package-register.md: Status ⚠️ teilweise umgesetzt (KRIT-04 offen)
- docs/compliance-roadmap.md: P-06 im Freigaben-Log
Offen: KRIT-04 (rechtliche Finalisierung Einwilligungsformulierung) — technisch
vollständig, Rechtstext VORLÄUFIG.
version: 0.8.75
module: media_rights 1.0.0, media_assets 1.13.0, exercises 2.20.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 08:12:44 +02:00
" exercises " : " 2.20.0 " , # P-06: upload_exercise_media + from-asset Rechtspruefung
2026-05-05 23:35:41 +02:00
" training_units " : " 0.2.0 " ,
2026-04-21 14:26:12 +02:00
" training_programs " : " 0.1.0 " ,
2026-05-05 22:11:05 +02:00
" planning " : " 0.8.1 " , # Vorlagen Leseprüfung library_content_visible_to_profile
2026-04-24 14:41:52 +02:00
" import_wiki " : " 1.0.0 " ,
2026-04-21 14:26:12 +02:00
" admin " : " 1.0.0 " ,
" membership " : " 1.0.0 " ,
2026-04-23 14:22:17 +02:00
" catalogs " : " 1.5.0 " , # Updated: Trainer Contexts API (Migration 012)
2026-04-27 13:13:36 +02:00
" maturity_models " : " 1.4.0 " , # matrix_stack_bundle: vollständiger Katalog+Modelle+Bindings Export/Import
2026-04-21 14:26:12 +02:00
}
CHANGELOG = [
2026-05-11 08:25:00 +02:00
{
" version " : " 0.8.76 " ,
" date " : " 2026-05-11 " ,
" changes " : [
" Fix P-06: RightsDeclarationDialog in ExerciseInlineFileMediaModal (Upload-Tab) und ExerciseInlineEmbedModal integriert; vor jedem Exercise-Media-Upload oeffnet sich der vollstaendige Einwilligungsdialog statt eines nicht-benutzbaren alert() " ,
] ,
} ,
feat(compliance): P-06 Upload-Einwilligungsdialog v1-conservative
Implementiert server-seitige Rechteerklärungspflicht für alle Medien-Uploads
und Sichtbarkeits-Promotions (konservative Erstannahme: alle Uploads).
Backend:
- backend/media_rights.py (NEU): Kernmodul — validate_rights_declaration,
check_rights_coverage, assert_rights_for_promotion, assert_rights_for_exercise_link,
write_rights_declaration, update_rights_quick_fields
- backend/migrations/048_media_rights_declarations.sql (NEU): Tabelle
media_asset_rights_declarations (Append-only Audit-Log), Felder
rights_status/rights_visibility_level in media_assets
- backend/routers/media_assets.py: P-06-Pflichtprüfung in PATCH (single + bulk),
POST /api/media-assets/{id}/rights-declarations (Re-Deklaration),
GET /api/admin/media-rights/legacy-summary|legacy-assets (Admin-Endpoints)
- backend/routers/exercises.py: P-06-Felder in upload_exercise_media,
assert_rights_for_exercise_link in attach_exercise_media_from_asset
- backend/main.py: admin_rights_router registriert
Frontend:
- frontend/src/components/RightsDeclarationDialog.jsx (NEU): 9-Felder-Dialog
(konservativ: immer alle Fragen), Client-Validierung, VORLÄUFIG-Hinweis
- frontend/src/pages/MediaLibraryPage.jsx: Dialog-Intercept vor Upload,
Altbestand-Indikator (legacy_unreviewed)
- frontend/src/utils/api.js: P-06-Felder in bulkUploadMediaAssets weitergeleitet
Tests:
- backend/tests/test_media_rights_declaration.py (NEU): 28 Unit-/Integrationstests
- backend/tests/test_media_assets_archive.py: P-06 fetchone-Slots + Mock ergänzt
- backend/tests/test_media_assets_copyright_promotion.py: check_rights_coverage gemockt
- tests/dev-smoke-test.spec.js: 5 P-06 E2E-Tests ergänzt
Dokumentation:
- docs/compliance-implementation.md: P-06-Abschnitt
- docs/compliance-package-register.md: Status ⚠️ teilweise umgesetzt (KRIT-04 offen)
- docs/compliance-roadmap.md: P-06 im Freigaben-Log
Offen: KRIT-04 (rechtliche Finalisierung Einwilligungsformulierung) — technisch
vollständig, Rechtstext VORLÄUFIG.
version: 0.8.75
module: media_rights 1.0.0, media_assets 1.13.0, exercises 2.20.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-11 08:12:44 +02:00
{
" version " : " 0.8.75 " ,
" date " : " 2026-05-11 " ,
" changes " : [
" P-06 (Upload-Einwilligungsdialog) technisch umgesetzt unter konservativen Erstannahmen (p06-v1-conservative): Migration 048 (media_asset_rights_declarations + rights_status/rights_declared_for_visibility/rights_declared_at in media_assets); zentrales Policy-Modul media_rights.py; Bulk-Upload und PATCH/Bulk-Patch mit P-06-Enforcement; Re-Deklarations-Endpoint (POST /api/media-assets/ {id} /rights-declarations); Admin-Legacy-Summary (GET /api/admin/media-rights/legacy-summary+/legacy-assets); exercises.py: P-06 bei upload_exercise_media und from-asset; Frontend: RightsDeclarationDialog + Altbestand-Indikator in Medienbibliothek. KRIT-04 bleibt offen bis juristische Validierung. " ,
] ,
} ,
2026-05-10 21:29:21 +02:00
{
" version " : " 0.8.74 " ,
" date " : " 2026-05-10 " ,
" changes " : [
" Rechtstexte: echtes PDF-Download via jsPDF (pdf.save) statt Browser-Print-Dialog; LegalPage und AdminLegalDocumentsPage " ,
" Rechtstexte Admin: Abschnitts-Reihenfolge per Pfeil-Buttons aendern; neuen Abschnitt an beliebiger Stelle einfuegen " ,
] ,
} ,
2026-05-10 16:47:52 +02:00
{
" version " : " 0.8.73 " ,
" date " : " 2026-05-10 " ,
" changes " : [
" Rechtstexte: PDF-Export via Browser-Print (kein neues Paket); Drucker-Button in AdminLegalDocumentsPage (laedt Volldokument) und auf LegalPage (nur bei veroeffentlichtem Inhalt); Dokument enthaelt Versionsnummer und Gueltigkeitsdatum " ,
] ,
} ,
2026-05-10 12:25:04 +02:00
{
" version " : " 0.8.72 " ,
" date " : " 2026-05-10 " ,
" changes " : [
" Rechtstexte: Als-Entwurf-kopieren — POST /api/admin/legal-documents/ {id} /copy-as-draft; Inhalt und Titel werden uebernommen, Versionsnummer inkrementiert " ,
] ,
} ,
2026-05-10 11:53:07 +02:00
{
" version " : " 0.8.71 " ,
" date " : " 2026-05-10 " ,
" changes " : [
" Compliance P-01c: Admin-konfigurierbare Rechtstexte — DB 047 (legal_documents + legal_document_audit); Superadmin CRUD + Publish/Archive-Workflow; LegalPage laedt aus API mit Platzhalter-Fallback; AdminLegalDocumentsPage unter /admin/legal-documents " ,
] ,
} ,
2026-05-10 10:51:20 +02:00
{
" version " : " 0.8.70 " ,
" date " : " 2026-05-10 " ,
" changes " : [
" Compliance P-01b: Einstellungen/Rechtliches (/settings/legal) fuer mobile/PWA-Darstellung; Hub mit Links zu Impressum, Datenschutz, Nutzungsbedingungen, Medienrichtlinie " ,
] ,
} ,
2026-05-10 09:41:45 +02:00
{
" version " : " 0.8.69 " ,
" date " : " 2026-05-10 " ,
" changes " : [
" Compliance P-01 (KRIT-01) technischer Teil: Rechtstextseiten /impressum, /datenschutz, /nutzungsbedingungen, /medienrichtlinie als oeffentliche Routen angelegt (Platzhalter, kein Auth erforderlich) " ,
" Login-Seite und Desktop-Sidebar enthalten Links zu allen vier Rechtstextseiten " ,
] ,
} ,
2026-05-10 09:08:28 +02:00
{
" version " : " 0.8.68 " ,
" date " : " 2026-05-10 " ,
" changes " : [
" Sicherheit P-12 (MITT-05): logout() bereinigt alle sj_coach_*-Schlüssel aus sessionStorage; Präfix-gezielte Löschung, keine fremden Schlüssel betroffen " ,
] ,
} ,
2026-05-09 22:11:33 +02:00
{
2026-05-10 08:26:15 +02:00
" version " : " 0.8.67 " ,
" date " : " 2026-05-10 " ,
" changes " : [
" Sicherheit P-05b: PasswordResetConfirm.new_password min_length=8 (POST /auth/reset-password) " ,
" Sicherheit P-03b: Retention-Default HIDDEN_TO_PURGE 90->30 Tage (gemaess Loeschkonzept 30+30) " ,
" Sicherheit P-04: Positive Promotion-Tests haerten (explizit 200 + Payload); Umlaut in Fehlermeldung " ,
] ,
} ,
{
2026-05-09 22:11:33 +02:00
" version " : " 0.8.66 " ,
" date " : " 2026-05-09 " ,
" changes " : [
" Sicherheit P-03: Papierkorb-Retention-Job (media_retention_job.py) als Docker-Service retention-cron aktiviert (lauft taglich um 03:00 Uhr) " ,
" Sicherheit P-04: Copyright-Pflicht bei Sichtbarkeits-Promotion auf club/official in PATCH und bulk-patch (media_assets) " ,
" Sicherheit P-05: Passwort-Mindestlange PUT /auth/pin von 4 auf 8 Zeichen angehoben " ,
" Sicherheit P-07: Release-Test fur ALLOW_PUBLIC_MEDIA_STATIC in test_security_release.py ergaenzt " ,
" Sicherheit P-23: LoginPage minLength 6 auf 8 angehoben; hartcodierter Versionsstring entfernt " ,
" Sicherheit P-24: CORS allow_methods und allow_headers auf benotigte Werte eingeschrankt " ,
] ,
} ,
2026-05-09 09:03:21 +02:00
{
" version " : " 0.8.65 " ,
" date " : " 2026-05-08 " ,
" changes " : [
" Übung auf Verein: fehlende Copyrights an Datei-Assets wieder per Bestätigung + Eingabe beim Speichern setzbar (PUT default_club_media_copyright; Bulk-PATCH ebenfalls) " ,
] ,
} ,
2026-05-08 12:35:28 +02:00
{
" version " : " 0.8.64 " ,
" date " : " 2026-05-08 " ,
" changes " : [
" Übung bearbeiten: Auto-Scroll beim Drag von Medien zu Textfeldern; Medien-Kacheln mehrspaltig; Sektion/Ablauf-Zuordnung an Medien entfernt (nur noch Titel bearbeiten); Picker: Video-Vorschau-Frame; Katalogvorschau ohne Anhangs-Medienliste; Ansehen mit Speichern-Hinweis + Zurück zur Bearbeitung von der Ansicht " ,
] ,
} ,
2026-05-08 12:20:24 +02:00
{
" version " : " 0.8.63 " ,
" date " : " 2026-05-08 " ,
" changes " : [
" RTE/Übung Medien: Picker-Thumbnails; Dateiauswahl-Anzeige; bereits verknüpfte Archive-Medien ins Fließtext einfügen; Platzhalter-Caption data-shinkan-exercise-media-caption + Caret nach ZWSP; Lesemodus: Medienliste nur für nicht eingebettete Anhänge; bearbeiten: kompakte Kacheln mit Drag-and-Drop in Textfelder, Upload unter Medien entfällt " ,
] ,
} ,
2026-05-08 12:00:02 +02:00
{
" version " : " 0.8.62 " ,
" date " : " 2026-05-08 " ,
" changes " : [
" RTE Inline-Medien: Modals Mediathek+Hochladen + „Embed im Text“; Darstellungsgröße small|medium|full (data-shinkan-exercise-media-size); Lesemodus begrenzt Bild/Video-Breite " ,
] ,
} ,
2026-05-08 11:51:28 +02:00
{
" version " : " 0.8.61 " ,
" date " : " 2026-05-08 " ,
" changes " : [
" RTE „Bild/Video im Text“: eingebaute Hilfe (Caret + insertHTML/Fallback); sichtbarer 📎-Chip im Editor; Hinweis bei fehlgeschlagener Einfügung/Prompt-ID " ,
] ,
} ,
2026-05-08 11:44:29 +02:00
{
" version " : " 0.8.60 " ,
" date " : " 2026-05-08 " ,
" changes " : [
" Inline-Medien im Übungs-Fließtext (MEDIA_SPEC §11): {{ exerciseMedia:id}} → kanonisches span; nur exercise_media dieser Übung; create ohne Platzhalter " ,
" Frontend: ExerciseRichTextBlock mit Allowlist-Sanitize + Embed; Toolbar „Bild/Video im Text“ im RichTextEditor wenn Medien an der Übung; Detail/Katalog/Liste konsistent " ,
] ,
} ,
2026-05-08 10:45:58 +02:00
{
" version " : " 0.8.59 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Aktiver Verein: Backend resolve_tenant_context für Plattform-Admin ohne X-Active-Club-Id nutzt gespeichertes active_club_id wenn der Verein existiert (kein effective=null nach hartem Reload mehr) " ,
" Frontend: Nach Vereinswechsel Profil neu laden; Dropdown-Wert aus effective_club_id / active_club_id / LocalStorage abgestimmt (getResolvedActiveClubIdForUi) " ,
] ,
} ,
2026-05-08 10:35:28 +02:00
{
" version " : " 0.8.58 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medienbibliothek offiziell: Ändern/Lifecycle nur Superadmin (nicht Plattform-Admin); Bearbeiten-Dialog für andere nur Lesemodus; Superadmin: Vereinsauswahl beim Archiv-Upload folgt aktiv/gesetzt effective_club_id " ,
] ,
} ,
2026-05-08 10:20:41 +02:00
{
" version " : " 0.8.57 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Governance: visibility=official nur noch Superadmin (nicht Plattform-Admin) " ,
" Medienarchiv: private Uploads als Plattform-Admin erfordern explizites club_id; gleiche Ordnerstruktur wie „Verein“, private Kopien mit .u {Profil} vor Dateiendung " ,
" Übung visibility=Verein: angebundene Archiv-Dateien müssen aktiv sein und Copyright (≥3 Zeichen) haben; UI- und API-Fehlercodes CLUB_MEDIA_* " ,
" Frontend: „Offiziell“ nur Superadmin (Bibliothek, Übungsformular, Bulk-Sichtbarkeit, Progressionsgraphen) " ,
] ,
} ,
2026-05-08 10:06:05 +02:00
{
" version " : " 0.8.56 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medienbibliothek: Vereinsmedien unter library/ { aus Name abgeleitet}-c {club_id} / statt festem library/club/c {id} /; Sonderzeichen/Umlaute zu sicheren Ordnernamen; fehlender Name → verein-c {id} ; Governance-Umzug liest aktuellen Vereinsnamen aus DB " ,
] ,
} ,
2026-05-08 10:03:00 +02:00
{
" version " : " 0.8.55 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medienbibliothek: Speicherpfad library/* mit Medientyp-Unterordnern (image, video, pdf, other) vor SHA-Dateinamen; Umzug bei Governance-PATCH nutzt mime_type aus DB " ,
] ,
} ,
2026-05-08 10:00:37 +02:00
{
" version " : " 0.8.54 " ,
" date " : " 2026-05-08 " ,
" changes " : [
" Medienpfade: vereinsgeteilt (club) direkt unter library/club/c {id} /; private unter library/club/c {id} /u {profile} / (kein Ordner „private“/„shared“); Dedupe private inkl. uploaded_by_profile_id " ,
] ,
} ,
2026-05-08 09:58:28 +02:00
{
" version " : " 0.8.53 " ,
" date " : " 2026-05-08 " ,
" changes " : [
" Medienablage vereinsbezogen: private → library/club/c {id} /private, Vereinssichtbarkeit → …/shared, official unverändert; private Archiv-Upload: club_id oder X-Active-Club-Id; DB club_id bei private gesetzt; PATCH/Bulk: club_id für private nicht mehr blind auf NULL " ,
] ,
} ,
2026-05-08 09:47:16 +02:00
{
" version " : " 0.8.52 " ,
" date " : " 2026-05-08 " ,
" changes " : [
2026-05-08 09:58:28 +02:00
" Neue lokale media_assets: hierarchische library/* Pfade; Dedupe nach sha+visibility+club_id; bei PATCH/Bulk-Patch Sichtbarkeit/Verein: Datei umziehen, exercise_media.file_path aktualisieren (Details siehe 0.8.53) " ,
2026-05-08 09:47:16 +02:00
] ,
} ,
2026-05-07 16:24:05 +02:00
{
" version " : " 0.8.51 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medienbibliothek GET: Verknüpfung zu Trainingseinheiten nur wenn Tabelle training_unit_exercises existiert (ältere/kaputte Schemas → keine 500, Einheiten-Liste leer) " ,
] ,
} ,
2026-05-07 16:15:07 +02:00
{
" version " : " 0.8.50 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medienbibliothek: DB 046 media_assets.tags (GIN); GET filter media_kind, club_id (Superadmin), uploaded_by; Suche über Copyright & Tags; Antwort usage exercises + training_units; PATCH/Bulk tags; UI volle Breite, Filterleiste, ©-Symbol auf Kacheln, Links zu Übungen/Planung, gleiche Sichtbarkeits-/Status-Symbole wie Übungsliste " ,
] ,
} ,
2026-05-07 14:33:02 +02:00
{
" version " : " 0.8.49 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medienbibliothek UI: Kacheln/Liste, Modal Bearbeiten, Video-First-Frame-Thumbs, Mobile/Safe-Area, Bulk; API: permissions pro Zeile, Uploader/Verein für Admin, PATCH Sichtbarkeit+Bezeichner, trash_soft nur Trainer-Eigenes-Privat / Vereinsorga / Plattform; purge nur Superadmin; superadmin_force_lifecycle + hard_delete; bulk-lifecycle, bulk-patch " ,
] ,
} ,
2026-05-07 14:10:26 +02:00
{
" version " : " 0.8.48 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medienbibliothek: GET /api/media-assets mit lifecycle (active|trash_soft|trash_hidden|all), copyright_notice in Liste; PATCH /api/media-assets/ {id} (Copyright); GET …/file für Papierkorb wenn Lifecycle-Recht; Frontend /media + Admin-Nav + Link Übungsformular " ,
] ,
} ,
2026-05-07 13:34:22 +02:00
{
" version " : " 0.8.47 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Übung „offiziell“ (§4.2): angehängte Datei-Assets müssen aktiv sein; Sichtbarkeit/Copyright per Bestätigung anheben; PUT /api/exercises/ {id} + PATCH bulk-metadata: Felder promote_attached_media_for_official, default_official_media_copyright; Frontend Bestätigungsdialog " ,
] ,
} ,
2026-05-07 13:30:25 +02:00
{
" version " : " 0.8.46 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Übung Medien-Upload: bei 409-Konflikt (Papierkorb-Dedupe) logger.warning mit exercise_id, profile_id, media_asset_id, lifecycle, visibility, club_id, sha256_prefix, Dateinamen " ,
" ExerciseFormPage: erklärende Medien-Hinweistexte in GUI entfernt (Kurzbeschreibung + Archiv-Dialog) " ,
] ,
} ,
2026-05-07 13:25:42 +02:00
{
" version " : " 0.8.45 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Upload Übungsmedien: gleicher Inhalt (SHA-256) wie Papierkorb-Asset → 409 MEDIA_ASSET_IN_TRASH statt DB-Fehler; Lifecycle action reactivate (trash_soft/hidden → active) " ,
" Frontend: Dialog Reaktivieren + Verknüpfen; uploadExerciseMedia wertet strukturiertes 409 aus " ,
] ,
} ,
2026-05-07 13:10:37 +02:00
{
" version " : " 0.8.44 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" DELETE /api/exercises/ {id} /media/ {mid} : entfernt nur exercise_media; keine Datei-/media_assets-Löschung; Response orphan_media_asset_id wenn letzte Referenz " ,
" Übung bearbeiten: Video-Kachel (Erstframe), Dateiname; Papierkorb-Schalter entfernt; „Aus Übung entfernen“ + optional Papierkorb bei Waise " ,
] ,
} ,
2026-05-07 13:00:57 +02:00
{
" version " : " 0.8.43 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medienarchiv: GET /api/media-assets (Suche, nur aktive Assets, Bibliotheks-Sichtbarkeit); GET /api/media-assets/ {id} /file (Thumbnails/Vorschau, ssetoken) " ,
" Übungen: POST /api/exercises/ {id} /media/from-asset — bestehendes Archiv-Medium verknüpfen ohne Upload-Duplikat " ,
" Frontend Übung bearbeiten: „Aus Archiv verknüpfen…“, Medienvorschau-Modal, Kachel-Thumbnails in der Medienliste " ,
] ,
} ,
2026-05-07 12:55:50 +02:00
{
" version " : " 0.8.42 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" Medien-Papierkorb: POST /api/media-assets/ {id} /lifecycle (trash_soft, trash_hidden, recover, purge); Retention-Job scripts/media_retention_job.py " ,
" Übungen: GET-Detail inkl. asset_lifecycle_state; Bearbeitungsrechte Erweiterung (Vereinsplanung); Frontend Übung bearbeiten: Reihenfolge, Papierkorb-Actions; Detail/Katalog: trash_hidden ausgeblendet, Hinweis trash_soft " ,
" Fix: ExerciseDetailPage zeigt „Hinweise für Trainer“ wieder an " ,
] ,
} ,
2026-05-07 12:36:46 +02:00
{
" version " : " 0.8.41 " ,
" date " : " 2026-05-07 " ,
" changes " : [
" DB 045: media_assets, exercise_media.media_asset_id, platform_media_storage; Migration bestehender Medien; Upload-Dedupe pro sha256+visibility+club_id " ,
" Effektives Medien-Verzeichnis: MEDIA_ROOT + Superadmin local_relative_root (GET/PUT /api/admin/platform-media-storage) " ,
" Neue Uploads: storage_key exercises/ {sha256} {ext} ; Download/Delete nutzen media_assets " ,
" api.js: getPlatformMediaStorage, putPlatformMediaStorage " ,
] ,
} ,
2026-05-06 17:15:44 +02:00
{
" version " : " 0.8.40 " ,
" date " : " 2026-05-06 " ,
" changes " : [
" Übungen Liste: Fokusfilter mit UND-+ (must_include) und UND-− (must_exclude), nur ohne Fokusbereich (focus_only_without); Frontend Dropdown + Mit / − Ohne " ,
] ,
} ,
2026-05-06 13:52:24 +02:00
{
" version " : " 0.8.39 " ,
" date " : " 2026-05-06 " ,
" changes " : [
" Übungen DELETE: Nur eigene private / Vereinsadmin für Vereins-Übungen / Plattform für globale; keine harte Löschung bei Verwendung in Blöcken, Plan-Abschnitten oder Progressionskanten (409 → archivieren) " ,
" GET /api/exercises: Negativfilter (visibility_exclude_any, status_exclude_any), exclude_without_focus, include_archived; archivierte standardmäßig ausgeblendet " ,
" Profile exercise_list_prefs (JSONB, Migration 043): gespeicherte Standardfilter; Frontend Übungsliste Filterdialog + „Als Standard speichern“ " ,
" Übungspicker: gleiche Negativfilter; Planung lädt archivierte Übungen immer mit (bestehende Zuordnungen) " ,
" pytest: tests/test_exercises_delete_policy.py " ,
] ,
} ,
2026-05-06 07:18:30 +02:00
{
" version " : " 0.8.38 " ,
" date " : " 2026-05-06 " ,
" changes " : [
" Trainingsplanung: Vereinsadmins sehen alle Einheiten bei club_id-/Gruppenliste; GET/PUT Einheit & Löschen mit can_manage_club_org " ,
" Planung UI: „Trainer zuweisen“ in Vereins-Ansicht (Liste + Kalender) + eigener Modal; Mitgliederverzeichnis für Vereinsorganisation " ,
] ,
} ,
2026-05-05 23:35:41 +02:00
{
" version " : " 0.8.37 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" DB 042: training_units.assistant_trainer_profile_ids (Co-Trainer-Zuweisung je Termin; NULL = Gruppen-Standard) " ,
" Trainingseinheiten: POST/PUT lead_trainer_profile_id & assistant_trainer_profile_ids; Leitung für Vereinsmitglieder (Vertretung); GET-Listen inkl. Zuweisung für Sichtbarkeit/assigned_to_me " ,
" Frontend Trainingsplanung: Leitung/Co-Trainer pro Einheit; Dashboard-Text " ,
" pytest: tests/test_training_unit_assignments.py " ,
] ,
} ,
2026-05-05 23:01:14 +02:00
{
" version " : " 0.8.36 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" POST /api/profiles: nur Plattform-Admin; Anlage schema-konform (SERIAL, E-Mail, temporärer PIN-Hash); ProfileCreate mit Pflichtfeldern name + email " ,
" pytest: POST-Szenarien in test_profiles_read_access.py " ,
] ,
} ,
2026-05-05 22:57:42 +02:00
{
" version " : " 0.8.35 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" DELETE /api/profiles/ {pid} : nur Plattform-Admin (403 sonst); Unit-Tests mit gemockter DB " ,
] ,
} ,
{
" version " : " 0.8.34 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" GET /api/profiles/ {pid} : Zugriff nur eigenes Profil oder Plattform-Admin (403 sonst); Unit-Tests ohne DB; zwei Integrationstests mit PostgreSQL " ,
" Integration: zwei zusätzliche Profil-Lese-Tests in test_access_layer_integration " ,
] ,
} ,
2026-05-05 22:51:59 +02:00
{
" version " : " 0.8.33 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" CI pytest-backend wie Mitai-Jinkendo: docker compose exec backend (deployte Stacks shinkan / shinkan-dev); keine Runner-Python/Postgres-Service " ,
" pytest.ini: Marker smoke/slow, addopts/-q wie Schwesterprojekt; CI: -m \" not slow \" , ACCESS_LAYER_STRICT + Integration im Container " ,
] ,
} ,
{
" version " : " 0.8.32 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" CI pytest-backend: kein setup-python — venv aus System-python3 (arm64/Debian Self-Host, Raspi) " ,
] ,
} ,
2026-05-05 22:47:00 +02:00
{
" version " : " 0.8.31 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" CI (Gitea): Job pytest-backend — Checkout, Postgres-Service, run_migrations, pytest (+ ACCESS_LAYER_INTEGRATION), ACCESS_LAYER_STRICT auf Router-Hinweis-Script " ,
" Workflow test.yml: pull_request auf main/develop zusätzlich zu push " ,
] ,
} ,
2026-05-05 22:34:35 +02:00
{
" version " : " 0.8.30 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" pytest: optionale PostgreSQL-Integration tests/test_access_layer_integration.py (Cross-Verein Übungen Liste/Detail; ACCESS_LAYER_INTEGRATION=1) " ,
" pytest.ini: Marker „integration“ " ,
] ,
} ,
2026-05-05 22:18:04 +02:00
{
" version " : " 0.8.29 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" Übungen: PATCH /api/exercises/bulk-metadata (bis 500 IDs) — Sichtbarkeit und/oder Status; Ersteller oder Plattform-Admin; Governance wie Einzel-PUT " ,
" Übungsliste: Mehrfachauswahl, Alle auf dieser Seite, Dialog Massenänderung (Verein/offiziell nur Admins) " ,
] ,
} ,
2026-05-05 22:11:05 +02:00
{
" version " : " 0.8.28 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" ACCESS_LAYER: Übungen-, Trainingsplanung-, Rahmenprogramme-Detail nutzen library_content_visible_to_profile (einheitliche Leseprüfung) " ,
" pytest: backend/requirements-dev.txt, pytest.ini, backend/tests/test_access_layer.py — ohne DB (library_content_visibility_sql, parse_active_club_header) " ,
] ,
} ,
2026-05-05 22:09:25 +02:00
{
" version " : " 0.8.27 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" ACCESS_LAYER Governance-Disziplin: .cursor/rules/access-layer.mdc; ARCHITECTURE 1.4 + CODING_RULES Tenant-Pfad; CLAUDE Pflichtlektüre Zugriffsschicht " ,
" backend/scripts/check_access_layer_hints.py — Router ohne get_tenant_context außerhalb EXEMPT melden (optional ACCESS_LAYER_STRICT=1) " ,
" club_tenancy.library_content_visible_to_profile; Audit-Tabelle um globale Router (EXEMPT) ergänzt " ,
] ,
} ,
2026-05-05 22:05:10 +02:00
{
" version " : " 0.8.26 " ,
" date " : " 2026-05-05 " ,
" changes " : [
" ACCESS_LAYER: clubs-, club_memberships-, club_join_requests-Router nutzen Depends(get_tenant_context) statt nur require_auth " ,
" profiles: PUT /profiles/ {id} und /profile mit TenantContext; profile_document für /auth/me und intern " ,
" exercise_progression_graphs: Liste/Detail nach library_content_visibility_sql; Leserechte Vereins-Graphs; POST/PUT mit assert_valid_governance_visibility und club_id wie Übungen " ,
] ,
} ,
2026-05-05 21:57:55 +02:00
{
" 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) " ,
] ,
} ,
2026-05-05 21:51:53 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 21:46:41 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 21:42:56 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 21:15:27 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 21:10:19 +02:00
{
" 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) " ,
] ,
} ,
2026-05-05 21:05:52 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 16:40:49 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 16:29:11 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 16:20:16 +02:00
{
" 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) " ,
] ,
} ,
2026-05-05 16:18:42 +02:00
{
" 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) " ,
] ,
} ,
2026-05-05 16:12:17 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 15:40:29 +02:00
{
" 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) " ,
] ,
} ,
2026-05-05 13:31:26 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 13:11:17 +02:00
{
" 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 " ,
] ,
} ,
2026-05-05 08:41:43 +02:00
{
" 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) " ,
] ,
} ,
2026-05-03 18:07:52 +02:00
{
" 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 " ,
] ,
} ,
2026-04-30 11:47:50 +02:00
{
" 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 " ,
] ,
} ,
2026-04-29 12:29:39 +02:00
{
" 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) " ,
] ,
} ,
2026-04-28 10:59:09 +02:00
{
2026-04-28 16:31:45 +02:00
" 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 " ,
] ,
} ,
2026-04-28 16:34:27 +02:00
{
" version " : " 0.7.9 " ,
2026-04-28 10:59:09 +02:00
" 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 " ,
] ,
} ,
2026-04-28 09:30:33 +02:00
{
" 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 " ,
] ,
} ,
2026-04-27 18:25:23 +02:00
{
" version " : " 0.7.7 " ,
" date " : " 2026-04-27 " ,
" changes " : [
" DB 029: Fähigkeitsstufen Einheit (basis– optimierung), model_levels Namen 1– 5 " ,
" Ü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 " ,
] ,
} ,
2026-04-27 13:13:36 +02:00
{
" 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 " ,
2026-04-27 14:27:25 +02:00
" DB 028: exercise_media (Embed/Metadaten), exercise_skills VARCHAR-Level/Intensität; API: POST/PUT/DELETE Medien, /media Static; Übungen-Listen-Fokus " ,
2026-04-27 13:13:36 +02:00
] ,
} ,
2026-04-27 13:05:18 +02:00
{
" 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) " ,
] ,
} ,
2026-04-27 12:48:22 +02:00
{
" 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) " ,
] ,
} ,
2026-04-27 12:35:48 +02:00
{
" 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 " ,
] ,
} ,
2026-04-27 11:42:03 +02:00
{
" 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 1– 5 " ,
" API+UI: Kontext als Mehrfachauswahl; Matrix zeigt Haupt-/Untergruppe pro Fähigkeit " ,
] ,
} ,
2026-04-27 11:32:30 +02:00
{
" 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) " ,
] ,
} ,
feat: Exercises v2.0 + Migrations 014/016/017 (Clean-Room Rebuild)
BREAKING CHANGES:
- exercises.py komplett neu gebaut (kein Legacy-Code)
- Legacy-Felder entfernt: age_groups, focus_area, secondary_areas, training_character
- Nur M:N Relations, keine JSONB-Kataloge
Migrations:
- Migration 014: Variant Progression + Search Vector + Legacy DROP
- exercise_variants: progression_level, sequence_order, prerequisite_variant_id
- exercises: search_vector (tsvector für Volltext-Suche)
- DROP age_groups, focus_area, secondary_areas, training_character
- Helper: update_timestamp() Funktion für Triggers
- Migration 016: Saved Exercise Searches
- saved_exercise_searches (profile_id, name, filters JSONB)
- Migration 017: Exercise Blocks + Template Blocks
- exercise_blocks (name, description, goal, is_template)
- exercise_block_items (exercise_id, variant_id, sequence_order, is_placeholder, placeholder_criteria)
Backend (exercises.py v2.0):
- GET /exercises: Volltext-Suche via tsvector, M:N Joins
- GET /exercises/{id}: enrich_exercise_detail() mit allen M:N Relations
- POST /exercises: M:N Relations (focus_areas_multi, training_styles_multi, target_groups_multi, age_groups, skills)
- PUT /exercises: Partial Update + M:N Relations
- DELETE /exercises: Cascade-Check für exercise_block_items
Architecture:
- Issue #53 konform: Import = Feld-Zuordnung, keine fachliche Interpretation
- Helper: enrich_exercise_detail() für vollständige Objekte
- Helper: assign_exercise_relations() für M:N Management (DELETE+INSERT Pattern)
Docs:
- SMW_IMPORTER_GAP_ANALYSIS.md: Vollständige Gap-Analyse + Umsetzungsplan
Version: 0.7.0
Module: exercises 2.0.0
Schema: 20260424002
2026-04-24 15:04:27 +02:00
{
" 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 " ,
]
} ,
2026-04-24 14:41:52 +02:00
{
" 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 " ,
]
} ,
2026-04-23 14:22:17 +02:00
{
" 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 " ,
]
} ,
2026-04-23 12:10:27 +02:00
{
" 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) " ,
2026-04-23 12:24:50 +02:00
" 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 " ,
2026-04-23 12:10:27 +02:00
]
} ,
2026-04-23 10:37:56 +02:00
{
" 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 " ,
]
} ,
2026-04-23 09:00:28 +02:00
{
" version " : " 0.3.3 " ,
" date " : " 2026-04-23 " ,
" changes " : [
" Fix: Admin-Navigation - Redirect /admin → /admin/catalogs " ,
" Fix: Admin-Link funktioniert jetzt (vorher 404) "
]
} ,
2026-04-23 08:55:54 +02:00
{
" 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) " ,
]
} ,
2026-04-23 08:51:45 +02:00
{
" 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 " ,
]
} ,
2026-04-23 08:46:56 +02:00
{
" 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) " ,
]
} ,
2026-04-23 08:05:11 +02:00
{
" 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 " ,
]
} ,
2026-04-21 14:26:12 +02:00
{
" 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 " ,
]
}
]