lifen_fhir 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +9 -0
  6. data/Gemfile +3 -0
  7. data/Gemfile.lock +74 -0
  8. data/License.txt +22 -0
  9. data/README.md +131 -0
  10. data/lib/lifen_fhir/app_authenticated_client.rb +38 -0
  11. data/lib/lifen_fhir/attachment.rb +26 -0
  12. data/lib/lifen_fhir/base.rb +7 -0
  13. data/lib/lifen_fhir/binary.rb +29 -0
  14. data/lib/lifen_fhir/category.rb +26 -0
  15. data/lib/lifen_fhir/channel.rb +31 -0
  16. data/lib/lifen_fhir/client.rb +107 -0
  17. data/lib/lifen_fhir/communication_request.rb +67 -0
  18. data/lib/lifen_fhir/configuration.rb +22 -0
  19. data/lib/lifen_fhir/content_string.rb +15 -0
  20. data/lib/lifen_fhir/error.rb +27 -0
  21. data/lib/lifen_fhir/medium.rb +15 -0
  22. data/lib/lifen_fhir/patient.rb +27 -0
  23. data/lib/lifen_fhir/practitioner.rb +97 -0
  24. data/lib/lifen_fhir/user_authenticated_client.rb +39 -0
  25. data/lib/lifen_fhir/version.rb +3 -0
  26. data/lib/lifen_fhir.rb +29 -0
  27. data/lifen_fhir.gemspec +30 -0
  28. data/spec/binary_spec.rb +29 -0
  29. data/spec/cassettes/binary/download/invalid.yml +65 -0
  30. data/spec/cassettes/binary/download/valid.yml +1320 -0
  31. data/spec/cassettes/communication_request/send/invalid_medium.yml +69 -0
  32. data/spec/cassettes/communication_request/send/valid_attributes.yml +75 -0
  33. data/spec/cassettes/communication_request/send/valid_attributes_binary.yml +74 -0
  34. data/spec/cassettes/practitionner/create_channel/address/old_valid_attributes.yml +71 -0
  35. data/spec/cassettes/practitionner/create_channel/address/valid_attributes.yml +71 -0
  36. data/spec/cassettes/practitionner/create_channel/telecom/valid_attributes.yml +70 -0
  37. data/spec/cassettes/practitionner/find_by_rpps/existing_rpps.yml +125 -0
  38. data/spec/cassettes/practitionner/find_by_rpps/missing_line_attribute.yml +122 -0
  39. data/spec/cassettes/practitionner/find_by_rpps/wrong_rpps.yml +68 -0
  40. data/spec/category_spec.rb +21 -0
  41. data/spec/communication_request_spec.rb +64 -0
  42. data/spec/practitionner_spec.rb +76 -0
  43. data/spec/spec_helper.rb +24 -0
  44. data/spec/support/master_plan.pdf +0 -0
  45. metadata +232 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1db22fe4077504ea3f23585828eb697f22763c39
