Skip to content

[Suggestion] Create a tutorial on how to work with profiles extending the available classes. #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jessicamrbr opened this issue Jan 24, 2024 · 15 comments

Comments

@jessicamrbr
Copy link

It may be interesting to create a tutorial showing how to extend the classes to apply created profiles or take advantage of the use of Basic for resources not yet canonically implemented.

What do you think?

@Dokotela
Copy link
Contributor

100% love it. I'd have to think about exactly how to do it. Have you already been trying? I'd be happy to add to whatever you've done so far. At some point I'd also like to be able to implement IGs, but that's an even bigger step. I have a validation repo that mostly works, but not completely, but I think could be helpful with the profiling.

@jessicamrbr
Copy link
Author

It's great that you liked the idea ☺️. Also thinking about how to do this in the best way. Freeezed makes it difficult to work well with native Dart extensions. I tried a decorator approach.

class NewResource implements Basic {
  late final Basic _basic;

  NewResource({
    // ---------- Default Basic Properties -------------------
    R4ResourceType resourceType = R4ResourceType.Basic,
   ...
   // ---------- Custom Properties -------------------
   FhirCode? newProperty,
   ...
  }) {
    _basic = Basic(
      resourceType: resourceType,
      ...
    );

    if(newProperty != null) {
      addExtensionNewProporty(newProperty);
    }
  }

...
  @override
  Reference? get author => _basic.author;
...
}

In the application's local cache, I validate against the entity's own methods in Dart.

When uploading to the server, it is valid in Node.JS against the StructureDefinition persisted in the database.

@Dokotela
Copy link
Contributor

I always find having an example helpful for things like these. Do you have a specific profile in mind we could work with?

Another question I had was do you think this should be something that has to be usable by any profile on the fly, or do you think it could be pregenerated? It's probably easier to set up a code generator, give it a profile, and then have it generate a class, methods, functions, etc. But that does make it less flexible, and you'd need to know your profiles ahead of time.

@jessicamrbr
Copy link
Author

I can try to bring a real example that I am acting on.

The R4/List resource allows healthcare professionals to group resources for a specific topic.

In my use case, professionals would like to have List models that served as a guide to create lists between each patient and professional.

Assuming that the client wants all professionals in a clinic to create lists of the most critical medications that are being monitored with their patients.

In this situation I am creating a ListDefinition resource through a set of extensions on the basic resource.


Regarding the solution approach, I believe we can list positive and negative points, perhaps a specific discussion about it.

Using a Fhir Profile in a .json file to generate the classes can be an advantage considering that the same file can be used in other languages and tools. A negative point may be the flexibility of having to run the constructor again for each change.

It may be that some dynamic generation approach would also be interesting from the point of view of flexibility and centralizing the .json on the server. But this can make debugging very difficult and in general it is difficult to see the context of success working with "reflection" in Dart.

For me, at first I found it interesting to build the class by hand. because it made it easier to organize my domain layer in the application and debug, despite looking at the application and the backend twice.

@Dokotela
Copy link
Contributor

Do you mean dart extensions or fhir extensions? Because I think the basic fhir list resource would already support the list of medications that you're describing.

@Dokotela
Copy link
Contributor

I agree about the reflection. Although I wonder if it would be possible to work with the json directly, and then use the class to ingest it after certain constraints were put on it.

@jessicamrbr
Copy link
Author

Do you mean dart extensions or fhir extensions? Because I think the basic fhir list resource would already support the list of medications that you're describing.

For the use case I described:

  • FHIR ListDefinition based on Basic with extensions:
{
  "resourceType": "Basic",
  "code": {"coding": [{
      "system": "http://.../r4/CodeSystem/basic-resource-type",
      "code": "SettingsProfileListDefinition"
  }]},
  "author": {"reference" : "Practitioner/123"},
  "extension": [
      {
        "url": "http://.../r4/StructureDefinition/Basic--SettingsProfileListDefinition-name",
        "valueString": "Monitored medications"
      },
      {
        "url": "http://.../r4/StructureDefinition/Basic--SettingsProfileListDefinition-status",
        "valueCode": "active"
      }
  ]
}
  • Based on the previous resource, I associate a list with all of the professional's patients:
{
  "resourceType": "List",
  "status": "current",
  "mode": "working",
  "title": "Monitored medications",
  "subject": {
    "reference": "Patient/example"
  },
  "source": {
    "reference": "Practitioner/123"
  },
  "entry": [
    {
      "item": {
        "reference": "MedicationStatement/345"
      }
    },
    {
      "item": {
        "reference": "MedicationStatement/567"
      }
    }
  ]

@Dokotela
Copy link
Contributor

I don't think I'm clear on the benefit of using an Extension in this case. If the List Resource already has all of the information that you need, what is the benefit of creating new extensions?

@Dokotela
Copy link
Contributor

I'm also happy to find some time and setup a meeting (I feel like I'm missing something).

