Clinical Meteor Track

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?
Thanks! :grinning:

Ooof. Totally legit questions, which I don’t have complete answers for yet. I published a super basic plugin last night, so lets do what we can.

Q: Wow a plugin architecture are you kidding? That is awesome.
Nope, took a while to figure out. Thank you. :slight_smile:

Could you tell me what are the 4 plugins you have built in meteor-on-fhir?

plugin-default-landing-page        #core
symptomatic-videoconferencing      #core; incomplete
symptomatic-continuity-of-care     #core; incomplete
symptomatic-landing-page           #proprietary
symptomatic-neo4j-routing          #proprietary
uhs-calculator                     #proprietary; client; incomplete

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.

Pull from the latest development branch, and look at meteor-on-fhir/webapp/packages/plugin-default-landing-page

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:

  • DynamicRoutes
  • SideBarMenuItems
  • FooterActionButtons
  • ModalDialogs
  • HeaderNavBarComponents

Q: Also, which config file is the one that we could customize?

Look in the webapp/configs/settings.dev.json is a good place to start. :slightly_smiling_face:

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.

public.platform
Displays sections on the landing page.

public.app
Deprecated in favor of public.platfrom.

public.defaults.avatars
Shows avatars in Patient and Practitioner menus.

public.defaults.barcodes
Displays mongo _ids as 3 of 9 barcodes in tables.

public.defaults.hexgridMenu
Experimental hexgrid gamification menu.

public.defaults.nfcOrbital
Displays the orbital by default. Will eventually be used to display NFC device proximity.

public.defaults.notificationMenu
Displays alerts and notifications in the navbar.

public.defaults.searchbarVisible
Display the searchbar by default. Sometimes used during mobile app layouts.

public.defaults.displayNavbars
Display the header and footer navars by default.

public.defaults.disableHeader
Disable the header navbar. Rarely used.

public.defaults.disableFooter
Disable the footer navbar. Useful for scrolling mobile apps, landing webpages, etc.

public.defaults.darkroom
Inverts the cards for darkroom usage (i.e. radiology apps).

public.defaults. iFrameEnabled
Enabled the slide-in context frame.

public.defaults.iFrameUrl
Set the default context URL. Popular entries include Wikipedia, Darmouth Health Atlas, and Zygote Avatar.

public.defaults.paginationLimit
How many rows should be showed in tables by default.

public.defaults.subscriptionLimit
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).

public.defaults.cards.opacity
Set the default card opacity level.

public.defaults.interfaces.default
The default outbound interface endpoint. Generally the upstream EHR and default FHIR datawarehouse that Meteor on FHIR will be querying from.

public.defaults.cards.meshNetwork.upstreamSync
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.

public.defaults.meshNetwork.autosync
Right now, set to once daily I think.

public.defaults.cards.modules.data
Enables the data management page.

public.defaults.cards.modules.epic
Enables the Query Epic buttons on some FHIR resources.

public.defaults.cards.modules
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.

public.defaults.cards.modules.apps
Turns on/off the app cards in the main index.

public.defaults.cards.modules.fhir
Turns on/off the FHIR cards in the main index. Will also enable/disable FHIR REST endpoints.

private.practitionerAccessCode
Default invite code for enrolling a practitioner.

private.practitionerAccessCode
Default invite code for enrolling an admin.

private.disableOauth
Disables security for testing REST endpoints. Do not use in production.

private.demo.nightlyDatabaseDrop
Clears the database every 24 hours.

2 Likes

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.

$0.02

2 Likes

Hi,

This is not exactly on topic, but this looks like an opportunity to mention my new product.

Clinical Summary Table Validation, runs on Meteor.

https://checkvals.com/

–thx, jw

1 Like

Hi Barwell,
Thanks for posting. Great to see data processing and pipelining apps in the Meteor world.

You know… one can actually turn off all the modules in the Meteor on FHIR boilerplate to get a ‘blank slate’ configuration.

Your app might be well positioned to be written as a plugin, if you’d like a forklift upgrade to get graphing, auditing, interoperability, and all the other features that Clinical Meteor implements.

Just a thought. $0.02

Thanks for the feedback and suggestions.

I will have to take a look and think about all of these things.

Right now I don’t have time to look at these in any detail, but will be back to them ASAP, maybe a few weeks.

-jw

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?
Dave

Hi Dave,
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! :wink:

1 Like

Abigail I would like to work with Communications. I do not see a Communication resource implementation. Shall I make one?

That would be kind of awesome. It will certainly get you up to speed on the internals of a FHIR resource in Meteor.

Although I will say that we’re in the process of forklift upgrading the rest of the resources with the JSON Schemas that HL7 has published.

So, toss together a minimal one to sketch out what functions you might want to attach to the Communications class. But don’t go crazy implementing a bunch of new resources.

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.

Use the Patient resource. It’s on FHIR v3.0.1 and under QA.

Do keep in mind that we’re eventually migrating to the JSON Shema definition, which can be found here:
https://www.hl7.org/fhir/Patient.schema.json

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.

2 Likes

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

  • fhir-schema-db
  • fhir-schema-graphql
  • fhir-schema-rest
  • fhir-schema-crudui
  • etc.

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 :stuck_out_tongue:

I would love to hear your thoughts!

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.

3 Likes

Also, ignore the blaze code. It’s in there for backwards compatibility; and will be removed in v4.x.

2 Likes

Hi Abigail
I could not get the link to work, for your biweekly healthcare call. Could you share again?

Scheduled for 10am Central time, every 2 weeks. Still working out the GSuite Calendar/Hangouts settings. Going to give it another try today though.