phi_attrs 0.1.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8f28f8b165404acd488de741070670268bb5e1a3
4
- data.tar.gz: 8610013fc23d93100ba5829327a85c32516a2f38
2
+ SHA256:
3
+ metadata.gz: f6271ebbfae4a5ddad7aa1ad27b812cc4056a5a4958b1067ddf2aa717975b738
4
+ data.tar.gz: '098ec65389f50bbe24876657a1ff9eb78bbbe17fb5192804ebbc2f75eedd97f4'
5
5
  SHA512:
6
- metadata.gz: 4b181df2aacce039f31c31a97051434f99a5dc96f975f2668eba97a7d7cff0a357f6aed8eca75a03a75945b1b4489083e489318e4ba680a446968b93d3142285
7
- data.tar.gz: 1bfa9fac24405baa8a8e3e91eb8f5db4f7602413254143d9b8526d61f45f396250351bb333ca99da35a49a293d303521466974c79ffa0a83ecf9ce8e391463a7
6
+ metadata.gz: a5832351881d96019071f9b77ac4e08b991104dca6f47c8a1917f5c3546002d7510c5d0fe7ceaa4fe37df7006ec71105acbbcc99a5c9928e57e78b43a7cd2d5d
7
+ data.tar.gz: 3a153bd1a992dbbb94de889f8a82c22f969dd1bb9b9f36254485d0265f70cba89d89f1c8b424e30056aa1c23c5b8e8be3142d7b5ccfed05c970ec67aa3614d69
@@ -0,0 +1,25 @@
1
+ name: Spec CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ name: Ruby ${{ matrix.ruby }}
9
+ strategy:
10
+ matrix:
11
+ ruby: [2.5, 2.6, 2.7]
12
+
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby ${{ matrix.ruby }}
16
+ uses: actions/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+ - name: Install dependencies
20
+ run: |
21
+ gem install bundler
22
+ bundle install
23
+ bundle exec appraisal install
24
+ - name: Run rspec
25
+ run: bundler exec appraisal rspec
data/.gitignore CHANGED
@@ -12,6 +12,11 @@
12
12
  .byebug_history
13
13
 
14
14
  /test/sample/tmp/
15
+ *.sqlite
15
16
  *.sqlite3
16
17
  *.log
17
18
  .rspec_status
