@@ -124,53 +124,62 @@ defmodule CopiWeb.PlayerLive.Show do
124124 end
125125 end
126126
127- CopiWeb.Endpoint . broadcast ( topic ( game . id ) , "game:updated" , game )
127+ # Reload fresh game record after continue vote mutations
128+ { :ok , updated_game } = Copi.Cornucopia.Game . find ( game_id )
128129
129- { :noreply , assign ( socket , :game , game ) }
130+ CopiWeb.Endpoint . broadcast ( topic ( updated_game . id ) , "game:updated" , updated_game )
131+
132+ { :noreply , assign ( socket , :game , updated_game ) }
130133 end
131134 else
132- { :noreply , socket }
135+ { :error , _reason } -> { : noreply, socket }
133136 end
134137 end
135138
136139 @ impl true
137140 def handle_event ( "toggle_vote" , % { "dealt_card_id" => dealt_card_id } , socket ) do
138- game = socket . assigns . game
139141 player = socket . assigns . player
140-
141- # Validate game lifecycle - voting only allowed during active games
142- unless Copi.Cornucopia.Game . game_active? ( game ) do
143- Logger . warning ( "Voting attempt on inactive game: player_id: #{ player . id } , game_id: #{ game . id } , started_at: #{ game . started_at } , finished_at: #{ game . finished_at } " )
144- { :noreply , socket }
145- else
146- { :ok , dealt_card } = DealtCard . find ( dealt_card_id )
147-
148- # Validate that dealt card belongs to current game
149- unless dealt_card_belongs_to_game? ( dealt_card , game ) do
150- Logger . warning ( "Unauthorized voting attempt: player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } " )
142+ game_id = socket . assigns . player . game_id
143+
144+ # Load fresh game record from DB to avoid stale socket assigns
145+ with { :ok , game } <- Copi.Cornucopia.Game . find ( game_id ) do
146+ # Validate game lifecycle - voting only allowed during active games
147+ unless Copi.Cornucopia.Game . game_active? ( game ) do
148+ Logger . warning ( "Voting attempt on inactive game: player_id: #{ player . id } , game_id: #{ game . id } , started_at: #{ game . started_at } , finished_at: #{ game . finished_at } " )
151149 { :noreply , socket }
152150 else
153- vote = get_vote ( dealt_card , player )
154-
155- if vote do
156- Logger . debug ( "Player has voted: player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } " )
157- Copi.Repo . delete! ( vote )
151+ { :ok , dealt_card } = DealtCard . find ( dealt_card_id )
152+
153+ # Validate that dealt card belongs to current game
154+ unless dealt_card_belongs_to_game? ( dealt_card , game ) do
155+ Logger . warning ( "Unauthorized voting attempt: player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } " )
156+ { :noreply , socket }
158157 else
159- Logger . debug ( "Player has not voted: player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } " )
160- case Copi.Repo . insert ( % Copi.Cornucopia.Vote { dealt_card_id: String . to_integer ( dealt_card_id ) , player_id: player . id } ) do
161- { :ok , _vote } ->
162- Logger . debug ( "Vote added successfully for player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } " )
163- { :error , changeset } ->
164- Logger . warning ( "Voting failed for player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } , errors: #{ inspect ( changeset . errors ) } " )
158+ vote = get_vote ( dealt_card , player )
159+
160+ if vote do
161+ Logger . debug ( "Player has voted: player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } " )
162+ Copi.Repo . delete! ( vote )
163+ else
164+ Logger . debug ( "Player has not voted: player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } " )
165+ case Copi.Repo . insert ( % Copi.Cornucopia.Vote { dealt_card_id: String . to_integer ( dealt_card_id ) , player_id: player . id } ) do
166+ { :ok , _vote } ->
167+ Logger . debug ( "Vote added successfully for player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } " )
168+ { :error , changeset } ->
169+ Logger . warning ( "Voting failed for player_id: #{ player . id } , dealt_card_id: #{ dealt_card_id } , game_id: #{ game . id } , errors: #{ inspect ( changeset . errors ) } " )
170+ end
165171 end
166- end
167172
168- { :ok , updated_game } = Game . find ( game . id )
173+ # Reload fresh game record after vote mutations
174+ { :ok , updated_game } = Copi.Cornucopia.Game . find ( game_id )
169175
170- CopiWeb.Endpoint . broadcast ( topic ( updated_game . id ) , "game:updated" , updated_game )
176+ CopiWeb.Endpoint . broadcast ( topic ( updated_game . id ) , "game:updated" , updated_game )
171177
172- { :noreply , assign ( socket , :game , updated_game ) }
178+ { :noreply , assign ( socket , :game , updated_game ) }
179+ end
173180 end
181+ else
182+ { :error , _reason } -> { :noreply , socket }
174183 end
175184 end
176185
0 commit comments