Offline caching of patient identifiers

Hi @mksd , @manuel , anyone else interested in the topic—

There’s a bug in the idgen REST API which makes it unable to represent an IdentifierPool.

When I mentioned this to @mogoodrich and @mseaton , they raised concern about patient identifiers from a pool being assigned offline. @mseaton , hope you don’t mind my pasting your comment here, to launch the discussion:

That is potentially concerning / problematic as we don’t want every client to consume identifiers from the pool/source frequently that are never used.

So it seems like there’s some design needed around how we’re assigning identifiers offline.

I don’t have an opinion, but I expect all of you do. Also maybe @ibacher and @jdick .

The scenario that needs to be avoided at all costs is accidentally assigning the same identifier to two or more patients, which can lead to confusion and patient harm.

This is why any pool of patient identifiers must always be generated & distributed from a single authority to ensure they can’t possibly be used twice.

Version 4 UUIDs use a gigantic space of randomness to allow id generation without a central authority; however, UUIDs aren’t viable for medical record numbers (MRNs) that need to be read & transcribed by humans.

For offline MRN assignment, you have to distribute sets of identifiers to each device with the contract that each device must ensure any identifier in the pool can only be used once and favors discarding identifiers unused if there is any doubt.

If you don’t want to “waste” identifiers (e.g., discarding large sets of identifiers), then you can use temporary identifiers: either do the same thing, but use a pool of temporary identifiers that you don’t care about wasting OR create device-specific identifiers that can never be repeated. The temporary identifier can be used until the device is online or the patient can be properly registered with a permanent MRN.

FWIW, I wouldn’t consider a patient officially registered until their offline or remote registration is received by the central master patient index (i.e., consider any registration incomplete until it has been received by the central authority).

I agree that an identifier from the pool should not be considered in use until the backend knows that for a fact.

“Lending” segments of the pool to a device (until that device comes back online with the outcome of what was done with the segment, i.e. which identifiers have actually been assigned and which ones are still free) would have to be modelled appropriately, and that sounds like a complicated thing to do.

Looks like a device should assign temporary, device-specific, identifiers before translating them to the actual ones from the online pool when the device syncs.

Mainly my reason for raising this was to make sure that we are being thoughtful about this with respect to how the frontend is consuming identifiers.

I don’t think there is any problem with having a client request a batch of identifiers from an authority to use offline, and we support this in idgen already - there are API methods, rest calls, and old-school administration pages that allow one to generate a batch of identifiers. Once these are generated, they are considered consumed by the source and a well-defined source will never generate or issue these again. It’s up to the consumer to ensure they are used efficiently.

My main concern is that those who are building the consuming application here (i.e. the registration module of O3) are being mindful that some identifier sources do not have an infinite supply of identifiers to issue, and that they should not “over-consume” if not needed.

This likely means allowing configuration around how many identifiers should be present in a pool on a given device, not discarding unused identifiers on a device unnecessarily or prematurely, and potentially configuring or detecting device-specific needs. For example, as a default setting, we might say that requesting a batch of identifiers to use in offline registration is something that a particular user on a particular device needs to request, or we might say that we should generate and issue a small offline batch only in response to particular events or routes in the registration module. What I’d like to avoid is having us ship an ESM that, by default, will consume lots of identifiers behind the scenes on every device regardless of whether or not those devices will ever be used offline or for registration.


1 Like

I think, as always, the best solution depends on the anticipated workflow.

One potential good practice around this might be to create an entirely new identifier pool just for offline ID usage, similar to the “pool of temporary identifiers” Burke described, but more durable. Basically, what I’m imagining in this scenario is the device is allocated a set of “offline” identifiers that are used with the patient record and stored long-term as part of the patient record (i.e., they are real identifiers), even though when the patient is synched with the central instance, a new “official” MRN is issued. Essentially, all patients registered this way would end up with two “MRNs” an “offline” MRN used before the record has been synched with the EHR and an “official” MRN after this has been done.

The simplest scenario I can imagine is one where the identifier issued at the time a patient is registered offline is stored on the device and does not need to be referenced anywhere else. In this case, we can use a genuinely “temporary” id. Something like a 6 character nanoid is probably sufficient. But the key to this is that the identifier is truly temporary and only used in the context of the device while offline, i.e., it should probably not be displayed to the user.

@mseaton summed up my thoughts very well…

Do we know what the current Registration App in 3.0 is doing?

Take care, Mark

Tangential to the discussion around the pros and cons of generating identifiers for offline use on a particular device, is the question of why this is happening by default in the first place, and whether or not we can agree to make this configurable.

I presume that anyone who wants to use the registration ESM has some configuration that they need to do to establish which questions they actually want to ask at registration. Yes, certainly an out-of-the-box, no-configuration-needed option is something to shoot for. But configuring what questions to ask and how they are asked is definitely a need. How is that currently being handled in the registration esm?

Assuming there is such a configuration, I’d ask that we make offline identifier generation something that can be controlled either as a runtime configuration or at compile-time based on identifier type and autogeneration option, and not always assumed to be desireable for all identifier types that are marked as only-autogenerated in the idgen tables.

@bistenes and @jdick ?

Yes, the registration app is configurable. Adding configuration is easy, but the configuration API should be thought through carefully.

So the idea is that an implementation might want to assign some autogenerated identifiers, but not others, to a new patient, if that patient is registered offline?

Or do we think that identifiers that come from a pool should just not be assigned until the client comes back online, at which point they are assigned for every patient that was created offline?

Do we believe that there might be some need for a client to assign identifiers from a pool while clients are offline?

I like @ibacher 's solution, and suspect that that would be adequate for most use cases. Though I’m not sure why the patient even needs a temporary identifier.

This is precisely what I meant by using temporary identifiers. The same approach can be used in emergency departments when there isn’t time or adequate information is not yet available for routine registration. Since these “temporary” identifiers can end up on paperwork, they remain on the patient as a secondary identifier.

Another option to consider would be to support clients returning unused identifiers to the pool. While you would always want to discard an identifier that might have possibly been used, if a client gets 100 identifiers from the pool and only assigns 70 while offline, it could conceivably safely return 30 to the pool.