From fb6c0e3d90da6ec46dfe542e4c0635b7e6c003fb Mon Sep 17 00:00:00 2001 From: Ryan Hamamura <58859899+ryanhamamura@users.noreply.github.com> Date: Mon, 2 Mar 2026 21:30:47 -1000 Subject: [PATCH] refactor: replace hardcoded NATS subjects with typed helpers Add GameSubject/ChatSubject helpers to connect4 and snake packages, eliminating magic string concatenation from handlers and main.go. --- connect4/types.go | 6 ++++++ features/c4game/handlers.go | 6 +++--- features/snakegame/handlers.go | 6 +++--- main.go | 4 ++-- snake/types.go | 6 ++++++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/connect4/types.go b/connect4/types.go index a423030..0aa56b7 100644 --- a/connect4/types.go +++ b/connect4/types.go @@ -6,6 +6,12 @@ import ( "github.com/ryanhamamura/games/player" ) +// NATS subject helpers. +const SubjectPrefix = "connect4" + +func GameSubject(gameID string) string { return SubjectPrefix + "." + gameID } +func ChatSubject(gameID string) string { return SubjectPrefix + ".chat." + gameID } + type Player struct { ID player.ID UserID *string // UUID for authenticated users, nil for guests diff --git a/features/c4game/handlers.go b/features/c4game/handlers.go index 777b0c6..8a8c309 100644 --- a/features/c4game/handlers.go +++ b/features/c4game/handlers.go @@ -111,14 +111,14 @@ func HandleGameEvents(store *connect4.Store, nc *nats.Conn, sm *scs.SessionManag )) chatCfg := c4ChatConfig(gameID) - room := chat.NewPersistentRoom(nc, "connect4.chat."+gameID, queries, gameID) + room := chat.NewPersistentRoom(nc, connect4.ChatSubject(gameID), queries, gameID) // Send initial render sendGameComponents(sse, gi, myColor, room, chatCfg) // Subscribe to game state updates gameCh := make(chan *nats.Msg, 64) - gameSub, err := nc.ChanSubscribe("connect4."+gameID, gameCh) + gameSub, err := nc.ChanSubscribe(connect4.GameSubject(gameID), gameCh) if err != nil { return } @@ -228,7 +228,7 @@ func HandleSendChat(store *connect4.Store, nc *nats.Conn, sm *scs.SessionManager Message: signals.ChatMsg, Time: time.Now().UnixMilli(), } - room := chat.NewPersistentRoom(nc, "connect4.chat."+gameID, queries, gameID) + room := chat.NewPersistentRoom(nc, connect4.ChatSubject(gameID), queries, gameID) room.Send(msg) sse := datastar.NewSSE(w, r) diff --git a/features/snakegame/handlers.go b/features/snakegame/handlers.go index e42471d..effa3ff 100644 --- a/features/snakegame/handlers.go +++ b/features/snakegame/handlers.go @@ -114,7 +114,7 @@ func HandleSnakeEvents(snakeStore *snake.SnakeStore, nc *nats.Conn, sm *scs.Sess // Subscribe to game updates via NATS gameCh := make(chan *nats.Msg, 64) - gameSub, err := nc.ChanSubscribe("snake."+gameID, gameCh) + gameSub, err := nc.ChanSubscribe(snake.GameSubject(gameID), gameCh) if err != nil { return } @@ -126,7 +126,7 @@ func HandleSnakeEvents(snakeStore *snake.SnakeStore, nc *nats.Conn, sm *scs.Sess var room *chat.Room if sg.Mode == snake.ModeMultiplayer { - room = chat.NewRoom(nc, "snake.chat."+gameID) + room = chat.NewRoom(nc, snake.ChatSubject(gameID)) chatCh, chatSub, err = room.Subscribe() if err != nil { return @@ -247,7 +247,7 @@ func HandleSendChat(snakeStore *snake.SnakeStore, nc *nats.Conn, sm *scs.Session Message: signals.ChatMsg, } - room := chat.NewRoom(nc, "snake.chat."+gameID) + room := chat.NewRoom(nc, snake.ChatSubject(gameID)) room.Send(msg) sse := datastar.NewSSE(w, r) diff --git a/main.go b/main.go index 4bf49a3..041e13c 100644 --- a/main.go +++ b/main.go @@ -73,12 +73,12 @@ func run(ctx context.Context) error { // Game stores store := connect4.NewStore(queries) store.SetNotifyFunc(func(gameID string) { - nc.Publish("connect4."+gameID, nil) //nolint:errcheck // best-effort notification + nc.Publish(connect4.GameSubject(gameID), nil) //nolint:errcheck // best-effort notification }) snakeStore := snake.NewSnakeStore(queries) snakeStore.SetNotifyFunc(func(gameID string) { - nc.Publish("snake."+gameID, nil) //nolint:errcheck // best-effort notification + nc.Publish(snake.GameSubject(gameID), nil) //nolint:errcheck // best-effort notification }) // Router diff --git a/snake/types.go b/snake/types.go index 62376f9..d1284c1 100644 --- a/snake/types.go +++ b/snake/types.go @@ -7,6 +7,12 @@ import ( "github.com/ryanhamamura/games/player" ) +// NATS subject helpers. +const SubjectPrefix = "snake" + +func GameSubject(gameID string) string { return SubjectPrefix + "." + gameID } +func ChatSubject(gameID string) string { return SubjectPrefix + ".chat." + gameID } + type Direction int const (