mirah-ruby 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +93 -0
- data/.gitignore +14 -0
- data/.overcommit.yml +48 -0
- data/.overcommit_gems.rb +9 -0
- data/.rspec +3 -0
- data/.rubocop.yml +54 -0
- data/.yardopts +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +187 -0
- data/Rakefile +24 -0
- data/bin/autocorrect +28 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/setup_overcommit +12 -0
- data/lib/mirah.rb +44 -0
- data/lib/mirah/base_input_object.rb +65 -0
- data/lib/mirah/base_object.rb +98 -0
- data/lib/mirah/client.rb +420 -0
- data/lib/mirah/collection.rb +98 -0
- data/lib/mirah/data/appointment.rb +65 -0
- data/lib/mirah/data/organization.rb +31 -0
- data/lib/mirah/data/page_info.rb +40 -0
- data/lib/mirah/data/patient.rb +46 -0
- data/lib/mirah/data/practitioner.rb +53 -0
- data/lib/mirah/errors.rb +39 -0
- data/lib/mirah/filters.rb +7 -0
- data/lib/mirah/filters/appointment_filters.rb +16 -0
- data/lib/mirah/filters/organization_filters.rb +16 -0
- data/lib/mirah/filters/paging.rb +33 -0
- data/lib/mirah/filters/patient_filters.rb +16 -0
- data/lib/mirah/filters/practitioner_filters.rb +16 -0
- data/lib/mirah/graphql.rb +33 -0
- data/lib/mirah/graphql/fragments.rb +97 -0
- data/lib/mirah/graphql/mutations.rb +72 -0
- data/lib/mirah/graphql/queries.rb +196 -0
- data/lib/mirah/inputs.rb +7 -0
- data/lib/mirah/inputs/appointment_input.rb +40 -0
- data/lib/mirah/inputs/organization_input.rb +20 -0
- data/lib/mirah/inputs/patient_input.rb +40 -0
- data/lib/mirah/inputs/practitioner_input.rb +44 -0
- data/lib/mirah/push_result.rb +40 -0
- data/lib/mirah/serializers.rb +57 -0
- data/lib/mirah/version.rb +5 -0
- data/mirah-ruby.gemspec +41 -0
- data/schema.json +8936 -0
- metadata +221 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
# Collections represent a pageable view into a given collection. They automatically let you iterate through
|
5
|
+
# record sets in a stable manner.
|
6
|
+
#
|
7
|
+
# @example Iterate through a collection of multiple pages
|
8
|
+
# while(collection.next_page?)
|
9
|
+
# collection = collection.next_page
|
10
|
+
# collection.records.each do |record|
|
11
|
+
# # process record
|
12
|
+
# end
|
13
|
+
# end
|
14
|
+
class Collection
|
15
|
+
def initialize(results:, page_info:, client:, query:)
|
16
|
+
@results = results
|
17
|
+
@page_info = page_info
|
18
|
+
@client = client
|
19
|
+
@query = query
|
20
|
+
end
|
21
|
+
|
22
|
+
# The Mirah client, used for sending additional paged requests.
|
23
|
+
attr_reader :client
|
24
|
+
|
25
|
+
# The current results of the query
|
26
|
+
attr_reader :results
|
27
|
+
|
28
|
+
# The information on the current page as returned by the server
|
29
|
+
attr_reader :page_info
|
30
|
+
|
31
|
+
# The current set of paging parameters
|
32
|
+
attr_reader :paging
|
33
|
+
|
34
|
+
# The original query, stored to allow us to retrigger a query with a new page.
|
35
|
+
attr_reader :query
|
36
|
+
|
37
|
+
def length
|
38
|
+
results&.length
|
39
|
+
end
|
40
|
+
|
41
|
+
def next_page?
|
42
|
+
page_info.next_page?
|
43
|
+
end
|
44
|
+
|
45
|
+
def prev_page?
|
46
|
+
page_info.prev_page?
|
47
|
+
end
|
48
|
+
|
49
|
+
def refresh_with_new_paging(paging)
|
50
|
+
# Update everything as before, but set the new paging.
|
51
|
+
client.query_connection(
|
52
|
+
query[:query],
|
53
|
+
query[:input],
|
54
|
+
paging,
|
55
|
+
query[:data_klass],
|
56
|
+
query[:path]
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def next_page
|
61
|
+
raise Errors::InvalidPage, 'This collection does not have a next page' unless next_page?
|
62
|
+
|
63
|
+
return @next_page if @next_page
|
64
|
+
|
65
|
+
@next_page = refresh_with_new_paging(next_page_params)
|
66
|
+
end
|
67
|
+
|
68
|
+
def prev_page
|
69
|
+
raise Errors::InvalidPage, 'This collection does not have a previous page' unless prev_page?
|
70
|
+
|
71
|
+
return @prev_page if @prev_page
|
72
|
+
|
73
|
+
@prev_page = refresh_with_new_paging(prev_page_params)
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def next_page_params
|
79
|
+
last = query[:paging]
|
80
|
+
Filters::Paging.new(
|
81
|
+
after: page_info.end_cursor,
|
82
|
+
before: nil,
|
83
|
+
first: last.first || last.last,
|
84
|
+
last: nil
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
def prev_page_params
|
89
|
+
last = query[:paging]
|
90
|
+
Filters::Paging.new(
|
91
|
+
before: page_info.start_cursor,
|
92
|
+
after: nil,
|
93
|
+
last: last.last || last.first,
|
94
|
+
first: nil
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
module Data
|
5
|
+
# Appointments represent a planned or past meeting between a patient and a practitioner. This is based
|
6
|
+
# on https://www.hl7.org/fhir/appointment.html
|
7
|
+
# As part of the integration flow, Mirah will work out whether this appointments needs an accompanying measurement
|
8
|
+
# encounter and automatically create one as appropriate. Mirah's ETL will generally make a best effort to estimate
|
9
|
+
# where and what context the measurement should be taken. The more information (Episode of Care, Organization,
|
10
|
+
# etc) that you supply, the more likely it is to be correct.
|
11
|
+
# Note that as part of this processing, Mirah may immediately choose to create assessments and trigger
|
12
|
+
# communications with the patient or other participants, for example by text message or email.
|
13
|
+
# In order to keep adherence statistics up to date, Mirah also requires that updates on past
|
14
|
+
# appointments are sent, so that we can calculate whether e.g. the appointment was a no-show.
|
15
|
+
class Appointment < BaseObject
|
16
|
+
# @!attribute [r] id
|
17
|
+
# @return [string] The internal Mirah identifier
|
18
|
+
attribute :id
|
19
|
+
|
20
|
+
# @!attribute [r] external_id
|
21
|
+
# @return [string] The identifier provided by your system
|
22
|
+
attribute :external_id
|
23
|
+
|
24
|
+
# @!attribute [r] start_date
|
25
|
+
# @return [Date] The appointment start date
|
26
|
+
attribute :start_date, serializer: Serializers::DateTimeSerializer
|
27
|
+
|
28
|
+
# @!attribute [r] end_date
|
29
|
+
# @return [Date] The appointment end date
|
30
|
+
attribute :end_date, serializer: Serializers::DateTimeSerializer
|
31
|
+
|
32
|
+
# @!attribute [r] minutes_duration
|
33
|
+
# @return [Integer] The legnth of this appointment in minutes
|
34
|
+
attribute :minutes_duration
|
35
|
+
|
36
|
+
# @!attribute [r] status
|
37
|
+
# @return [string] The appointment status
|
38
|
+
attribute :status
|
39
|
+
|
40
|
+
# @!attribute [r] patient_id
|
41
|
+
# @return [string] The internal mirah id of the patient
|
42
|
+
attribute :patient_id, path: %w[patient], target: 'id'
|
43
|
+
|
44
|
+
# @!attribute [r] external_patient_id
|
45
|
+
# @return [string] Your system identifier for the patient
|
46
|
+
attribute :external_patient_id, path: %w[patient], target: 'externalId'
|
47
|
+
|
48
|
+
# @!attribute [r] practitioner_id
|
49
|
+
# @return [string] The internal mirah id of the practitioner this appointment is with
|
50
|
+
attribute :practitioner_id, path: %w[practitioner], target: 'id'
|
51
|
+
|
52
|
+
# @!attribute [r] external_practitioner_id
|
53
|
+
# @return [string] Your system identifier for the practitioner this appointment is with
|
54
|
+
attribute :external_practitioner_id, path: %w[practitioner], target: 'externalId'
|
55
|
+
|
56
|
+
# @!attribute [r] organization_id
|
57
|
+
# @return [string] The internal mirah id of the organization this appointment is with
|
58
|
+
attribute :organization_id, path: %w[organization], target: 'id'
|
59
|
+
|
60
|
+
# @!attribute [r] external_organization_id
|
61
|
+
# @return [string] Your system identifier for the organization this appointment is with
|
62
|
+
attribute :external_organization_id, path: %w[organization], target: 'externalId'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
module Data
|
5
|
+
# Organizations in the Mirah system currently represent a hierarchy of units/facilities
|
6
|
+
# requiring either different treatment configurations (e.g. inpatient facilities require different
|
7
|
+
# measurement protocols to outpatient) or useful for the purpose of analytics. It is roughly based on
|
8
|
+
# https://www.hl7.org/fhir/organization.html
|
9
|
+
class Organization < BaseObject
|
10
|
+
# @!attribute [r] id
|
11
|
+
# @return [string] The internal Mirah identifier
|
12
|
+
attribute :id
|
13
|
+
|
14
|
+
# @!attribute [r] external_id
|
15
|
+
# @return [string] The identifier provided by your system
|
16
|
+
attribute :external_id
|
17
|
+
|
18
|
+
# @!attribute [r] name
|
19
|
+
# @return [string] The organization's name
|
20
|
+
attribute :name
|
21
|
+
|
22
|
+
# @!attribute [r] part_of_id
|
23
|
+
# @return [string] The internal mirah id of the organization this organization is a child of
|
24
|
+
attribute :part_of_id, path: %w[partOf], target: 'id'
|
25
|
+
|
26
|
+
# @!attribute [r] external_part_of_id
|
27
|
+
# @return [string] Your system identifier for the organization this organization is a child of
|
28
|
+
attribute :external_part_of_id, path: %w[partOf], target: 'externalId'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
module Data
|
5
|
+
# PageInfo gives information on the current state of paging as returned by the server. This includes information
|
6
|
+
# about the start and the end cursors of the result set, and whether or not there are additiona pages.
|
7
|
+
# This can be used in combination with {Mirah::Filters::Paging} to make a stable cursor-based pagination call.
|
8
|
+
class PageInfo < BaseObject
|
9
|
+
# @!attribute [r] end_cursor
|
10
|
+
# @return [string] The cursor of the last record of the current set.
|
11
|
+
# This can be used as a starting point for the next page of the query.
|
12
|
+
attribute :end_cursor
|
13
|
+
|
14
|
+
# @!attribute [r] start_cursor
|
15
|
+
# @return [string] The cursor of the first record of the current set.
|
16
|
+
# This can be used to get the previous page.
|
17
|
+
attribute :start_cursor
|
18
|
+
|
19
|
+
# @!attribute [r] has_next_page
|
20
|
+
# @return [Boolean] Whether the data set has a next page
|
21
|
+
attribute :has_next_page
|
22
|
+
|
23
|
+
# @!attribute [r] has_previous_page
|
24
|
+
# @return [Boolean] Whether the data set has a next page
|
25
|
+
attribute :has_previous_page
|
26
|
+
|
27
|
+
# @see has_next_page
|
28
|
+
# @return [Boolean]
|
29
|
+
def next_page?
|
30
|
+
has_next_page
|
31
|
+
end
|
32
|
+
|
33
|
+
# @see has_previous_page
|
34
|
+
# @return [Boolean]
|
35
|
+
def prev_page?
|
36
|
+
has_previous_page
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
module Data
|
5
|
+
# Patients represent people who are in treatment. They can have appointments, and be the target of assessments.
|
6
|
+
# Patients are only treated in the context of an episode of care.
|
7
|
+
class Patient < BaseObject
|
8
|
+
# @!attribute [r] id
|
9
|
+
# @return [string] The internal Mirah identifier
|
10
|
+
attribute :id
|
11
|
+
|
12
|
+
# @!attribute [r] external_id
|
13
|
+
# @return [string] The identifier provided by your system
|
14
|
+
attribute :external_id
|
15
|
+
|
16
|
+
# @!attribute [r] given_name
|
17
|
+
# @return [string] The patient's first or given name
|
18
|
+
attribute :given_name
|
19
|
+
|
20
|
+
# @!attribute [r] family_name
|
21
|
+
# @return [string] The patient's last or family name
|
22
|
+
attribute :family_name
|
23
|
+
|
24
|
+
# @!attribute [r] birth_date
|
25
|
+
# @return [Date] The patient's date of birth.
|
26
|
+
attribute :birth_date, serializer: Serializers::DateSerializer
|
27
|
+
|
28
|
+
# @!attribute [r] gender
|
29
|
+
# @return [string] The patient's gender
|
30
|
+
attribute :gender
|
31
|
+
|
32
|
+
# @!attribute [r] primary_language
|
33
|
+
# @return [string] The patient's primary language
|
34
|
+
attribute :primary_language
|
35
|
+
|
36
|
+
# @!attribute [r] email
|
37
|
+
# @return [string] The patient's primary email address
|
38
|
+
attribute :email
|
39
|
+
|
40
|
+
# @!attribute [r] phone_number
|
41
|
+
# @return [string] The patient's primary phone number that is suitable for receiving text messages.
|
42
|
+
# Please do not use a phone number which corresponds to a landline as text messages will not be received.
|
43
|
+
attribute :phone_number
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
module Data
|
5
|
+
# FHIR Practitioners represent people directly involved in the provision of care.
|
6
|
+
# See https://www.hl7.org/fhir/practitioner.html for more details.
|
7
|
+
class Practitioner < BaseObject
|
8
|
+
# @!attribute [r] id
|
9
|
+
# @return [string] The internal Mirah identifier
|
10
|
+
attribute :id
|
11
|
+
|
12
|
+
# @!attribute [r] external_id
|
13
|
+
# @return [string] The identifier provided by your system
|
14
|
+
attribute :external_id
|
15
|
+
|
16
|
+
# @!attribute [r] given_name
|
17
|
+
# @return [string] The practitioner's first or given name
|
18
|
+
attribute :given_name
|
19
|
+
|
20
|
+
# @!attribute [r] family_name
|
21
|
+
# @return [string] The practitioner's last or family name
|
22
|
+
attribute :family_name
|
23
|
+
|
24
|
+
# @!attribute [r] title
|
25
|
+
# @return [string] The practitioner's title, e.g. 'Dr'
|
26
|
+
attribute :title
|
27
|
+
|
28
|
+
# @!attribute [r] suffix
|
29
|
+
# @return [string] The practitioner's suffix, e.g. 'MD'
|
30
|
+
attribute :suffix
|
31
|
+
|
32
|
+
# @!attribute [r] email
|
33
|
+
# @return [string] The practitioner's primary email address
|
34
|
+
attribute :email
|
35
|
+
|
36
|
+
# @!attribute [r] default_practitioner_role
|
37
|
+
# @return [string] The clinical role for this practitioner
|
38
|
+
attribute :default_practitioner_role
|
39
|
+
|
40
|
+
# @!attribute [r] sso_username
|
41
|
+
# @return [string] The username (nameid) used for single sign on by this practitioner.
|
42
|
+
attribute :sso_username
|
43
|
+
|
44
|
+
# @!attribute [r] organization_ids
|
45
|
+
# @return [Array<string>] The internal mirah organization ids this practitioner has a role in
|
46
|
+
attribute :organization_ids, path: %w[organization], target: 'id'
|
47
|
+
|
48
|
+
# @!attribute [r] external_organization_ids
|
49
|
+
# @return [Array<string>] The identifiers from your system of the organizations this practitioner has a role in
|
50
|
+
attribute :external_organization_ids, path: %w[organizations], target: 'externalId'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/mirah/errors.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
# A top level error from the Mirah system. It is implemented in multiple places with a
|
5
|
+
class Error < StandardError; end
|
6
|
+
|
7
|
+
module Errors
|
8
|
+
# This exception is thrown when the credentials you have specified for the service are invalid.
|
9
|
+
class InvalidCredentials < Error; end
|
10
|
+
|
11
|
+
# This exception is thrown when an unknown error occurs on the server side.
|
12
|
+
class ServerError < Error; end
|
13
|
+
|
14
|
+
# This exception is thrown when an error happens in this process rather than on the server side.
|
15
|
+
class ClientError < Error; end
|
16
|
+
|
17
|
+
# A parameter you supplied as an input was not valid for the query.
|
18
|
+
# An error class that shows the record was invalid
|
19
|
+
class InvalidParameter < Error
|
20
|
+
def initialize(param)
|
21
|
+
@param = param
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :param
|
25
|
+
end
|
26
|
+
|
27
|
+
# A required parameter was not passed in
|
28
|
+
class MissingParameter < Error
|
29
|
+
def initialize(param)
|
30
|
+
@param = param
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :param
|
34
|
+
end
|
35
|
+
|
36
|
+
# You attempted to fetch a page that was not valid - you probably called `next_page` on the end of the collection.
|
37
|
+
class InvalidPage < Error; end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
module Filters
|
5
|
+
# Input parameters and filters for queries returning {Data::Appointment} objects.
|
6
|
+
class AppointmentFilters < BaseObject
|
7
|
+
# @!attribute [r] external_id
|
8
|
+
# @return [Array<string>] An array of external identifiers to match.
|
9
|
+
attribute :external_id
|
10
|
+
|
11
|
+
# @!attribute [r] status
|
12
|
+
# @return [string] The appointment status
|
13
|
+
attribute :status
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
module Filters
|
5
|
+
# Input parameters and filters for queries returning {Data::Organization} objects.
|
6
|
+
class OrganizationFilters < BaseObject
|
7
|
+
# @!attribute [r] external_id
|
8
|
+
# @return [Array<string>] An array of external identifiers to match.
|
9
|
+
attribute :external_id
|
10
|
+
|
11
|
+
# @!attribute [r] search
|
12
|
+
# @return [string] Smart search by name and other fields where appropriate
|
13
|
+
attribute :search
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mirah
|
4
|
+
module Filters
|
5
|
+
# A set of input parameters designed to let you select how many and which records you want from a pagination cursor.
|
6
|
+
# It is based on Graphql's Relay specification.
|
7
|
+
# This can be used with {Data::PageInfo}, which will be provided by the results of a server query, to provide
|
8
|
+
# stable pagination framework.
|
9
|
+
class Paging < BaseObject
|
10
|
+
# @!attribute [r] first
|
11
|
+
# @return [string] Return the first N rows from either the start, or the current cursor position.
|
12
|
+
# Cannot be used at the same time as #last
|
13
|
+
attribute :first
|
14
|
+
|
15
|
+
# @!attribute [r] last
|
16
|
+
# @return [string] Return the last N rows from either the end, or the current cursor position.
|
17
|
+
# Cannot be used at the same time as #first
|
18
|
+
attribute :last
|
19
|
+
|
20
|
+
# @!attribute [r] before
|
21
|
+
# @return [string] Return rows before the given cursor position
|
22
|
+
attribute :before
|
23
|
+
|
24
|
+
# @!attribute [r] after
|
25
|
+
# @return [string] Return rows after the given cursor position
|
26
|
+
attribute :after
|
27
|
+
|
28
|
+
def self.default
|
29
|
+
new(first: 100)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|