Wednesday, May 30, 2018

Are you lost on how GDPR is related to Health IT standards?

Yesterday, after posting for the first time in a while, Google alerts me that as a publisher of content on THEIR technology platform, using THEIR tools, that I have a responsibility to notify you (if you happen to live in a European Economic Area) of how I use your personal data, and if necessary obtain your consent, as a result of the General Data Protection Regulations (GDPR).

Conveniently, I don't use your personal data.  Instead, I let Google do it all for me.  If there are cookies generated by this site, they are generated by Google software.  If there is tracking being done by geography, cookie, topic or other data you supply to access this site.

If you happen to be reading this blog through a syndicated site, well, all bets are off because I don't control how those who syndicate this content use your personal data, but they are subject to the same requirements as I am.

I don't use cookies for Ads (because I don't do AdWords or anything like that here).  I do use Google Analytics with my blogger account.

But apparently, I still have some responsibilities to you, or at least, that is what Google is telling me.

Here's Google's policies and an explanation of how it uses your data, and how you can opt out of certain uses.

Now, here's what is interesting about what Google did.  They transferred their compliance risk to me even though I use their platform and their tools.  This is a classic technique to mitigate risk that we look at all the time in developing IHE profiles and other implementation guides.  It's one of several techniques for risk mitigation.  More often, we apply other technical mitigations (e.g., the use of ATNA or TLS, the requirement for authentication).

If you are reading this site in a European Economic Area, Google tells me that this site will display a notice to you.  I've not seen it yet because even though Google tells me I should be able to by using the blogspot.fr or .blogspot.co.uk or similar name, my browser conveniently redirects me to the .com site.  So, if you got the notice, please let me know.  Otherwise, I may need to do something more.

    Keith

P.S. Unlike HIPAA, GDPR doesn't really have an an easily acceptable pronunciation, although it does bring to mind several different acronym decodes.  In that, it's somewhat like BPPC.






Tuesday, May 29, 2018

On CMS 's Promoting Interoperability Program (the program formerly known as the EHR Incentive Program)

A while back I read through CMS's recent rule changing the EHR Incentive program to the Promoting Interoperability program.  I promised a blog update but for some reason (work), didn't get around to writing it.  I decided to take action and finally sit down and finish it.

The published rule is something like 1800 pages, 36 reams of paper when printed double-spaced (as preprints are).  You can find it at the link above.  It goes by the precise but lengthy title of:

Medicare Program; Hospital Inpatient Prospective Payment Systems for Acute Care Hospitals and the Long-Term Care Hospital Prospective Payment System and Proposed Policy Changes and Fiscal Year 2019 Rates; Proposed Quality Reporting Requirements for Specific Providers; Proposed Medicare and Medicaid Electronic Health Record (EHR) Incentive Programs (Promoting Interoperability Programs) Requirements for Eligible Hospitals, Critical Access Hospitals, and Eligible Professionals; Medicare Cost Reporting Requirements; and Physician Certification and Recertification of Claims

I will only cover two parts: Quality Reporting Requirements, and the Promoting Interoperability Programs.  The first part is interesting because everyone who cares about the second part also has to deal with the quality reporting part.  You can find my raw read-through comments on Twitter.

Quality Reporting Requirements

If you haven't been paying attention to CQL, you really need to be.  The first publication of reporting requirements technical specifications will be this spring (coming REAL soon) for use in 2019 (coming sooner than you think).  According to CMS (and me) "We believe that compared to CQL, QDM logic is more complex and difficult to compute".  CMS will be using a sub-regulatory process to make technical corrections to the measure specifications.  This is good because it means that the quality measure specifications will be able to have more quality without going through a heavyweight process to fix mistakes.  But it also means you have to pay attention.

Hospital measure data will join the myriad of other public data out there, as it will .  Soon we'll be able to compare not just meaningful users and their EHR systems, but also the quality results they'll be able to get from the use of them.  That should be an interesting mashup.  Hey ONC! Are you listening?

A lot of measures are going to be eliminated, either because they are topped out (hospitals are doing so well its not worth measuring any more), duplicative, or cost too much to produce for value received or ...  There's are lists of the measures that CMS is proposing to remove in the rule.  While everyone is happy about measures being removed, just remember that also means that there are fewer choices to succeed with...

Promoting Interoperability Programs

