Conversation
What was broken Completed challenge phases in the work app schedule editor still exposed editable end date and duration controls, unlike legacy work-manager. Root cause Challenge phase normalization dropped `actualEndDate`, so the form lost the completion signal used by the legacy `canChangeDuration` rule and the schedule rows never disabled completed phases. What was changed Preserved phase completion timestamps when hydrating challenge editor form data. Applied the legacy completed-phase editability rule to schedule row end date and duration controls while keeping the existing start-date rules intact. Updated the challenge editor README to note the restored legacy behavior. Any added/updated tests Added a challenge-editor utils test that keeps `actualEndDate` in form state. Added a schedule section test that verifies completed phases lock end date and duration controls.
What was broken The work app schedule editor recalculated successor phase start times from the predecessor's scheduled end date, so a two-round design challenge could keep the Submission phase anchored to the old Checkpoint Review schedule after autopilot closed checkpoint review early. That made the Submission end-date picker reject earlier valid dates. Root cause The ChallengeScheduleSection recalculation helper ignored predecessor actual end dates during hydration and subsequent row recalculation, overwriting the shifted schedule returned by the backend. What was changed Updated the schedule recalculation helper to use a completed predecessor phase's actual end date when deriving successor phase start times. Added targeted schedule tests covering the checkpoint review to submission transition. Updated the ChallengeEditorPage schedule documentation to reflect the completed-predecessor behavior. Any added/updated tests Added unit coverage in ChallengeScheduleSection.spec.ts for closed predecessors shifting successor start times. Added component coverage in ChallengeScheduleSection.component.spec.tsx for the submission row start date after an early checkpoint review close.
| function getPredecessorEndDate(phase?: ChallengePhase): Date | undefined { | ||
| return toDate(phase?.actualEndDate || phase?.scheduledEndDate) | ||
| } |
There was a problem hiding this comment.
🟡 getPredecessorEndDate applies || before parsing, losing scheduledEndDate fallback on invalid actualEndDate
The || in phase?.actualEndDate || phase?.scheduledEndDate operates on raw string values before date parsing. If actualEndDate is a truthy but unparseable string (e.g., malformed API data), the expression evaluates to that invalid string, toDate() returns undefined, and the valid scheduledEndDate is never tried. The correct pattern is toDate(phase?.actualEndDate) || toDate(phase?.scheduledEndDate) which tries parsing each value independently. This matters because actualEndDate is not validated through toIsoDateString during normalization (challenge-editor.utils.ts:858) unlike scheduledEndDate (challenge-editor.utils.ts:870), so invalid values could flow through undetected.
| function getPredecessorEndDate(phase?: ChallengePhase): Date | undefined { | |
| return toDate(phase?.actualEndDate || phase?.scheduledEndDate) | |
| } | |
| function getPredecessorEndDate(phase?: ChallengePhase): Date | undefined { | |
| return toDate(phase?.actualEndDate) || toDate(phase?.scheduledEndDate) | |
| } |
Was this helpful? React with 👍 or 👎 to provide feedback.
What was broken
The work app schedule editor recalculated successor phase start times from the predecessor's scheduled end date, so a two-round design challenge could keep the Submission phase anchored to the old Checkpoint Review schedule after autopilot closed checkpoint review early. That made the Submission end-date picker reject earlier valid dates.
Root cause
The ChallengeScheduleSection recalculation helper ignored predecessor actual end dates during hydration and subsequent row recalculation, overwriting the shifted schedule returned by the backend.
What was changed
Updated the schedule recalculation helper to use a completed predecessor phase's actual end date when deriving successor phase start times.
Added targeted schedule tests covering the checkpoint review to submission transition.
Updated the ChallengeEditorPage schedule documentation to reflect the completed-predecessor behavior.
Any added/updated tests
Added unit coverage in ChallengeScheduleSection.spec.ts for closed predecessors shifting successor start times.
Added component coverage in ChallengeScheduleSection.component.spec.tsx for the submission row start date after an early checkpoint review close.
Ran yarn lint and yarn run build successfully.
Ran yarn test:no-watch --runTestsByPath for the updated schedule tests successfully.
Ran yarn test:no-watch for the full suite; it still fails in the pre-existing wallet-admin PaymentsListView spec expectations around default filter values, unrelated to this schedule change.