diff --git a/packages/shared/src/ws-messages.ts b/packages/shared/src/ws-messages.ts index 722501e..f62a32b 100644 --- a/packages/shared/src/ws-messages.ts +++ b/packages/shared/src/ws-messages.ts @@ -1,5 +1,6 @@ import { z } from "zod" import { ACTS } from "./constants" +import { gameStateSchema, dishSchema } from "./game-types" import { playerSchema, roomStateSchema } from "./room-types" // ─── Client → Server ─────────────────────────────────────────────── @@ -22,12 +23,41 @@ export const endRoomMessage = z.object({ type: z.literal("end_room"), }) +// ─── Client → Server (Act 1 games) ───────────────────────────────── + +export const submitPredictionMessage = z.object({ + type: z.literal("submit_prediction"), + predictedWinner: z.string(), + top3: z.array(z.string()).length(3), + nulPointsPick: z.string(), +}) + +export const addDishMessage = z.object({ + type: z.literal("add_dish"), + name: z.string().min(1).max(100), + correctCountry: z.string(), +}) + +export const submitDishGuessMessage = z.object({ + type: z.literal("submit_dish_guess"), + dishId: z.string().uuid(), + guessedCountry: z.string(), +}) + +export const revealDishesMessage = z.object({ + type: z.literal("reveal_dishes"), +}) + /** Union of all client → server messages (room system only — games add more) */ export const clientMessage = z.discriminatedUnion("type", [ joinRoomMessage, reconnectMessage, advanceActMessage, endRoomMessage, + submitPredictionMessage, + addDishMessage, + submitDishGuessMessage, + revealDishesMessage, ]) export type ClientMessage = z.infer @@ -69,6 +99,45 @@ export const errorMessage = z.object({ message: z.string(), }) +// ─── Server → Client (Act 1 games) ───────────────────────────────── + +export const gameStateMessage = z.object({ + type: z.literal("game_state"), + gameState: gameStateSchema, +}) + +export const predictionsLockedMessage = z.object({ + type: z.literal("predictions_locked"), +}) + +export const dishAddedMessage = z.object({ + type: z.literal("dish_added"), + dish: dishSchema, +}) + +export const dishGuessRecordedMessage = z.object({ + type: z.literal("dish_guess_recorded"), + dishId: z.string().uuid(), + guessedCountry: z.string(), +}) + +export const dishesRevealedMessage = z.object({ + type: z.literal("dishes_revealed"), + results: z.array( + z.object({ + dish: dishSchema, + guesses: z.array( + z.object({ + playerId: z.string().uuid(), + displayName: z.string(), + guessedCountry: z.string(), + correct: z.boolean(), + }), + ), + }), + ), +}) + /** Union of all server → client messages (room system only) */ export const serverMessage = z.discriminatedUnion("type", [ roomStateMessage, @@ -78,6 +147,11 @@ export const serverMessage = z.discriminatedUnion("type", [ actChangedMessage, roomEndedMessage, errorMessage, + gameStateMessage, + predictionsLockedMessage, + dishAddedMessage, + dishGuessRecordedMessage, + dishesRevealedMessage, ]) export type ServerMessage = z.infer