111 lines
3.7 KiB
Ruby
111 lines
3.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Api
|
|
module V1
|
|
##
|
|
# ImportController is responsible for importing game data (e.g. deck data)
|
|
# and creating a new Party along with associated records (job, characters, weapons, summons, etc.).
|
|
#
|
|
# The controller expects a JSON payload whose top-level key is "import". If not wrapped,
|
|
# the controller will wrap the raw data automatically.
|
|
#
|
|
# @example Valid payload structure
|
|
# {
|
|
# "import": {
|
|
# "deck": { "name": "My Party", ... },
|
|
# "pc": { "job": { "master": { "name": "Warrior" } }, ... }
|
|
# }
|
|
# }
|
|
class ImportController < Api::V1::ApiController
|
|
ELEMENT_MAPPING = {
|
|
0 => nil,
|
|
1 => 4,
|
|
2 => 2,
|
|
3 => 3,
|
|
4 => 1,
|
|
5 => 6,
|
|
6 => 5
|
|
}.freeze
|
|
|
|
##
|
|
# Processes an import request.
|
|
#
|
|
# It reads and parses the raw JSON, wraps the data under the "import" key if necessary,
|
|
# transforms the deck data using BaseDeckTransformer, validates that the transformed data
|
|
# contains required fields, and then creates a new Party record (and its associated objects)
|
|
# inside a transaction.
|
|
#
|
|
# @return [void] Renders JSON response with a party shortcode or an error message.
|
|
def create
|
|
Rails.logger.info '[IMPORT] Checking input...'
|
|
|
|
body = parse_request_body
|
|
return unless body
|
|
|
|
raw_params = body['import']
|
|
unless raw_params.is_a?(Hash)
|
|
Rails.logger.error "[IMPORT] 'import' key is missing or not a hash."
|
|
return render json: { error: 'Invalid JSON data' }, status: :unprocessable_content
|
|
end
|
|
|
|
unless raw_params['deck'].is_a?(Hash) &&
|
|
raw_params['deck'].key?('pc') &&
|
|
raw_params['deck'].key?('npc')
|
|
Rails.logger.error "[IMPORT] Deck data incomplete or missing."
|
|
return render json: { error: 'Invalid deck data' }, status: :unprocessable_content
|
|
end
|
|
|
|
Rails.logger.info '[IMPORT] Starting import...'
|
|
|
|
return if performed? # Rendered an error response already
|
|
|
|
party = Party.create(user: current_user)
|
|
deck_data = raw_params['import']
|
|
process_data(party, deck_data)
|
|
|
|
render json: { shortcode: party.shortcode }, status: :created
|
|
rescue StandardError => e
|
|
render json: { error: e.message }, status: :unprocessable_content
|
|
end
|
|
|
|
private
|
|
|
|
##
|
|
# Reads and parses the raw JSON request body.
|
|
#
|
|
# @return [Hash] Parsed JSON data.
|
|
# @raise [JSON::ParserError] If the JSON is invalid.
|
|
def parse_request_body
|
|
raw_body = request.raw_post
|
|
JSON.parse(raw_body)
|
|
rescue JSON::ParserError => e
|
|
Rails.logger.error "[IMPORT] Invalid JSON: #{e.message}"
|
|
render json: { error: 'Invalid JSON data' }, status: :bad_request and return
|
|
end
|
|
|
|
##
|
|
# Ensures that the provided data is wrapped under an "import" key.
|
|
#
|
|
# @param data [Hash] The parsed JSON data.
|
|
# @return [Hash] Data wrapped under the "import" key.
|
|
def wrap_import_data(data)
|
|
data.key?('import') ? data : { 'import' => data }
|
|
end
|
|
|
|
##
|
|
# Processes the deck data using processors.
|
|
#
|
|
# @param party [Party] The party to insert data into
|
|
# @param data [Hash] The wrapped data.
|
|
# @return [Hash] The transformed deck data.
|
|
def process_data(party, data)
|
|
Rails.logger.info '[IMPORT] Transforming deck data'
|
|
|
|
Processors::JobProcessor.new(party, data).process
|
|
Processors::CharacterProcessor.new(party, data).process
|
|
Processors::SummonProcessor.new(party, data).process
|
|
Processors::WeaponProcessor.new(party, data).process
|
|
end
|
|
end
|
|
end
|
|
end
|