4
+ data.tar.gz: 5fcccdd90ef76bea15800c296280788d02c3f168
5
+ SHA512:
6
+ metadata.gz: 392a47b43059e7eb3f844f7ab5244290697b815734db38403c895f2acba03d52f75bd45e52ae91732535be5d6a84e22da3e2e8b4cb362acbc5120a7c2f2ce2d0
7
+ data.tar.gz: 6ca727e4b24cdbeda29c4b00ade9223700109dfc3e2904f7ff366ac460c0966e5ada293439a0956ef702dce97ad23df74febc81ffadef47d66781750685adf75
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ .DS_Store
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.4.1
data/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ 0.1.1
2
+ -----
3
+
4
+ - Fixed incorrect domain name
5
+
6
+ 0.1.0
7
+ -----
8
+
9
+ - Lifen is on FHIR !
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,74 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lifen_fhir (0.1.1)
5
+ faraday (>= 0.9)
6
+ inflecto
7
+ virtus (>= 1.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.5.1)
13
+ public_suffix (~> 2.0, >= 2.0.2)
14
+ awesome_print (1.7.0)
15
+ axiom-types (0.1.1)
16
+ descendants_tracker (~> 0.0.4)
17
+ ice_nine (~> 0.11.0)
18
+ thread_safe (~> 0.3, >= 0.3.1)
19
+ coercible (1.0.0)
20
+ descendants_tracker (~> 0.0.1)
21
+ crack (0.4.3)
22
+ safe_yaml (~> 1.0.0)
23
+ descendants_tracker (0.0.4)
24
+ thread_safe (~> 0.3, >= 0.3.1)
25
+ diff-lcs (1.3)
26
+ equalizer (0.0.11)
27
+ faraday (0.12.1)
28
+ multipart-post (>= 1.2, < 3)
29
+ hashdiff (0.3.4)
30
+ ice_nine (0.11.2)
31
+ inflecto (0.0.2)
32
+ multipart-post (2.0.0)
33
+ public_suffix (2.0.5)
34
+ rake (10.5.0)
35
+ rspec (3.6.0)
36
+ rspec-core (~> 3.6.0)
37
+ rspec-expectations (~> 3.6.0)
38
+ rspec-mocks (~> 3.6.0)
39
+ rspec-core (3.6.0)
40
+ rspec-support (~> 3.6.0)
41
+ rspec-expectations (3.6.0)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.6.0)
44
+ rspec-mocks (3.6.0)
45
+ diff-lcs (>= 1.2.0, < 2.0)
46
+ rspec-support (~> 3.6.0)
47
+ rspec-support (3.6.0)
48
+ safe_yaml (1.0.4)
49
+ thread_safe (0.3.6)
50
+ vcr (3.0.3)
51
+ virtus (1.0.5)
52
+ axiom-types (~> 0.1)
53
+ coercible (~> 1.0)
54
+ descendants_tracker (~> 0.0, >= 0.0.3)
55
+ equalizer (~> 0.0, >= 0.0.9)
56
+ webmock (1.24.6)
57
+ addressable (>= 2.3.6)
58
+ crack (>= 0.3.2)
59
+ hashdiff
60
+
61
+ PLATFORMS
62
+ ruby
63
+
64
+ DEPENDENCIES
65
+ awesome_print
66
+ bundler (~> 1.12)
67
+ lifen_fhir!
68
+ rake (~> 10.5)
69
+ rspec (~> 3.5)
70
+ vcr (~> 3.0)
71
+ webmock (~> 1.24)
72
+
73
+ BUNDLED WITH
74
+ 1.14.6
data/License.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2017 Honestica
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,131 @@
1
+ # Lifen
2
+
3
+ Lifen is a Ruby client for [Lifen](http://developers.lifen.fr/) FHIR API (over JSON).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'lifen_fhir'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install lifen_fhir
20
+
21
+ ## Usage
22
+
23
+ ### Configuration
24
+
25
+ Lifen can be configured (ideally inside an initializer) like so:
26
+
27
+ ```ruby
28
+ LifenFhir.configure do |config|
29
+ config.site = "https://demo.lifen.fr/"
30
+ config.application_access_token = "application_access_token"
31
+
32
+ # optionnal
33
+ config.proxy_url = "http://my.proxy.fr/"
34
+ end
35
+ ```
36
+
37
+ Optionnal configuration:
38
+
39
+ - `proxy_url`: enables you to route all your requests via a proxy
40
+
41
+ ### Internal
42
+
43
+ #### Managing a Binary
44
+
45
+ ```ruby
46
+ binary = LifenFhir::Binary.new(uuid: "b7c7dae671b93e951ce6a4f530736276")
47
+ binary.download
48
+ ```
49
+
50
+ ### Communication Request
51
+
52
+ ```ruby
53
+ sender = LifenFhir::Practitioner.find_by_rpps("899900018483")
54
+
55
+ recipient = LifenFhir::Practitioner.find_by_rpps("899900018484")
56
+ channel = recipient.channels.first
57
+
58
+ binary = LifenFhir::Binary.new(uuid: "b7c7dae671b93e951ce6a4f530736276")
59
+
60
+ communication_request = LifenFhir::CommunicationRequest.new(sender: sender, recipient: recipient, channel: channel, binary: binary, patient: patient, category: category)
61
+
62
+ communication_request.send
63
+
64
+ ```
65
+
66
+ #### Communication Request with multiple recipients
67
+
68
+ ```ruby
69
+ sender = LifenFhir::Practitioner.find_by_rpps("899900018483")
70
+
71
+ recipient = LifenFhir::Practitioner.find_by_rpps("899900018484")
72
+ medium = LifenFhir::Medium(uuid: recipient.channels.first.uuid)
73
+
74
+ other_recipient = LifenFhir::Practitioner.find_by_rpps("899900018484")
75
+ other_medium = LifenFhir::Medium(uuid: other_recipient.channels.first.uuid)
76
+
77
+ binary = LifenFhir::Binary.new(uuid: "b7c7dae671b93e951ce6a4f530736276")
78
+
79
+ communication_request_request = LifenFhir::CommunicationRequest.new(sender: sender, recipients: [recipient, other_recipient], medium: [medium, other_medium], binary: binary, patient: patient, category: category)
80
+
81
+ communication_request_request.send
82
+
83
+ ```
84
+
85
+ #### Custom Channels management
86
+
87
+ ```ruby
88
+ recipient = LifenFhir::Practitioner.new(uuid: "valid-user-uuid")
89
+
90
+ # To create a new mailing address channel
91
+ channel = recipient.create_address(type: "address", lines: ["39 rue Aboukir"], city: "Paris", postal_code: "75002", country: "France")
92
+
93
+ # To create a new telecom channel fax
94
+ channel = recipient.create_telecom(type: "telecom", system: "fax", value: "+33102030405")
95
+ ```
96
+
97
+ ## Deploying to Rubygems
98
+
99
+ Once the new version is validated, the deployment follows those steps :
100
+
101
+ 1. update `lib/lifen/version.rb`
102
+ 2. run `bundle install` to update `Gemfile.lock`
103
+ 3. update `CHANGELOG.md` with the additional features of the new version
104
+ 4. commit changes to Github
105
+ 5. build the gem using `gem build lifen_fhir.gemspec`
106
+ 6. publish the gem using `gem publish lifen_fhir-X.X.X.gem`
107
+ 7. run `bundle update lifen` in related projects :)
108
+
109
+ ## License
110
+
111
+ The MIT License (MIT)
112
+
113
+ Copyright (c) 2016-2017 Honestica
114
+
115
+ Permission is hereby granted, free of charge, to any person obtaining a copy
116
+ of this software and associated documentation files (the "Software"), to deal
117
+ in the Software without restriction, including without limitation the rights
118
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
119
+ copies of the Software, and to permit persons to whom the Software is
120
+ furnished to do so, subject to the following conditions:
121
+
122
+ The above copyright notice and this permission notice shall be included in
123
+ all copies or substantial portions of the Software.
124
+
125
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
128
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
129
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
130
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
131
+ THE SOFTWARE.
@@ -0,0 +1,38 @@
1
+ module LifenFhir
2
+
3
+ class AppAuthenticatedClient < Client
4
+
5
+ private
6
+
7
+ def handle_errors(response, params)
8
+ super(response, params)
9
+
10
+ case response.status
11
+ when 400
12
+ raise Error, "Error 400, Unknown error, #{response_error(response, params)}"
13
+ when 401
14
+ raise InvalidSecretTokenError, "Error 401, Invalid app bearer, #{response_error(response, params)}"
15
+ when 403
16
+ raise UserAlreadyExistingError, "Error 403, User already existing, #{response_error(response, params)}"
17
+ when 404
18
+ raise Error, "Error 404, Page not found, #{response_error(response, params)}"
19
+ when 422
20
+ json = JSON.parse response.body
21
+
22
+ diagnostic = json["issue"][0]["diagnostics"]
23
+
24
+ raise Error, "Error 422, Unprocessable Entity, Diagnostic: '#{diagnostic}', #{response_error(response, params)}"
25
+ end
26
+
27
+ end
28
+
29
+ def response_error(response, params)
30
+ "App Client, #{super(response, params)}"
31
+ end
32
+
33
+ def bearer
34
+ LifenFhir.configuration.application_access_token
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ module LifenFhir
2
+
3
+ class Attachment < Base
4
+
5
+ attribute :title, String
6
+ attribute :path, String
7
+ attribute :content_type, String
8
+
9
+ def fhir_payload
10
+ {
11
+ contentAttachment: {
12
+ data: base_64_encoded_content,
13
+ title: title,
14
+ contentType: "{#{content_type}}"
15
+ }
16
+ }
17
+ end
18
+
19
+ private
20
+
21
+ def base_64_encoded_content
22
+ Base64.encode64(File.open(path, "rb").read)
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ module LifenFhir
2
+ class Base
3
+
4
+ include Virtus.model
5
+
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ module LifenFhir
2
+ class Binary < Base
3
+
4
+ attribute :uuid, String
5
+
6
+ def fhir_payload
7
+ {
8
+ contentReference: {
9
+ reference: reference
10
+ }
11
+ }
12
+ end
13
+
14
+ def download
15
+ application_client.get("fhir/#{reference}", { accept: "application/pdf" })
16
+ end
17
+
18
+ private
19
+
20
+ def application_client
21
+ @application_client ||= AppAuthenticatedClient.new
22
+ end
23
+
24
+ def reference
25
+ "Binary/#{uuid}"
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module LifenFhir
2
+ class Category < Base
3
+
4
+ CODES = ["MEDICAL_REPORT", "MESSAGE", "MEDICATION_ORDER", "REFERRAL_REQUEST", "OTHER"]
5
+
6
+ attribute :code, String, default: "MEDICAL_REPORT"
7
+
8
+ def fhir_payload
9
+ raise LifenFhir::Error, "Invalid category: code must be in the authorized values" if !valid?
10
+
11
+ {
12
+ coding: [
13
+ {
14
+ system: "http://honestica.com/fhir/communication/category",
15
+ code: code
16
+ }
17
+ ]
18
+ }
19
+ end
20
+
21
+ def valid?
22
+ CODES.include? code
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ module LifenFhir
2
+ class Channel < Base
3
+
4
+ attribute :uuid, String
5
+ attribute :type, String
6
+ attribute :value, String
7
+
8
+ def fhir_payload(user)
9
+ raise LifenFhir::Error, "Invalid channel: an UUID is required" if !valid?
10
+
11
+ {
12
+ id: user.uuid,
13
+ resourceType: "Practitioner",
14
+ type => [
15
+ {
16
+ id: uuid
17
+ }
18
+ ]
19
+ }
20
+ end
21
+
22
+ def valid?
23
+ uuid and uuid.length != 0
24
+ end
25
+
26
+ def self.from_json(json, type = nil)
27
+ new(uuid: json["id"], type: type, value: json["value"] || "#{Array(json["line"]).join(", ")}, #{json["postalCode"]} #{json["city"]}")
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,107 @@
1
+ module LifenFhir
2
+ class Client
3
+
4
+ def request(mode, url, params = {})
5
+ before_request
6
+
7
+ response = faraday_client.send(mode) do |req|
8
+ req.url url
9
+
10
+ req.headers['Authorization'] = "Bearer #{bearer}"
11
+ req.headers['Accept'] = use_and_remove_accept(params)
12
+
13
+ if mode == :post
14
+ req.headers['Content-Type'] = "application/json"
15
+ end
16
+
17
+ req.body = JSON.generate(params)
18
+ end
19
+
20
+ handle_errors(response, params)
21
+
22
+ handle_response(response)
23
+ end
24
+
25
+ def post(url, params = {})
26
+ request(:post, url, params)
27
+ end
28
+
29
+ def put(url, params = {})
30
+ request(:put, url, params)
31
+ end
32
+
33
+ def get(url, params = {})
34
+ request(:get, url, params)
35
+ end
36
+
37
+ private
38
+
39
+ def handle_errors(response, params)
40
+ if response.status == 500
41
+
42
+ json = JSON.parse response.body
43
+
44
+ trace_id = json.fetch("X-B3-TraceId", "unknown")
45
+
46
+ raise Error, "Error 500, Internal server error (trace ID: #{trace_id}), #{response_error(response, params)}"
47
+ end
48
+ end
49
+
50
+ def handle_response(response)
51
+ if response.headers['Content-Type'].match "json"
52
+ JSON.parse response.body
53
+ else
54
+ response.body
55
+ end
56
+ end
57
+
58
+ def faraday_client
59
+ @faraday_client ||= Faraday.new(faraday_options) do |faraday|
60
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
61
+ end
62
+ end
63
+
64
+ def faraday_options
65
+ options = {url: site}
66
+
67
+ options[:proxy] = proxy_url if !proxy_url.nil?
68
+
69
+ options
70
+ end
71
+
72
+ def site
73
+ LifenFhir.configuration.site
74
+ end
75
+
76
+ def proxy_url
77
+ LifenFhir.configuration.proxy_url
78
+ end
79
+
80
+ def before_request
81
+ end
82
+
83
+ def response_error(response, params)
84
+ params[:payload] = "filtered" if params.is_a?(Hash) and params.has_key? :payload
85
+
86
+ "#{response.env.method.upcase} '#{response.env.url}' with params '#{params.inspect}' and bearer '#{trucanted_bearer}'"
87
+ end
88
+
89
+ def trucanted_bearer
90
+ if m = /^(.{24})(.*)$/.match(bearer)
91
+ "#{m[1]}#{"*" * m[2].length}"
92
+ else
93
+ bearer
94
+ end
95
+ end
96
+
97
+ def bearer
98
+ raise "A bearer method must be defined"
99
+ end
100
+
101
+ def use_and_remove_accept(params)
102
+ return params.delete :accept if params.is_a?(Hash) and params.has_key? :accept
103
+
104
+ "application/json"
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,67 @@
1
+ module LifenFhir
2
+ class CommunicationRequest < Base
3
+
4
+ attribute :uuid, String
5
+ attribute :number_communications, Integer
6
+
7
+ attribute :sender, LifenFhir::Practitioner
8
+ attribute :recipients, [LifenFhir::Practitioner]
9
+
10
+ attribute :category, LifenFhir::Category, default: LifenFhir::Category.new
11
+ attribute :medium, [LifenFhir::Medium]
12
+ attribute :patient, LifenFhir::Patient
13
+ attribute :attachment, LifenFhir::Attachment
14
+ attribute :binary, LifenFhir::Binary
15
+ attribute :content_string, LifenFhir::ContentString
16
+
17
+ def send
18
+ json = application_client.post("fhir/CommunicationRequest", fhir_payload)
19
+
20
+ self.uuid = json["id"]
21
+ self.number_communications = Array(json["issue"]).length
22
+
23
+ self
24
+ end
25
+
26
+ private
27
+
28
+ def fhir_payload
29
+
30
+ payload = {
31
+ resourceType: "CommunicationRequest",
32
+ sender: [ sender.fhir_payload ],
33
+ recipient: recipients.map(&:fhir_payload),
34
+ contained: [],
35
+ medium: medium.map(&:fhir_payload) ,
36
+ category: [ category.fhir_payload],
37
+ payload: [ document_content ]
38
+ }
39
+
40
+ if patient
41
+ payload[:contained] << patient.fhir_payload
42
+ payload[:subject] = [
43
+ {reference: "patient"}
44
+ ]
45
+ end
46
+
47
+ if content_string
48
+ payload[:payload] << content_string.fhir_payload
49
+ end
50
+
51
+ payload
52
+ end
53
+
54
+ def document_content
55
+ if !attachment.nil?
56
+ attachment.fhir_payload
57
+ else
58
+ binary.fhir_payload
59
+ end
60
+ end
61
+
62
+ def application_client
63
+ @application_client ||= AppAuthenticatedClient.new
64
+ end
65
+
66
+ end
67
+ end
@@ -0,0 +1,22 @@
1
+ module LifenFhir
2
+ class Configuration
3
+
4
+ attr_accessor :site, :application_access_token, :proxy_url
5
+
6
+ def site=(url)
7
+ if !/(.*)\/$/.match(url)
8
+ raise LifenFhir::Error, "Invalid 'site' provided in configuration: '#{url}', a trailing slash is missing"
9
+ end
10
+
11
+ @site = url
12
+ end
13
+ end
14
+
15
+ def self.configuration
16
+ @configuration ||= Configuration.new
17
+ end
18
+
19
+ def self.configure
20
+ yield(configuration) if block_given?
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module LifenFhir
2
+
3
+ class ContentString < Base
4
+
5
+ attribute :text, String
6
+
7
+ def fhir_payload
8
+ {
9
+ contentString: text
10
+
11
+ }
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ module LifenFhir
2
+
3
+ class Error < StandardError
4
+ end
5
+
6
+ class UnauthorizedError < Error
7
+ end
8
+
9
+ class InvalidCredentialsError < Error
10
+ end
11
+
12
+ class InvalidParamsError < Error
13
+ end
14
+
15
+ class InvalidSecretTokenError < Error
16
+ end
17
+
18
+ class InvalidTokenError < Error
19
+ end
20
+
21
+ class UserAlreadyExistingError < Error
22
+ end
23
+
24
+ class CantRefreshTokenError < Error
25
+ end
26
+
27
+ end
@@ -0,0 +1,15 @@
1
+ module LifenFhir
2
+ class Medium < Base
3
+
4
+ attribute :uuid, String
5
+
6
+ def fhir_payload
7
+ {
8
+ coding:[{
9
+ id: uuid
10
+ }]
11
+ }
12
+ end
13
+
14
+ end
15
+ end