quality-measure-engine 1.1.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/.gitignore +12 -0
  2. data/.travis.yml +16 -0
  3. data/Gemfile +5 -21
  4. data/Gemfile.lock +126 -0
  5. data/LICENSE.txt +13 -0
  6. data/README.md +23 -44
  7. data/Rakefile +6 -29
  8. data/lib/qme/bundle/bundle.rb +34 -0
  9. data/lib/qme/bundle/importer.rb +69 -0
  10. data/lib/qme/database_access.rb +7 -11
  11. data/lib/qme/map/map_reduce_builder.rb +4 -1
  12. data/lib/qme/map/map_reduce_executor.rb +55 -43
  13. data/lib/qme/map/measure_calculation_job.rb +24 -23
  14. data/lib/qme/quality_measure.rb +5 -5
  15. data/lib/qme/quality_report.rb +37 -19
  16. data/lib/qme/railtie.rb +7 -0
  17. data/lib/qme/tasks/bundle.rake +14 -0
  18. data/lib/qme/version.rb +3 -0
  19. data/lib/quality-measure-engine.rb +13 -25
  20. data/quality-measure-engine.gemspec +28 -0
  21. data/test/fixtures/bundles/just_measure_0002.zip +0 -0
  22. data/test/fixtures/delayed_backend_mongoid_jobs/queued_job.json +9 -0
  23. data/test/fixtures/measures/measure_metadata.json +52 -0
  24. data/test/fixtures/records/barry_berry.json +471 -0
  25. data/test/fixtures/records/billy_jones_ipp.json +78 -0
  26. data/test/fixtures/records/jane_jones_numerator.json +120 -0
  27. data/test/fixtures/records/jill_jones_denominator.json +78 -0
  28. data/test/simplecov_setup.rb +18 -0
  29. data/test/test_helper.rb +26 -0
  30. data/test/unit/qme/map/map_reduce_builder_test.rb +38 -0
  31. data/test/unit/qme/map/map_reduce_executor_test.rb +56 -0
  32. data/test/unit/qme/map/measure_calculation_job_test.rb +22 -0
  33. data/test/unit/qme/quality_measure_test.rb +14 -0
  34. data/{spec/qme/quality_report_spec.rb → test/unit/qme/quality_report_test.rb} +32 -20
  35. metadata +91 -115
  36. data/VERSION +0 -1
  37. data/js/map_reduce_utils.js +0 -173
  38. data/js/underscore_min.js +0 -25
  39. data/lib/qme/ext/record.rb +0 -43
  40. data/lib/qme/importer/entry.rb +0 -126
  41. data/lib/qme/importer/generic_importer.rb +0 -117
  42. data/lib/qme/importer/measure_properties_generator.rb +0 -39
  43. data/lib/qme/importer/property_matcher.rb +0 -110
  44. data/lib/qme/measure/database_loader.rb +0 -83
  45. data/lib/qme/measure/measure_loader.rb +0 -174
  46. data/lib/qme/measure/properties_builder.rb +0 -184
  47. data/lib/qme/measure/properties_converter.rb +0 -27
  48. data/lib/qme/randomizer/patient_randomization_job.rb +0 -47
  49. data/lib/qme/randomizer/patient_randomizer.rb +0 -250
  50. data/lib/qme/randomizer/random_patient_creator.rb +0 -47
  51. data/lib/qme_test.rb +0 -13
  52. data/lib/tasks/fixtures.rake +0 -91
  53. data/lib/tasks/measure.rake +0 -110
  54. data/lib/tasks/mongo.rake +0 -68
  55. data/lib/tasks/patient_random.rake +0 -45
  56. data/spec/qme/bundle_spec.rb +0 -37
  57. data/spec/qme/importer/generic_importer_spec.rb +0 -73
  58. data/spec/qme/importer/measure_properties_generator_spec.rb +0 -15
  59. data/spec/qme/importer/property_matcher_spec.rb +0 -174
  60. data/spec/qme/map/map_reduce_builder_spec.rb +0 -38
  61. data/spec/qme/map/measures_spec.rb +0 -38
  62. data/spec/qme/map/patient_mapper_spec.rb +0 -11
  63. data/spec/qme/measure_loader_spec.rb +0 -12
  64. data/spec/qme/properties_builder_spec.rb +0 -61
  65. data/spec/spec_helper.rb +0 -120
  66. data/spec/validate_measures_spec.rb +0 -21
