Skip to content

Commit

Permalink
Include V2 registrations in WCIF output (#9074)
Browse files Browse the repository at this point in the history
* Make 'Assignemnts' table polymorphic

* Hook up WCIF associations for MicroserviceRegistrations

* Add missing WCIF methods to MicroserviceRegistration

* Stub microservice writing methods

* Store non-competing dummy registrations in cache table

* Add 'roles' field to migration and harmonize 'is_competing'

* Clarify comments about nil values for comment strings

* Fix column sanitizers for overhauled registration tables

* Fix WCIF status cancelled VS deleted and waiting_list VS pending

* Remove redundant 'roles' accessor
  • Loading branch information
gregorbg authored Mar 18, 2024
1 parent 8ec167f commit 4281067
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 24 deletions.
2 changes: 1 addition & 1 deletion app/models/assignment.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

class Assignment < ApplicationRecord
belongs_to :registration
belongs_to :registration, polymorphic: true
belongs_to :schedule_activity

validates :station_number, numericality: { only_integer: true }, allow_nil: true
Expand Down
32 changes: 18 additions & 14 deletions app/models/competition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1773,25 +1773,29 @@ def competition_series_ids
def persons_wcif(authorized: false)
managers = self.managers
includes_associations = [
:events,
{ assignments: [:schedule_activity] },
{ user: {
person: [:ranksSingle, :ranksAverage],
} },
:wcif_extensions,
]
# V2 registrations store the event IDs in the microservice data, not in the monolith
includes_associations << :events unless self.uses_new_registration_service?

registrations_relation = self.uses_new_registration_service? ? self.microservice_registrations : self.registrations

# NOTE: we're including non-competing registrations so that they can have job
# assignments as well. These registrations don't have accepted?, but they
# should appear in the WCIF.
persons_wcif = registrations.order(:id)
.includes(includes_associations)
.to_enum
.with_index(1)
.select { |r, registrant_id| authorized || r.wcif_status == "accepted" }
.map do |r, registrant_id|
managers.delete(r.user)
r.user.to_wcif(self, r, registrant_id, authorized: authorized)
end
persons_wcif = registrations_relation.order(:id)
.includes(includes_associations)
.to_enum
.with_index(1)
.select { |r, registrant_id| authorized || r.wcif_status == "accepted" }
.map do |r, registrant_id|
managers.delete(r.user)
r.user.to_wcif(self, r, registrant_id, authorized: authorized)
end
# NOTE: unregistered managers may generate N+1 queries on their personal bests,
# but that's fine because there are very few of them!
persons_wcif + managers.map { |m| m.to_wcif(self, authorized: authorized) }
Expand Down Expand Up @@ -1930,11 +1934,13 @@ def set_wcif_events!(wcif_events, current_user)

# Takes an array of partial Person WCIF and updates the fields that are not immutable.
def update_persons_wcif!(wcif_persons, current_user)
registrations = self.registrations.includes [
registrations_relation = self.uses_new_registration_service? ? self.microservice_registrations : self.registrations
registration_includes = [
{ assignments: [:schedule_activity] },
:user,
:registration_competition_events,
]
registration_includes << :registration_competition_events unless self.uses_new_registration_service?
registrations = registrations_relation.includes(registration_includes)
competition_activities = all_activities
new_assignments = []
removed_assignments = []
Expand All @@ -1947,8 +1953,6 @@ def update_persons_wcif!(wcif_persons, current_user)
registration ||= registrations.create(
competition: self,
user_id: wcif_person["wcaUserId"],
created_at: DateTime.now,
updated_at: DateTime.now,
is_competing: false,
)
end
Expand Down
4 changes: 2 additions & 2 deletions app/models/concerns/microservice_registration_holder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ def microservice_registrations
# we hydrate each model with the microservice information directly from above
ar_models.each do |ar_model|
matching_ms_model = ms_models.find { |ms_model| ms_model['competition_id'] == ar_model.competition_id && ms_model['user_id'] == ar_model.user_id }
raise "No matching Microservice registration found. This should not happen!" unless matching_ms_model.present?
raise "No matching Microservice registration found. This should not happen!" if !matching_ms_model.present? && ar_model.is_competing?

ar_model.load_ms_model(matching_ms_model)
ar_model.load_ms_model(matching_ms_model) if matching_ms_model.present?
end
end
end
Expand Down
68 changes: 64 additions & 4 deletions app/models/microservice_registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,27 @@ class MicroserviceRegistration < ApplicationRecord
belongs_to :competition, inverse_of: :microservice_registrations
belongs_to :user, inverse_of: :microservice_registrations

has_many :assignments, as: :registration
has_many :wcif_extensions, as: :extendable, dependent: :delete_all

serialize :roles, coder: YAML

delegate :name, :email, to: :user

attr_accessor :ms_registration
attr_writer :competing_status, :event_ids
attr_writer :competing_status, :event_ids, :guests, :comments, :administrative_notes

def load_ms_model(ms_model)
self.ms_registration = ms_model

self.competing_status = ms_model['competing_status']
self.guests = ms_model['guests']

competing_lane = ms_model['lanes']&.find { |lane| lane['lane_name'] == 'competing' }

self.event_ids = ms_model['lanes']&.find do |lane|
lane['lane_name'] == 'competing'
end&.dig('lane_details', 'event_details')&.pluck('event_id')
self.event_ids = competing_lane&.dig('lane_details', 'event_details')&.pluck('event_id')
self.comments = competing_lane&.dig('lane_details', 'comment')
self.administrative_notes = competing_lane&.dig('lane_details', 'admin_comment')
end

def ms_loaded?
Expand All @@ -30,20 +38,72 @@ def ms_loaded?
end

def competing_status
# Treat non-competing registrations as accepted, see also `registration.rb`
return "accepted" unless self.is_competing?

self.read_ms_data :competing_status
end

alias :status :competing_status

def wcif_status
return "deleted" if self.deleted?
return "pending" if self.pending?

self.competing_status
end

def event_ids
return [] unless self.is_competing?

self.read_ms_data :event_ids
end

def guests
return 0 unless self.is_competing?

self.read_ms_data :guests
end

def comments
# nil is not allowed here, see WCIF spec!
return '' unless self.is_competing?

self.read_ms_data :comments
end

def administrative_notes
# nil is not allowed here, see WCIF spec!
return '' unless self.is_competing?

self.read_ms_data :administrative_notes
end

def accepted?
self.status == "accepted"
end

def deleted?
self.status == "cancelled"
end

def pending?
# WCIF interprets "pending" as "not approved to compete yet"
# which is why these two statuses collapse into one.
self.status == "pending" || self.status == "waiting_list"
end

def to_wcif(authorized: false)
authorized_fields = {
"guests" => guests,
"comments" => comments || '',
"administrativeNotes" => administrative_notes || '',
}
{
"wcaRegistrationId" => id,
"eventIds" => event_ids.sort,
"status" => wcif_status,
"isCompeting" => is_competing?,
}.merge(authorized ? authorized_fields : {})
end
end
2 changes: 1 addition & 1 deletion app/models/registration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Registration < ApplicationRecord
has_many :registration_payments
has_many :competition_events, through: :registration_competition_events
has_many :events, through: :competition_events
has_many :assignments, dependent: :delete_all
has_many :assignments, as: :registration, dependent: :delete_all
has_many :wcif_extensions, as: :extendable, dependent: :delete_all
has_many :stripe_payment_intents, as: :holder, dependent: :delete_all

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class MakeAssignmentsTableRegistrationPolymorphic < ActiveRecord::Migration[7.1]
def change
add_column :assignments, :registration_type, :string, after: :registration_id

remove_index :assignments, column: :registration_id
add_index :assignments, [:registration_id, :registration_type]

Assignment.update_all(registration_type: 'Registration')
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

class AddStaffDummyFieldsToMicroserviceRegistrations < ActiveRecord::Migration[7.1]
def change
add_column :microservice_registrations, :roles, :text, after: :user_id, null: true
add_column :microservice_registrations, :is_competing, :boolean, after: :roles, default: true, null: false
end
end
5 changes: 4 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -549,10 +549,11 @@

create_table "assignments", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
t.bigint "registration_id"
t.string "registration_type"
t.bigint "schedule_activity_id"
t.integer "station_number"
t.string "assignment_code", null: false
t.index ["registration_id"], name: "index_assignments_on_registration_id"
t.index ["registration_id", "registration_type"], name: "index_assignments_on_registration_id_and_registration_type"
t.index ["schedule_activity_id"], name: "index_assignments_on_schedule_activity_id"
end

Expand Down Expand Up @@ -776,6 +777,8 @@
create_table "microservice_registrations", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
t.string "competition_id"
t.integer "user_id"
t.text "roles"
t.boolean "is_competing", default: true, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["competition_id", "user_id"], name: "index_microservice_registrations_on_competition_id_and_user_id", unique: true
Expand Down
16 changes: 15 additions & 1 deletion lib/database_dumper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,20 @@ def self.actions_to_column_sanitizers(columns_by_action)
},
),
}.freeze,
"microservice_registrations" => :skip_all_rows,
"microservice_registrations" => {
where_clause: JOIN_WHERE_VISIBLE_COMP,
column_sanitizers: actions_to_column_sanitizers(
copy: %w(
id
competition_id
user_id
roles
is_competing
created_at
updated_at
),
),
}.freeze,
"sanity_checks" => :skip_all_rows,
"sanity_check_categories" => :skip_all_rows,
"sanity_check_exclusions" => :skip_all_rows,
Expand Down Expand Up @@ -851,6 +864,7 @@ def self.actions_to_column_sanitizers(columns_by_action)
copy: %w(
id
registration_id
registration_type
schedule_activity_id
station_number
assignment_code
Expand Down

0 comments on commit 4281067

Please sign in to comment.