Why did they change the name?  Well, they remind us in the rule that the EHR Incentive part of the program is about over for anyone participating (we're now in the penalty stage).  So that part makes sense.  One significant change is that the singular program became the plural programs. 

They are planning to require 2015 Certified EHRs for these programs because, in part, ONC has confirmed that at least 66 percent of eligible clinicians and 90 percent of eligible hospitals and CAHs have 2015 Edition available (see the link above at meaningful users and their EHR systems).  Also, the evaluation period is a minimum of any continuous 90-day period within each of the calendar years 2019 and 2020, as you all probably hoped and expect.  The rationale for this change was that health care providers may need extra time to fully implement and test workflows with the 2015 Edition of CEHRT.

Miscellaneous

Security Risk analysis is simply required, you don't get any extra points for doing what you are required by law and regulation to already do.

For ONC and CMS, it's pretty routine to ensure that whatever the latest and greatest healthcare crisis is, there needs to be something to in the regulations about it.  So new measures have been added to address opioid abuse, including Queries of prescription drug monitoring programs (PDMPs), and verification of opioid treament.

Closing the referral loop also gets some love with a new quality measure supporting that buzz phrase.

A number of exclusions (loopholes) are being removed, few are using them or they aren't warranted according to CMS.

Puerto Rico hospitals become eligible for the program, something that wasn't available to them previously.

Some capabilities will no longer be required to be used (though they will still exist in the certification requirement): Secure Messaging, View/Download/Transmit.

So, there you have it, my summary of about 10% of the rule.

For what it's worth

The section on Future Directions is worth reading for those of you who are worried about what is next, but that is merely non-binding self-promotion for the most part.  The really important part related to that is where CMS asks you to tell them where they should go.














Thursday, April 19, 2018

Additional SMART on FHIR Authorizations


I sent something similar to this to the HL7 Security workgroup today:

This strikes me as an interesting use case for SMART or similar OAuth2 based authentication.

The use case is thus:

Through an API, a user wants to include certain kind of information into the record.  A given example might be an uncoded medication.  The provider organization wants to ensure that any uncoded medications have a SEPARATE provider authorization before entry, specific to the API call that attempted the request.  For example, in a system that I am familiar with, if using the EHR client, when an uncoded medication is attempted to be entered, the provider is requested to verify their intent (via a button click).  In another case, to “sign” a document, it requires them to re-enter their password information.

An authorization protocol that might work with a server and 3rd party applications wishing to adhere to these rules would be one in which:

API call which failed due to these sorts of rules would generate a user override authorization request token and pass it back to the caller in an extension to the OperationOutcome resource.  Such a token may also need to be communicated in an out-of-band manner to an authorization endpoint (but could also just be a signed JWT).  The code associated with the OperationOutcome might indicate that additional user authorization is required.

The application would call the authorization server with this token to request user authorization to complete the API request via a web-based UI that used redirection much in the same way that SMART on FHIR does today.  It might also include its current user's access token, although that seems unnecessary since the token supplied by the application would seem to be enough validation of the user.

The authorization server would interact with the user to request their authorization to complete the request.  On receipt of the user authorization (either by clicking yes, or reauthenticating, or whatever), it would provide an override token to the calling application.  Such token could then be passed in to a repeat of the API call.  The API call would find the same problem, but having been given the override token, would be able to accept the request.

Such a protocol might also include in the given override request token a signal with regard to the degree of user reauthentication/authorization necessary.  For example, many systems that have a physician “sign” a document, require the physician to reauthenticate to the application, whereas other override responses are simply a button click (e.g., uncoded medication).

An application that is aware of these special cases might also want to have a way to short circuit the API failure part of the request loop, and preemptively obtain provider authorization.



Your thoughts?  Is this a reasonable thing to consider?



   Keith

Monday, April 16, 2018

If I'm baffled by this, how can patients possibly manage?

I have passwords I use about once a quarter for five different health accounts so that I can track what is going on with myself and my family.  Two Patient portals, one mail-order prescription company, my insurer, my HSA and God alone only knows what else.  I sit through five different sets of menu options whenever I have to call these people one the phone.

Sometimes I can access my children's data, sometimes I cannot.  Usually the latter unless my children have remembered to allow me access (which they willingly do), because one is an adult and the other is over 13.  I could probably have any person in my house claim to be them when I call one of these organizations AND FINALLY GET to a human, but always make sure to have them available.

In trying to follow up on a refill where I know the drug, the dose, the quantity, the ordering provider, and even the providers order number, I cannot get access to whether an order has been placed.  My children's healthcare providers are almost as baffled as I am by the systems they must use.

If trained and aware people are challenged by this system, how could the average patient cope?  How would a disabled patient have any ****ing chance of working through this?  This ISN'T about technology.  Technology could solve these problems.  It's about interpretations of policy that make it difficult for anyone to do anything even remotely difficult.  It's about appropriate use of technology that makes my life better, not yours.  It's NOT about paying attention to your stuff first instead of mine.

Does anyone EVER LIVE test tree menus on automated call systems?  I've had to enter account number and zip code twice, enter my phone number (even though I'm not blocking them from receiving that information), and then when I finally get to a human, repeat the same information, and then be routed to the right person to help me and repeat it AGAIN. Then I have to go through a standard set of three questions they ask on every call that have NOTHING to do with the reason I'm calling.  Yes, this is my address, no it has not changed, and yes you have my current information.  Where is the patient service here?  It's not in my immediate service to make sure you have up to date information, that is NOT my #1 reason for calling you today.  Can we solve my problem first before we make sure that everything else is ok?