19
+ gemfiles/*.gemfile.lock
20
+
21
+ # Macs. Ugh.
22
+ .DS_Store
@@ -0,0 +1,91 @@
1
+ Rails:
2
+ Enabled: true
3
+
4
+ AllCops:
5
+ Exclude:
6
+ - 'bin/**/*'
7
+ - 'gemfiles/**/*'
8
+ - 'spec/internal/db/schema.rb'
9
+ TargetRubyVersion: 2.5
10
+
11
+ Documentation:
12
+ Enabled: false
13
+
14
+ Layout/IndentationWidth:
15
+ Enabled: true
16
+
17
+ Lint/UnreachableCode:
18
+ Exclude:
19
+ - 'lib/phi_attrs/phi_record.rb' # TODO: RUBOCOP Cleanup exclusion
20
+
21
+ Lint/UnusedMethodArgument:
22
+ Exclude:
23
+ - 'lib/phi_attrs.rb' # TODO: RUBOCOP Cleanup exclusion
24
+
25
+ Metrics/AbcSize:
26
+ Max: 30
27
+ Exclude:
28
+ - 'spec/internal/db/**/*'
29
+ - 'lib/phi_attrs/phi_record.rb' # TODO: RUBOCOP Cleanup exclusion
30
+
31
+ Metrics/BlockLength:
32
+ Enabled: false
33
+
34
+ Metrics/ClassLength:
35
+ Max: 1500
36
+
37
+ Metrics/CyclomaticComplexity:
38
+ Exclude:
39
+ - 'lib/phi_attrs/phi_record.rb' # TODO: RUBOCOP Cleanup exclusion
40
+
41
+ Metrics/LineLength:
42
+ Exclude:
43
+ - 'spec/**/*'
44
+ - 'lib/phi_attrs/phi_record.rb' # TODO: RUBOCOP Cleanup exclusion
45
+ Max: 140
46
+
47
+ Metrics/MethodLength:
48
+ Exclude:
49
+ - 'spec/**/*'
50
+ - 'lib/phi_attrs/phi_record.rb' # TODO: RUBOCOP Cleanup exclusion
51
+ Max: 20
52
+
53
+ Metrics/ModuleLength:
54
+ Exclude:
55
+ - 'lib/phi_attrs/phi_record.rb' # TODO: RUBOCOP Cleanup exclusion
56
+
57
+ Metrics/PerceivedComplexity:
58
+ Exclude:
59
+ - 'lib/phi_attrs/phi_record.rb' # TODO: RUBOCOP Cleanup exclusion
60
+
61
+ Naming/PredicateName:
62
+ Enabled: false
63
+
64
+ Rails/DynamicFindBy:
65
+ Exclude:
66
+ - 'spec/spec_helper.rb' # TODO: RUBOCOP Cleanup exclusion
67
+
68
+ Style/BracesAroundHashParameters:
69
+ Enabled: false
70
+
71
+ Style/ClassVars:
72
+ Enabled: false
73
+
74
+ Style/CommentedKeyword:
75
+ Exclude:
76
+ - 'spec/**/*'
77
+
78
+ Style/ConditionalAssignment:
79
+ Enabled: false
80
+
81
+ Style/EmptyMethod:
82
+ EnforcedStyle: expanded
83
+
84
+ Style/SymbolArray:
85
+ EnforcedStyle: brackets
86
+
87
+ Style/RedundantReturn:
88
+ Enabled: false
89
+
90
+ Style/WordArray:
91
+ MinSize: 4
data/Appraisals CHANGED
@@ -1,4 +1,16 @@
1
- appraise 'rails-5.0' do
2
- gem 'rails', '5.0.0'
3
- gem 'tzinfo-data'
1
+ # frozen_string_literal: true
2
+
3
+ appraise 'rails-5.1' do
4
+ gem 'rails', '5.1.3'
5
+ gem 'sqlite3', '~> 1.3', '< 1.4'
4
6
  end
7
+
8
+ appraise 'rails-5.2' do
9
+ gem 'rails', '5.2.4'
10
+ gem 'sqlite3', '~> 1.4'
11
+ end
12
+
13
+ appraise 'rails-6.0' do
14
+ gem 'rails', '6.0.3'
15
+ gem 'sqlite3', '~> 1.4'
16
+ end
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+ ### Added
9
+ - Added documentation for CHANGELOG to README
10
+
11
+ ## [v0.1.4] - 2018-07-05
12
+ ## [v0.1.3] - 2018-07-05
13
+ ## [v0.1.2] - 2018-07-05
14
+ ## [v0.1.1] - 2018-07-05
15
+
16
+ ## [v0.1.0] - 2018-07-04
17
+ Initial release
@@ -0,0 +1,15 @@
1
+ DISCLAIMER
2
+ ==========
3
+
4
+ While access logging is part of maintaining a HIPAA compliant application, there are many requirements for building a HIPAA secure application which are not addressed by `phi_attrs`, and as such use of `phi_attrs` on its own does not ensure HIPAA Compliance. As such, this software is provided on an "as-is" basis, and Apsis Labs, LLP makes no warranties or assurances with regards to the HIPAA compliance of any application which makes use of `phi_attrs`.
5
+
6
+ For further reading on how to ensure your application meets the HIPAA security standards, review the HHS Security Series Technical Safeguards and the Summary of the HIPAA Security Rule, in addition to consulting your compliance and legal counsel.
7
+
8
+ Apsis Labs, LLP is not a law firm and does not provide legal advice. The information in this software does not constitute legal advice, nor does usage of this software create an attorney-client relationship.
9
+
10
+ Apsis Labs, LLP is not a HIPAA covered entity, and usage of this software does not create a business associate relationship, nor does it enact a business associate agreement.
11
+
12
+ ---
13
+
14
+ 1. HHS Security Series Technical Safeguards: https://www.hhs.gov/sites/default/files/ocr/privacy/hipaa/administrative/securityrule/techsafeguards.pdf
15
+ 2. Summary of the HIPAA Security Rule: https://www.hhs.gov/hipaa/for-professionals/security/laws-regulations/index.html
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:2.5.1-alpine
1
+ FROM ruby:2.5.3-alpine3.8
2
2
  MAINTAINER wyatt@apsis.io
