Skip to content

Commit

Permalink
feat: Added support for R4 resources and environment setup
Browse files Browse the repository at this point in the history
BREAKING CHANGE: New resources contain new dependencies. One of these
contains graphql which may require you to delete and reinstall node
modules. We have updated several versions so when updating, you should
rerun yarn install and may need to remove node_modules before hand.
  • Loading branch information
Robert Winterbottom committed Jan 9, 2019
1 parent be3b700 commit 686a764
Show file tree
Hide file tree
Showing 5,007 changed files with 417,141 additions and 151,605 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
5 changes: 3 additions & 2 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,10 @@ We also allow for partial error handling, so you can reject things in one resolv
```

## Resource configuration
By default, we support almost all the resources from STU3(3.0.1) and DSTU2(1.0.2). We allow you to turn on or off entire versions very easily. We also allow you to turn off individual profiles or even capabilities within a profile if you desire.
By default, we support almost all the resources from R4(4.0.0), STU3(3.0.1), and DSTU2(1.0.2). Since most teams will not need to support all the resources for all three versions, we make it very easy to disable resources or even entire versions. Furthermore, you can disable operations at the resource level incase you only want to support read or something similar.

To configure which version you want to support, add/remove a value to the `VERSION` constant in `src/config.js`. You just need to make sure you have a corresponding set of resources in `src/resources`.
### Version configuration
To configure which version you want to support, add/remove a value to the `VERSION` constant in `src/config.js`. You just need to make sure you have a corresponding set of resources in `src/resources`. So if you only want to support R4, just remove the `1_0_2` and `3_0_1` entries.

In order to explain how to configure a specific profile, let's walk through an example of configuring the patient profile and completely disabling the observation profile for version 1.0.2.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ src
- [ ] Support for more versions
- [x] DSTU2 (1.0.2).
- [x] STU3 (3.0.1).
- [ ] R4
- [x] R4
- [ ] Work with community to continue to establish best practices for FHIR with GraphQL and implement them here.

## Contributing
Expand Down
12 changes: 7 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "graphql-fhir",
"version": "0.9.1",
"version": "1.0.0",
"description": "A Javascript based GraphQL FHIR server",
"main": "index.js",
"author": "Robert-W <rwinterbottom@asymmetrik.com>>",
"license": "MIT",
"private": false,
"scripts": {
"start": "node src/index",
"nodemon": "node src/scripts/nodemon",
"test": "node src/scripts/test --env=jsdom",
"start": "cross-env NODE_ENV=production node src/index",
"nodemon": "cross-env NODE_ENV=development node src/scripts/nodemon",
"test": "cross-env NODE_ENV=test node src/scripts/test --env=jsdom",
"prettier": "prettier \"src/**/*.js\" --write",
"lint": "eslint \"src/**/*.js\""
},
Expand All @@ -19,12 +19,14 @@
},
"dependencies": {
"@asymmetrik/fhir-gql-schema-utils": "^1.0.1",
"@asymmetrik/sof-graphql-invariant": "^1.0.2",
"body-parser": "^1.18.3",
"compression": "^1.7.2",
"cross-env": "^5.2.0",
"express": "^4.16.3",
"express-graphql": "^0.6.12",
"glob": "^7.1.2",
"graphql": "^0.13.2",
"graphql": "^14.0.2",
"graphql-outfields": "^0.9.1",
"helmet": "^3.12.1",
"moment-timezone": "^0.5.21",
Expand Down
3 changes: 2 additions & 1 deletion src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const path = require('path');
const VERSION = {
'1_0_2': '1_0_2',
'3_0_1': '3_0_1',
'4_0_0': '4_0_0'
};

/**
Expand Down Expand Up @@ -57,7 +58,7 @@ const RESOURCE_CONFIG = {
// base folder for all the resources relative to src
resourceBase: 'resources',
// Path is relative to version folder under resources
profilesRelativePath: 'profiles/**/index.js',
profilesRelativePath: 'profiles/**/register.js',
};

module.exports = {
Expand Down
14 changes: 14 additions & 0 deletions src/environment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* WARNING: DO NOT PUT ANY SECRETS IN HERE, THIS IS ONLY INTENDED TO SETUP
* SIMPLE FEATURE FLAGS. SECRETS SHOULD BE PART OF YOUR DEPLOYMENT STRATEGY
*/

if (process.env.NODE_ENV === 'development') {
process.env.SOF_AUTHENTICATION = true;
process.env.HAS_GRAPHIQL = true;
}

if (process.env.NODE_ENV === 'production') {
process.env.SOF_AUTHENTICATION = true;
process.env.HAS_GRAPHIQL = false;
}
7 changes: 5 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const { SERVER_CONFIG } = require('./config');
const FHIRServer = require('./lib/server');
const { SERVER_CONFIG } = require('./config.js');
const FHIRServer = require('./lib/server.js');

// load environment settings
require('./environment.js');

// Start buliding our server
let server = new FHIRServer(SERVER_CONFIG)
Expand Down
235 changes: 142 additions & 93 deletions src/resources/1_0_2/inputs/account.input.js
Original file line number Diff line number Diff line change
@@ -1,105 +1,154 @@
const CodeScalar = require('../scalars/code.scalar');
const {
GraphQLInputObjectType,
GraphQLEnumType,
GraphQLNonNull,
GraphQLString,
GraphQLEnumType,
GraphQLList,
GraphQLString,
GraphQLInputObjectType,
} = require('graphql');

// Util for extending gql objects
const { extendSchema } = require('@asymmetrik/fhir-gql-schema-utils');

let AccountResourceInputType = new GraphQLEnumType({
name: 'AccountResourceInputType',
values: {
Account: { value: 'Account' },
},
});
const IdScalar = require('../scalars/id.scalar.js');
const UriScalar = require('../scalars/uri.scalar.js');
const CodeScalar = require('../scalars/code.scalar.js');

/**
* @name exports
* @summary Account Input Schema
*/
module.exports = new GraphQLInputObjectType({
name: 'Account_Input',
description: 'Base StructureDefinition for Account Resource.',
fields: () =>
extendSchema(require('./domainresource.input'), {
resourceType: {
type: new GraphQLNonNull(AccountResourceInputType),
description: 'Type of this resource.',
},
identifier: {
type: new GraphQLList(require('./identifier.input')),
description:
'Unique identifier used to reference the account. May or may not be intended for human use (e.g. credit card number).',
},
name: {
type: GraphQLString,
description:
'Name used for the account when displaying it to humans in reports, etc.',
},
_name: {
type: require('./element.input'),
description:
'Name used for the account when displaying it to humans in reports, etc.',
},
type: {
type: require('./codeableconcept.input'),
description:
'Categorizes the account for reporting and searching purposes.',
},
// ValueSetReference: http://hl7.org/fhir/ValueSet/account-status
status: {
type: CodeScalar,
description:
'Indicates whether the account is presently used/useable or not.',
},
_status: {
type: require('./element.input'),
description:
'Indicates whether the account is presently used/useable or not.',
},
activePeriod: {
type: require('./period.input'),
description:
'Indicates the period of time over which the account is allowed.',
},
currency: {
type: require('./coding.input'),
description:
'Identifies the currency to which transactions must be converted when crediting or debiting the account.',
},
balance: {
type: require('./quantity.input'),
description:
'Represents the sum of all credits less all debits associated with the account. Might be positive, zero or negative.',
},
coveragePeriod: {
type: require('./period.input'),
description:
'Identifies the period of time the account applies to; e.g. accounts created per fiscal year, quarter, etc.',
},
subject: {
type: require('./reference.input'),
description:
'Identifies the patient, device, practitioner, location or other object the account is associated with.',
},
owner: {
type: require('./reference.input'),
description:
'Indicates the organization, department, etc. with responsibility for the account.',
},
description: {
type: GraphQLString,
description:
'Provides additional information about what the account tracks and how it is used.',
},
_description: {
type: require('./element.input'),
description:
'Provides additional information about what the account tracks and how it is used.',
},
}),
description: 'Base StructureDefinition for Account Resource',
fields: () => ({
resourceType: {
type: new GraphQLNonNull(
new GraphQLEnumType({
name: 'Account_Enum_input',
values: { Account: { value: 'Account' } },
}),
),
description: 'Type of resource',
},
_id: {
type: require('./element.input.js'),
description:
'The logical id of the resource, as used in the URL for the resource. Once assigned, this value never changes.',
},
id: {
type: IdScalar,
description:
'The logical id of the resource, as used in the URL for the resource. Once assigned, this value never changes.',
},
meta: {
type: require('./meta.input.js'),
description:
'The metadata about the resource. This is content that is maintained by the infrastructure. Changes to the content may not always be associated with version changes to the resource.',
},
_implicitRules: {
type: require('./element.input.js'),
description:
'A reference to a set of rules that were followed when the resource was constructed, and which must be understood when processing the content.',
},
implicitRules: {
type: UriScalar,
description:
'A reference to a set of rules that were followed when the resource was constructed, and which must be understood when processing the content.',
},
_language: {
type: require('./element.input.js'),
description: 'The base language in which the resource is written.',
},
language: {
type: CodeScalar,
description: 'The base language in which the resource is written.',
},
text: {
type: require('./narrative.input.js'),
description:
"A human-readable narrative that contains a summary of the resource, and may be used to represent the content of the resource to a human. The narrative need not encode all the structured data, but is required to contain sufficient detail to make it 'clinically safe' for a human to just read the narrative. Resource definitions may define what content should be represented in the narrative to ensure clinical safety.",
},
contained: {
type: new GraphQLList(GraphQLString),
description:
'These resources do not have an independent existence apart from the resource that contains them - they cannot be identified independently, and nor can they have their own independent transaction scope.',
},
extension: {
type: new GraphQLList(require('./extension.input.js')),
description:
'May be used to represent additional information that is not part of the basic definition of the resource. In order to make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.',
},
modifierExtension: {
type: new GraphQLList(require('./extension.input.js')),
description:
'May be used to represent additional information that is not part of the basic definition of the resource, and that modifies the understanding of the element that contains it. Usually modifier elements provide negation or qualification. In order to make the use of extensions safe and manageable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.',
},
identifier: {
type: new GraphQLList(require('./identifier.input.js')),
description:
'Unique identifier used to reference the account. May or may not be intended for human use (e.g. credit card number).',
},
_name: {
type: require('./element.input.js'),
description:
'Name used for the account when displaying it to humans in reports, etc.',
},
name: {
type: GraphQLString,
description:
'Name used for the account when displaying it to humans in reports, etc.',
},
type: {
type: require('./codeableconcept.input.js'),
description:
'Categorizes the account for reporting and searching purposes.',
},
_status: {
type: require('./element.input.js'),
description:
'Indicates whether the account is presently used/useable or not.',
},
// valueSetReference: http://hl7.org/fhir/ValueSet/account-status
status: {
type: CodeScalar,
description:
'Indicates whether the account is presently used/useable or not.',
},
activePeriod: {
type: require('./period.input.js'),
description:
'Indicates the period of time over which the account is allowed.',
},
currency: {
type: require('./coding.input.js'),
description:
'Identifies the currency to which transactions must be converted when crediting or debiting the account.',
},
balance: {
type: require('./quantity.input.js'),
description:
'Represents the sum of all credits less all debits associated with the account. Might be positive, zero or negative.',
},
coveragePeriod: {
type: require('./period.input.js'),
description:
'Identifies the period of time the account applies to; e.g. accounts created per fiscal year, quarter, etc.',
},
subject: {
type: GraphQLString,
description:
'Identifies the patient, device, practitioner, location or other object the account is associated with.',
},
owner: {
type: GraphQLString,
description:
'Indicates the organization, department, etc. with responsibility for the account.',
},
_description: {
type: require('./element.input.js'),
description:
'Provides additional information about what the account tracks and how it is used.',
},
description: {
type: GraphQLString,
description:
'Provides additional information about what the account tracks and how it is used.',
},
}),
});
Loading

0 comments on commit 686a764

Please sign in to comment.