Refactor phase handling in training unit sections for improved data integrity
All checks were successful
Deploy Development / deploy (push) Successful in 40s
Test Suite / pytest-backend (push) Successful in 36s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 11s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m8s

- 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.
This commit is contained in:
Lars 2026-05-16 07:35:35 +02:00
parent 88c4201f80
commit 79e748b470

View File

@ -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) }
}