From fa4e29f5917017be928fd6f0fd429b8ff7f452e4 Mon Sep 17 00:00:00 2001 From: AndyMik90 Date: Sat, 14 Feb 2026 00:33:14 +0100 Subject: [PATCH] auto-claude: subtask-1-3 - Create roadmap-state-utils.ts with state name constants, settled states, and mapping utilities Co-Authored-By: Claude Opus 4.6 --- .../state-machines/roadmap-state-utils.ts | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 apps/frontend/src/shared/state-machines/roadmap-state-utils.ts diff --git a/apps/frontend/src/shared/state-machines/roadmap-state-utils.ts b/apps/frontend/src/shared/state-machines/roadmap-state-utils.ts new file mode 100644 index 00000000..bdb3a16d --- /dev/null +++ b/apps/frontend/src/shared/state-machines/roadmap-state-utils.ts @@ -0,0 +1,99 @@ +/** + * Shared XState roadmap state utilities. + * + * Provides type-safe state names, settled states, and mapping helpers + * derived from the roadmap machine definitions. Used by roadmap-store + * and roadmap hooks to avoid duplicate constants. + */ +import type { RoadmapGenerationStatus, RoadmapFeatureStatus } from '../types/roadmap'; + +/** + * All XState generation state names. + * + * IMPORTANT: These must match the state keys in roadmap-generation-machine.ts. + * If you add/remove a state in the machine, update this array. + */ +export const GENERATION_STATE_NAMES = [ + 'idle', 'analyzing', 'discovering', 'generating', 'complete', 'error' +] as const; + +export type GenerationStateName = typeof GENERATION_STATE_NAMES[number]; + +/** + * All XState feature state names. + * + * IMPORTANT: These must match the state keys in roadmap-feature-machine.ts. + * If you add/remove a state in the machine, update this array. + */ +export const FEATURE_STATE_NAMES = [ + 'under_review', 'planned', 'in_progress', 'done' +] as const; + +export type FeatureStateName = typeof FEATURE_STATE_NAMES[number]; + +/** + * Generation states where the machine has settled — the generation is + * complete or has errored. Stale progress events should NOT overwrite + * these states, as XState is the source of truth. + */ +export const GENERATION_SETTLED_STATES: ReadonlySet = new Set([ + 'complete', 'error' +]); + +/** + * Feature states where the machine has settled — the feature is done. + * Stale task lifecycle events should NOT overwrite this state. + */ +export const FEATURE_SETTLED_STATES: ReadonlySet = new Set([ + 'done' +]); + +/** + * Maps an XState generation state to the RoadmapGenerationStatus phase. + * + * The generation machine states map 1:1 to the phase union type, so this + * is a type-safe identity mapping with a fallback for unknown states. + */ +export function mapGenerationStateToPhase( + state: string +): RoadmapGenerationStatus['phase'] { + switch (state) { + case 'idle': + return 'idle'; + case 'analyzing': + return 'analyzing'; + case 'discovering': + return 'discovering'; + case 'generating': + return 'generating'; + case 'complete': + return 'complete'; + case 'error': + return 'error'; + default: + return 'idle'; + } +} + +/** + * Maps an XState feature state to the RoadmapFeatureStatus type. + * + * The feature machine states map 1:1 to the status union type, so this + * is a type-safe identity mapping with a fallback for unknown states. + */ +export function mapFeatureStateToStatus( + state: string +): RoadmapFeatureStatus { + switch (state) { + case 'under_review': + return 'under_review'; + case 'planned': + return 'planned'; + case 'in_progress': + return 'in_progress'; + case 'done': + return 'done'; + default: + return 'under_review'; + } +}