class OrderSubmissionService def initialize(turn, user, client: GameApiClient.new) @turn = turn @game = turn.game @user = user @client = client end def submit(power:, orders:) # Check permissions unless valid_permission?(power) return { success: false, message: "権限がありません。" } end # Handle multiplayer updates (orders_submitted flag) if !@game.solo_mode? participant = @game.participants.find_by(user: @user) participant.update(orders_submitted: true) if participant end # Update orders tentatively for validation current_orders = @turn.orders || {} tentative_orders = current_orders.merge(power => orders) # Validate validation_result = @client.api_calculate_validate(@turn.game_state, tentative_orders) if validation_result.nil? return { success: false, message: "バリデーションサーバーとの通信に失敗しました。" } end # Assuming validation_result is an array of error messages or empty if valid # Adjust this based on actual API response structure if known differently. # Common pattern: ["Order A is invalid", "Order B is impossible"] if validation_result.is_a?(Array) && validation_result.any? return { success: false, message: "命令に誤りがあります: #{validation_result.join(', ')}" } end # Check if it returns hash with "errors" key? if validation_result.is_a?(Hash) && validation_result["errors"]&.any? return { success: false, message: "命令に誤りがあります: #{validation_result['errors'].join(', ')}" } end # If passed validation, update current_orders current_orders[power] = orders # Generate SVGs svg_orders_data = @turn.svg_orders || {} # None SVG (first time only) unless svg_orders_data["NONE"] none_svg = @client.api_render(@turn.game_state, orders: nil) svg_orders_data["NONE"] = none_svg if none_svg end # Power specific SVG power_orders = { power => orders } power_svg = @client.api_render(@turn.game_state, orders: power_orders) svg_orders_data[power] = power_svg if power_svg # All SVG all_svg = @client.api_render(@turn.game_state, orders: current_orders) svg_orders_data["ALL"] = all_svg if all_svg # Save if @turn.update(orders: current_orders, svg_orders: svg_orders_data) { success: true, message: "命令を送信しました" } else { success: false, message: "命令の送信に失敗しました" } end rescue StandardError => e Rails.logger.error("Order submission failed: #{e.message}") { success: false, message: "予期せぬエラーが発生しました。" } end private def valid_permission?(power) return true if @game.solo_mode? participant = @game.participants.find_by(user: @user) return false unless participant # Compare case-insensitive participant.power&.upcase == power&.upcase end end