shinkan-jinkendo/.claude/docs/technical/SKILL_SCORING_SPEC.md
Lars 1d698e4b0a
Some checks failed
Deploy Development / deploy (push) Failing after 22s
Test Suite / pytest-backend (push) Successful in 35s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Failing after 3s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m14s
Implement Phase 3 Enhancements for Skill Scoring and Profiles
- Added capabilities for weighted skill profiles, allowing trainers to compare training modules, frameworks, and regression paths based on skill contributions.
- Updated the skill scoring specification to include peer context separation and list filtering, ensuring accurate comparisons among visible artifacts of the same type.
- Enhanced the API to support batch summaries for skill profiles and discovery suggestions, improving data retrieval efficiency.
- Refactored frontend components to display skill metrics, including scores and peer percentages, with improved filtering options for better user experience.
- Updated documentation to reflect the latest changes and enhancements in the skill scoring system.
2026-05-21 12:35:45 +02:00

8.4 KiB
Raw Blame History

Gewichtetes Fähigkeiten-Scoring (Phase 3)

Stand: 2026-05-20
Status: Variante A (regelbasiert) umgesetzt — v1.3 (Peer-Kontext getrennt + Listen-Filter)
Modul: backend/skill_scoring.py, Router backend/routers/skill_profiles.py

Ziel

Trainer wählen Schwerpunkt-Fähigkeiten und finden passende Bausteine für die Trainingsplanung:

  • Trainingsmodule — wiederverwendbare Übungsfolgen
  • Rahmenprogramme — Programme mit Zielen und Session-Slots
  • Regressionspfade (Progressionsgraphen) — Übungsketten

Das Scoring beantwortet: Wie stark trainiert dieser Baustein eine Fähigkeit? und Wie stark ist er im Vergleich zu anderen sichtbaren Bausteinen desselben Typs?

Fachliche Kernregel: Peer-Kontext (nicht vermischen)

Planungs-Artefakt Vergleichsgruppe (universal_percent)
Trainingsmodul nur andere sichtbare Module
Rahmenprogramm nur andere sichtbare Rahmenprogramme
Regressionspfad nur andere sichtbare Pfade

Nicht verglichen werden:

  • Module vs. Rahmenprogramme vs. Pfade (kein Mix)
  • Artefakte anderer Vereine, auf die der Nutzer keinen Planungszugriff hat

Sichtbarkeit: library_content_visibility_sql — private, vereinsinterne und offizielle Inhalte gemäß Mandant/Rolle, analog zu anderen Bibliothekslisten.

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 / v1.2)

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

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

Aggregierte Metriken

Feld Bedeutung
weight / score Absolutes Trainingsgewicht (gewichtete Minuten) — über alle Fähigkeiten eines Artefakts vergleichbar
share_percent Anteil am total_weight innerhalb dieses Artefakts (summiert 100 %) — sekundär
by_main_category[] Je Unterkategorie top_skill (stärkste Fähigkeit nach Gewicht)
universal_percent Anteil am Maximum derselben Fähigkeit im Peer-Kontext (max. 100 %)
is_club_best_for_skill Stärkster sichtbarer Peer für diese Fähigkeit (★ in UI)
club_best Referenz-Peer (Titel, Typ, Gewicht) — Legacy-Name, fachlich Peer-Best

Berechnung universal_percent

effective_ref = max(max_weight_in_peer_corpus(skill_id), eigenes_gewicht)
universal_percent = min(100, weight / effective_ref × 100)

Corpus je Typ: compute_planning_corpus_by_type() scannt sichtbare Artefakte getrennt nach framework_program, training_module, progression_graph.

Discovery-Sortierung nutzt match_score (= Summe absoluter Gewichte der gewählten Fähigkeiten), nicht den Plan-internen Anteil. Discovery verwendet typ-getrennte Referenz (fw_ref, mod_ref, graph_ref).

API

Methode Pfad Beschreibung
GET /api/training-framework-programs/{id}/skill-profile overall + slots[] mit je profile; reference_scale (Peer-Kontext Rahmenprogramme)
GET /api/training-modules/{id}/skill-profile overall; reference_scale (Peer-Kontext Module)
GET /api/exercise-progression-graphs/{id}/skill-profile overall; reference_scale (Peer-Kontext Pfade)
POST /api/skill-profiles/batch-summaries Kompakte Profile für Listen; Body: frameworkProgramIds, trainingModuleIds, …; Response: summaries, reference_scale_by_type, club_best_by_skill
GET /api/skill-discovery/suggestions?skill_ids=1,2,3 Ranking sichtbarer Artefakte; Query types, limit

