From dfcf02083f27e253e3ccbe55c7ec89b80fd81be2 Mon Sep 17 00:00:00 2001 From: Alistair White-Horne Date: Wed, 22 Apr 2026 09:38:09 +0100 Subject: [PATCH] Remove transaction during national reporting team reset The CLI tool should be retested after more indexes are added, to ascertain whether the locking issue is still extant. If the issue is still present, then this should help reduce the possibility of a big database lock which we witnessed last time we tested this CLI tool in data replication. Jira-Issue: MAV-7083 --- .../teams/reset_national_reporting.rb | 130 +++++++++--------- 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/app/lib/mavis_cli/teams/reset_national_reporting.rb b/app/lib/mavis_cli/teams/reset_national_reporting.rb index 9f4186311b..2951bb4004 100644 --- a/app/lib/mavis_cli/teams/reset_national_reporting.rb +++ b/app/lib/mavis_cli/teams/reset_national_reporting.rb @@ -82,81 +82,77 @@ def find_teams(workgroup) end def reset_team(team) - patient_ids_to_update = Set.new - - ActiveRecord::Base.transaction do - immunisation_imports = find_immunisation_imports_for_team(team) - puts " - Found #{immunisation_imports.count} immunisation import(s) created before team's cut off date: " \ - "#{team.national_reporting_cut_off_date}" - - patient_ids = find_patients_for_team(team).ids - puts " - Found #{patient_ids.count} patient(s) in this team" - - vaccination_records = find_vaccination_records_for_team(team) - puts " - Found #{vaccination_records.count} vaccination record(s) in this team's imports" - - not_synced_vaccination_records = - vaccination_records.not_synced_to_nhs_immunisations_api - synced_vaccination_records = - vaccination_records.synced_to_nhs_immunisations_api - patient_ids_of_not_synced_records = - not_synced_vaccination_records.pluck(:patient_id).uniq - if synced_vaccination_records.exists? - puts " - #{synced_vaccination_records.count} vaccination" \ - " record(s) have been synced to NHS Immunisations API and" \ - " will NOT be deleted" - puts " - #{not_synced_vaccination_records.count} vaccination" \ - " record(s) will be deleted" - end - - puts "Destroying #{not_synced_vaccination_records.count} vaccination records..." - not_synced_vaccination_records.find_each(&:destroy) - - puts "Refreshing immunisations imports..." - if immunisation_imports.joins(:vaccination_records).any? - immunisation_imports_with_records = - immunisation_imports.joins(:vaccination_records).distinct - immunisation_imports = - immunisation_imports.where.not( - id: immunisation_imports_with_records.select(:id) - ) - puts " - #{immunisation_imports_with_records.count} immunisation" \ - " import(s) have associated vaccination records and will NOT" \ - " be deleted" - puts " - #{immunisation_imports.count} immunisation import(s) will" \ - " be deleted" - end + immunisation_imports = find_immunisation_imports_for_team(team) + puts " - Found #{immunisation_imports.count} immunisation import(s) created before team's cut off date: " \ + "#{team.national_reporting_cut_off_date}" + + patient_ids = find_patients_for_team(team).ids + puts " - Found #{patient_ids.count} patient(s) in this team" + + vaccination_records = find_vaccination_records_for_team(team) + puts " - Found #{vaccination_records.count} vaccination record(s) in this team's imports" + + not_synced_vaccination_records = + vaccination_records.not_synced_to_nhs_immunisations_api + synced_vaccination_records = + vaccination_records.synced_to_nhs_immunisations_api + patient_ids_of_not_synced_records = + not_synced_vaccination_records.pluck(:patient_id).uniq + if synced_vaccination_records.exists? + puts " - #{synced_vaccination_records.count} vaccination" \ + " record(s) have been synced to NHS Immunisations API and" \ + " will NOT be deleted" + puts " - #{not_synced_vaccination_records.count} vaccination" \ + " record(s) will be deleted" + end - puts "Destroying #{immunisation_imports.count} immunisation imports..." - immunisation_imports.find_each(&:destroy) + puts "Destroying #{not_synced_vaccination_records.count} vaccination records..." + not_synced_vaccination_records.find_each(&:destroy) - archive_reasons = - ArchiveReason.where( - patient_id: patient_ids_of_not_synced_records, - team: + puts "Refreshing immunisations imports..." + if immunisation_imports.joins(:vaccination_records).any? + immunisation_imports_with_records = + immunisation_imports.joins(:vaccination_records).distinct + immunisation_imports = + immunisation_imports.where.not( + id: immunisation_imports_with_records.select(:id) ) - puts "Destroying #{archive_reasons.count} archive reasons..." - archive_reasons.find_each(&:destroy) + puts " - #{immunisation_imports_with_records.count} immunisation" \ + " import(s) have associated vaccination records and will NOT" \ + " be deleted" + puts " - #{immunisation_imports.count} immunisation import(s) will" \ + " be deleted" + end - puts "Updating patient-team relationships..." - PatientTeamUpdater.call( - patient_scope: Patient.where(id: patient_ids_of_not_synced_records) + puts "Destroying #{immunisation_imports.count} immunisation imports..." + immunisation_imports.find_each(&:destroy) + + archive_reasons = + ArchiveReason.where( + patient_id: patient_ids_of_not_synced_records, + team: ) + puts "Destroying #{archive_reasons.count} archive reasons..." + archive_reasons.find_each(&:destroy) + + puts "Updating patient-team relationships..." + PatientTeamUpdater.call( + patient_scope: Patient.where(id: patient_ids_of_not_synced_records) + ) - patients_to_destroy = - find_patients_without_team(patient_ids_of_not_synced_records) + patients_to_destroy = + find_patients_without_team(patient_ids_of_not_synced_records) - patient_ids_to_update += - patient_ids_of_not_synced_records - patients_to_destroy.ids - puts " - Found #{patients_to_destroy.count}" \ - " patient(s) who were in the imports, and no longer have teams" + patient_ids_to_update = + patient_ids_of_not_synced_records - patients_to_destroy.ids + puts " - Found #{patients_to_destroy.count}" \ + " patient(s) who were in the imports, and no longer have teams" - puts "Destroying #{patients_to_destroy.count} patients..." - PatientDeleter.call( - patients: patients_to_destroy, - confirm_production_delete: true - ) - end + puts "Destroying #{patients_to_destroy.count} patients..." + PatientDeleter.call( + patients: patients_to_destroy, + confirm_production_delete: true + ) puts "Enqueueing jobs to update statuses for" \ " #{patient_ids_to_update.size} patient(s) left over..."