Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add teacher migrator #389

Merged
merged 4 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/controllers/migration/failures_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Migration::FailuresController < ::AdminController
layout "full"

def index
@migration_failures = MigrationFailure.where(data_migration_id: DataMigration.where(model: params[:model]).select(:id))
@model = params[:model]
end
end
8 changes: 6 additions & 2 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module ApplicationHelper
def page_data(title:, header: nil, header_size: "l", error: false)
def page_data(title:, header: nil, header_size: "l", error: false, backlink_href: nil)
page_title = if error
"Error: #{title}"
else
Expand All @@ -10,10 +10,14 @@ def page_data(title:, header: nil, header_size: "l", error: false)

return { page_title: } if header == false

backlink_or_breadcrumb = govuk_back_link(href: backlink_href) unless backlink_href.nil?

content_for(:backlink_or_breadcrumb) { backlink_or_breadcrumb }

page_header = tag.h1(header || title, class: "govuk-heading-#{header_size}")

content_for(:page_header) { page_header }

{ page_title:, page_header: }
{ page_title:, backlink_or_breadcrumb:, page_header: }
end
end
24 changes: 24 additions & 0 deletions app/helpers/migration_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,35 @@ def data_migration_percentage_migrated_successfully_tag(data_migrations)
govuk_tag(text: "#{avg_percentage.floor}%", colour:)
end

def data_migration_failures_link(data_migrations)
failure_count = data_migrations.sum(&:failure_count)

return unless failure_count.positive?

model = data_migrations.sample.model
govuk_link_to("Failures for #{model}", failures_migrations_path(model))
end

def data_migration_download_failures_report_link(data_migrations)
failure_count = data_migrations.sum(&:failure_count)

return unless failure_count.positive?

govuk_link_to("Failures report", download_report_migrations_path(data_migrations.sample.model))
end

def failure_item_json_code(item)
"<code>#{JSON.pretty_unparse(item).gsub(/\n/, '<br/>').gsub(/\s/, '&nbsp;')}</code>".html_safe
end

def failure_item_summary_list(item)
govuk_summary_list(html_attributes: { class: "govuk-!-font-size-16" }) do |summary_list|
item.each do |k, v|
summary_list.with_row do |row|
row.with_key { k }
row.with_value { v }
end
end
end
end
end
3 changes: 2 additions & 1 deletion app/migration/migrators/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ def offset
end

def limit
self.class.records_per_worker
# allow us to select a subset for testing if record_count is huge and we limit it
[self.class.records_per_worker, self.class.record_count].min
end

def start_migration!(total_count)
Expand Down
47 changes: 47 additions & 0 deletions app/migration/migrators/teacher.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module Migrators
class Teacher < Migrators::Base
def self.record_count
teachers.count
end

def self.model
:teacher
end

def self.teachers
::Migration::TeacherProfile.where(id: ::Migration::ParticipantProfile.ect_or_mentor.select(:teacher_profile_id).distinct)
end

def self.reset!
if Rails.env.development?
::Teacher.connection.execute("TRUNCATE #{::Teacher.table_name} RESTART IDENTITY CASCADE")
end
end

def migrate!
Rails.logger.info("Migrating #{self.class.record_count} teachers")

migrate(self.class.teachers.includes(:user)) do |teacher_profile|
Rails.logger.info(" --> #{teacher_profile.id}")

::Teacher.create!(trn: teacher_profile.trn,
first_name: first_name_of(teacher_profile.user.full_name),
last_name: last_name_of(teacher_profile.user.full_name))
end
end

def first_name_of(full_name)
parts = full_name.split(' ')
if parts.count > 2 && parts.first.downcase.in?(%w[mr miss ms mrs dr])
parts.second
else
parts.first
end
end

def last_name_of(full_name)
# FIXME: check for suffix titles perhaps e.g. Esq.
full_name.split(' ').last
end
end
end
1 change: 1 addition & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<div class="govuk-width-container">
<%= environment_specific_phase_banner %>
<%= yield(:backlink_or_breadcrumb) %>

<main class="govuk-main-wrapper" id="main-content" role="main">
<div class="govuk-grid-row">
Expand Down
1 change: 1 addition & 0 deletions app/views/layouts/full.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<div class="govuk-width-container">
<%= environment_specific_phase_banner %>
<%= yield(:backlink_or_breadcrumb) %>

<main class="govuk-main-wrapper" id="main-content" role="main">
<div class="govuk-grid-row">
Expand Down
23 changes: 23 additions & 0 deletions app/views/migration/failures/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<% page_data(title: "Migration failures for #{@model}", backlink_href: migrations_path) %>

<p class="govuk-body"><strong><%= @migration_failures.count %></strong> failed records</p>

<%= govuk_table do |table|
table.with_head do |head|
head.with_row do |row|
row.with_cell(text: "No.")
row.with_cell(text: "Source record")
row.with_cell(text: "Validation failure")
end
end

table.with_body do |body|
@migration_failures.each_with_index do |failure, index|
body.with_row(html_attributes: { class: "govuk-!-font-size-16" }) do |row|
row.with_cell(text: index + 1)
row.with_cell(text: failure_item_json_code(failure.item))
row.with_cell(text: failure.failure_message)
end
end
end
end %>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
row.with_cell(html_attributes: { class: "total-count" }, text: data_migration_total_count_tag(data_migrations))
row.with_cell(html_attributes: { class: "failure-count" }, text: data_migration_failure_count_tag(data_migrations))
row.with_cell(html_attributes: { class: "percentage-successfully-migrated" }, text: data_migration_percentage_migrated_successfully_tag(data_migrations))
row.with_cell(text: data_migration_download_failures_report_link(data_migrations))
row.with_cell(text: data_migration_failures_link(data_migrations))
end
end
end
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

scope module: "migration" do
resources :migrations, only: %i[index create] do
get ":model/failures", on: :collection, to: "failures#index", as: :failures
get "download_report/:model", on: :collection, action: :download_report, as: :download_report
post "reset", on: :collection, action: :reset, as: :reset
end
Expand Down
36 changes: 18 additions & 18 deletions config/solid_queue.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# default: &default
# dispatchers:
# - polling_interval: 1
# batch_size: 500
# workers:
# - queues: "*"
# threads: 3
# processes: 1
# polling_interval: 0.1
#
# development:
# <<: *default
#
# test:
# <<: *default
#
# production:
# <<: *default
default: &default
dispatchers:
- polling_interval: 1
batch_size: 500
workers:
- queues: "*"
threads: 3
processes: 3
polling_interval: 0.1

development:
<<: *default

test:
<<: *default

production:
<<: *default