From 79e748b4705d3e4825bd39fb383ed74e0ccb3cc3 Mon Sep 17 00:00:00 2001 From: Lars Date: Sat, 16 May 2026 07:35:35 +0200 Subject: [PATCH] Refactor phase handling in training unit sections for improved data integrity - Introduced canonicalization for plan locations in phased saves to ensure consistent phase representation. - Enhanced the `inheritPlanLocForPhasedSave` function to utilize the new canonicalization logic, improving data flow. - Updated payload building logic to check for canonicalized plan locations, ensuring accurate phase detection during saves. --- .../src/utils/trainingUnitSectionsForm.js | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/frontend/src/utils/trainingUnitSectionsForm.js b/frontend/src/utils/trainingUnitSectionsForm.js index f2ce62f..dd733c4 100644 --- a/frontend/src/utils/trainingUnitSectionsForm.js +++ b/frontend/src/utils/trainingUnitSectionsForm.js @@ -721,20 +721,47 @@ function stripPlanLoc(sec) { return rest } -export function inheritPlanLocForPhasedSave(sections) { - let prev = { - phaseKind: 'whole_group', - phaseOrderIndex: 0, - parallelStreamOrderIndex: null, - phaseTitle: null, - phaseGuidanceNotes: null, - streamTitle: null, - streamNotes: null, - streamAssignedTrainerProfileIds: null, +function phaseIndexToInt(v, fallback = 0) { + if (v === null || v === undefined || v === '') return fallback + const n = typeof v === 'number' ? v : Number(v) + return Number.isFinite(n) ? n : fallback +} + +/** + * planLoc für Phasen-PUT kanonisieren (Großschreibung, numerische Indizes). + * Verhindert u. a. abgebrochene Phasen-Runs bei "0" !== 0 und falsche whole_group-Zweige. + */ +function canonicalPlanLocForPhasedSave(pl) { + if (!pl || typeof pl !== 'object') return null + const rawKind = String(pl.phaseKind || '').toLowerCase().trim() + let kind = rawKind === 'parallel' || rawKind === 'whole_group' ? rawKind : null + if ( + !kind && + pl.parallelStreamOrderIndex != null && + pl.parallelStreamOrderIndex !== '' + ) { + kind = 'parallel' } + if (!kind) return null + const phaseOrderIndex = phaseIndexToInt(pl.phaseOrderIndex, 0) + let parallelStreamOrderIndex = null + if (kind === 'parallel') { + parallelStreamOrderIndex = phaseIndexToInt(pl.parallelStreamOrderIndex, 0) + } + return { + ...pl, + phaseKind: kind, + phaseOrderIndex, + parallelStreamOrderIndex, + } +} + +export function inheritPlanLocForPhasedSave(sections) { + let prev = { ...defaultPlanLocWholeGroup(0) } return (sections || []).map((s) => { - if (s?.planLoc && s.planLoc.phaseKind) { - prev = { ...s.planLoc } + const canon = canonicalPlanLocForPhasedSave(s?.planLoc) + if (canon) { + prev = { ...canon } return { ...s, planLoc: prev } } return { ...s, planLoc: { ...prev } } @@ -1127,7 +1154,7 @@ function buildPhasesPayloadFromFlat(sections) { */ export function buildPlanPayloadForSave(sections) { const list = Array.isArray(sections) ? sections : [] - const anyPhased = list.some((s) => s && s.planLoc && s.planLoc.phaseKind) + const anyPhased = list.some((s) => s && canonicalPlanLocForPhasedSave(s.planLoc) != null) if (!anyPhased) { return { sections: buildSectionsPayload(list) } }