add gw scores history endpoints for members and phantoms

This commit is contained in:
Justin Edmund 2025-12-18 11:02:59 -08:00
parent cc722b9660
commit 4a6ae93d20
4 changed files with 83 additions and 3 deletions

View file

@ -6,11 +6,14 @@ module Api
include CrewAuthorizationConcern
before_action :restrict_access
before_action :set_crew
before_action :set_crew, except: %i[gw_scores]
before_action :set_crew_from_user, only: %i[gw_scores]
before_action :set_membership, only: %i[update destroy promote demote]
before_action :set_membership_for_scores, only: %i[gw_scores]
before_action :authorize_crew_officer!, only: %i[destroy]
before_action :authorize_crew_captain!, only: %i[promote demote]
before_action :authorize_membership_update!, only: %i[update]
before_action :authorize_crew_member!, only: %i[gw_scores]
# PUT /crews/:crew_id/memberships/:id
def update
@ -55,16 +58,51 @@ module Api
render json: CrewMembershipBlueprint.render(@membership, view: :with_user, root: :membership)
end
# GET /crew/memberships/:id/gw_scores
def gw_scores
# Group scores by participation/event and calculate totals
scores_by_event = @membership.gw_individual_scores
.includes(crew_gw_participation: :gw_event)
.group_by(&:crew_gw_participation)
event_scores = scores_by_event.map do |participation, scores|
{
gw_event: GwEventBlueprint.render_as_hash(participation.gw_event),
total_score: scores.sum(&:score)
}
end
# Sort by event number descending (most recent first)
event_scores.sort_by! { |es| -es[:gw_event][:event_number] }
grand_total = event_scores.sum { |es| es[:total_score] }
render json: {
member: CrewMembershipBlueprint.render_as_hash(@membership, view: :with_user),
event_scores: event_scores,
grand_total: grand_total
}
end
private
def set_crew
@crew = Crew.find(params[:crew_id])
end
def set_crew_from_user
@crew = current_user.crew
raise CrewErrors::NotInCrewError unless @crew
end
def set_membership
@membership = @crew.crew_memberships.find(params[:id])
end
def set_membership_for_scores
@membership = @crew.crew_memberships.find(params[:id])
end
def membership_params
params.require(:membership).permit(:role, :joined_at, :retired, :retired_at)
end

View file

@ -6,10 +6,12 @@ module Api
include CrewAuthorizationConcern
before_action :restrict_access
before_action :set_crew
before_action :authorize_crew_member!, only: %i[index confirm_claim decline_claim]
before_action :set_crew, except: %i[gw_scores]
before_action :set_crew_from_user, only: %i[gw_scores]
before_action :authorize_crew_member!, only: %i[index confirm_claim decline_claim gw_scores]
before_action :authorize_crew_officer!, only: %i[create bulk_create update destroy assign]
before_action :set_phantom, only: %i[show update destroy assign confirm_claim decline_claim]
before_action :set_phantom_for_scores, only: %i[gw_scores]
# GET /crews/:crew_id/phantom_players
def index
@ -86,16 +88,51 @@ module Api
render json: PhantomPlayerBlueprint.render(@phantom, view: :with_claimed_by, root: :phantom_player)
end
# GET /crew/phantom_players/:id/gw_scores
def gw_scores
# Group scores by participation/event and calculate totals
scores_by_event = @phantom.gw_individual_scores
.includes(crew_gw_participation: :gw_event)
.group_by(&:crew_gw_participation)
event_scores = scores_by_event.map do |participation, scores|
{
gw_event: GwEventBlueprint.render_as_hash(participation.gw_event),
total_score: scores.sum(&:score)
}
end
# Sort by event number descending (most recent first)
event_scores.sort_by! { |es| -es[:gw_event][:event_number] }
grand_total = event_scores.sum { |es| es[:total_score] }
render json: {
phantom: PhantomPlayerBlueprint.render_as_hash(@phantom),
event_scores: event_scores,
grand_total: grand_total
}
end
private
def set_crew
@crew = Crew.find(params[:crew_id])
end
def set_crew_from_user
@crew = current_user.crew
raise CrewErrors::NotInCrewError unless @crew
end
def set_phantom
@phantom = @crew.phantom_players.find(params[:id])
end
def set_phantom_for_scores
@phantom = @crew.phantom_players.find(params[:id])
end
def phantom_params
params.require(:phantom_player).permit(:name, :granblue_id, :notes, :joined_at, :retired, :retired_at)
end

View file

@ -3,6 +3,7 @@
class CrewMembership < ApplicationRecord
belongs_to :crew
belongs_to :user
has_many :gw_individual_scores, dependent: :nullify
enum :role, { member: 0, vice_captain: 1, captain: 2 }

View file

@ -238,6 +238,10 @@ Rails.application.routes.draw do
# Create individual scores by event (auto-creates participation if needed)
post 'gw_events/:gw_event_id/individual_scores', to: 'gw_individual_scores#create_by_event'
post 'gw_events/:gw_event_id/individual_scores/batch', to: 'gw_individual_scores#batch_by_event'
# Member/phantom GW score history
get 'memberships/:id/gw_scores', to: 'crew_memberships#gw_scores'
get 'phantom_players/:id/gw_scores', to: 'phantom_players#gw_scores'
end
# Reading collections - works for any user with privacy check