I tell you what, the Redis-Oplog package is a welcome addition; and likely to make it into the project. It requires the Redis binaries and a Redis server though, correct? Or does it deploy it’s own?
I ask because I’ve been experimenting with a Docker Meteor on FHIR deployment. I’m thinking of adding a Redis server to the docker-compose.yml file, and then adding Redis-Oplog to the deployment script. I knew that we had slava's older Redis libraries available as fallback; and I had basically planned to use whatever was the Redis best practice since then. The only think I’m held up on is that I need to figure out the development story, of where it fits in the build/deployment pipeline and how it gets used in local development if the Redis binaries haven’t been installed or running on the local machine.
@awatson1978 thank you for your thoughtful reply!
Wow a plugin architecture are you kidding? That is awesome.
Could you tell me what are the 4 plugins you have built in meteor-on-fhir? Just a little direction would be helpful so I could find the plugins in the codebase and see what you did. Also, which config file is the one that we could customize?
What kinds of things could we add onto the system with a plugin? pages, menu elements?
What kinds of things can we change with change in the config file?
As you can see, we’re only just now beginning to refactor things into plugins. And we haven’t figured out naming conventions, namespaces, etc. But it does support public/private repositories, and provides a way for people to ‘own’ their workflow while using and supporting a common data layer.
Q: Just a little direction would be helpful so I could find the plugins in the codebase and see what you did.
Q: What kinds of things could we add onto the system with a plugin?
We’re still in the very early stages of the plugin pattern, so I’ve only got page routes set up so far. But menu elements, action buttons, and more will be coming within the next quarter. If I get funding and support, I’d be happy to roll those features out sooner. And I’ll be happy to accept pull requests.
Regardless, here are the relevant files to that compose the plugin pattern:
With those 3 files, a package can expose React components and routes into the app dynamically.
Q: Pages, menu elements?
Yeah, the idea is that we’ll be using that Package scanning approach, and exposing more components via packages. The plan is to support the following arrays:
Q: Also, which config file is the one that we could customize?
Q: What kinds of things can we change with change in the config file?
public.theme defaultVideo will override the backgroundImagePath. Generally speaking I’ll always accept pull requests that expand support for darkroomTextEnabled. There’s a minimally used palette field also.
Displays sections on the landing page.
Deprecated in favor of public.platfrom.
Shows avatars in Patient and Practitioner menus.
Displays mongo _ids as 3 of 9 barcodes in tables.
Displays the orbital by default. Will eventually be used to display NFC device proximity.
Displays alerts and notifications in the navbar.
Display the searchbar by default. Sometimes used during mobile app layouts.
Display the header and footer navars by default.
Disable the header navbar. Rarely used.
Disable the footer navbar. Useful for scrolling mobile apps, landing webpages, etc.
Inverts the cards for darkroom usage (i.e. radiology apps).
Enabled the slide-in context frame.
Set the default context URL. Popular entries include Wikipedia, Darmouth Health Atlas, and Zygote Avatar.
How many rows should be showed in tables by default.
How many records should be prefetched to the client by default. Important. Adjust this based on your target audience devices. I.e. set lower on mobile devices and laptops; set higher for workstations).
Set the default card opacity level.
The default outbound interface endpoint. Generally the upstream EHR and default FHIR datawarehouse that Meteor on FHIR will be querying from.
The upstream node that a node should sync with. Right now, only supports syncing Organizations. We plan synchronizing default Medicare/Medicaid data through the mesh network; and will eventually be supporting IPFS.
Right now, set to once daily I think.
Enables the data management page.
Enables the Query Epic buttons on some FHIR resources.
Everything under the modules selection will turn on/off a card and subsequent route in the system. Eventually, this will be hooked into the plugin system. But for now, it’s sort of hardcoded. The items in apps and fhir are much more active than the modules directory, which is getting a bit stale. Some of these are effectively deprecated.
Turns on/off the app cards in the main index.
Turns on/off the FHIR cards in the main index. Will also enable/disable FHIR REST endpoints.
Default invite code for enrolling a practitioner.
Default invite code for enrolling an admin.
Disables security for testing REST endpoints. Do not use in production.
Clears the database every 24 hours.
Also, a bit on project governance and how this config file came to exist.
As a general rule, I don’t prefer to delete or remove functionality that has been implemented. I’ve spent a lot of time consulting with physicians, nurses, social workers, and other specialists to come up with the features that are in Meter on FHIR and Symptomatic. What’s in the project is not in there by accident.
I’ve had some very bad experiences in the past with teams in startup accelerators who have asked me to consult on their project, and then have proceeded to rip out large chunks of Meteor on FHIR and asked me to rewrite their custom workflow as work-for-hire. That’s a good way to burn bridges with me.
Rather, it’s far better to ask how to isolate functionality and add a toggle in the config file to enable/disable the feature. This approach respects that other people may have interest in retaining that feature, it respects past contributions to the project, it preserves functionality in case we need to re-enable it, it helps move the entire system towards A/B market testing, and it doesn’t break existing validation/verification tests.
Thanks for this clear documentation. Just wanted to report back that I am working on a plugin to meteor-on-fhir. I am new to React (have been using Angular 2) so I am getting started slowly with the UI elements. I need a lookup capability as people type. Do you recommend any widget libraries? Anything already embedded?
Looks like a great platform on which to build modern health apps. I am excited to see security and so many other fundamentals are already solved using best practices. Thanhs again @awatson1978 for your hard work on this.
I am curious, what are your ambitions/plans in 2018 for meteor-on-fhir?
I’ve been gravitating towards Material Design implementations, such as Material UI, since they create a common UI/UX design paradigm to implement towards. With a bit of styling, Material Design is quite adaptable to Day Made of Glass and Minority Report style interfaces. It can be optimized down to the GPU level, so we’ve had no problem pushing native style response out of it on Chrome.
As for ambitions… well, we’re doing a fund raising round right now, and blockchain seems to be where the VC community is at. The PHR component is probably going to get published into the Apple/Google App Stores. And we’ve got an Epic App Orchard integration on the books. We’re keeping busy!
OK my approach would be to clone a existing implementation and make alterations. Can you recommend a project to clone as a starting project? Naturally I am looking for something that is built according to latest schema and latest standards.
Hi @dpdonohue ,
So, there’s been a bunch of people asking about writing plugins for Symptomatic/Meteor on FHIR, and I finally got around to writing a quick-start article: Creating a Symptomatic Plugin . Thought I’d follow up to your questions.
Also, I’m looking to finally start up a biweekly healthcare call. I believe @rafikicai and others will be joining. Let me know if this calendar link works for you. I’m a little unclear about the Hangouts integration; but I think it’s included.
Love it! A full blown plugin architecture! Question: I see in the project clinical:hl7-resource-patient, you have both blaze UI code and react UI code. When implementing a new package, is it necessary to include that blaze code? Can we skip that directory client/blaze?
I tried the Google Calendar link but it does not work for me sorry.
I am modifying the code for hl7-resource-patient, for replacing “patient” with “communication”.
The activity involves a lot of global find/replace and then remove the patient properties and add the communication properties.
I can’t help think this could all be dynamic. I.e. we have a single codebase, and feed it one JSON FHIR spec at a time. This package dynamically creates the schema, Mongo tables, REST endpoints etc. Actually this should be a series of packages that each fill 1 such function. You know better than me @awatson1978, but I would think we would have packages like this
Advantages: codebase would be more modular, future-proof when FHIR spec is updated, could make it more generic (NPM) than Meteor-specific
Disadvantages: a lot of work
Well, you’re certainly not the first person to think along those lines. My perspective is that it’s one of those cases where easy to implement can be difficult to maintain; and difficult to implement is easy to maintain. And we’ve opted for the later.
Keep in mind that the resources are different because they use different data models. So, for instance… the Location resource tracks latitude/longitude. Which can benefit from a Mongo 2sphere index for geospatial lookups. And which needs Google Maps loaded up. That’s completely different than the Patient resource, which needs to track a photo/avatar and medical record numbers (maybe a thumbprint, even). Versus a Communications resource, which might track API keys for Twilio and other messaging services.
So each of the resources tracks it’s one-off differences from the base DomainResource. The only catch is that, over time, we’ve wound up modeling the default case, not just the one-off. So, we model a 2sphere index in Location, but we also model a regular index in all the other packages.
You’ve heard the phrase TANSTAAFL, right? There Aint No Such Thing As A Free Lunch. From a computational entropy perspective, all these one-offs have to modeled somewhere. You can’t just load in a JSON FHIR spec, and expect Node and Mongo and Meteor to spit out a working app. There has to be some engineering along the way. At best, we can shuffle things around a bit and make easier to use interfaces.
And that’s what you’re basically asking for… is a refactor to put all the HL7 resources in a single package. Which… we’re working on. But we’re not quite there yet.
What we have done, is we’ve created the fhir-schemas package, which has all the FHIR JSON schemas in it. In the future, we’re going to refactor the hl7-resource-* packages to pull in from this NPM package.
We’ve also created the material-fhir-ui package, added all the hl7-resource packages as submodules, and tried to refactor the React packages into the a common library. Unfortunately, we can’t rely on Atmosphere dependencies in Npm, so no access to Meteor, Session, Tracker, Meteor-React-Data, or all the other things that Clinical Meteor is built on. So, we have to do refactors on the existing FHIR React components to make them pure components; which is good design in principle, but fairly inconvenient and annoying in practice.
One thing we’ve learned with these experiments is that there’s a long tail distribution in both the usage and complexity of the FHIR resources. Of the 150+ Resources defined by HL7, only about 12 of them are used by all major EHR vendors or are Maturity Level 4 or greater. There’s a long tail of 80+ resources or more that are at Maturity Level 0, and which are little more than data models.
Those resources are good candidates for dynamically generated schemas, autoforms, and the like. So, we’re looking at react-jsonschema-form as a replacement for AutoForms. But, gotta remember: TANSTAAFL. The definitions in the JSON Schemas that are provided by HL7 for data exchange aren’t necessarily the JSON Schema that will generate a form that is pleasing to a user. So, either a new set of form schemas need to be generated by hand; or a function has to be written that autogenerates them. But, again TANSTAAFL. That autogeneration function has to have all the one-offs to write out a usable schema. We can’t get away from the information entropy problem; we can only shuffle the entropy around.
So, yeah…we’re working on what you’ve described as a refactor from the existing packages; but there’s a lot of gotchyas and one-offs and dependency issues. If we had funding, it’s one of the tasks I would probably assign to a senior software engineer to ramp them up to speed on the platform. But even then it’s probably a 500 hour project to get right. It will happen eventually. But it will also take time.