Module-defined (Location) Tags

Following up from discussion on TRUNK-4722

@burke (moving this to talk, and simultaneously testing whether the workflow of reply-to-JIRA-notification-but-change-address-to-dev-list works)

This is a good thought example…

Here are some “magic” location tags in the reference application:

  • Login Location => can be selected from the login screen
  • Visit Location => allowed to be used as visit.location
  • Admission Location => can be the first assigned location at an admission
  • Transfer Location => an inpatient can be transferred to this location

PIH introduces a bunch of additional ones in its Core EMR: Vitals Location, Consult Note Location, Dispensing Location, etc. The Ebola module introduces some additional ones: Ebola Suspect Ward, Ebola Confirmed Ward, Ebola Recovery Ward, Inpatient Bed. (The PIH and Ebola examples are all “implementation-specific” but you could easily imagine generic modules providing similar functionality.)

I think it’s important for a module to be able to create a “magic” location tag, and own the tag’s definition and meaning. In fact I think the primary use case for location tags should be to have code that knows how to behave differently, given tags. Letting implementers create a folksonomy of tags through the UI adds much less value. (As far as I know, the place these are at all useful is where HTML Form Entry lets you do <encounterLocation tags="Admission Location" />.)

So, I propose that we add a way for code to lock a Location Tag such that a user can’t edit or delete it through the UI. (And in general I think this should be the pattern for all our tag types.)

1 Like


It sounds like location tags are being used as attributes (i.e., metadata with specific expections & rules around it) or module configuration settings rather than tags (i.e., tokens attached to a resource) and, as a result, imposing special constraints onto tags. It’s proably a side effect of location tags being created as resources/metdata instead of tokens.

Why can’t the code be written to not break the application if nothing is tagged? Locking a tag so it can’t be edited still doesn’t prevent an admin from removing the tag from every location.

Location Tags are being used to mark (or “tag” :slight_smile: ) locations so that code can act based on the presence of those tags on certain locations.

Let me focus on my main point…the following is really really useful and is being used a lot:

  1. module code creates a tag
  2. admin configures the implementation by applying this tag to certain locations
  3. module code checks which locations have a given tag before doing something

Whereas I have literally never seen the “folksonomy” use case for LocationTag used, in all of my OpenMRS experience.

We should evolve the platform to make it easy for devs to do the things they frequently want to do in real life.

If I’m reading you right, you’re saying that these examples should be boolean attributes instead of tags, e.g. instead of a LocationTag called “Admission Location” we’d have a LocationAttributeType with boolean datatype, and instead of having code call getLocationsHavingTag(admissionLocation) it would call getLocationsHavingAttributeValue(admissionLocation, true).

This could be made to work, though the API for working with attributes is more awkward (because of the CustomDatatype approach), so it would be more annoying for developers. And I don’t personally see the point of making a bunch of code get rewritten in a more awkward way to preserve a use case for LocationTag that has never been used.

Note that in this scenario I would still want to introduce the idea of locking things, just that now we’d want a module to be able to lock/own a LocationAttributeType.

(Alternately you’re saying these are “module configuration” e.g. you could have a global property that is a comma-separated list of location UUIDs, but I’m going to discard this option out of hand.)

About breaking/not breaking the application:

I’m mainly saying that module code should not have to be written to assume that the admin might sneak in and deleted the row from the location_tag table. It would be really annoying to have to code like this, to no purpose! In a handful of cases (e.g. Login Location) the whole application should not break if no location is tagged, because otherwise the admin may be unable to even fix the misconfiguration. But more often it’s better practice to fail loudly and quickly rather than having incorrect behavior if the system is misconfigured. E.g. if the admin removes the Admission Location tag from all locations, I would rather have the admission note show an empty dropdown and break, rather than letting you admit patients to a non-admission location like the pharmacy.)