My God, today, when I'm home sick and still have to deal with their mess, my patience for how patients are treated is 0, and I just want to )_*(&*(&%*!~ scream.

Payers and providers: here are some things that you can do to fix your systems:

  1. Make your call 911 message as short and direct as possible.  I understand and appreciate why it is there, but I don't call you when I should call 911, and having to wait for you to draw it out drives me crazy.
  2. Let me hit the button I know I need before you finish your first message.  It should be: If you are a current patient/member please press 1.  Get me in the door quickly to solving MY problem.
  3. Solve my problem first, then yours (e.g., has my contact info changed), and NOT the other way around.
  4. If I ask for an operator or hit 0, take me to an operator, not another menu.
  5. Yes, I know you have an online system, IT DIDN'T HELP ME, which is why I'm calling you.  Don't frustrate me further with that information until I'm on the path to queue I need, or at least let me get there quickly.  Making me wait through that message doesn't solve my problem.
  6. Make it easy for me and my family to allow me (or some other individual) to act on their behalf.
  7. Thank you for trying to protect my privacy.  Stop gloating about the great job you are doing and help me solve my problem.  Another message I want to hear AFTER I'm in the right queue and have to wait for the next available operator.


   Keith

I swear I want one of those answering machines I can program myself, just to make you feel my pain when you call me.

Thank you for calling the Boone residence.  If you are a family friend you have called the wrong unpublished number.  Please hang up and call the other number we gave you, or text the person you wish to reach.  If you are a member of the police or fire or other public safety department, please press 1.  If you are a vendor with whom we have an account please press 2. If you are a vendor or charitable society that we have not contacted, please hang up and do not call again.  This phone is on a do not call list, and repeated attempts to call this number will result in criminal prosecution. 3. If you are a healthcare provider, a health insurer, a pharmacy or PBM program with whom a member of this household has an affiliation please press 8 now.  *8*  If you need immediate ...

Thank you for contact the Boone family.  If you are a healthcare provider or pharmacy please press 1.  If you are a payer or PBM please ... *1*

Please enter the extension of the person you wish to reach.  If you would like a dial by name directory, please press 1.  Or press 0 for immediate... *0*

Then we'll ask for you name, phone number and 10 digit NPI number, and if you don't have it immediately, we'll wait a few minutes and then ask you to hang up and call us back when you have it.

How will that work for you?



And to follow up, today, I had to call my homeowners.  They knew who I was BEFORE I told them.  Their claims specialist already had my policy available because they KNEW who was calling them.  And then contacts a water damage specialist for me who called me withing 15 minutes for a same day appointment.  Thank you Liberty Mutual for getting it COMPLETELY right.

Sunday, April 8, 2018

In which I finally figure out dates and timestamps in FHIR

The key is in the last sentence of my last post (half the reason I do these things is to think out loud).  Two DIFFERENT things.  A timestamp is a date and a timestamp.  A date is just a date.  When you compare a date to a timestamp, you are comparing ONLY the date aspect.  When comparing times, you are getting into the timestamp aspect.

User expectations met, problem resolved.  I may have to think about saving the date only representation of a timestamp for efficiency reasons.

    Keith

Right, Wrong and Right again about TimeZones in FHIR

So I am back to dates again.  I forgot to check in the change for setting the servers default time zone, and almost all my unit tests failed on a build machine located outside of my home zone.  Dang it.  I KNEW that would happen.

So I made the fix (following the advice of reasonably smart people), and set the server's default time zone to UTC.  And my date tests are still failing.

