Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
ruby-version: ["3.0", "3.1", "3.2", "3.4", "4.0"]

steps:
- uses: actions/checkout@v4

- name: Set up Ruby ${{ matrix.ruby-version }}
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true

- name: Run tests
run: bundle exec rspec

lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: "3.2"
bundler-cache: true

- name: Run RuboCop
run: bundle exec rubocop
4 changes: 2 additions & 2 deletions .mise.local.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
# This file is gitignored and should contain your local dev/test credentials

[env]
# The vast majority of these are for testing against a local DataNexus instance and recording VCR cassettes.
DATANEXUS_API_KEY = "your-real-api-key"
DATANEXUS_BASE_URL = "https://localhost:4000"
DATANEXUS_SSL_VERIFY = "false"
DATANEXUS_TEST_PROGRAM_ID = "your-real-program-id"
DATANEXUS_TEST_MEMBER_ID = "your-real-member-id"
DATANEXUS_TEST_CONSENT_ID = "your-real-consent-id"

# Required filters for testing (the API requires at least one filter combination)
DATANEXUS_TEST_ENROLLMENT_ID = "your-real-enrollment-id"
DATANEXUS_TEST_BORN_ON = "1980-01-15"
DATANEXUS_TEST_EMPLOYEE_ID = "EMP123"
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ plugins:
- rubocop-rspec

AllCops:
TargetRubyVersion: 2.7
TargetRubyVersion: 3.0
NewCops: enable

# Integration tests have different expectations
Expand Down
6 changes: 6 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ gem 'rubocop-rspec', '~> 3.0'

gem 'vcr', '~> 6.0'
gem 'webmock', '~> 3.0'

# Pin public_suffix for Ruby 3.0/3.1 compatibility (7.0+ requires Ruby >= 3.2)
gem 'public_suffix', '< 7.0'

# Pin erb for Ruby 3.0/3.1 compatibility (5.0+ requires Ruby >= 3.2)
gem 'erb', '~> 4.0'
11 changes: 6 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ GEM
public_suffix (>= 2.0.2, < 8.0)
ast (2.4.3)
bigdecimal (4.0.1)
cgi (0.5.1)
crack (1.0.1)
bigdecimal
rexml
date (3.5.1)
diff-lcs (1.6.2)
erb (6.0.1)
erb (4.0.4)
cgi (>= 0.3.3)
faraday (2.14.0)
faraday-net_http (>= 2.0, < 3.5)
json
Expand Down Expand Up @@ -49,7 +51,7 @@ GEM
psych (5.3.1)
date
stringio
public_suffix (7.0.2)
public_suffix (6.0.2)
racc (1.8.1)
rainbow (3.1.1)
rake (13.3.1)
Expand Down Expand Up @@ -113,14 +115,13 @@ PLATFORMS

DEPENDENCIES
data_nexus!
erb (~> 4.0)
irb
public_suffix (< 7.0)
rake (~> 13.0)
rspec (~> 3.0)
rubocop (~> 1.0)
rubocop-rake (~> 0.6)
rubocop-rspec (~> 3.0)
vcr (~> 6.0)
webmock (~> 3.0)

BUNDLED WITH
2.7.1
108 changes: 96 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ Ruby client for the DataNexus API.

## Installation

Install from GitHub (before gem is published):

```ruby
gem 'data_nexus', git: 'https://github.com/DartHealth/datanexus-ruby.git', tag: 'v0.1.0'
```

Or from RubyGems (once published):

