shinkan-jinkendo/.claude/docs/technical/SKILL_SCORING_SPEC.md
Lars 78c6c51520
All checks were successful
Deploy Development / deploy (push) Successful in 39s
Test Suite / pytest-backend (push) Successful in 42s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 13s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m15s
Enhance Skill Scoring and Profile Features
- Updated the skill scoring specification to include club-specific metrics and improved aggregation methods for skill profiles.
- Introduced new API endpoints for batch skill profile summaries, allowing for efficient retrieval of compact skill data.
- Enhanced frontend components to display skill profiles with club comparisons, improving user interaction and visibility of skill strengths.
- Added filtering options for skills in the framework programs, enabling users to refine selections based on training weight relative to club maximums.
- Improved CSS styles for skill profile displays, ensuring a cohesive and user-friendly interface across the application.
2026-05-21 09:05:13 +02:00

4.3 KiB
Raw Blame History

Gewichtetes Fähigkeiten-Scoring (Phase 3)

Stand: 2026-05-20
Status: Variante A (regelbasiert) umgesetzt — v1.2 (Kategorien-Gruppierung + universelle Skala)
Modul: backend/skill_scoring.py, Router skill_profiles

Ziel

Trainer wählen Schwerpunkt-Fähigkeiten und erhalten Vorschläge für Rahmenprogramme, Trainingsmodule und Regressionspfade (Progressionsgraphen), deren Übungen diese Fähigkeiten stark abdecken.

Datenquellen

Artefakt Übungen aus
Rahmenprogramm (gesamt) Alle Blueprint-training_units der Slots → training_unit_section_items
Rahmenprogramm (pro Slot) Blueprint einer Session
Trainingsmodul training_module_items (nur item_type = exercise)
Progressionsgraph from_exercise_id + to_exercise_id je Kante (Vorkommen zählt)

Fähigkeiten je Übung: exercise_skillsskills (nur status = active).

Gewichtungsformel (v1.1)

Pro Übungsvorkommen (eine Zeile im Ablauf / Modul / Kanten-Endpunkt):

  1. Basis-Minuten = planned_duration_min der Position, sonst Default (Einheit/Modul: 8 Min, Graph: 10 Min).
  2. Pro verknüpfte Fähigkeit der Übung:
    • Beitrag = Basis-Minuten × Anzahl Vorkommen × Link-Faktor
    • Link-Faktor = Intensität × Stufen-Faktor

Intensität (Nutzeneinschätzung, UI-Feld)

Wert Faktor
niedrig 0,85
mittel / leer 1,0
hoch 1,2

Stufen-Spanne (required_leveltarget_level, UI „von/bis“)

Kanonische Slugs: basis … optimierung (15). Fehlen beide: Faktor 1,0.

  • Spanne = Anzahl Stufen von „von“ bis „bis“ (15)
  • Mittelpunkt = durchschnittliche Stufe
  • Faktor ≈ (0,92 + 0,04 × Spanne) × (0,95 + 0,025 × Mittelpunkt) → typisch 0,961,20

Beispiel: von Grundlagen bis Aufbau (Spanne 2) > nur Basis (Spanne 1).

Bewusst nicht im Scoring

Feld Grund
is_primary Perspektivabhängig; bleibt in Übungs-UI, fließt nicht ins Profil ein
development_contribution Legacy-DB-Feld, in UI nicht gepflegt

Aggregation:

  • Summe pro skill_idweight / score (Trainingsgewicht in gewichteten Minuten — absolut, über Programme vergleichbar)
  • artifact_share_percent / share_percent = Anteil an total_weight innerhalb dieses Artefakts (summiert 100 % — nur noch sekundär)
  • by_main_category[] → je Unterkategorie top_skill (stärkste Fähigkeit nach absolutem Gewicht)
  • universal_percent = weight / max_weight_in_corpus(skill_id) × 100 — Referenz aus Vereins-Artefakten (visibility=club, aktiver Verein): Rahmenprogramme, Module, Regressionspfade
  • club_best / club_best_by_skill: stärkstes Vereins-Element je Fähigkeit (Titel, Typ, Gewicht)
  • Listen: POST /api/skill-profiles/batch-summaries — ein Corpus-Durchlauf, kompakte Profile für viele IDs

Discovery-Sortierung und Vorschläge nutzen match_score (= Summe absoluter Gewichte der gewählten Fähigkeiten), nicht den Plan-internen Anteil.

API

Methode Pfad Beschreibung
GET /api/training-framework-programs/{id}/skill-profile overall + slots[] mit je profile
GET /api/training-modules/{id}/skill-profile overall
GET /api/exercise-progression-graphs/{id}/skill-profile overall
GET /api/skill-discovery/suggestions?skill_ids=1,2,3 Ranking sichtbarer Artefakte; Query types, limit

Zugriff: get_tenant_context + gleiche Sichtbarkeit wie Parent-Artefakt (library_content_visibility_sql).

UI

  • Rahmenprogramm bearbeiten: Panel „Fähigkeiten-Schwerpunkte“, inkl. Aufklapp pro Session
  • Trainingsmodul bearbeiten: Panel „Fähigkeiten im Modul“
  • Progressionsgraph: Panel „Fähigkeiten entlang des Pfads“
  • Fähigkeiten-Seite → Planungs-Vorschläge: Multi-Select + Bibliothekssuche

Profil wird nach Speichern neu geladen (skillProfileTick).

Grenzen / später

  • Kein Cache in DB (skill_profile_json) — on-the-fly; bei Performance >50 Artefakte serverseitiger Index
  • Entwicklungsziele am Rahmenkopf bleiben Freitext (kein Scoring)
  • KI-Zusammenfassung (Variante B Roadmap) nicht Teil von v1.0
  • Trainingseinheiten (Kalender) optional als nächste Erweiterung

Tests

  • backend/tests/test_skill_scoring.py — Multiplikator, Aggregation, Match-Score