Here's the failure:  There's a record that updated on 2017-06-26T17:51:45.233-07:00 (the source of that record is on the left coast, it doesn't matter where the server is).

And I query for it by asking for records updated on that date using _lastUpdated=2017-06-26.

What should happen?

Well, everyone I asked who answered without much thought say that these should match. But they don't.

Because 2017-06-26T17:51:45.233-07:00 is 2017-06-27T00:51:45.233Z in UTC.  And clearly 2017-06-26 is not the same date once you transform the timestamp to UTC, and therefore _lastUpdated=2017-06-26 fails.

The principle of least surprise should apply, and if we use a fixed time zone for the server, it surely doesn't.  Especially a case where the server time zone isn't one my users care about.

So, the conclusion I've come to is, when comparing two dates:

IF both specify precision, the comparison proceeds based on the time as reflected by each date, as it was specified.  There's no problem here.  If neither specifies a time zone, any time zone will do, as long as it is the same for both.

Here's the tricky bit: if A does not specify a precision but B does, the comparison should be based on a common time frame, either A specified a TimeZone and B didn't, or A didn't and B did.  In the presence of a time zone in A or B but NOT both, they should be compared using the same zone.  Otherwise, someone is going to get an unexpected result.

It's that odd duck case where the user asked for a particular date, the server has a specific date and time zone specified for the date (which may be different from where the server itself is located), and boom.

Otherwise, imagine what could happen.  Any test without a time zone is by necessity, imprecise.  I think it's better to specify what should happen in these cases quite specifically, so that time based comparisons don't surprise anyone.

Date has a legal function, time stamps a technical one.  Comparing a DateTime might be used for either case.  So, in my view, even though it seems weird, one has to consider that a DateTime comparison WILL behave differently when using 2017-06-27T00:00+00:00 as compared to 2017-06-27.  The questions are different.  The first is about time, the second about a date, and the two are DIFFERENT but related things.

Ah well.  Another day goes by.

     Keith

P.S. A similar problem will show up when comparing durations. Did it happen in the last two days or in the last 48 hours are two DIFFERENT questions, just as when I speak to my colleagues in India yesterday, today and tomorrow mean different things to each of us, depending on where we are in the world.  Let's not even talk about business days ...

Friday, April 6, 2018

The FHIRWalker Interface

The DOM has the TreeWalker interface, I would suggest that FHIR would benefit from a FhirWalker interface which would allow a resource, datatype or component to be walked in a traversal and processed in certain ways.  Definition of such an interface would benefit many.  Already such interfaces about in implementation code, e.g., in HAPI there are multiple parsers and readers that do the very thing that my FhirWalker interface would support.

Two such walkers would be valuable, one which walked a structure definition for a prospective resource, and the other which walked an actual resource.

Such walkers could be used for reporting, query implementation, et cetera.

I've personally written three, four, (I've now lost count) of these for various purposes.  I got fed up with writing one more and wrote a Walker class for myself.  It looks something like this (though I must admit to some artistic license in the names of things.

interface FhirWalker() {

   // Step describes the interface of the methods that can be
   // performed with the Victim of the FhirWalk.  It's not really
   // used in any way by walk or walkBackwards, but might find 
   // some use in implementations.
   interface Step implements BiFunction<String, Any, Boolean>;

   // Walk defines the interface for a traversal. Like 
   interface Walk implements BiConsumer<Any, Victim>;

   interface Victim {
       // tremble is called before walking on any coal.
       // if tremble returns true, the processor chickened out.
       boolean tremble(String path, Any coal) throws FhirWalkerTrippedException;

       // stumble is called on anything that caused a problem.
       // think of it an an exception handler.  If it returns
       // true, the victim recovered.  Otherwise, the victim 
       // fell down and help needs to be called (an exception thrown)
       // immediately.
       boolean stumble(String path, Any coal) throws FhirWalkerTrippedException;

       // burned is called after walking on a coal.
       boolean burned(String path, Any coal) throws FhirWalkerTrippedException;
   }

   public class FhirWalkerTrippedException {
       public FhirWalkerTrippedException(
           String exclamation, Any coalStumbledUpon, Throwable excuse
       );
   }

   // Walk the FHIR tree in order
   public void walk(Any startingCoal, Victim victim) 
      throws FhirWalkerTrippedException;

   // Walk the FHIR tree in reverse order
   public void walkBackwards(Any startingCoal, Victim victim)
      throws FhirWalkerTrippedException;

   public void walkCanonically(Any startingCoal, Victim victim)
      throws FhirWalkerTrippedException;
}


The walk() method implements a NLRN traversal, calling tremble before processing a node, then processing the children left to right, then calling burned after processing the children.  The walkBackwards() method implements an NRLN traversal, calling tremble first, and burned last. 

Tremble and burned have the same signature even though the return on burned is ignored (once burned it twice shy?)  The reason for that is so that a function used for burned in one place can be
used for tremble in a different traversal.

For what it is worth, something implementing the FhirWalker interface need not traverse an entire tree of a FHIR Resource.  It could implement a traversal of selected subnodes.  For example, a DataTypeWalker might only call tremble and burned on FHIR Data types found, a PrimitiveWalker only on primitives.  A whole host of walkers could be created with great benefit.

Somewhere in the back of my head is a BlindfoldedWalker but I don't know where that's going.

Anyway, enough amusement for the day.  I have my own walker now, time to go for a stroll.

   Keith