@jessicamrbr
Copy link
Author

I don't think I'm clear on the benefit of using an Extension in this case. If the List Resource already has all of the information that you need, what is the benefit of creating new extensions?

"SettingsProfileListDefinition" is used to create a list of lists that practitioners must have for each patient.

ListDefinition (Based on Basic): eea0a229-0869-4326-867b-541ab8447b72
-- For Practitioner: aacfce52-d9ed-4e4c-8917-92de92e77f89

will generate:

List: f28b8156-659c-4510-ad27-253a0d27fac1
-- For Practitioner: aacfce52-d9ed-4e4c-8917-92de92e77f89
-- For Patient: 5ffb49b7-7d65-4bcb-8472-e446b3ff1c10
-- Based on: eea0a229-0869-4326-867b-541ab8447b72

List: 00befcee-0d8e-4242-acff-a42c22b4305d
-- For Practitioner: aacfce52-d9ed-4e4c-8917-92de92e77f89
-- For Patient: 54ddf295-2b4b-4b0f-b6ce-39764974dc88
-- Based on: eea0a229-0869-4326-867b-541ab8447b72

...

@Dokotela
Copy link
Contributor

Ok, I think I'm starting to see. My next question then is why an extension, and not a profile or IG. If I understand what you're doing, you're not actually extending a Resource, as the List Resource already has all of the information included that you want in it (namely, an ability to make a List of resources, in this case a List of Lists). What you're actually doing is constraining a List, to say that instead of allowing it to have ANY other resources, it can only have List resources. And then you're going to fill it with List resources that can only contain a list of Medications. At least for me, that idea fits better with having one (or maybe two? - I'd ask on Zulip about it) List Profiles inside of an Implementation Guide around medication lists. What do you think?

@jessicamrbr
Copy link
Author

List of lists can also work well for this use case.

I can try to bring another scenario. Practitioners will create health records through compositions. The platform for creating health records makes it possible to use snippets templates (similar to .phrases from EPIC). An extended Basic resource could store each practitioner's snippet for query in the software and injection into the composition.

{
  "resourceType": "Basic",
  "code": {"coding": [{
      "system": "http://.../r4/CodeSystem/basic-resource-type",
      "code": "SettingsProfileSnippetDefinition"
  }]},
  "author": {"reference" : "Practitioner/123"},
  "extension": [
      {
        "url": "http://.../r4/StructureDefinition/Basic--SettingsProfileSnippetDefinition-name",
        "valueString": "Abdominal Pain (unspecified)"
      },
      {
        "url": "http://.../r4/StructureDefinition/Basic--SettingsProfileSnippetDefinition-status",
        "valueCode": "active"
      },
      {
        "url": "http://.../r4/StructureDefinition/Basic--SettingsProfileSnippetDefinition-shortcut",
        "valueString": ".ap"
      },
      {
        "url": "http://.../r4/StructureDefinition/Basic--SettingsProfileSnippetDefinition-content",
        "valueString": "Patient reports new abdominal pain characterized by..."
      }
  ]
}

The system could query for typed shortcut and replace (expand text) for the content, then inject it into the composition.

This could be a second hypothetical use case for basic's extension mechanism.

And generalizing outside of use cases, it might be interesting to think of a way to work with:

  • Extensions
  • Profile changes
  • Type limitations
  • ...

Fhir mechanisms, through this library for Dart.

@Dokotela
Copy link
Contributor

That one is interesting. You could have different codes for templates too. So it wouldn't just be for text, but it could be for something like a standard physical exam. Where when you use that shortcut, it prints out a typical physical exam on your note, but it also records the corresponding FHIR observations.

@Dokotela
Copy link
Contributor

Have you brought this idea up on Zulip to get feedback about the best way to format this?

@jessicamrbr
Copy link
Author

Have you brought this idea up on Zulip to get feedback about the best way to format this?

I didn't interact about these topics on Zulip.

Generically about the expansion of basic, I don't see much doubt about it, or the path of the subject beyond what is already documented.

Regarding the use case of lists, I believe that the point you brought up makes a lot of sense. And maybe just using a list, without a list of lists, will solve the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants