shinkan-jinkendo/frontend/src/utils/skillProfileListHelpers.js
Lars 2de4c0b7c9
All checks were successful
Deploy Development / deploy (push) Successful in 40s
Test Suite / pytest-backend (push) Successful in 38s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m17s
Refactor Skill Scoring Functions and Enhance Corpus Handling
- Introduced new helper functions for managing artifact type corpus, improving code organization and readability.
- Updated the `compute_club_corpus_reference` function to utilize the new corpus handling methods, enhancing clarity and maintainability.
- Refactored skill profile functions to leverage the new corpus structure, ensuring consistent data retrieval across different artifact types.
- Improved the handling of visibility clauses for library content, streamlining database queries for skill profiles.
- Enhanced the batch skill profile summary function to aggregate reference data by artifact type, improving performance and accuracy.
2026-05-21 10:17:22 +02:00

111 lines
3.4 KiB
JavaScript

export function frameworkSkillSummaryKey(id) {
return `framework_program:${id}`
}
export function moduleSkillSummaryKey(id) {
return `training_module:${id}`
}
export function skillEntryFromSummary(summary, skillId) {
if (!summary) return null
const sid = String(skillId)
const fromSkills = (summary.skills || []).find((s) => String(s.skill_id) === sid)
if (fromSkills) return fromSkills
return (summary.top_by_category || []).find((s) => String(s.skill_id) === sid) || null
}
export function summaryHasSkill(summary, skillId, minClubPct = 0) {
const sk = skillEntryFromSummary(summary, skillId)
if (!sk || !(Number(sk.weight) > 0)) return false
const pct = sk.universal_percent
if (pct == null) return minClubPct === 0
return pct >= minClubPct
}
export function maxSelectedSkillClubPercent(summary, skillIds = []) {
if (!summary || !skillIds.length) return null
let max = null
for (const id of skillIds) {
const sk = skillEntryFromSummary(summary, id)
if (!sk) continue
const pct = sk.universal_percent
if (pct == null) continue
if (max == null || pct > max) max = pct
}
return max
}
export function formatClubPercent(value) {
if (value == null || !Number.isFinite(Number(value))) return '—'
const n = Math.min(100, Number(value))
return n % 1 === 0 ? `${n}%` : `${n.toFixed(1)}%`
}
export function formatSkillWeight(value) {
const n = Number(value)
if (!Number.isFinite(n)) return '—'
return n % 1 === 0 ? String(n) : n.toFixed(1)
}
const PEER_LABELS = {
framework_program: 'Rahmenpr.',
training_module: 'Module',
progression_graph: 'Pfade',
}
const PEER_COUNT_LABELS = {
framework_program: 'Rahmenprogramme',
training_module: 'Module',
progression_graph: 'Regressionspfade',
}
export function peerPercentSuffix(artifactType = 'training_module') {
return PEER_LABELS[artifactType] || 'Peers'
}
export function peerCorpusCountLabel(artifactType = 'training_module') {
return PEER_COUNT_LABELS[artifactType] || 'Planungs-Artefakte'
}
/** KPI-Zeilen: immer Top je Unterkategorie; bei Skill-Filter nur passende Kategorien. */
export function kpiRowsFromSummary(summary, { skillIds = [], limit = 8 } = {}) {
if (!summary) return []
let rows = (summary.top_by_category || []).map((row) => ({
skill_id: row.skill_id,
skill_name: row.skill_name,
category_name: row.category_name,
main_category_name: row.main_category_name,
weight: row.weight ?? row.score,
universal_percent: row.universal_percent,
is_club_best_for_skill: row.is_club_best_for_skill,
}))
if (skillIds.length) {
const wanted = new Set(skillIds.map(String))
rows = rows.filter((row) => wanted.has(String(row.skill_id)))
}
return rows.slice(0, limit)
}
/** @deprecated Nutze kpiRowsFromSummary für Listen */
export function compactSkillDisplayRows(summary, opts = {}) {
return kpiRowsFromSummary(summary, opts)
}
export function artifactTypeLabel(type) {
if (type === 'framework_program') return 'Rahmenprogramm'
if (type === 'training_module') return 'Modul'
if (type === 'progression_graph') return 'Regressionspfad'
return type || 'Artefakt'
}
export function artifactPath(ref) {
if (!ref) return null
if (ref.artifact_type === 'framework_program') {
return `/planning/framework-programs/${ref.artifact_id}`
}
if (ref.artifact_type === 'training_module') {
return `/planning/training-modules/${ref.artifact_id}`
}
return null
}