add artifact controllers and routes
This commit is contained in:
parent
069118cbe9
commit
cc7ac1956b
5 changed files with 343 additions and 0 deletions
29
app/controllers/api/v1/artifact_skills_controller.rb
Normal file
29
app/controllers/api/v1/artifact_skills_controller.rb
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ArtifactSkillsController < Api::V1::ApiController
|
||||
# GET /artifact_skills
|
||||
def index
|
||||
@skills = ArtifactSkill.all
|
||||
@skills = @skills.where(skill_group: params[:group]) if params[:group].present?
|
||||
@skills = @skills.where(polarity: params[:polarity]) if params[:polarity].present?
|
||||
|
||||
render json: ArtifactSkillBlueprint.render(@skills, root: :artifact_skills)
|
||||
end
|
||||
|
||||
# GET /artifact_skills/for_slot/:slot
|
||||
# Returns skills valid for a specific slot (1-4)
|
||||
def for_slot
|
||||
slot = params[:slot].to_i
|
||||
|
||||
unless (1..4).cover?(slot)
|
||||
return render json: { error: 'Slot must be between 1 and 4' }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
@skills = ArtifactSkill.for_slot(slot)
|
||||
render json: ArtifactSkillBlueprint.render(@skills, root: :artifact_skills)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
31
app/controllers/api/v1/artifacts_controller.rb
Normal file
31
app/controllers/api/v1/artifacts_controller.rb
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class ArtifactsController < Api::V1::ApiController
|
||||
before_action :set_artifact, only: [:show]
|
||||
|
||||
# GET /artifacts
|
||||
def index
|
||||
@artifacts = Artifact.all
|
||||
@artifacts = @artifacts.where(rarity: params[:rarity]) if params[:rarity].present?
|
||||
@artifacts = @artifacts.where(proficiency: params[:proficiency]) if params[:proficiency].present?
|
||||
|
||||
render json: ArtifactBlueprint.render(@artifacts, root: :artifacts)
|
||||
end
|
||||
|
||||
# GET /artifacts/:id
|
||||
def show
|
||||
render json: ArtifactBlueprint.render(@artifact)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_artifact
|
||||
@artifact = Artifact.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_not_found_response('artifact')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
147
app/controllers/api/v1/collection_artifacts_controller.rb
Normal file
147
app/controllers/api/v1/collection_artifacts_controller.rb
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class CollectionArtifactsController < ApiController
|
||||
# Read actions: look up user from params, check privacy
|
||||
before_action :set_target_user, only: %i[index show]
|
||||
before_action :check_collection_access, only: %i[index show]
|
||||
before_action :set_collection_artifact_for_read, only: %i[show]
|
||||
|
||||
# Write actions: require auth, use current_user
|
||||
before_action :restrict_access, only: %i[create update destroy batch]
|
||||
before_action :set_collection_artifact_for_write, only: %i[update destroy]
|
||||
|
||||
def index
|
||||
@collection_artifacts = @target_user.collection_artifacts.includes(:artifact)
|
||||
|
||||
@collection_artifacts = @collection_artifacts.where(artifact_id: params[:artifact_id]) if params[:artifact_id]
|
||||
@collection_artifacts = @collection_artifacts.where(element: params[:element]) if params[:element]
|
||||
|
||||
@collection_artifacts = @collection_artifacts.paginate(page: params[:page], per_page: params[:limit] || 50)
|
||||
|
||||
render json: Api::V1::CollectionArtifactBlueprint.render(
|
||||
@collection_artifacts,
|
||||
root: :artifacts,
|
||||
meta: pagination_meta(@collection_artifacts)
|
||||
)
|
||||
end
|
||||
|
||||
def show
|
||||
render json: Api::V1::CollectionArtifactBlueprint.render(
|
||||
@collection_artifact,
|
||||
view: :full
|
||||
)
|
||||
end
|
||||
|
||||
def create
|
||||
@collection_artifact = current_user.collection_artifacts.build(collection_artifact_params)
|
||||
|
||||
if @collection_artifact.save
|
||||
render json: Api::V1::CollectionArtifactBlueprint.render(
|
||||
@collection_artifact,
|
||||
view: :full
|
||||
), status: :created
|
||||
else
|
||||
render_validation_error_response(@collection_artifact)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
if @collection_artifact.update(collection_artifact_params)
|
||||
render json: Api::V1::CollectionArtifactBlueprint.render(
|
||||
@collection_artifact,
|
||||
view: :full
|
||||
)
|
||||
else
|
||||
render_validation_error_response(@collection_artifact)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@collection_artifact.destroy
|
||||
head :no_content
|
||||
end
|
||||
|
||||
# POST /collection/artifacts/batch
|
||||
# Creates multiple collection artifacts in a single request
|
||||
def batch
|
||||
items = batch_artifact_params[:collection_artifacts] || []
|
||||
created = []
|
||||
errors = []
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
items.each_with_index do |item_params, index|
|
||||
collection_artifact = current_user.collection_artifacts.build(item_params)
|
||||
|
||||
if collection_artifact.save
|
||||
created << collection_artifact
|
||||
else
|
||||
errors << {
|
||||
index: index,
|
||||
artifact_id: item_params[:artifact_id],
|
||||
error: collection_artifact.errors.full_messages.join(', ')
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
status = errors.any? ? :multi_status : :created
|
||||
|
||||
render json: Api::V1::CollectionArtifactBlueprint.render(
|
||||
created,
|
||||
root: :artifacts,
|
||||
meta: { created: created.size, errors: errors }
|
||||
), status: status
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_target_user
|
||||
@target_user = User.find(params[:user_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render json: { error: 'User not found' }, status: :not_found
|
||||
end
|
||||
|
||||
def check_collection_access
|
||||
return if @target_user.nil?
|
||||
|
||||
return if @target_user.collection_viewable_by?(current_user)
|
||||
|
||||
render json: { error: 'You do not have permission to view this collection' }, status: :forbidden
|
||||
end
|
||||
|
||||
def set_collection_artifact_for_read
|
||||
@collection_artifact = @target_user.collection_artifacts.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
raise CollectionErrors::CollectionItemNotFound.new('artifact', params[:id])
|
||||
end
|
||||
|
||||
def set_collection_artifact_for_write
|
||||
@collection_artifact = current_user.collection_artifacts.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
raise CollectionErrors::CollectionItemNotFound.new('artifact', params[:id])
|
||||
end
|
||||
|
||||
def collection_artifact_params
|
||||
params.require(:collection_artifact).permit(
|
||||
:artifact_id, :element, :proficiency, :level, :nickname,
|
||||
skill1: %i[modifier strength level],
|
||||
skill2: %i[modifier strength level],
|
||||
skill3: %i[modifier strength level],
|
||||
skill4: %i[modifier strength level]
|
||||
)
|
||||
end
|
||||
|
||||
def batch_artifact_params
|
||||
params.permit(collection_artifacts: [
|
||||
:artifact_id, :element, :proficiency, :level, :nickname,
|
||||
{ skill1: %i[modifier strength level] },
|
||||
{ skill2: %i[modifier strength level] },
|
||||
{ skill3: %i[modifier strength level] },
|
||||
{ skill4: %i[modifier strength level] }
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
119
app/controllers/api/v1/grid_artifacts_controller.rb
Normal file
119
app/controllers/api/v1/grid_artifacts_controller.rb
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class GridArtifactsController < Api::V1::ApiController
|
||||
before_action :find_grid_artifact, only: %i[update destroy]
|
||||
before_action :find_party, only: %i[create update destroy]
|
||||
before_action :find_grid_character, only: %i[create]
|
||||
before_action :find_artifact, only: %i[create]
|
||||
before_action :authorize_party_edit!, only: %i[create update destroy]
|
||||
|
||||
# POST /grid_artifacts
|
||||
def create
|
||||
# Check if grid_character already has an artifact
|
||||
if @grid_character.grid_artifact.present?
|
||||
@grid_character.grid_artifact.destroy
|
||||
end
|
||||
|
||||
@grid_artifact = GridArtifact.new(
|
||||
grid_artifact_params.merge(
|
||||
grid_character_id: @grid_character.id,
|
||||
artifact_id: @artifact.id
|
||||
)
|
||||
)
|
||||
|
||||
if @grid_artifact.save
|
||||
render json: GridArtifactBlueprint.render(@grid_artifact, view: :nested, root: :grid_artifact), status: :created
|
||||
else
|
||||
render_validation_error_response(@grid_artifact)
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /grid_artifacts/:id
|
||||
def update
|
||||
if @grid_artifact.update(grid_artifact_params)
|
||||
render json: GridArtifactBlueprint.render(@grid_artifact, view: :nested, root: :grid_artifact), status: :ok
|
||||
else
|
||||
render_validation_error_response(@grid_artifact)
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /grid_artifacts/:id
|
||||
def destroy
|
||||
if @grid_artifact.destroy
|
||||
render json: GridArtifactBlueprint.render(@grid_artifact, view: :destroyed), status: :ok
|
||||
else
|
||||
render_unprocessable_entity_response(
|
||||
Api::V1::GranblueError.new(@grid_artifact.errors.full_messages.join(', '))
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_grid_artifact
|
||||
@grid_artifact = GridArtifact.find_by(id: params[:id])
|
||||
render_not_found_response('grid_artifact') unless @grid_artifact
|
||||
end
|
||||
|
||||
def find_party
|
||||
@party = if @grid_artifact
|
||||
@grid_artifact.grid_character.party
|
||||
else
|
||||
Party.find_by(id: params[:party_id])
|
||||
end
|
||||
render_not_found_response('party') unless @party
|
||||
end
|
||||
|
||||
def find_grid_character
|
||||
@grid_character = GridCharacter.find_by(id: params.dig(:grid_artifact, :grid_character_id))
|
||||
render_not_found_response('grid_character') unless @grid_character
|
||||
end
|
||||
|
||||
def find_artifact
|
||||
artifact_id = params.dig(:grid_artifact, :artifact_id)
|
||||
@artifact = Artifact.find_by(id: artifact_id)
|
||||
render_not_found_response('artifact') unless @artifact
|
||||
end
|
||||
|
||||
def authorize_party_edit!
|
||||
if @party.user.present?
|
||||
authorize_user_party
|
||||
else
|
||||
authorize_anonymous_party
|
||||
end
|
||||
end
|
||||
|
||||
def authorize_user_party
|
||||
return if current_user.present? && @party.user == current_user
|
||||
|
||||
render_unauthorized_response
|
||||
end
|
||||
|
||||
def authorize_anonymous_party
|
||||
provided_edit_key = edit_key.to_s.strip.force_encoding('UTF-8')
|
||||
party_edit_key = @party.edit_key.to_s.strip.force_encoding('UTF-8')
|
||||
return if valid_edit_key?(provided_edit_key, party_edit_key)
|
||||
|
||||
render_unauthorized_response
|
||||
end
|
||||
|
||||
def valid_edit_key?(provided_edit_key, party_edit_key)
|
||||
provided_edit_key.present? &&
|
||||
provided_edit_key.bytesize == party_edit_key.bytesize &&
|
||||
ActiveSupport::SecurityUtils.secure_compare(provided_edit_key, party_edit_key)
|
||||
end
|
||||
|
||||
def grid_artifact_params
|
||||
params.require(:grid_artifact).permit(
|
||||
:grid_character_id, :artifact_id, :element, :proficiency, :level,
|
||||
skill1: %i[modifier strength level],
|
||||
skill2: %i[modifier strength level],
|
||||
skill3: %i[modifier strength level],
|
||||
skill4: %i[modifier strength level]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -101,6 +101,17 @@ Rails.application.routes.draw do
|
|||
|
||||
resources :weapon_series, only: %i[index show create update destroy]
|
||||
|
||||
# Artifacts (read-only reference data)
|
||||
resources :artifacts, only: %i[index show]
|
||||
resources :artifact_skills, only: %i[index] do
|
||||
collection do
|
||||
get 'for_slot/:slot', action: :for_slot, as: :for_slot
|
||||
end
|
||||
end
|
||||
|
||||
# Grid artifacts
|
||||
resources :grid_artifacts, only: %i[create update destroy]
|
||||
|
||||
# Grid endpoints - new prefixed versions
|
||||
post 'grid_characters/resolve', to: 'grid_characters#resolve'
|
||||
post 'grid_characters/update_uncap', to: 'grid_characters#update_uncap_level'
|
||||
|
|
@ -134,6 +145,7 @@ Rails.application.routes.draw do
|
|||
resources :characters, only: [:index, :show], controller: '/api/v1/collection_characters'
|
||||
resources :weapons, only: [:index, :show], controller: '/api/v1/collection_weapons'
|
||||
resources :summons, only: [:index, :show], controller: '/api/v1/collection_summons'
|
||||
resources :artifacts, only: [:index, :show], controller: '/api/v1/collection_artifacts'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -156,6 +168,11 @@ Rails.application.routes.draw do
|
|||
end
|
||||
resources :job_accessories, controller: '/api/v1/collection_job_accessories',
|
||||
only: [:index, :show, :create, :destroy]
|
||||
resources :artifacts, only: [:create, :update, :destroy], controller: '/api/v1/collection_artifacts' do
|
||||
collection do
|
||||
post :batch
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue