GSoC'20: Add support for FHIR Narratives

Seems like a sensible place to keep them to me.

1 Like

@ibacher One thing about the new approach for FM2-193. How are we going to get the resource name at runtime if we put this into the initialize method of FhirRestServlet? I mean, the resource name is needed to check for presence of Default Narrative provided by HAPI right?

That’s why I was suggesting just loading the default HAPI narrative properties and our own custom properties in a single CustomThymeleafNarrativeGenerator, because that way, we can let the narrative generator worry about where the narrative is defined and we don’t need to track that kind of thing (it’s a moving target anyways, so needing to maintain that list would quickly become a nightmare).

1 Like

Yeah I just saw it on GitHub. Thanks! :slight_smile: Even I was gonna ask about just using CustomThymeleafNarrativeGenerator.

So for FM2-193, maybe I’ll just set the default HAPI narrative properties in the properties file, after which I’ll be adding OpenMRS narrative properties to it in further subtasks.

I’ve created a draft PR at https://github.com/openmrs/openmrs-module-fhir2/pull/198 so that it’d be easier to track the addition of narrative templates. PTAL!

cc @ibacher @herbert24 @suthagar23

1 Like

great we got to see the pr @iamsr

1 Like

I see that this build is failing due to difference in timezone of the expected narrative and the one which is being generated.

It’s happening in the dispenseRequest.validityPeriod element of MedicationRequest which is of type Period. The thing is that its narrative is provided by HAPI itself. The diff is as follows:

>>>
Thu Jan 15 00:00:00 IST 2015 - Fri Jan 15 00:00:00 IST
----
Thu Jan 15 00:00:00 UTC 2015 - Fri Jan 15 00:00:00 UTC
<<<

Any suggestions for fixing it? One approach might be to define a new narrative for Period, but then we won’t be using the HAPI version of it.

cc: @ibacher @herbert24 @suthagar23

1 Like

Just change the timezone values in the expected result from IST to UTC. This will probably work consistently.

1 Like

I guess it is taking the local timezone, because making manual changes in timezone (IST to UTC) in the expected narrative makes the tests fail for me locally.

@ibacher Thanks a lot for this suggestion! It works now.

For the Location resource, all the examples here just mention a brief location summary (kind of a general address) in the narratives, even if the resource object carries more detailed information with it. This example displayed the maximum info in its narrative, among the other examples, which is still a subset of all the info carried by the object.

So how should we create our narrative for the Location resource? Should we mention each element in the narrative? Or should we rather keep it minimal, the way it is in the examples?

cc: @ibacher @herbert24 @suthagar23

This PR is now ready for review. PTAL!

cc @ibacher @herbert24 @suthagar23

Hi there. Please find the draft PR for narratives of resources Encounter, Observation and Location here. It also contains the commit associated with PR#198, which should be merged before this PR. Changes specific to this PR are in this commit.

For now, I’ve kept the narrative of Location Resource minimal (referring to this post).

cc: @ibacher @herbert24 @suthagar23

I guess I’ll be adding the default narrative for PractionerRole resource too, considering the scope for its support in the future.

Please find the draft PR for narratives of resources Person, Practitioner and ServiceRequest here. It also contains the commits related to PR#198 and PR#207. Please refer to this commit for the changes specifically intended for this PR.

cc: @ibacher @herbert24 @suthagar23

Please find the link to PR for narratives of resources Task, RelatedPerson and PractitionerRole below.

cc @ibacher @herbert24 @suthagar23

1 Like

PR for FM2-249:

cc @ibacher @herbert24 @suthagar23

1 Like

looked through this and also requested other people to look through added a comment on the pr thanks

1 Like

Now that all the tasks for Coding Phase-1 have been wrapped up with this PR, these are the initial objectives for Coding Phase-2.

Overall Objective: Developing a framework to support user defined custom narratives.

Initial Approach:

  • The framework would be implemented as a class in FHIR module’s OMOD.
  • There would be a separate custom narratives properties file for the custom narratives template assignment.
  • The framework would handle setting up of the custom narrative template for the resource in the custom narratives properties file, using helper methods.
  • There would be a check for custom narratives in the initialize() method of FhirRestServlet and the properties file will be provided to the narrative generator accordingly.
  • Apart from this, there will be tests to check for errors in the user defined templates.

Looking forward to feedback/suggestions.

cc: @ibacher @herbert24 @suthagar23

Hi! I’ve come up with something like this for updating the customNarratives.properties file. It gives a rough idea of the approach I’m following:

public void addToPropertiesFile(String resourceName, String templateLocation) throws IOException {
	Properties customProperties = new Properties();
	try {
		customProperties.load(new FileInputStream(getCustomNarrativesPropFile()));
	}
	finally {
		Map<String, String> propertiesMap = getProperties(resourceName, templateLocation);
		propertiesMap.forEach(customProperties::put);
		customProperties.store(new FileOutputStream(getCustomNarrativesPropFile()), null);
	}
}

protected File getCustomNarrativesPropFile() {
	return new File(OpenmrsUtil.getDirectoryInApplicationDataDirectory(FhirConstants.CUSTOM_NARRATIVES_FOLDER_NAME),
	        FhirConstants.CUSTOM_NARRATIVES_PROPERTY_FILE_NAME);
}
	
protected Map<String, String> getProperties(String resourceClass, String templateResourceClasspath {
	Map<String, String> propertiesMap = new HashMap<String, String>();
	propertiesMap.put(String.join(".", resourceClass.toLowerCase(), "resourceType"), resourceClass);
	propertiesMap.put(String.join(".", resourceClass.toLowerCase(), "narrative"), templateResourceClasspath);
	return propertiesMap;
}
  • If a properties file is not present, it creates one in the subdirectory customNarratives of OpenMRS Application Data Directory.
  • The addToPropertiesFile() method takes in the resource class and template location and assigns the template for the resource narrative.
  • In case there already is an entry for that resource, it will automatically update it with the new resource narrative template.
  • Also, I’m thinking of adding a method to remove the listing of a custom narrative for some resource.

Does it look fine? @ibacher @herbert24 @suthagar23

Also, since this is something that the implementer would do on choice and not every time when the FHIR module is used, should it be in a separate module?