```ruby
gem 'data_nexus'
```
Expand All @@ -17,6 +25,8 @@ client = DataNexus::Client.new(
)
```

## Program Members

### List Members

Filters are required. Valid combinations:
Expand Down Expand Up @@ -54,31 +64,31 @@ end
### Find Member

```ruby
member = client.programs('program-id').members.find('member-id')
member = client.programs('program-id').members('member-id').find
puts member[:first_name]
```

### Update Member

```ruby
response = client.programs('program-id').members.update('member-id',
response = client.programs('program-id').members('member-id').update(
member: { phone_number: '+15551234567' }
)
```

### Household Members

```ruby
household = client.programs('program-id').members.household('member-id')
household.data.each { |member| puts member[:first_name] }
household = client.programs('program-id').members('member-id').household
household.each { |member| puts member[:first_name] }
```

### Member Consents

#### Create Consent

```ruby
response = client.programs('program-id').members.consents('member-id').create(
response = client.programs('program-id').members('member-id').consents.create(
consent: {
category: 'sms',
member_response: true,
Expand All @@ -91,29 +101,102 @@ response = client.programs('program-id').members.consents('member-id').create(
#### Find Consent

```ruby
consent = client.programs('program-id').members.consents('member-id').find(123)
consent = client.programs('program-id').members('member-id').consents.find(123)
puts consent[:category]
```

#### Update Consent

```ruby
response = client.programs('program-id').members.consents('member-id').update(123,
response = client.programs('program-id').members('member-id').consents.update(123,
consent: { member_response: false }
)
```

#### Delete Consent

```ruby
client.programs('program-id').members.consents('member-id').delete(123)
client.programs('program-id').members('member-id').consents.delete(123)
```

### Member Enrollments

#### Create Enrollment

```ruby
response = client.programs('program-id').members('member-id').enrollments.create(
enrollment: {
enrolled_at: '2024-01-01T00:00:00Z',
expires_at: '2025-01-01T00:00:00Z'
}
)
# program_id is automatically injected
```

#### Find Enrollment

```ruby
enrollment = client.programs('program-id').members('member-id').enrollments.find(123)
puts enrollment[:enrolled_at]
```

#### Update Enrollment

```ruby
response = client.programs('program-id').members('member-id').enrollments.update(123,
enrollment: { expires_at: '2026-01-01T00:00:00Z' }
)
```

#### Delete Enrollment

```ruby
client.programs('program-id').members('member-id').enrollments.delete(123)
```

## Top-Level Members

You can also access members without a program scope:

### List Members

```ruby
collection = client.members.list(
first_name: 'George',
last_name: 'Washington',
born_on: '1976-07-04'
)

# Filter by program eligibility
collection = client.members.list(program_id: 'program-uuid')

# Filter by update time
collection = client.members.list(updated_since: '2024-01-01T00:00:00Z')

# Pagination
collection = client.members.list(first: 50, after: 'cursor')
```

### Find Member

```ruby
member = client.members.find('member-id')
puts member[:first_name]
```

### Update Member

```ruby
response = client.members.update('member-id',
member: { phone_number: '+15551234567' }
)
```

## Error Handling

```ruby
begin
client.programs('id').members.find('id')
client.programs('id').members('id').find
rescue DataNexus::AuthenticationError
# 401
rescue DataNexus::NotFoundError
Expand All @@ -129,11 +212,12 @@ end

## Development

```
```bash
cp .mise.local.toml.example .mise.local.toml
# Edit .mise.local.toml with your test credentials
mise run test
mise run lint
bundle install
bundle exec rspec
bundle exec rubocop
```

## License
Expand Down
3 changes: 2 additions & 1 deletion data_nexus.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ Gem::Specification.new do |spec|
spec.description = "A Ruby gem for interacting with the Dart Health's DataNexus API."
spec.homepage = 'https://github.com/DartHealth/datanexus-ruby'
spec.license = 'MIT'
spec.required_ruby_version = '>= 2.7.0'
spec.required_ruby_version = '>= 3.0.0'

spec.metadata['homepage_uri'] = spec.homepage
spec.metadata['source_code_uri'] = spec.homepage
spec.metadata['changelog_uri'] = "#{spec.homepage}/releases"
spec.metadata['rubygems_mfa_required'] = 'true'

# Specify which files should be added to the gem when it is released.
Expand Down
14 changes: 13 additions & 1 deletion lib/data_nexus/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative 'configuration'
require_relative 'connection'
require_relative 'resources/members'
require_relative 'resources/programs'

module DataNexus
Expand All @@ -16,7 +17,7 @@ module DataNexus
#
# @example Access program members
# client.programs("program-uuid").members.list
# client.programs("program-uuid").members.find("member-id")
# client.programs("program-uuid").members("member-id").find
#
class Client
# @return [Configuration] The client configuration
Expand Down Expand Up @@ -48,6 +49,17 @@ def initialize(api_key: nil, base_url: nil, timeout: nil, open_timeout: nil, ssl
@connection = Connection.new(@config)
end

# Access top-level member resources
#
# @return [Resources::Members] A members resource
#
# @example
# client.members.list
# client.members.find("member-id")
def members
Resources::Members.new(connection)
end

# Access program-scoped resources
#
# @param program_id [String] The program UUID
Expand Down
Loading