fix phase regression

This commit is contained in:
Oliver Kieselbach
2026-04-04 01:12:05 +02:00
parent 19bd6f8a68
commit a8305c95b5
3 changed files with 8 additions and 3 deletions
@@ -690,12 +690,12 @@ export default function SessionDetailPage() {
// Group events by phase — single timeline for normal sessions, two groups for WhiteGlove
const { eventsByPhase, orderedPhases } = useMemo(() => {
if (isWhiteGloveSession) return { eventsByPhase: {} as Record<string, EnrollmentEvent[]>, orderedPhases: [] as string[] };
return groupEventsByPhase(filteredEvents, phaseNamesMap, phaseOrder);
return groupEventsByPhase(filteredEvents, phaseNamesMap, phaseOrder, { preventPhaseRegression: true });
}, [filteredEvents, isWhiteGloveSession, phaseNamesMap, phaseOrder]);
const preProvGrouped = useMemo(() =>
isWhiteGloveSession && preProvEvents.length > 0
? groupEventsByPhase(preProvEvents, phaseNamesMap, phaseOrder)
? groupEventsByPhase(preProvEvents, phaseNamesMap, phaseOrder, { preventPhaseRegression: true })
: { eventsByPhase: {} as Record<string, EnrollmentEvent[]>, orderedPhases: [] as string[] },
[preProvEvents, isWhiteGloveSession, phaseNamesMap, phaseOrder]
);
File diff suppressed because one or more lines are too long
+5
View File
@@ -14,6 +14,11 @@
## Common Mistakes
### Timeline sequence must NEVER regress in the curated UI view (2026-04-04)
**What went wrong:** `groupEventsByPhase` was called without `preventPhaseRegression: true` for normal sessions and WhiteGlove pre-provisioning. A mid-enrollment reboot emits a new `agent_started` (Phase 0 = "Start"), which regressed the active phase back to Start, dumping post-reboot events (seq 173+) into the Start section — breaking the sequential appearance.
**Rule:** ALL `groupEventsByPhase` calls MUST use `{ preventPhaseRegression: true }`. The curated timeline sequence must appear continuous within each phase section. Reboots and agent restarts must NOT create phase regression — events stay in whatever phase was active before the reboot.
**Severity:** UX — confuses users, violates core timeline principle.
### Table Storage mapping defaults must match domain defaults (2026-03-31)
**What went wrong:** Added `NtpServer` mapping with `?? ""` fallback. Existing tenants had no value stored → got empty string instead of `"time.windows.com"` → agent NTP check broke.
**Rule:** When adding missing Table Storage read mappings, the `??` fallback MUST match the domain/model default (check `AgentConfigResponse`, `GetAgentConfigFunction`, or the property initializer). Never use empty string as fallback for fields that have a meaningful default.