From 3afee9463f0d358d55c58ac5bddd33e8ac1b10e6 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sat, 20 Dec 2025 01:58:23 -0800 Subject: [PATCH] add unlimited flag to raid groups --- app/blueprints/api/v1/raid_group_blueprint.rb | 4 +- .../api/v1/raid_groups_controller.rb | 77 +++++++++++++++++++ app/models/raid_group.rb | 18 ++++- ...1220014422_add_unlimited_to_raid_groups.rb | 5 ++ 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 app/controllers/api/v1/raid_groups_controller.rb create mode 100644 db/migrate/20251220014422_add_unlimited_to_raid_groups.rb diff --git a/app/blueprints/api/v1/raid_group_blueprint.rb b/app/blueprints/api/v1/raid_group_blueprint.rb index 66f1320..111eab4 100644 --- a/app/blueprints/api/v1/raid_group_blueprint.rb +++ b/app/blueprints/api/v1/raid_group_blueprint.rb @@ -4,6 +4,8 @@ module Api module V1 class RaidGroupBlueprint < ApiBlueprint view :flat do + identifier :id + field :name do |group| { en: group.name_en, @@ -11,7 +13,7 @@ module Api } end - fields :difficulty, :order, :section, :extra, :guidebooks, :hl + fields :difficulty, :order, :section, :extra, :guidebooks, :hl, :unlimited end view :full do diff --git a/app/controllers/api/v1/raid_groups_controller.rb b/app/controllers/api/v1/raid_groups_controller.rb new file mode 100644 index 0000000..300e6df --- /dev/null +++ b/app/controllers/api/v1/raid_groups_controller.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module Api + module V1 + class RaidGroupsController < Api::V1::ApiController + before_action :set_raid_group, only: %i[show update destroy] + before_action :ensure_editor_role, only: %i[create update destroy] + + # GET /raid_groups + def index + groups = RaidGroup.includes(:raids).ordered + render json: RaidGroupBlueprint.render(groups, view: :full) + end + + # GET /raid_groups/:id + def show + if @raid_group + render json: RaidGroupBlueprint.render(@raid_group, view: :full) + else + render json: { error: 'Raid group not found' }, status: :not_found + end + end + + # POST /raid_groups + def create + raid_group = RaidGroup.new(raid_group_params) + + if raid_group.save + render json: RaidGroupBlueprint.render(raid_group, view: :full), status: :created + else + render_validation_error_response(raid_group) + end + end + + # PATCH/PUT /raid_groups/:id + def update + if @raid_group.update(raid_group_params) + render json: RaidGroupBlueprint.render(@raid_group, view: :full) + else + render_validation_error_response(@raid_group) + end + end + + # DELETE /raid_groups/:id + def destroy + if @raid_group.raids.exists? + render json: ErrorBlueprint.render(nil, error: { + message: 'Cannot delete group with associated raids', + code: 'has_dependencies' + }), status: :unprocessable_entity + else + @raid_group.destroy! + head :no_content + end + end + + private + + def set_raid_group + @raid_group = RaidGroup.find_by(id: params[:id]) + end + + def raid_group_params + params.require(:raid_group).permit( + :name_en, :name_jp, :difficulty, :order, :section, :extra, :hl, :guidebooks, :unlimited + ) + end + + def ensure_editor_role + return if current_user&.role && current_user.role >= 7 + + Rails.logger.warn "[RAID_GROUPS] Unauthorized access attempt by user #{current_user&.id}" + render json: { error: 'Unauthorized - Editor role required' }, status: :unauthorized + end + end + end +end diff --git a/app/models/raid_group.rb b/app/models/raid_group.rb index 3c1010b..484ffd1 100644 --- a/app/models/raid_group.rb +++ b/app/models/raid_group.rb @@ -1,7 +1,23 @@ # frozen_string_literal: true class RaidGroup < ApplicationRecord - has_many :raids, class_name: 'Raid', foreign_key: :group_id + has_many :raids, class_name: 'Raid', foreign_key: :group_id, dependent: :restrict_with_error + + # Validations + validates :name_en, presence: true + validates :name_jp, presence: true + validates :order, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 } + validates :section, presence: true, numericality: { only_integer: true, greater_than: 0 } + validates :difficulty, numericality: { only_integer: true }, allow_nil: true + + # Scopes + scope :ordered, -> { order(order: :asc) } + scope :by_section, ->(section) { where(section: section) if section.present? } + scope :by_difficulty, ->(difficulty) { where(difficulty: difficulty) if difficulty.present? } + scope :hl_only, -> { where(hl: true) } + scope :extra_only, -> { where(extra: true) } + scope :with_guidebooks, -> { where(guidebooks: true) } + scope :unlimited_only, -> { where(unlimited: true) } def blueprint RaidGroupBlueprint diff --git a/db/migrate/20251220014422_add_unlimited_to_raid_groups.rb b/db/migrate/20251220014422_add_unlimited_to_raid_groups.rb new file mode 100644 index 0000000..2b86e0e --- /dev/null +++ b/db/migrate/20251220014422_add_unlimited_to_raid_groups.rb @@ -0,0 +1,5 @@ +class AddUnlimitedToRaidGroups < ActiveRecord::Migration[8.0] + def change + add_column :raid_groups, :unlimited, :boolean, default: false, null: false + end +end