@@ -85,12 +85,15 @@ module QME
85
85
  "function (key, value) {
86
86
  var patient = value;
87
87
  patient.measure_id = \"#{@measure_def['id']}\";\n"
88
- if @params['test_id'] && @params['test_id'].class==BSON::ObjectId
88
+ if @params['test_id'] && @params['test_id'].class==Moped::BSON::ObjectId
89
89
  reduce += " patient.test_id = new ObjectId(\"#{@params['test_id']}\");\n"
90
90
  end
91
91
  if @measure_def['sub_id']
92
92
  reduce += " patient.sub_id = \"#{@measure_def['sub_id']}\";\n"
93
93
  end
94
+ if @measure_def['nqf_id']
95
+ reduce += " patient.nqf_id = \"#{@measure_def['nqf_id']}\";\n"
96
+ end
94
97
 
95
98
  reduce += "patient.effective_date = #{@params['effective_date']};
96
99
  if (patient.provider_performances) {
@@ -16,7 +16,8 @@ module QME
16
16
  @measure_id = measure_id
17
17
  @sub_id = sub_id
18
18
  @parameter_values = parameter_values
19
- determine_connection_information
19
+ @measure_def = QualityMeasure.new(@measure_id, @sub_id).definition
20
+ determine_connection_information()
20
21
  end
21
22
 
22
23
  # Examines the patient_cache collection and generates a total of all groups
@@ -24,7 +25,7 @@ module QME
24
25
  # collection.
25
26
  # @return [Hash] measure groups (like numerator) as keys, counts as values
26
27
  def count_records_in_measure_groups
27
- patient_cache = get_db.collection('patient_cache')
28
+ pipeline = []
28
29
  base_query = {'value.measure_id' => @measure_id, 'value.sub_id' => @sub_id,
29
30
  'value.effective_date' => @parameter_values['effective_date'],
30
31
  'value.test_id' => @parameter_values['test_id']}
@@ -34,25 +35,37 @@ module QME
34
35
  query = base_query.clone
35
36
 
36
37
  query.merge!({'value.manual_exclusion' => {'$in' => [nil, false]}})
38
+
39
+ pipeline << {'$match' => query}
40
+ pipeline << {'$group' => {
41
+ "_id" => "$value.measure_id", # we don't really need this, but Mongo requires that we group
42
+ "population" => {"$sum" => "$value.population"},
43
+ "denominator" => {"$sum" => "$value.denominator"},
44
+ "numerator" => {"$sum" => "$value.numerator"},
45
+ "antinumerator" => {"$sum" => "$value.antinumerator"},
46
+ "exclusions" => {"$sum" => "$value.exclusions"},
47
+ "denexcep" => {"$sum" => "$value.denexcep"},
48
+ "considered" => {"$sum" => 1}
49
+ }}
37
50
 
38
- result = {:measure_id => @measure_id, :sub_id => @sub_id,
51
+ aggregate = get_db.command(:aggregate => 'patient_cache', :pipeline => pipeline)
52
+ if aggregate['ok'] != 1
53
+ raise RuntimeError, "Aggregation Failed"
54
+ elsif aggregate['result'].size !=1
55
+ raise RuntimeError, "Expected one group from patient_cache aggregation, got #{aggregate['result'].size}"
56
+ end
57
+
58
+ nqf_id = @measure_def['nqf_id'] || @measure_def['id']
59
+ result = {:measure_id => @measure_id, :sub_id => @sub_id, :nqf_id => nqf_id, :population_ids => @measure_def["population_ids"],
39
60
  :effective_date => @parameter_values['effective_date'],
40
61
  :test_id => @parameter_values['test_id'], :filters => @parameter_values['filters']}
41
-
42
- # need to time the old way agains the single query to verify that the single query is more performant
43
- aggregate = {"population"=>0, "denominator"=>0, "numerator"=>0, "antinumerator"=>0, "exclusions"=>0}
44
- %w(population denominator numerator antinumerator exclusions).each do |measure_group|
45
- patient_cache.find(query.merge("value.#{measure_group}" => true)) do |cursor|
46
- aggregate[measure_group] = cursor.count
47
- end
48
- end
49
- aggregate["considered"] = patient_cache.find(query).count
50
- aggregate["exclusions"] += patient_cache.find(base_query.merge({'value.manual_exclusion'=>true})).count
51
- result.merge!(aggregate)
52
62
 
63
+ result.merge!(aggregate['result'].first)
64
+ result.reject! {|k, v| k == '_id'} # get rid of the group id the Mongo forced us to use
65
+ result['exclusions'] += get_db['patient_cache'].find(base_query.merge({'value.manual_exclusion'=>true})).count
53
66
  result.merge!(execution_time: (Time.now.to_i - @parameter_values['start_time'].to_i)) if @parameter_values['start_time']
54
-
55
- get_db.collection("query_cache").save(result, safe: true)
67
+ get_db()["query_cache"].insert(result)
68
+ get_db().command({:getLastError => 1}) # make sure last insert finished before we continue
56
69
  result
57
70
  end
58
71
 
@@ -60,13 +73,13 @@ module QME
60
73
  # in the patient_cache collection. These documents will state the measure groups
61
74
  # that the record belongs to, such as numerator, etc.
62
75
  def map_records_into_measure_groups
63
- qm = QualityMeasure.new(@measure_id, @sub_id)
64
- measure = Builder.new(get_db, qm.definition, @parameter_values)
65
- records = get_db.collection('records')
66
- records.map_reduce(measure.map_function, "function(key, values){return values;}",
67
- :out => {:reduce => 'patient_cache'},
68
- :finalize => measure.finalize_function,
69
- :query => {:test_id => @parameter_values['test_id']})
76
+ measure = Builder.new(get_db(), @measure_def, @parameter_values)
77
+ get_db().command(:mapReduce => 'records',
78
+ :map => measure.map_function,
79
+ :reduce => "function(key, values){return values;}",
80
+ :out => {:reduce => 'patient_cache'},
81
+ :finalize => measure.finalize_function,
82
+ :query => {:test_id => @parameter_values['test_id']})
70
83
  apply_manual_exclusions
71
84
  end
72
85
 
@@ -74,13 +87,13 @@ module QME
74
87
  # This will create a document in the patient_cache collection. This document
75
88
  # will state the measure groups that the record belongs to, such as numerator, etc.
76
89
  def map_record_into_measure_groups(patient_id)
77
- qm = QualityMeasure.new(@measure_id, @sub_id)
78
- measure = Builder.new(get_db, qm.definition, @parameter_values)
79
- records = get_db.collection('records')
80
- records.map_reduce(measure.map_function, "function(key, values){return values;}",
81
- :out => {:reduce => 'patient_cache'},
82
- :finalize => measure.finalize_function,
83
- :query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
90
+ measure = Builder.new(get_db(), @measure_def, @parameter_values)
91
+ get_db().command(:mapReduce => 'records',
92
+ :map => measure.map_function,
93
+ :reduce => "function(key, values){return values;}",
94
+ :out => {:reduce => 'patient_cache'},
95
+ :finalize => measure.finalize_function,
96
+ :query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
84
97
  apply_manual_exclusions
85
98
  end
86
99
 
@@ -88,14 +101,14 @@ module QME
88
101
  # This will *not* create a document in the patient_cache collection, instead the
89
102
  # result is returned directly.
90
103
  def get_patient_result(patient_id)
91
- qm = QualityMeasure.new(@measure_id, @sub_id)
92
- measure = Builder.new(get_db, qm.definition, @parameter_values)
93
- records = get_db.collection('records')
94
- result = records.map_reduce(measure.map_function, "function(key, values){return values;}",
95
- :out => {:inline => true},
96
- :raw => true,
97
- :finalize => measure.finalize_function,
98
- :query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
104
+ measure = Builder.new(get_db(), @measure_def, @parameter_values)
105
+ result = get_db().command(:mapReduce => 'records',
106
+ :map => measure.map_function,
107
+ :reduce => "function(key, values){return values;}",
108
+ :out => {:inline => true},
109
+ :raw => true,
110
+ :finalize => measure.finalize_function,
111
+ :query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
99
112
  raise result['err'] if result['ok']!=1
100
113
  result['results'][0]['value']
101
114
  end
@@ -104,12 +117,11 @@ module QME
104
117
  # and sets a flag in each cached patient result for patients that have been excluded from the
105
118
  # current measure
106
119
  def apply_manual_exclusions
107
- exclusions = get_db.collection('manual_exclusions').find({'measure_id'=>@measure_id, 'sub_id'=>@sub_id}).to_a.map do |exclusion|
120
+ exclusions = get_db()['manual_exclusions'].find({'measure_id'=>@measure_id, 'sub_id'=>@sub_id}).to_a.map do |exclusion|
108
121
  exclusion['medical_record_id']
109
122
  end
110
- get_db.collection('patient_cache').update(
111
- {'value.measure_id'=>@measure_id, 'value.sub_id'=>@sub_id, 'value.medical_record_id'=>{'$in'=>exclusions} },
112
- {'$set'=>{'value.manual_exclusion'=>true}}, :multi=>true)
123
+ get_db()['patient_cache'].find({'value.measure_id'=>@measure_id, 'value.sub_id'=>@sub_id, 'value.medical_record_id'=>{'$in'=>exclusions} })
124
+ .update_all({'$set'=>{'value.manual_exclusion'=>true}})
113
125
  end
114
126
 
115
127
  def filter_parameters
@@ -117,7 +129,7 @@ module QME
117
129
  conditions = []
118
130
  if(filters = @parameter_values['filters'])
119
131
  if (filters['providers'] && filters['providers'].size > 0)
120
- providers = filters['providers'].map {|provider_id| BSON::ObjectId(provider_id) if (provider_id and provider_id != 'null') }
132
+ providers = filters['providers'].map {|provider_id| Moped::BSON::ObjectId(provider_id) if (provider_id and provider_id != 'null') }
121
133
  # provider_performances have already been filtered by start and end date in map_reduce_builder as part of the finalize
122
134
  conditions << {'value.provider_performances.provider_id' => {'$in' => providers}}
123
135
  end
@@ -1,11 +1,8 @@
1
1
  module QME
2
2
  module MapReduce
3
- # A Resque job that allows for measure calculation by a Resque worker. Can be created as follows:
3
+ # A delayed_job that allows for measure calculation by a delayed_job worker. Can be created as follows:
4
4
  #
5
- # MapReduce::MeasureCalculationJob.create(:measure_id => '0221', :sub_id => 'a', :effective_date => 1291352400, :test_id => xyzzy)
6
- #
7
- # This will return a uuid which can be used to check in on the status of a job. More details on this can be found
8
- # at the {Resque Stats project page}[https://github.com/quirkey/resque-status].
5
+ # Delayed::Job.enqueue QME::MapRedude::MeasureCalculationJob.new(:measure_id => '0221', :sub_id => 'a', :effective_date => 1291352400, :test_id => xyzzy)
9
6
  #
10
7
  # MeasureCalculationJob will check to see if a measure has been calculated before running the calculation. It does
11
8
  # this by creating a QME::QualityReport and asking if it has been calculated. If so, it will complete the job without
@@ -13,36 +10,40 @@ module QME
13
10
  #
14
11
  # When a measure needs calculation, the job will create a QME::MapReduce::Executor and interact with it to calculate
15
12
  # the report.
16
- class MeasureCalculationJob < Resque::JobWithStatus
17
- def perform
18
- MeasureCalculationJob.calculate(options)
13
+ class MeasureCalculationJob
14
+ attr_accessor :test_id, :measure_id, :sub_id, :effective_date, :filters
15
+
16
+ def initialize(options)
17
+ @measure_id = options['measure_id']
18
+ @sub_id = options['sub_id']
19
+ @options = options
19
20
  end
20
21
 
21
- def self.calculate(options)
22
- test_id = options['test_id'] ? BSON::ObjectId(options['test_id']) : nil
23
- qr = QualityReport.new(options['measure_id'], options['sub_id'], 'effective_date' => options['effective_date'], 'test_id' => test_id, 'filters' => options['filters'])
22
+ def perform
23
+ qr = QualityReport.new(@measure_id, @sub_id, @options)
24
24
  if qr.calculated?
25
- completed("#{options['measure_id']}#{options['sub_id']} has already been calculated") if respond_to? :completed
25
+ completed("#{@measure_id}#{@sub_id} has already been calculated")
26
26
  else
27
- map = QME::MapReduce::Executor.new(options['measure_id'], options['sub_id'], 'effective_date' => options['effective_date'], 'test_id' => test_id, 'filters' => options['filters'], 'start_time' => Time.now.to_i)
28
-
27
+ map = QME::MapReduce::Executor.new(@measure_id, @sub_id, @options.merge('start_time' => Time.now.to_i))
29
28
  if !qr.patients_cached?
30
- tick('Starting MapReduce') if respond_to? :tick
29
+ tick('Starting MapReduce')
31
30
  map.map_records_into_measure_groups
32
- tick('MapReduce complete') if respond_to? :tick
31
+ tick('MapReduce complete')
33
32
  end
34
33
 
35
- tick('Calculating group totals') if respond_to? :tick
34
+ tick('Calculating group totals')
36
35
  result = map.count_records_in_measure_groups
37
- completed("#{options['measure_id']}#{options['sub_id']}: p#{result['population']}, d#{result['denominator']}, n#{result['numerator']}, e#{result['exclusions']}") if respond_to? :completed
36
+ completed("#{@measure_id}#{@sub_id}: p#{result['population']}, d#{result['denominator']}, n#{result['numerator']}, excl#{result['exclusions']}, excep#{result['denexcep']}")
38
37
  end
38
+ end
39
+
40
+ def completed(message)
41
+
42
+ end
43
+
44
+ def tick(message)
39
45
 
40
46
  end
41
-
42
- # This can be uncommented and changed to put the jobs on a separate queue.
43
- # def self.queue
44
- # :statused
45
- # end
46
47
  end
47
48
  end
48
49
  end
@@ -8,7 +8,7 @@ module QME
8
8
  # @return [Hash] an hash of measure definitions
9
9
  def self.all
10
10
  result = {}
11
- measures = get_db.collection('measures')
11
+ measures = get_db()['measures']
12
12
  measures.find().each do |measure|
13
13
  id = measure['id']
14
14
  sub_id = measure['sub_id']
@@ -19,7 +19,7 @@ module QME
19
19
  end
20
20
 
21
21
  def self.get_measures(measure_ids)
22
- get_db.collection('measures').find('id' => {"$in" => measure_ids})
22
+ get_db()['measures'].find('id' => {"$in" => measure_ids})
23
23
  end
24
24
 
25
25
  # Creates a new QualityMeasure
@@ -34,11 +34,11 @@ module QME
34
34
  # Retrieve a measure definition from the database
35
35
  # @return [Hash] a JSON hash of the encoded measure
36
36
  def definition
37
- measures = get_db.collection('measures')
37
+ measures = get_db()['measures']
38
38
  if @sub_id
39
- measures.find_one({'id' => @measure_id, 'sub_id' => @sub_id})
39
+ measures.find({'id' => @measure_id, 'sub_id' => @sub_id}).first()
40
40
  else
41
- measures.find_one({'id' => @measure_id})
41
+ measures.find({'id' => @measure_id}).first()
42
42
  end
43
43
  end
44
44
  end
@@ -10,25 +10,25 @@ module QME
10
10
  # and query_cache collections
11
11
  def self.destroy_all
12
12
  determine_connection_information
13
- get_db.collection("query_cache").drop
14
- get_db.collection("patient_cache").drop
13
+ get_db()["query_cache"].drop
14
+ get_db()["patient_cache"].drop
15
15
  end
16
16
 
17
17
  # Removes the cached results for the patient with the supplied id and
18
18
  # recalculates as necessary
19
19
  def self.update_patient_results(id)
20
- determine_connection_information
20
+ determine_connection_information()
21
21
 
22
22
  # TODO: need to wait for any outstanding calculations to complete and then prevent
23
23
  # any new ones from starting until we are done.
24
24
 
25
25
  # drop any cached measure result calculations for the modified patient
26
- get_db.collection("patient_cache").remove('value.medical_record_id' => id)
26
+ get_db()["patient_cache"].find('value.medical_record_id' => id).remove_all()
27
27
 
28
28
  # get a list of cached measure results for a single patient
29
- sample_patient = get_db.collection('patient_cache').find_one()
29
+ sample_patient = get_db()['patient_cache'].find().first()
30
30
  if sample_patient
31
- cached_results = get_db.collection('patient_cache').find({'value.patient_id' => sample_patient['value']['patient_id']})
31
+ cached_results = get_db()['patient_cache'].find({'value.patient_id' => sample_patient['value']['patient_id']})
32
32
 
33
33
  # for each cached result (a combination of measure_id, sub_id, effective_date and test_id)
34
34
  cached_results.each do |measure|
@@ -42,7 +42,7 @@ module QME
42
42
 
43
43
  # remove the query totals so they will be recalculated using the new results for
44
44
  # the modified patient
45
- get_db.collection("query_cache").drop
45
+ get_db()["query_cache"].drop()
46
46
  end
47
47
 
48
48
  # Creates a new QualityReport
@@ -74,29 +74,47 @@ module QME
74
74
  # Kicks off a background job to calculate the measure
75
75
  # @return a unique id for the measure calculation job
76
76
  def calculate(asynchronous=true)
77
- options = {'measure_id' => @measure_id, 'sub_id' => @sub_id,
78
- 'effective_date' => @parameter_values['effective_date'],
79
- 'test_id' => @parameter_values['test_id'],
80
- 'filters' => QME::QualityReport.normalize_filters(@parameter_values['filters'])}
77
+
78
+ options = {'measure_id' => @measure_id, 'sub_id' => @sub_id}
79
+
80
+ options.merge! @parameter_values
81
+ options['filters'] = QME::QualityReport.normalize_filters(@parameter_values['filters'])
82
+
81
83
  if (asynchronous)
82
- MapReduce::MeasureCalculationJob.create(options)
84
+ job = Delayed::Job.enqueue(QME::MapReduce::MeasureCalculationJob.new(options))
85
+ job._id
83
86
  else
84
- MapReduce::MeasureCalculationJob.calculate(options)
87
+ mcj = QME::MapReduce::MeasureCalculationJob.new(options)
88
+ mcj.perform
85
89
  end
86
90
  end
87
91
 
88
92
  # Returns the status of a measure calculation job
89
93
  # @param job_id the id of the job to check on
90
- # @return [Hash] containing status information on the measure calculation job
94
+ # @return [Symbol] Will return the status: :complete, :queued, :running, :failed
91
95
  def status(job_id)
92
- Resque::Status.get(job_id)
96
+ job = Delayed::Job.where(_id: job_id).first
97
+ if job.nil?
98
+ # If we can't find the job, we assume that it is complete
99
+ :complete
100
+ else
101
+ if job.locked_at.nil?
102
+ :queued
103
+ else
104
+ if job.failed?
105
+ :failed
106
+ else
107
+ :running
108
+ end
109
+ end
110
+ end
93
111
  end
94
112
 
95
113
  # Gets the result of running a quality measure
96
114
  # @return [Hash] measure groups (like numerator) as keys, counts as values or nil if
97
115
  # the measure has not yet been calculated
98
116
  def result
99
- cache = get_db.collection("query_cache")
117
+ cache = get_db()["query_cache"]
100
118
  query = {:measure_id => @measure_id, :sub_id => @sub_id,
101
119
  :effective_date => @parameter_values['effective_date'],
102
120
  :test_id => @parameter_values['test_id']}
@@ -106,7 +124,7 @@ module QME
106
124
  query.merge!({filters: nil})
107
125
  end
108
126
 
109
- cache.find_one(query)
127
+ cache.find(query).first()
110
128
  end
111
129
 
112
130
  # make sure all filter id arrays are sorted
@@ -115,11 +133,11 @@ module QME
115
133
  end
116
134
 
117
135
  def patient_result
118
- cache = get_db.collection("patient_cache")
136
+ cache = get_db()["patient_cache"]
119
137
  query = {'value.measure_id' => @measure_id, 'value.sub_id' => @sub_id,
120
138
  'value.effective_date' => @parameter_values['effective_date'],
121
139
  'value.test_id' => @parameter_values['test_id']}
122
- cache.find_one(query)
140
+ cache.find(query).first()
123
141
  end
124
142
 
125
143
  end
@@ -0,0 +1,7 @@
1
+ module QME
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].each { |f| load f }
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ require 'quality-measure-engine'
2
+
3
+ db_name = ENV['DB_NAME'] || 'test'
4
+
5
+ namespace :bundle do
6
+ desc 'Import a quality bundle into the database.'
7
+ task :import, :bundle_path, :delete_existing, :needs => :environment do |task, args|
8
+ raise "The path to the measures zip file must be specified" unless args.bundle_path
9
+
10
+ bundle = File.open(args.bundle_path)
11
+ importer = QME::Bundle::Importer.new(db_name)
12
+ importer.import(bundle, args.delete_existing)
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module QME
2
+ VERSION = "2.0.0"
3
+ end
@@ -1,32 +1,20 @@
1
1
  require "bundler/setup"
2
2
 
3
- require 'resque/job_with_status'
3
+ require 'moped'
4
+ require 'delayed_job_mongoid'
5
+ require 'zip/zip'
4
6
 
5
- require_relative 'qme/database_access'
6
- require_relative 'qme/quality_measure'
7
+ require "qme/version"
8
+ require 'qme/database_access'
9
+ require 'qme/quality_measure'
7
10
 
8
- require_relative 'qme/map/map_reduce_builder'
9
- require_relative 'qme/map/map_reduce_executor'
10
- require_relative 'qme/map/measure_calculation_job'
11
+ require 'qme/map/map_reduce_builder'
12
+ require 'qme/map/map_reduce_executor'
13
+ require 'qme/map/measure_calculation_job'
11
14
 
12
- require_relative 'qme/quality_report'
15
+ require 'qme/quality_report'
13
16
 
14
- require_relative 'qme/randomizer/random_patient_creator'
15
- require_relative 'qme/randomizer/patient_randomizer'
16
- require_relative 'qme/randomizer/patient_randomization_job'
17
+ require 'qme/bundle/bundle'
18
+ require 'qme/bundle/importer'
17
19
 
18
- require 'singleton'
19
- require 'health-data-standards'
20
-
21
- require_relative 'qme/ext/record'
22
-
23
- require_relative 'qme/importer/property_matcher'
24
- require_relative 'qme/importer/generic_importer'
25
- require_relative 'qme/importer/measure_properties_generator'
26
-
27
- require 'json'
28
- require 'mongo'
29
- require 'nokogiri'
30
-
31
- require_relative 'qme/measure/measure_loader'
32
- require_relative 'qme/measure/database_loader'
20
+ require 'qme/railtie' if defined?(Rails)