-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
import api: ensure no duplicates for Conditions (#5378)
**Story card:** [sc-11839] ## Because Conditions were wrongly assumed to be longitudinal, resulting in 1:n mapping of patients to medical histories. Ideally every patient must have only one medical history to ensure that the reporting pipeline is accurate. ## Changes * Change in the import API to ensure that all Conditions will always map to a previous medical history (it will only create a new one if it didn't exist at all for a patient) * A data migration that merges all the previous medical histories for ICDDRB (no one else has sent multiple medical_histories yet).
- Loading branch information
1 parent
9621cb6
commit fff9102
Showing
5 changed files
with
145 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# frozen_string_literal: true | ||
|
||
class DedupeIcddrbMedicalHistories < ActiveRecord::Migration[6.1] | ||
FACILITY_ID = "f472c5db-188f-4563-9bc7-9f86a6ed6403" | ||
|
||
def up | ||
unless CountryConfig.current_country?("Bangladesh") && SimpleServer.env.production? | ||
return print "DedupeIcddrbMedicalHistories is only for production Bangladesh" | ||
end | ||
|
||
merge_resolution_rules = { | ||
Set["no"] => "no", | ||
Set["yes"] => "yes", | ||
Set["unknown"] => "unknown", | ||
Set["no", "yes"] => "yes", | ||
Set["no", "unknown"] => "no", | ||
Set["yes", "unknown"] => "yes", | ||
Set["yes", "no", "unknown"] => "yes" | ||
} | ||
|
||
fields_to_resolve = MedicalHistory.defined_enums.keys | ||
|
||
transaction do | ||
medical_histories_by_patient = MedicalHistory.joins(:patient) | ||
.where(patient: {assigned_facility_id: FACILITY_ID}) | ||
.group_by(&:patient_id) | ||
|
||
medical_histories_by_patient.each_value do |merge_candidates| | ||
next if merge_candidates.size < 2 | ||
merged_med_history_attrs = merge_candidates.first&.attributes&.except("id") | ||
fields_to_resolve.each do |field_name| | ||
conflicting_values = merge_candidates.map(&field_name.to_sym).to_set | ||
merged_med_history_attrs[field_name] = merge_resolution_rules.fetch(conflicting_values) | ||
end | ||
MedicalHistory.create!(merged_med_history_attrs) | ||
merge_candidates.map(&:discard!) | ||
end | ||
end | ||
end | ||
|
||
def down | ||
puts "This migration cannot be reversed." | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
require "rails_helper" | ||
require Rails.root.join("db", "data", "20240117114102_dedupe_icddrb_medical_histories.rb") | ||
|
||
describe DedupeIcddrbMedicalHistories do | ||
before do | ||
allow(CountryConfig).to receive(:current_country?).with("Bangladesh").and_return true | ||
stub_const("SIMPLE_SERVER_ENV", "production") | ||
end | ||
|
||
describe "when the data migration is run" do | ||
it "deduplicates medical histories and deletes older medical history records" do | ||
facility = create(:facility, id: "f472c5db-188f-4563-9bc7-9f86a6ed6403") | ||
patients = create_list(:patient, 3, :without_medical_history, assigned_facility_id: facility.id) | ||
|
||
medical_history1 = create(:medical_history, patient: patients[0], hypertension: "yes", diabetes: "no") | ||
|
||
medical_history2 = create(:medical_history, patient: patients[1], hypertension: "yes", diabetes: "no") | ||
medical_history3 = create(:medical_history, patient: patients[1], hypertension: "no", diabetes: "no") | ||
medical_history4 = create(:medical_history, patient: patients[1], hypertension: "no", diabetes: "yes") | ||
|
||
medical_history5 = create(:medical_history, patient: patients[2], hypertension: "no", diabetes: "no") | ||
medical_history6 = create(:medical_history, patient: patients[2], hypertension: "no", diabetes: "no") | ||
|
||
described_class.new.up | ||
|
||
deduped_patient2 = MedicalHistory.find_by(patient_id: patients[1].id) | ||
deduped_patient3 = MedicalHistory.find_by(patient_id: patients[2].id) | ||
|
||
expect(medical_history1.reload.deleted_at).to be_nil | ||
|
||
expect(medical_history2.reload.deleted_at).to be_a(Time) | ||
expect(medical_history3.reload.deleted_at).to be_a(Time) | ||
expect(medical_history4.reload.deleted_at).to be_a(Time) | ||
expect(deduped_patient2).to have_attributes(hypertension: "yes", diabetes: "yes") | ||
|
||
expect(medical_history5.reload.deleted_at).to be_a(Time) | ||
expect(medical_history6.reload.deleted_at).to be_a(Time) | ||
expect(deduped_patient3).to have_attributes(hypertension: "no", diabetes: "no") | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters