@@ -140,6 +140,89 @@ export function getGameDisplayName(type: GameType): string {
140140}
141141` ` `
142142
143+ ## Constants and Common Values
144+
145+ ### Centralized Constants and Derived Types
146+ ** Types are derived from constants using ` as const ` assertions - constants are the single source of truth :**
147+
148+ ` ` ` typescript
149+ // ✅ Constants define the source of truth
150+ export const DIFFICULTIES = ['easy', 'medium', 'hard'] as const
151+ export const GAME_TYPES = ['tic-tac-toe', 'rock-paper-scissors'] as const
152+ export const PLAYER_IDS = { HUMAN: 'player1', PLAYER2: 'player2', AI: 'ai' } as const
153+
154+ // ✅ Types are derived from constants
155+ export type Difficulty = typeof DIFFICULTIES[number]
156+ export type GameType = typeof GAME_TYPES[number]
157+ export type PlayerId = typeof PLAYER_IDS[keyof typeof PLAYER_IDS]
158+
159+ // ✅ Import the derived types
160+ import type { Difficulty, GameType } from '@turn-based-mcp/shared'
161+
162+ // ❌ Don't define duplicate union types
163+ export type Difficulty = 'easy' | 'medium' | 'hard' // This duplicates the constants!
164+ ` ` `
165+
166+ ### Available Constants
167+ Key constants provided by the shared library :
168+
169+ ` ` ` typescript
170+ // Constants with derived types
171+ export const GAME_TYPES = ['tic-tac-toe', 'rock-paper-scissors'] as const
172+ export const DIFFICULTIES = ['easy', 'medium', 'hard'] as const
173+ export const PLAYER_IDS = { HUMAN: 'player1', PLAYER2: 'player2', AI: 'ai' } as const
174+ export const GAME_STATUSES = ['waiting', 'playing', 'finished'] as const
175+
176+ // Derived types (auto-generated from constants)
177+ export type GameType = typeof GAME_TYPES[number]
178+ export type Difficulty = typeof DIFFICULTIES[number]
179+ export type PlayerId = typeof PLAYER_IDS[keyof typeof PLAYER_IDS]
180+ export type GameStatus = typeof GAME_STATUSES[number]
181+
182+ // Default values
183+ export const DEFAULT_PLAYER_NAME = 'Player'
184+ export const DEFAULT_AI_DIFFICULTY: Difficulty = 'medium'
185+
186+ // UI display configuration
187+ export const DIFFICULTY_DISPLAY = {
188+ easy: { emoji: '😌', label: 'Easy' },
189+ medium: { emoji: '🎯', label: 'Medium' },
190+ hard: { emoji: '🔥', label: 'Hard' }
191+ } as const
192+ ` ` `
193+
194+ ### Type Guards and Utilities
195+ Use provided validation functions that work with the constants :
196+
197+ ` ` ` typescript
198+ // Type guards (check against the constant arrays)
199+ export function isSupportedGameType(gameType: string): gameType is GameType
200+ export function isValidDifficulty(difficulty: string): difficulty is Difficulty
201+ export function isValidPlayerId(playerId: string): playerId is PlayerId
202+
203+ // Display helpers
204+ export function getDifficultyDisplay(difficulty: Difficulty)
205+ ` ` `
206+
207+ ### Architecture Benefits
208+ This approach ensures :
209+ - ** Single source of truth ** : Constants define what values are valid
210+ - ** Type safety ** : TypeScript derives exact types from the constant values
211+ - ** Runtime validation ** : Type guards check against the same arrays used to derive types
212+ - ** Maintainability ** : Add a new difficulty by updating one constant array
213+
214+ ### Testing Constants
215+ For mocking and test data , use shared testing utilities :
216+
217+ ` ` ` typescript
218+ // Test data from shared/src/testing/
219+ import {
220+ mockTicTacToeGameState,
221+ mockRPSGameState,
222+ createMockGameSession
223+ } from '@turn-based-mcp/shared/testing'
224+ ` ` `
225+
143226## Testing Infrastructure
144227
145228### Test Database Utilities
0 commit comments