import type { IValueObject } from '@gridpilot/shared/domain'; export type SessionStateValue = | 'PENDING' | 'IN_PROGRESS' | 'PAUSED' | 'COMPLETED' | 'FAILED' | 'STOPPED_AT_STEP_18' | 'AWAITING_CHECKOUT_CONFIRMATION' | 'CANCELLED'; const VALID_STATES: SessionStateValue[] = [ 'PENDING', 'IN_PROGRESS', 'PAUSED', 'COMPLETED', 'FAILED', 'STOPPED_AT_STEP_18', 'AWAITING_CHECKOUT_CONFIRMATION', 'CANCELLED', ]; const VALID_TRANSITIONS: Record = { PENDING: ['IN_PROGRESS', 'FAILED'], IN_PROGRESS: ['PAUSED', 'COMPLETED', 'FAILED', 'STOPPED_AT_STEP_18', 'AWAITING_CHECKOUT_CONFIRMATION'], PAUSED: ['IN_PROGRESS', 'FAILED'], COMPLETED: [], FAILED: [], STOPPED_AT_STEP_18: [], AWAITING_CHECKOUT_CONFIRMATION: ['COMPLETED', 'CANCELLED', 'FAILED'], CANCELLED: [], }; export interface SessionStateProps { value: SessionStateValue; } export class SessionState implements IValueObject { private readonly _value: SessionStateValue; private constructor(value: SessionStateValue) { this._value = value; } static create(value: SessionStateValue): SessionState { if (!VALID_STATES.includes(value)) { throw new Error('Invalid session state'); } return new SessionState(value); } get value(): SessionStateValue { return this._value; } isPending(): boolean { return this._value === 'PENDING'; } isInProgress(): boolean { return this._value === 'IN_PROGRESS'; } isCompleted(): boolean { return this._value === 'COMPLETED'; } isFailed(): boolean { return this._value === 'FAILED'; } isStoppedAtStep18(): boolean { return this._value === 'STOPPED_AT_STEP_18'; } isAwaitingCheckoutConfirmation(): boolean { return this._value === 'AWAITING_CHECKOUT_CONFIRMATION'; } isCancelled(): boolean { return this._value === 'CANCELLED'; } canTransitionTo(targetState: SessionState): boolean { const allowedTransitions = VALID_TRANSITIONS[this._value]; return allowedTransitions.includes(targetState._value); } isTerminal(): boolean { return ( this._value === 'COMPLETED' || this._value === 'FAILED' || this._value === 'STOPPED_AT_STEP_18' || this._value === 'CANCELLED' ); } get props(): SessionStateProps { return { value: this._value }; } equals(other: IValueObject): boolean { return this.props.value === other.props.value; } }