Zugriff: get_tenant_context + library_content_visibility_sql wie Parent-Artefakt.

reference_scale / reference_scale_by_type

{
  "scope": "planning_peer",
  "artifact_type": "training_module",
  "artifacts_scanned": 12,
  "skills_in_corpus": 34,
  "description": "Prozent = Anteil am stärksten sichtbaren Eintrag unter Trainingsmodulen …"
}

UI

Bearbeitung (Vollprofil)

Ort Panel artifactType
Rahmenprogramm bearbeiten Fähigkeiten-Schwerpunkte (+ Sessions) framework_program
Trainingsmodul bearbeiten Fähigkeiten im Modul training_module
Progressionsgraph Fähigkeiten entlang des Pfads progression_graph

Anzeige: Top je Kategorie (Editor) oder alle Fähigkeiten (Modal). Hinweise nennen Peer-Kontext explizit (z. B. „72 % Rahmenpr.“).

Listen & Filter (UX wie Übungsliste)

Liste Filter
Rahmenprogramme (/planning/framework-programs) Suche, Katalog (Fokus/Trainingsart/Zielgruppe), Session-Dauer, Fähigkeiten (SkillTreeMultiSelect), Mindest-% im Peer-Kontext, Sortierung nach Stärke
Trainingsmodule (/planning/training-modules) Suche, Fähigkeiten (+ Min-%, Sortierung)
  • Filter-Button mit Badge, entfernbare Chips, Einstellungen im Modal (PlanningArtifactFilterModal)
  • KPI-Kacheln: Top-Fähigkeit je Unterkategorie mit Score + Peer-%
  • Vollprofil-Modal: SkillProfileFullModal mit displayMode=full

Profil wird nach Speichern neu geladen (skillProfileTick in Editoren).

Discovery

Fähigkeiten-Seite → Planungs-Vorschläge: Multi-Select + API /api/skill-discovery/suggestions (optional Filter types).

Frontend-Module (Auswahl)

Pfad Rolle
frontend/src/components/planning/PlanningArtifactFilterModal.jsx Filter-Modal
frontend/src/components/planning/PlanningSkillFilterSection.jsx Fähigkeiten-Block im Modal
frontend/src/utils/planningArtifactFilterChips.js Chip-Labels + Entfernen
frontend/src/utils/frameworkProgramListHelpers.js Client-Filter Rahmenprogramme
frontend/src/utils/trainingModuleListHelpers.js Client-Filter Module
frontend/src/components/skills/SkillProfileCompact.jsx KPI-Kacheln in Listen
frontend/src/components/SkillTreeMultiSelect.jsx Baumauswahl (Portal-Dropdown in Modals)

Grenzen / später

  • Kein DB-Cache (skill_profile_json) — on-the-fly; bei >50 Artefakten pro Typ serverseitiger Index/Caching
  • Entwicklungsziele am Rahmenkopf bleiben Freitext (kein Scoring)
  • KI-Zusammenfassung (Variante B) nicht Teil von v1.0
  • Trainingseinheiten (Kalender) optional als nächste Erweiterung
  • Filter-Persistenz („Als Standard speichern“) wie bei Übungen — noch nicht für Planungslisten
  • Fähigkeiten-Filter im Dialog Planung → Rahmen übernehmen — Katalog ja, Skill-Filter optional nachziehen
  • API-Feldnamen club_* / skillMinClubPercent — technische Altlast, semantisch Peer-Kontext

Tests

  • backend/tests/test_skill_scoring.py — Multiplikator, Aggregation, Match-Score, Cap 100 %
  • Offen: dedizierte Tests für compute_planning_corpus_by_type (Typ-Trennung)

Verweise

Dokument Inhalt
functional/DOMAIN_MODEL.md Domänenabschnitt Planungs-Fähigkeiten-Profil
docs/FACHLICHE_NUTZERFUNKTIONEN.md Nutzerüberblick Listen/Filter
docs/HANDOVER.md Handover-Abschnitt Phase 3
technical/ACCESS_LAYER_AND_GOVERNANCE_PLAN.md Sichtbarkeit / Mandant