3
3
 
4
4
  RUN apk add --no-cache --update \
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2018 Wyatt Kirby
3
+ Copyright (c) 2018 Apsis Labs, LLP
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,4 +1,25 @@
1
- # PhiAttrs
1
+ # phi_attrs [![Gem Version](https://badge.fury.io/rb/phi_attrs.svg)](https://badge.fury.io/rb/phi_attrs) [![Spec CI](https://github.com/apsislabs/phi_attrs/workflows/Spec%20CI/badge.svg)](https://github.com/apsislabs/phi_attrs/actions)
2
+
3
+
4
+ HIPAA compliant PHI access logging for Ruby on Rails.
5
+
6
+ According to [HIPAA Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/index.html) `§ 164.312(b)`, HIPAA covered entities are required to:
7
+
8
+ > Implement hardware, software, and/or procedural mechanisms that record and examine activity in information systems that contain or use electronic protected health information.
9
+
10
+ The `phi_attrs` gem is intended to assist with implementing logging to comply with the access log requirements of `§ 164.308(a)(1)(ii)(D)`:
11
+
12
+ > Information system activity review (Required). Implement procedures to regularly review records of information system activity, such as audit logs, access reports, and security incident tracking reports.
13
+
14
+ To do so, `phi_attrs` extends `ActiveRecord` models by adding automated logging and explicit access control methods. The access control mechanism creates a separate `phi_access_log`.
15
+
16
+ **Please Note:** while `phi_attrs` helps facilitate access logging, it still requires due diligence by developers, both in ensuring that models and attributes which store PHI are flagged with `phi_model` and that calls to `allow_phi!` properly attribute both a _unique_ identifier and an explicit reason for PHI access.
17
+
18
+ **Please Note:** there are other aspects of building a HIPAA secure application which are not addressed by `phi_attrs`, and as such _use of `phi_attrs` on its own does not ensure HIPAA Compliance_. For further reading on how to ensure your application meets the HIPAA security standards, review the [HHS Security Series Technical Safeguards](https://www.hhs.gov/sites/default/files/ocr/privacy/hipaa/administrative/securityrule/techsafeguards.pdf) and [Summary of the HIPAA Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/laws-regulations/index.html), in addition to consulting your compliance and legal counsel.
19
+
20
+ ## Stability
21
+
22
+ All versions of this project below `1.0.0` should be considered unstable beta software. Even minor-version updates may introduce breaking changes to the public API at this stage. We strongly suggest that you lock the installed version in your Gemfile to avoid unintended breaking updates.
2
23
 
3
24
  ## Installation
4
25
 
@@ -16,6 +37,20 @@ Or install it yourself as:
16
37
 
17
38
  $ gem install phi_attrs
18
39
 
40
+ ## Initialize
41
+
42
+ Create an initializer to configure the PHI log file location.
43
+
44
+ Example:
45
+
46
+ `config/initializers/phi_attrs.rb`
47
+
48
+ ```ruby
49
+ PhiAttrs.configure do |conf|
50
+ conf.log_path = Rails.root.join("log", "phi_access_#{Rails.env}.log")
51
+ end
52
+ ```
53
+
19
54
  ## Usage
20
55
 
21
56
  ```ruby
@@ -31,36 +66,399 @@ class PatientInfo < ActiveRecord::Base
31
66
  end
32
67
  ```
33
68
 
34
- Access is granted on a model level:
69
+ Access is granted on a instance level:
70
+
35
71
  ```ruby
36
- info = new PatientInfo
72
+ info = PatientInfo.new
37
73
  info.allow_phi!("allowed_user@example.com", "Customer Service")
38
74
  ```
39
75
 
76
+ *When using on an instance if you find it in a second place you will need to call allow_phi! again.*
77
+
40
78
  or a class:
79
+
41
80
  ```ruby
42
81
  PatientInfo.allow_phi!("allowed_user@example.com", "Customer Service")
43
82
  ```
44
83
 
84
+ As of version `0.1.5`, a block syntax is available. As above, this is available on both class and instance levels.
85
+
86
+ Note the lack of a `!` at the end. These methods should not be used alongside the mutating (bang) methods! We recommend using the block syntax for tighter control.
87
+
88
+ ```ruby
89
+ patient = PatientInfo.find(params[:id])
90
+ patient.allow_phi('allowed_user@example.com', 'Display Customer Data') do
91
+ @data = patient.to_json
92
+ end # Access no longer allowed beyond this point
93
+ ```
94
+
95
+ or a block on a class:
96
+
97
+ ```ruby
98
+ PatientInfo.allow_phi('allowed_user@example.com', 'Display Customer Data') do
99
+ @data = PatientInfo.find(params[:id]).to_json
100
+ end # Access no longer allowed beyond this point
101
+ ```
102
+
103
+ ### Controlling What Is PHI
104
+
105
+ When you include `phi_model` on your active record all fields except the id will be considered PHI.
106
+
107
+ To remove fields from PHI tracking use `exclude_from_phi`:
108
+
109
+ ```ruby
110
+ # created_at and updated_at will be accessible as normal
111
+ class PatientInfo < ActiveRecord::Base
112
+ phi_model
113
+
114
+ exclude_from_phi :created_at, :updated_at
115
+ end
116
+ ```
117
+
118
+ To add a method as PHI use `include_in_phi`. Include takes precedence over exclude so a method that appears in both will be considered PHI.
119
+
120
+ ```ruby
121
+ # birthday and node will throw PHIExceptions if accessed without permission
122
+ class PatientInfo < ActiveRecord::Base
123
+ phi_model
124
+
125
+ include_in_phi :birthday, :note
126
+
127
+ def birthday
128
+ Time.current
129
+ end
130
+
131
+ attr_accessor :note
132
+ end
133
+ ```
134
+
135
+ #### Example Usage
136
+
137
+ Example of `exclude_from_phi` and `include_in_phi` with inheritance.
138
+
139
+ ```ruby
140
+ class PatientInfo < ActiveRecord::Base
141
+ phi_model
142
+ end
143
+
144
+ pi = PatientInfo.new(first_name: "Ash", last_name: "Ketchum")
145
+ pi.created_at
146
+ # PHIAccessException!
147
+ pi.last_name
148
+ # PHIAccessException!
149
+ pi.allow_phi "Ash", "Testing PHI Attrs" { pi.last_name }
150
+ # "Ketchum"
151
+ ```
152
+
153
+ ```ruby
154
+ class PatientInfoTwo < PatientInfo
155
+ exclude_from_phi :created_at
156
+ end
157
+
158
+ pi = PatientInfoTwo.new(first_name: "Ash", last_name: "Ketchum")
159
+ pi.created_at
160
+ # current time
161
+ pi.last_name
162
+ # PHIAccessException!
163
+ pi.allow_phi "Ash", "Testing PHI Attrs" { pi.last_name }
164
+ # "Ketchum"
165
+ ```
166
+
167
+ ```ruby
168
+ class PatientInfoThree < PatientInfoTwo
169
+ include_in_phi :created_at # Changed our mind
170
+ end
171
+
172
+ pi = PatientInfoThree.new(first_name: "Ash", last_name: "Ketchum")
173
+ pi.created_at
174
+ # PHIAccessException!
175
+ pi.last_name
176
+ # PHIAccessException!
177
+ pi.allow_phi "Ash", "Testing PHI Attrs" { pi.last_name }
178
+ # "Ketchum"
179
+ ```
180
+
181
+ ### Extending PHI Access
182
+
183
+ Sometimes you'll have a single mental model that is composed of several `ActiveRecord` models joined by association. In this case, instead of calling `allow_phi!` on all joined models, we expose a shorthand of extending PHI access to related models.
184
+
185
+ ```ruby
186
+ class PatientInfo < ActiveRecord::Base
187
+ phi_model
188
+ end
189
+
190
+ class Patient < ActiveRecord::Base
191
+ has_one :patient_info
192
+
193
+ phi_model
194
+
195
+ extend_phi_access :patient_info
196
+ end
197
+
198
+ patient = Patient.new
199
+ patient.allow_phi!('user@example.com', 'reason')
200
+ patient.patient_info.first_name
201
+ ```
202
+
203
+ **NOTE:** This is not intended to be used on all relationships! Only those where you intend to grant implicit access based on access to another model. In this use case, we assume that allowed access to `Patient` implies allowed access to `PatientInfo`, and therefore does not require an additional `allow_phi!` check. There are no guaranteed safeguards against circular `extend_phi_access` calls!
204
+
205
+ ### Check If PHI Access Is Allowed
206
+
207
+ To check if PHI is allowed for a particular instance of a class call `phi_allowed?`.
208
+
209
+ ```ruby
210
+ patient = Patient.new
211
+ patient.phi_allowed? # => false
212
+
213
+ patient.allow_phi('user@example.com', 'reason') do
214
+ patient.phi_allowed? # => true
215
+ end
216
+
217
+ patient.phi_allowed? # => false
218
+
219
+ patient.allow_phi!('user@example.com', 'reason')
220
+ patient.phi_allowed? # => true
221
+ ```
222
+
223
+ This also works if access was granted at the class level:
224
+
225
+ ```ruby
226
+ patient = Patient.new
227
+ patient.phi_allowed? # => false
228
+ Patient.allow_phi!('user@example.com', 'reason')
229
+ patient.phi_allowed? # => true
230
+ ```
231
+
232
+ There is also a `phi_allowed?` check available to see at the class level.
233
+
234
+ ```ruby
235
+ Patient.phi_allowed? # => false
236
+ Patient.allow_phi!('user@example.com', 'reason')
237
+ Patient.phi_allowed? # => true
238
+ ```
239
+
240
+ **Note that any instance level access grants will not change class level access:**
241
+
242
+ ```ruby
243
+ patient = Patient.new
244
+
245
+ patient.phi_allowed? # => false
246
+ Patient.phi_allowed? # => false
247
+
248
+ patient.allow_phi!('user@example.com', 'reason')
249
+
250
+ patient.phi_allowed? # => true
251
+ Patient.phi_allowed? # => false
252
+ ```
253
+
254
+
255
+ ### Revoking PHI Access
256
+
257
+ You can remove access to PHI with `disallow_phi!`. Each `disallow_phi!` call removes all access granted by `allow_phi!` at that level (class or instance).
258
+
259
+ At a class level:
260
+
261
+ ```ruby
262
+ Patient.disallow_phi!
263
+ ```
264
+
265
+ Or at a instance level:
266
+
267
+ ```ruby
268
+ patient.disallow_phi!
269
+ ```
270
+
271
+ * *If access is granted at both class and instance level you will need to call `disallow_phi!` twice, once for the instance and once for the class.*
272
+
273
+ There is also a block syntax of `disallow_phi` for temporary suppression phi access to the class or instance level
274
+
275
+ ```ruby
276
+ patient = PatientInfo.find(params[:id])
277
+ patient.allow_phi!('allowed_user@example.com', 'Display Patient Data')
278
+ patient.diallow_phi do
279
+ @data = patient.to_json # PHIAccessException
280
+ end # Access is allowed again beyond this point
281
+ ```
282
+
283
+ or a block level on a class:
284
+
285
+ ```ruby
286
+ PatientInfo.allow_phi!('allowed_user@example.com', 'Display Patient Data')
287
+ PatientInfo.diallow_phi do
288
+ @data = PatientInfo.find(params[:id]).to_json # PHIAccessException
289
+ end # Access is allowed again beyond this point
290
+ ```
291
+
292
+ * *Reminder instance level `phi_allow` will take precedent over a class level `disallow_phi`*
293
+
294
+ ### Manual PHI Access Logging
295
+
296
+ If you aren't using `phi_record` you can still use `phi_attrs` to manually log phi access in your application. Where ever you are granting PHI access call:
297
+
298
+ ```ruby
299
+ user = 'user@example.com'
300
+ message = 'accessed list of all patients'
301
+ PhiAttrs.log_phi_access(user, message)
302
+ ```
303
+
304
+ ### Reason Translations
305
+
306
+ It can get cumbersome to pass around PHI Access reasons. PHI Attrs allows you to
307
+ use your translations file to keep your code dry. If your translation file
308
+ contains a reason for the combination of controller, action, and model you can
309
+ skip passing `reason`:
310
+
311
+ ```ruby
312
+ module Admin
313
+ class PatientDashboardController < ApplicationController
314
+ def expelliarmus
315
+ patient_info.allow_phi(current_user) do
316
+ # reason tries to use `phi.admin.patient_dashbaord.expelliarmus.patient_info`
317
+ end
318
+ end
319
+
320
+ def leviosa
321
+ patient_info.allow_phi(current_user) do
322
+ # reason tries to use `phi.admin.patient_dashbaord.expelliarmus.patient_info`
323
+ end
324
+ end
325
+ end
326
+ end
327
+ ```
328
+
329
+ The following `en.yml` file would work:
330
+
331
+ ```yml
332
+ en:
333
+ phi:
334
+ admin:
335
+ patient_dashboard:
336
+ expelliarmus:
337
+ patient_info: "Patient Disarmed"
338
+ leviosa:
339
+ patient_info: "Patient Levitated"
340
+ ```
341
+
342
+ If you have a typo in your en.yml file or you choose not to provide a translation
343
+ for your phi reasons your code will fail with an ArgumentError. To assist you in
344
+ debugging PHI Attrs will print a `:warn` message with the expected location for
345
+ the missing translation.
346
+
347
+ If you would like to change from `phi` to a custom location you can set the path in your initializer.
348
+
349
+ ```ruby
350
+ PhiAttrs.configure do |conf|
351
+ conf.translation_prefix = 'custom_prefix'
352
+ end
353
+ ```
354
+
355
+ ### Default User
356
+
357
+ Passing around the current user can clutter your code. PHI Attrs allows you to
358
+ configure a controller method that will be called to get the currently logged in
359
+ user:
360
+
361
+ #### `config/initializers/phi_attrs.rb`
362
+
363
+ ```ruby
364
+ PhiAttrs.configure do |conf|
365
+ conf.current_user_method = :user_email
366
+ end
367
+ ```
368
+
369
+ #### `app/controllers/home_controller.rb`
370
+
371
+ ```ruby
372
+ class ApplicationController < ActionController::Base
373
+ private
374
+
375
+ def user_email
376
+ current_user&.email
377
+ end
378
+ end
379
+ ```
380
+
381
+ With the above code, any call to `allow_phi` (that starts in a controller
382
+ derived from ApplicationController) will use the result of `user_email` as the
383
+ user argument of `allow_phi`.
384
+
385
+ Note that if you have a default user, but choose not to use translations for
386
+ reasons you'll have to pass `nil` as the user:
387
+
388
+ ```ruby
389
+ person_phi.allow_phi(nil, "Because I felt like looking at PHI") do
390
+ # Allows PHI
391
+ end
392
+ ```
393
+
394
+ ## Best Practices
395
+
396
+ * Mix and matching `instance`, `class` and `block` syntaxes for allowing/denying PHI is not recommended.
397
+ * Sticking with one style in your application will make it easier to understand what access is granted and where.
398
+
45
399
  ## Development
46
400
 
47
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
401
+ It is recommended to use the provided `docker-compose` environment for development to help ensure dependency consistency and code isolation from other projects you may be working on.
402
+
403
+ ### Begin
404
+
405
+ $ docker-compose up
406
+ $ bin/ssh_to_container
407
+
408
+ ### Tests
409
+
410
+ Tests are written using [RSpec](http://rspec.info/) and are setup to use [Appraisal](https://github.com/thoughtbot/appraisal) to run tests over multiple rails versions.
411
+
412
+ $ bin/run_tests
413
+ or for individual tests:
414
+ $ bin/ssh_to_container
415
+ $ bundle exec appraisal rspec spec/path/to/spec.rb
416
+
417
+ To run just a particular rails version:
418
+ $ bundle exec appraisal rails-5.1 rspec
419
+ $ bundle exec appraisal rails-5.2 rspec
420
+ $ bundle exec appraisal rails-6.0 rspec
421
+
422
+ ### Console
48
423
 
49
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
424
+ An interactive prompt that will allow you to experiment with the gem.
50
425
 
51
- ### Docker
426
+ $ bin/ssh_to_container
427
+ $ bin/console
52
428
 
53
- * `docker-compose up`
54
- * `bin/ssh_to_container`
429
+ ### Local Install
55
430
 
56
- ## Testing
431
+ Run `bin/setup` to install dependencies. Then, run `bundle exec appraisal rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
432
+
433
+ To install this gem onto your local machine, run `bundle exec rake install`.
434
+
435
+ ### Versioning
436
+
437
+ To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
57
438
 
58
- $ bundle exec appraisal rspec spec/phi_attrs_spec.rb
59
439
 
60
440
  ## Contributing
61
441
 
62
- Bug reports and pull requests are welcome on GitHub at https://github.com/wkirby/phi_attrs.
442
+ Bug reports and pull requests are welcome on GitHub at https://github.com/apsislabs/phi_attrs.
443
+
444
+ Any PRs should be accompanied with documentation in `README.md`, and changes documented in [`CHANGELOG.md`](https://keepachangelog.com/).
63
445
 
64
446
  ## License
65
447
 
66
448
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
449
+
450
+ ## Legal Disclaimer
451
+
452
+ Apsis Labs, LLP is not a law firm and does not provide legal advice. The information in this repo and software does not constitute legal advice, nor does usage of this software create an attorney-client relationship.
453
+
454
+ Apsis Labs, LLP is not a HIPAA covered entity, and usage of this software does not create a business associate relationship, nor does it enact a business associate agreement.
455
+
456
+ [Full Disclaimer](./DISCLAIMER.txt)
457
+
458
+ ---
459
+
460
+ # Built by Apsis
461
+
462
+ [![apsis](https://s3-us-west-2.amazonaws.com/apsiscdn/apsis.png)](https://www.apsis.io)
463
+
464
+ `phi_attrs` was built by Apsis Labs. We love sharing what we build! Check out our [other libraries on Github](https://github.com/apsislabs), and if you like our work you can [hire us](https://www.apsis.io/work-with-us/) to build your vision.