AidboxForm BuilderSQL on FHIRCCDA -> FHIRValidator
Report 2024-09-30

FHIR Digest

A weekly summary of chat.fhir.org to help you stay up to date on important discussions in the FHIR world.

The chat discusses the intricacies of implementing Smart on FHIR, particularly around the authorization process, access controls based on authorization scopes, and security considerations regarding launch tokens in EHR applications. Participants debate the appropriate server responses for unauthorized access, the implications of user sessions in mobile applications, and potential security risks associated with launch tokens, ultimately emphasizing the importance of binding launch parameters to specific user contexts to prevent unauthorized data access.
90 comments
DC
VG
SM

Hi all! Could you help me to understand some use cases of Smart on FHIR (v1)?

I have a FHIR Server on [base-url] and an Authorization Server on [auth-server]. And a user has an access to couple of Patients resources and their clinical data (pt-1 & pt-2).

1) Let's suppose that the user provided a grant to 3rd party app within next scope 'patient/Patient.read patient/Observation.read patient/Observation.write' and patient=pt-1 in context. As a 3rd party, what responses should I expect?

GET [base-url]/Patient/pt-1
GET [base-url]/Observation?subject=pt-1
GET [base-url]/Patient/pt-1/Observation

GET [base-url]/Patient
GET [base-url]/Patient/pt-2
GET [base-url]/Observation?subject=pt-2
GET [base-url]/Observation?subject=pt-3
GET [base-url]/Observation

POST [base-url]/Observation

subject:
  reference: Patient/pt-2

I believe that the first three requests should return 200 OK + data, and the rest of them 403 Unauthorized. Right? Or it depends on something?

2) Let's say we have not Observation, but CommunicationRequest resource. Which are search parameters available for 3rd party app within patient/CommunicationRequest.read scope? subject, sender, recipient, requester?

3) I'm thinking of building a tenant-based FHIR API which uses user-id as url prefix for every request.

[base-url]/user/<user-id>/Patient/pt-1 => 200 OK
[base-url]/user/<user-id>/Patient/pt-2 => 200 OK
[base-url]/user/<user-id>/Patient/pt-3 => 404 Not Found

I would say I have a lot of logical FHIR Servers on top of physical one. In case of EHR launch I could provide different iss parameters depending on the user who launched the app, so it could help me simplify access control module.

But I can't find an answer if it's possible to make something similar in case of Standalone launch. It seems like 3rd party app should know the only base-url and use it for every user? Is it possible to subsistute [base-url] somehow while launching?

Vlad Ganshin2021-09-08T21:06:43Z

For (1): in our server they are all 200 OK, they just return only the data of pt-2, so GET [base-url]/Observation?subject=pt-2 returns an empty bundle

Michele Mottini2021-09-08T22:56:33Z

(2) Which search parameter are available is unrelated to the scopes

Michele Mottini2021-09-08T22:57:08Z

(3) Don't think that would work, clients expect a fixed URL to connect to

Michele Mottini2021-09-08T22:58:13Z

(1.1) We have the same solution for now, but I'm not sure if it's correct using Authorization header as an implicit parameter for business logic. Will my server be conformant with FHIR Specification (which is RESTful) if it provides different responses on the same url depending on Authorization header? I believe, that according to REST, the role of Access Conrol is only accept/reject requests, but not influence on the result. So, I would say that in this case our FHIR Servers are not conformant with FHIR Specification. Is it correct, or I miss something?

(1.2) And what about saving resources (POST/PUT/PATCH)? Should my FHIR Server set reference to the patient implicitly or validate and require correct reference value in the body?

(2) From the smart app developer point of view, how should I understand which endpoints (or/and search parameters) are available within a specific scope I got from user? Does specification have this answer, or I have to adopt my application to every specific FHIR Server?

(3) I feel that the specification tries to connect Smart App Developer and FHIR Server Developer and it provides a concrete authentication flow. But as a Smart App dev, once I have a token, I don't see my capability within my scopes. And as FHIR Server dev I don't see a standard way to provide such capabilities.

So, once FHIR Server provided 'patient/Patient.read patient/Observation.*' scope, does it obligated to accept requests to [base-url]/Patient/<pt-id>, [base-url]/Observation, etc?

Will my server be conformant with FHIR if I just say in documentation, that within patient/... scopes smart app should use another base-url. e.g. [base-url]/patient/<pt-id> ([base-url]/patient/«pt-id>/Patient/<pt-id>, [base-url]/patient/<pt-id>/Observation).

Vlad Ganshin2021-09-09T07:18:18Z
John Moehrke2021-09-09T12:17:37Z

policies are important. principles of REST do not override policies.

John Moehrke2021-09-09T12:18:07Z

In general with smart, it is okay for a server to reject a query prospectively/statically because of scopes. It is also okay for a server too simply redact results because of scopes. We don't have prescriptive behavior on this. The only thing it's not okay to do is return data beyond what the scopes allow.

Josh Mandel2021-09-09T12:55:33Z

The question of what endpoints are available is somewhat orthogonal to your scopes. For example, a server might advertise in its documentation or in its capability statement that it supports a "batch" endpoint; if it does, clients can call this end point with requests that are consistent with the available scopes. If it does not, clients can't.

Josh Mandel2021-09-09T12:56:40Z

I wonder SMART on FHIR based on baseUrl convention instead of more flexible HATEOAS. Why server after auth could not just return explicit baseUrl for the client with access_token ?

{
  access_token: ....
  fhirBaseUrl: ....
}
Nikolai Ryzhikov2021-09-09T13:48:54Z

Compartments like /Patient/<id>/{metadata,Observation,Encounter} look like good fit for SMART Clients and Servers.

Nikolai Ryzhikov2021-09-09T13:52:16Z

Thank you! I do missed that part in Access Denied Response Handling chapter.

Just to clarify, if I have a FHIR Server which is rich on capability, it is ok to restrict some access depending on client type, not only scopes provided to that client, isn't it?

Vlad Ganshin2021-09-09T13:52:30Z

That would work for areas like the patient compartment where fhir explicitly defines some context, but the mapping breaks down pretty quickly too. For example even with "patient" compartments, a smart app authorized to access data about a given patient might be able to see certain data outside of a compartment, such as data directly linked from or needed to interpret the data in the compartment. So passing the patient id (or fhirContext[] as array of references as proposed in SMARTv2) has been a flexible choice.

Josh Mandel2021-09-09T13:56:03Z

Michele Mottini said:

For (1): in our server they are all 200 OK, they just return only the data of pt-2, so GET [base-url]/Observation?subject=pt-2 returns an empty bundle

Should not server respond with 403 for (1)?

Nikolai Ryzhikov2021-09-09T13:56:31Z

Josh Mandel said:

That would work for areas like the patient compartment where fhir explicitly defines some context, but the mapping breaks down pretty quickly too. For example even with "patient" compartments, a smart app authorized to access data about a given patient might be able to see certain data outside of a compartment, such as data directly linked from or needed to interpret the data in the compartment. So passing the patient id (or fhirContext[] as array of references as proposed in SMARTv2) has been a flexible choice.

What is fhirContext?

Nikolai Ryzhikov2021-09-09T13:58:25Z

We are thinking about "poko yoko" for Smart on FHIR apps - i.e. implicitly inject patient id into all search and even CRUD operations.

Nikolai Ryzhikov2021-09-09T14:00:22Z

@Josh Mandel what is your opinion about such an implicit server behavior?

Nikolai Ryzhikov2021-09-09T14:01:52Z

nicola (RIO/SS): Michele Mottini said:

For (1): in our server they are all 200 OK, they just return only the data of pt-2, so GET [base-url]/Observation?subject=pt-2 returns an empty bundle
Should not server respond with 403 for (1)?

From the SMART spec perspective, both of these are OK behaviors.

Josh Mandel2021-09-09T14:44:32Z

What is fhirContext?

See FHIR-32253; this is being added to resolve SMARTv2 ballot feedback

Josh Mandel2021-09-09T14:45:07Z

nicola (RIO/SS): We are thinking about "poko yoko" for Smart on FHIR apps - i.e. implicitly inject patient id into all search and even CRUD operations.

I like this, but there are edge cases where it'll prevent access that a client should have (e.g., with patient/*.cruds access, you might still be allowed to issue a query like GET /Observation/123 where the subject of the observation is something other than the patient (say, a patient's device or location).

Josh Mandel2021-09-09T14:47:08Z

Michele Mottini said:

For (1): in our server they are all 200 OK, they just return only the data of pt-2, so GET [base-url]/Observation?subject=pt-2 returns an empty bundle

I think for (1) - 403 is more honest - otherwise, the client may be confused and interpret the empty response as a lack of data

Nikolai Ryzhikov2021-09-10T08:10:49Z

I think no error is better. Using 403 is actually _leaking_ the information that there is data that the client cannot see

Michele Mottini2021-09-10T13:43:47Z

Yep, if they're fishing for information, a 200 tells them nothing, a 403 says there's data which is a problem from a privacy point of view

David Pyke2021-09-10T13:46:35Z

AND this is why the actual value returned should be driven by POLICY. http://hl7.org/fhir/security.html#AccessDenied

John Moehrke2021-09-10T13:51:22Z

i’m reviewing smart on FHIR (EHR launch) implementation (based on oauth 2.0 authorization code flow) where the EHR launches the application calling a launch URL specified in EHR configuration. The launch url contains a launch token in the query parameter and then the application exchanges the launch token along with the client identification parameter to get an authorization code and eventually access token from the authorization server.

My concern is that an attacker can steal or copy a valid launch token which hasn’t been used before and get an authorization code from the EHR authorization server, this is because the server cannot determine if the entity redeeming the launch token is the same user for whom the token was originally generated. There is no mechanism for the server to verify the identity of the redeemer and ensure only the right user receives the authorization code. Is this a valid threat or am I missing something?

For reference, Epic’s implementation is based on SMART on FHIR, an industry standard through HL7, link- https://fhir.epic.com/Documentation?docId=oauth2&section=EmbeddedOauth2Launch

snahil2024-09-20T07:29:57Z

(deleted)

snahil2024-09-20T07:30:41Z

Don't ask the same question multiple times please?

The launch token is not a security feature, is just a way to convey context from the EHR to the app.

Michele Mottini2024-09-20T11:37:58Z

The step of the workflow after receiving the launch parameter is to authorize with the auth server. So at that point the auth server will know who the user is and can verify that the launch value they submitted was associated with them.

Stephen MacVicar2024-09-20T12:07:51Z

Are you both saying that the context communicated from EHR to the external app does NOT include the logged in user session? Meaning- the practitioner would have to enter their credentials into the browser again?

My understanding up to this point has been that the launch parameter kinda doubles as an "SSO" credential so if the EHR is a thick client and/or mobile app- the practitioners EHR session would be extended into the browser.

If I'm right about that- that's where I can definitely see some security challenges to mitigate (which i've seen strategies for)- but first wanted to confirm my understanding.

Dan Cinnamon2024-09-20T13:56:47Z

(deleted)

Michele Mottini2024-09-20T14:34:49Z

(deleted)

Michele Mottini2024-09-20T14:35:49Z

The launch parameter is opaque to the app and doesn't include identifiable information.

The EHR should not treat this as a credential, or an access grant, but rather as a correlation handle for an authorization that's happening in the usual way (authorization code flow).

There is probably more guidance that we could provide (potentially: cross check any launch context with the permissions of the authorizing user) but since we don't mandate the semantics of this field, we leave it to EHRs to use it as they deem appropriate.

Josh Mandel2024-09-20T15:13:20Z

The threat model is: an app or user can mess with this value before it's supplied to the authorize endpoint, and the EHR should be robust to that.

Josh Mandel2024-09-20T15:14:45Z

that would be a good security consideration to mention, in addition to a warning to make sure the value is opaque. EHR can handle that in many ways that don't need to be elaborated upon (e.g., signed, a hash, nonce, etc).

John Moehrke2024-09-20T15:23:47Z

Currently we document:

In an EHR launch, an opaque handle to the EHR context is passed along to the app as part of the launch URL

Opaque identifier for this specific launch and any EHR context associated with it

Josh Mandel2024-09-20T15:26:11Z

opaque is read by some as okay to include understandable stuff, with expectation the user will not look closely. Much like an OID, UUID, or URL. So we might want to be more specific than opaque. No idea what words better explain that the value must not be understandable by the client.

John Moehrke2024-09-20T15:42:15Z

must not be tamperable

Grahame Grieve2024-09-20T15:54:16Z

Maybe this?

Launch Parameter Security Considerations

Servers should design their launch parameter implementation with the assumption that malicious actors may attempt to replay, tamper with, or infer sensitive information from these values. Key security properties to consider include uniqueness, integrity verification, and protection against information disclosure. Implementers should ensure their design is robust against scenarios where the launch parameter might be intercepted, manipulated, or forged before being presented to the authorization endpoint.

Josh Mandel2024-09-20T16:05:26Z

The attack I've described above is NOT a replay/tamper attack, let's say the launch token is a random value and it can only be used once. A bad actor could still get access to a valid token and then can try to use it to associate wrong account with the patient record, or it could be intentional as well where a user shared their token with another individual. I think it is important to mention that the EHR system should have some logic implemented to verify the identity of the redeemer of the launch token when issuing the authorization code.

snahil2024-09-20T16:27:27Z

Since the launch token is sent as a query parameter in the URL to the authorization server, it is susceptible to leakage, for e.g, when using referer header, this information will be leaked if a user visits subsequent pages controlled by the attacker. The launch token is not transmitted securely to the authorization server. It should maybe use back channel for it.

snahil2024-09-20T16:36:44Z

Thanks for the clarification, @Josh Mandel - spending most of my time in the standalone flow- i was not aware that the user will re-authenticate in the browser during an EHR launch flow. That helps a ton, as it means that we can at least trust that the user is valid, and the EHR can then ensure that the launch context is valid for that user (as called out), and underlying permissions are enforced as well.

Dan Cinnamon2024-09-20T17:17:51Z

brg-shrngi said:

The attack I've described above is NOT a replay/tamper attack, let's say the launch token is a random value and it can only be used once. A bad actor could still get access to a valid token and then can try to use it to associate wrong account with the patient record

The launch value doesn't associate accounts with records. Do you think it would help to add the following to the suggestion above?

Sservers must not treat the launch parameter as conferring access rights; authorization decisions should be based on the authenticated user's permissions, not solely on the presence or content of a launch token.

Josh Mandel2024-09-20T17:51:57Z

it won't hurt to say that, even though it should be obvious

Grahame Grieve2024-09-20T18:28:11Z

Josh Mandel said:

The launch value doesn't associate accounts with records.

The launch token doesn't directly establish the association but it helps getting the authorization code and access token which can be used for establishing the association.

I think we should also share that the launch token is susceptible to leakage (because it is transmitted in URL), and we can maybe suggest some mitigations for e.g., by asking the user to sign in again

snahil2024-09-20T18:52:59Z

I'm not following what the launch token has to do with the authentication context. The launch already/always includes an authentication step.

Josh Mandel2024-09-20T19:00:05Z

"leakage" is already covered by the proposed language

assumption that malicious actors may ...

Josh Mandel2024-09-20T19:01:29Z

The phrase "infer sensitive information from these values" implies that if the token contains sensitive information, there’s a risk of leakage. It’s important to highlight that the token itself could be compromised, even if it’s designed to be random, unique and used only once. The client application needs a mechanism to send contextual information to the EHR authorization server for verification. This will ensure that the entity redeeming the launch token is the same user for whom the token was originally generated.

snahil2024-09-20T19:19:09Z

I am not sure I follow what you're suggesting here. Are you proposing that we add additional explanatory language or are you proposing that the specification needs new functionality?

Josh Mandel2024-09-20T19:19:49Z

We should add some explanation to clarify the language ensuring that readers are aware not only of the security risks but also of the potential impacts of this implementation.

Regarding functionality, I see a security flaw in this algorithm. I think we can implement a mechanism to link the requests to one another. For instance, the OAuth authorization code flow helps mitigate authorization code injection attacks, where a malicious actor could swap authorization codes to log into someone else's account by using PKCE parameters to protect the token exchange flow. We can use a similar approach for the launch token, by using code verifier and code challenge in the requests to ensure that the entity redeeming the token is the same entity who started the flow. Additionally, we can also recommend that the launch token should be transmitted via a back channel, which is a more secure option for sending the token to the authorization server.

Alternatively, we could remove the launch token step from this flow and instead obtain user consent directly in the EHR application. However, this might make the process similar to a standalone launch. Please let me know if my understanding is incorrect here.

snahil2024-09-20T20:43:07Z

We already have pkce. I can't tell if you're advocating for that or for something analogous that runs in parallel.

I'm not sure I understand the actual threat you were describing.

Josh Mandel2024-09-20T20:44:22Z

I understand this implementation is based on OAuth authorization code flow but it adds a step where launch token is required to be sent to the authorization server. PKCE parameters are not used when launch token is being exchanged
with the server hence this step is vulnerable to code injection attacks. PKCE is used in the later steps where request is being sent for authorization code and access tokens.

snahil2024-09-20T20:46:23Z

That's accurate re: PKCE.

I think the concern you are articulating is a kind of substitution attack on the launch value. But substituting a different launch value should never enable an app or user to accomplish anything that they could not accomplish before. It does not authorize the app to see any new data, does not leak sensitive information to the app, etc.

Given the advice we drafted above, what is the residual threat that we need to mitigate?

Josh Mandel2024-09-20T20:50:48Z

it's not a security threat, but it might be a clinical threat - mixing contexts - specially in the case where patient-banner is true - could result in disastrous clinical outcomes

Grahame Grieve2024-09-20T20:59:28Z

on the other hand, it really seems like a marginal threat in practice

Grahame Grieve2024-09-20T20:59:40Z

The user tricking herself is not a threat. And if the app wants to trick the user about context, it can simply lie, not without actually manipulating the context; the user doesn't see this information directly, but only as mediated through the app's UI.

Josh Mandel2024-09-20T21:00:50Z

This is true, but @snahil is elucidating a risk that an attacker could intercept and change the launch context between the EHR and the launched app, so that an app that is (rightly) trusted to not do things like actually does that anyway

Grahame Grieve2024-09-20T21:01:57Z

I think it is a possible theoretical attack but wow a lot of work for a limited outcome.

Grahame Grieve2024-09-20T21:02:45Z

Let’s consider an example: Alice gains access to the launch token issued for user Bob. She generates a linking request from her client application, intending to send a launch token to the EHR authorization server. However, Alice swaps the original launch token with the one she stole from Bob. When the EHR authorization server receives the request, it has no way to determine whether the request is coming from Alice or Bob becuase it only receives the launch token (no other information). It verifies the launch token and issues an authorization token. Alice then uses this authorization token to obtain an access token, allowing her to link her account to Bob's patient record and gain access to all of Bob's data.

snahil2024-09-20T21:03:39Z

nah, not that

Grahame Grieve2024-09-20T21:04:01Z

the launch token does not allow her to link her account to bob's record. The approval for that is in the AS, independent of the launch context

Grahame Grieve2024-09-20T21:04:34Z

Launch tokens are not authorization grants. The server does not issue an authorization token on the basis of the fact that a launch token was provided in request. The server issues an authorization token only when a valid authorization code is provided, and an authorization code is only available to Alice if she has successfully authenticated and authorized the app to launch.

Josh Mandel2024-09-20T21:04:39Z

The threat Grahame Is describing makes More sense to me, but it involves a third party being able to intercept an app launch... At which point the user's device or session or app is compromised (i.e., similar threats could be carried out without having to go through this injection dance).

Josh Mandel2024-09-20T21:07:15Z

I agree that if you're compromised, you're compromised, and there's very higher gain threats than the one I described in that case

Grahame Grieve2024-09-20T21:08:59Z

but I was thinking that there's a chance that you could inject a proxy with a DNS poisoning attack that can get at the launch context and not get at any other part of the request. In which case, my attack becomes the worst thing you can pull off.

But if you have a proxy that can MITM the SSL and get at the launch, this comes back to 'you're compromised', with all the consequences of that

Grahame Grieve2024-09-20T21:10:22Z

Josh Mandel said:

The server issues an authorization token only when a valid authorization code is provided, and an authorization code is only available to Alice if she has successfully authenticated and authorized the app to launch.

Alice has a valid user account in the client application and successfully logged in and authenticated. She then authorized the app to launch but used Bob's launch token in her request instead. @Josh Mandel why do you think this scenario is not possible?

snahil2024-09-20T21:11:38Z

Thank you for sharing that case report BTW -- terrifying stuff. AI summary:

This case involves the death of Paul Lau due to a medication error at Macquarie University Hospital in 2015. The error occurred when an anesthetist, Dr. Kim, mistakenly prescribed high-dose opioids intended for another patient to Paul Lau's electronic medical record. This is a clear example of a context error in healthcare IT systems.

For what it's worth, this is part of the reason that we did not try to tackle communication of context switches to a smart app once it has launched (rather, we provide a mechanism where the app can be closed and relaunched in another context).

Josh Mandel2024-09-20T21:13:37Z

Alice has a valid user account in the client application and successfully logged in and authenticated. She then authorized the app to launch but used Bob's launch token in her request instead.

I'm following along so far. In this scenario, Alice has gained access to a launch token that was issued in association with Bob's session. According to the guidance above, this is not going to give her access to anything she would not otherwise be able to access.

We could encourage the EHR to bind the launch token to a user context, and to reject an authorization request if the user does not match the initial context. I'm not sure what this buys us but we could incorporate that into the proposed language with a sentence like

Furthermore, servers should bind launch parameters to a particular user and reject authorization requests where the authenticating user differs from the user bound to the launch parameter.

Josh Mandel2024-09-20T21:20:28Z

Thank you, this language would surely help readers to understand the security risk and its potential impact.

Josh Mandel said:

According to the guidance above, this is not going to give her access to anything she would not otherwise be able to access.

To address your concern, once Alice obtains Bob's launch token, she can create a valid account linking request using that token and send it to the server. A valid launch token signals to the authorization server that the user has consented to account linking and is requesting an authorization code. However, the server has no way to verify whether the request is coming from Alice or Bob, as it only receives the launch token without any identifying information. If the launch token is valid, the server issues an authorization code for Bob, which is then sent to Alice. She can use this authorization code to obtain an access token for Bob. She then uses the access token to send a linking request that includes her account information and Bob's access token. The server, recognizing the access token as belonging to Bob, mistakenly links Bob's patient record to Alice's account.

Stealing a launch token from another user can have a cascading effect, potentially leading to unauthorized access to that user's authorization code and access token. I would like to share that we were able to successfully test this scenario in Epic's sandbox environment for EHR launch.

snahil2024-09-20T21:46:39Z

She then uses the access token to send a linking request that includes her account information and Bob's access token.

We do not define an account linking request, and no launch that Alice presents to the authorization server can cause her to have access to data she would not otherwise have. This is because the launch value is not an authorization grant.

Josh Mandel2024-09-20T21:49:19Z

I'm still not convinced that servers need to bind launch values to user sessions. I say this with an understanding of the dangers of session fixation attacks and of the effects that cascading assumptions can have in the overall security of a system.

I don't mind incorporating the guidance above, but I don't think we should imply that a server cannot be secure without this binding -- unless of course someone can explain why this is the case.

Josh Mandel2024-09-20T21:52:12Z

In the scenario described above, what do you think Alice would need in addition to Bob's launch token to obtain his authorization code and eventually his access token?

snahil2024-09-20T21:56:56Z

She would need her own account to authenticate to the system, and then she would approve access and then the app would get an access token bound to her account.

Josh Mandel2024-09-20T21:57:25Z

She could not receive an access token bound to Bob's account.

Josh Mandel2024-09-20T21:57:36Z

(not without being able to authenticate as Bob)

Josh Mandel2024-09-20T21:57:51Z

@Josh Mandel are you referring to the step "Authorize app (MAY include end user authentication and end user authorization)" in the flow diagram linked here - http://hl7.org/fhir/smart-app-launch/2021May/#smart-authorization-sequence ? The explanation says "The authorization decision is up to the EHR authorization server, which MAY request authorization from the end-user."

But the above link is from May 2021, the latest doc here (https://build.fhir.org/ig/HL7/smart-app-launch/app-launch.html#response-4) doesn't have this step or any flow diagram but it only says "The authorization decision is up to the EHR authorization server which MAY request authorization from the end-user".

Is there any reason why the step says "MAY" instead of "MUST" ?
I believe the wording should be changed to "The server MUST seek authentication and/or authorization from the end user before issuing the authorization code to the application."

snahil2024-09-22T21:57:06Z

The color on this is that there is always an authentication step but it may be automatic if the user already has a session established -- and ditto for authorization. Both of these steps occur but they may not involve any user interaction. This is a very common case for the ehr launch because ehrs don't want to interrupt their users with a reauthentication step or a reauthorization step every time an app is launched. Policies can drive the authorization (e.g., remembering previous decisions or implementing an organizational choice).

Nevertheless, the launch will fail if Alice is not authenticated properly.

Josh Mandel2024-09-22T22:08:59Z

A user may not always have an active session with the EHR, especially when sending request from a mobile app. Therefore, the standard should mandate an authorization step. This step can be implicit if the user already has an active session with the EHR server, or explicit if not. The May 2021 version was clearer, as it included this step in the flow diagram.

snahil2024-09-23T00:14:39Z

If they don't have an active session, then the authentication is explicit

Josh Mandel2024-09-23T01:00:38Z

If we're confident that the correct user is authenticated/authorized in the browser, then it seems like this threat is similar to a "cross site request forgery" style attack where an attacker might trick a valid, logged in user to act on data they didn't intend to act upon (injecting a launch context that's different than the user created with their action in the EHR). I would agree that this type of attack, on it's own, seems pretty low risk here, since there are a number of steps that all this stuff flows through before anything actually happens, and the EHR would have plenty of opportunity to catch it.

Dan Cinnamon2024-09-23T18:00:41Z

Josh Mandel said:

If they don't have an active session, then the authentication is explicit

I think it's really important to note that, in a native/mobile + web situation, that the active session in the application, and the active session in the browser are completely separate, and that the launch parameter is not trying to bridge them together. If the launch parameter is used in any way to extend that mobile session into the web, then the risk/threat is way higher.

Dan Cinnamon2024-09-23T18:19:42Z

In mobile apps (or where user does not have an active session with EHR hence no implicit authorization), this would allow a bad actor to steal an unused, valid launch token from another user and link their account to that user's patient record and obtain access to all their information.

snahil2024-09-23T18:26:07Z

Also, without user authorization how does the server confirm the scope that needs to be associated with the tokens it provisions to the client app? The standard is somewhat not very clear about these aspects.

snahil2024-09-23T18:39:01Z

If the launch parameter is used in any way to extend that mobile session into the web, then the risk/threat is way higher.

The launch parameter does not establish a session. It needs to be consistent with (or at least not inconsistent with) the session that the EHR does establish during the authorize step.

Josh Mandel2024-09-23T18:40:35Z

steal an unused, valid launch token from another user and link their account to that user's patient record and obtain access to all their information.

Again, launch tokens are not grants. They don't give you access to any information you can't already see.

Josh Mandel2024-09-23T18:43:04Z

in a native/mobile + web situation

How are you doing EHR launch with a native/mobile app?

Michele Mottini2024-09-23T18:59:59Z

I'm not with an EHR- so my personal experience with this type of thing actually stems from use cases outside of healthcare. The case I'm referring to is where the user is logged into a native mobile app (or desktop app- doesn't matter), and the user clicks on some sort of button within the app to launch a third party app, but that third party app runs in a browser as a web app.

The native/mobile app will then either launch the browser, or use an embedded browser to show the content from the 3rd party. From the user's perspective, the user expects that to be a seamless process, and they expect to not have to login again (it's all one app, right?). However- what's actually happening is that this use case now becomes an omni-channel use case, and great care must be taken to ensure that the user's logged in session is properly instantiated within the browser.

I had incorrectly understood that the EHR launch flow would be used to offer such experience. If the EHR launch flow requires the user to login separately to the launched web app at least once- then a significant attack vector is out of the equation. I was merely calling out this use case specifically because it's easy to get things mixed up.

Dan Cinnamon2024-09-23T19:49:16Z

The native/mobile app will then either launch the browser, or use an embedded browser to show the content from the 3rd party.

This is where the EHR is native/mobile - and it is surely something that exists -but I was asking about the _SMART app_ being native/mobile - I don't think you can even do an EHR launch in that case? (or if you can - how?)

Michele Mottini2024-09-23T21:29:41Z

Oh interesting @Michele Mottini - I can't say that I've seen that in healthcare, no. I'd say the closest thing to this would be outside of healthcare there's this concept of a "magic link". It's generally seen in cases where someone forgot their password, or performs a passwordless "login with email" type of login flow.
So in the browser (or potentially an email application)- the user clicks a link called a "universal link"- which is a non http:// URL that the mobile OS associates with an app. Whenever a user visits one of these special URLs, it's treated by the mobile device as sort of a "deep link" to the native mobile app. There's a fair bit of security and hoops to jump through with apple/google to get your app associated with a universal link.
So theoretically, I could develop a mobile app, and there could be a launch URL like this: "dansawesomeapp://launch", and if a user clicks on that link within a browser on a mobile device, my mobile app would pull up, and it would begin the smart launch flow automatically.
Perhaps we'll see more of this in the future within the context of smart launch, but I personally haven't at this time.

Dan Cinnamon2024-09-24T14:59:04Z

but was asking about the _SMART app_ being native/mobile - don't think you can even do an EHR launch in that case? (or if you can - how?)

I don't know if this is done in the real world, but technically a mobile SMART EHR could open a system browser context onto the launch URL of a mobile smart app; if this is an app-claimed URL and the app is installed, then the app would be opened and would proceed by parsing the launch id from its context to initiate an authorize request.

(Again, this launch is is not an authorization grant and proceeding to authorization will lead to a user authentication + authorization step as determined by EHR policy.)

Josh Mandel2024-09-25T02:57:06Z
During a discussion about the Chocolate Special Interest Group (SIG), participants shared details about chocolate deliveries for upcoming events and planned meetups to enjoy various international chocolate varieties together. The conversation highlighted the anticipation and excitement surrounding chocolate-related gatherings, emphasizing their importance and community spirit.
62 comments
ML

Like taxes, delays at Schiphol, and other things in life, the Chocolate SIG seems inevitable. But unlike the others, chocolate has a meaning and purpose, and does not(1) leave that feeling of void.

Jose Costa Teixeira2022-09-20T16:16:46Z

For security, today we have individually packaged chocolates. Of course, that SupplyDelivery is handled by OO. The delivery period is between Q3 and Q4 today.

Jose Costa Teixeira2022-09-20T16:17:01Z

(We don't care what's inside, so no need to debate which resource we'd use for that. SupplyDelivery is enough).
Provenance includes 3166-1-2#CH

Jose Costa Teixeira2022-09-20T16:17:20Z

(1) because the Provenance does not include #BE this time, the feeling of fulfillment is NOT as guaranteed

Jose Costa Teixeira2022-09-20T16:17:56Z

Is there a binding of the chocolate to a Location so we know where to find them, or at least a SearchParameter?

Elliot Silver2022-09-20T16:29:06Z

....so, is it happening? Today afternoon or tomorrow? I'm not carrying these Belgian goodies back.

Jose Costa Teixeira2023-05-10T13:15:38Z

....or do we need to create a NutritionOrder?

Jose Costa Teixeira2023-05-10T13:17:29Z

heck you can leave them at reg desk when you leave!!!

Lynn Laakso2023-05-10T13:22:08Z

The Swiss will join!

Michaela Ziegler2023-05-10T15:26:32Z

This is a mustSupport event.....

Matt Blackmon2023-05-10T15:55:16Z

🇨🇭 🇧🇪 🍫today at 🍪 break close to reg desk @Jose Costa Teixeira for any 🍫 lovers ..

Oliver Egger2023-05-10T17:59:45Z

And in DevDays?

Mikael Rinnetmäki2023-06-04T20:50:56Z

@Michaela Ziegler did you already book a room? Thursday 15:15 to 15:45, right?

Mikael Rinnetmäki2023-06-06T14:07:32Z

Mikael Rinnetmäki said:

Michaela Ziegler did you already book a room? Thursday 15:15 to 15:45, right?

Yes, it will happen in the BrightLab on the 1st floor :chocolate:

Michaela Ziegler2023-06-06T14:09:07Z

:flag_switzerland: chocolate will be there ...

Oliver Egger2023-06-06T14:12:16Z

Just a reminder in preparation for Dallas

Jose Costa Teixeira2024-05-03T19:40:21Z

I'm picking some up tomorrow!

Gino Canessa2024-05-03T20:14:55Z

@Jose Costa Teixeira swiss chocolate is on the way to dallas

Michaela Ziegler2024-05-17T09:40:46Z

@Michaela Ziegler also Belgian Pralines :)

Jose Costa Teixeira2024-05-17T10:46:38Z

And some world-renowned Wisconsin chocolate.

Gino Canessa2024-05-17T11:37:03Z

I bought some Australian chocolate

Grahame Grieve2024-05-18T07:42:07Z

Grahame Grieve said:

I bought some Australian chocolate

WHat kind?

Michael Lawley2024-05-20T01:53:36Z

macadamia and something

Grahame Grieve2024-05-20T03:44:09Z

What time slot suits you all for a meet and eat? :chocolate: :smiley:

Michaela Ziegler2024-05-20T13:03:18Z

Tue, 3 p.m.?

Michaela Ziegler2024-05-20T13:03:58Z

I think so. Tuesday at 3 pm.

Jose Costa Teixeira2024-05-21T03:06:38Z

In one of the rooms around the coffee area?

Jose Costa Teixeira2024-05-21T03:07:07Z

Yeah, I could organize room C :chocolate:

Michaela Ziegler2024-05-21T12:58:07Z

@Grahame Grieve @Gino Canessa ok for you?

Jose Costa Teixeira2024-05-21T13:07:46Z

also on whova

Michaela Ziegler2024-05-21T13:09:02Z

That works, thanks!

Gino Canessa2024-05-21T13:09:58Z

works for me

Grahame Grieve2024-05-21T13:45:37Z

Grahame Grieve said:

works for me

We've started

Jose Costa Teixeira2024-05-21T20:14:36Z

thanks all for joining us and thanks @Jose Costa Teixeira @Grahame Grieve @Gino Canessa @Line Saele for bringing the chocolate :star_struck:
PXL_20240521_201349752.MP.jpg

Michaela Ziegler2024-05-21T20:36:59Z

Look at those very very happy people who got chocolate! <3

Line Saele2024-05-21T21:13:03Z

....and it's that time of the year again :chocolate: :love: :tada:

Jose Costa Teixeira2024-09-24T13:52:10Z

Does anyone have preferences or constraints on when to meet and share?

Jose Costa Teixeira2024-09-24T13:54:20Z

tomorrow? thursday?

Jose Costa Teixeira2024-09-24T13:54:43Z

both fine for me

Giorgio Cangioli2024-09-24T13:54:58Z

perhaps at the end of the lunch break?

Jose Costa Teixeira2024-09-24T13:55:05Z

afternoon break ?

Giorgio Cangioli2024-09-24T13:56:59Z

Q5 Thursday?

David Pyke2024-09-24T13:57:49Z

PS José is 20 cm next to me .. I don't know why we are typing :rolling_on_the_floor_laughing:

Giorgio Cangioli2024-09-24T13:58:13Z

David Pyke said:

Q5 Thursday?

Leaving on Thursday

Giorgio Cangioli2024-09-24T13:58:30Z

Tomorrow afternoon break?

David Pyke2024-09-24T13:59:04Z

please post a nice picture :cowboy:

Michaela Ziegler2024-09-24T14:03:48Z

Michaela Ziegler said:

please post a nice picture :cowboy:

We miss you and Oliver ...and CH chocolate :-)

Giorgio Cangioli2024-09-24T14:27:07Z

but I know that Roeland is around

Giorgio Cangioli2024-09-24T14:28:23Z

Giorgio Cangioli said:

but I know that Roeland is around

I reminded @Roeland Luykx to bring chocolate :yum:

Michaela Ziegler2024-09-24T14:29:17Z

I have chocolate. Not exiting one, since I forgot until I arrived at the airport in Norway.

Line Saele2024-09-24T16:58:07Z

An I miss you @Michaela Ziegler - please come to Madrid! We need a Cava SIG too!

Line Saele2024-09-24T16:58:36Z

I have chocolate over from the HL7 Europe meeting. Will bring it.

Roeland Luykx2024-09-24T17:09:34Z

Memo to self: bring Dutch chocolates to Madrid.

René Spronk2024-09-24T17:32:06Z

lets instantiate the Chocolate SIG for all WGM's!

Roeland Luykx2024-09-24T17:33:23Z

Roeland Luykx said:

lets instantiate the Chocolate SIG for all WGM's!

Meet-Up in Whova defined

Roeland Luykx2024-09-24T19:44:03Z

Well????

Jose Costa Teixeira2024-09-25T19:03:14Z

@Roeland Luykx

Jose Costa Teixeira2024-09-25T19:04:15Z

@Giorgio Cangioli

Jose Costa Teixeira2024-09-25T19:04:22Z

where are you?

Roeland Luykx2024-09-25T19:04:36Z

At the registration desk

Jose Costa Teixeira2024-09-25T19:05:12Z

4th

Jose Costa Teixeira2024-09-25T19:05:14Z

Inside the ballroom

Jose Costa Teixeira2024-09-25T19:06:11Z
The discussion revolves around the management of the shared .fhir/packages directory, highlighting issues related to package installation conflicts and proposing improvements such as using temporary directories for installs and maintaining separate directories for each tool to avoid alterations and collisions. Additionally, there are conversations about the necessity and potential restructuring of the packages.ini and .index.json files to better manage version control and indexing while conforming to established specifications.
63 comments
DO
EK

This is a discussion thread regarding the requirements for tools using the shared .fhir/packages registry.

Many tools are installing packages in this directory and relying on packages installed by other tools, but some behaviours (the content of packages.ini, the addition of indexing files), can lead to conflicts, particularly if multiple processes are trying to utilize this directory at the same time.

.lock file usage is used by the java core libraries (Validator, IG Publisher), but this is, as @Josh Mandel pointed out could be needlessly complex and avoided altogether if package installs were guaranteed to be an atomic action (install into a temp directory in .fhir/packages, and then rename) and idempotent (I don't care if another process installed a package over the one I just installed, because they will be guaranteed to be exactly the same).

What if we maintained that all tools should NOT be able to alter the content of installed packages, and should limit their own data to a subdirectory (for example .fhir/packages/.firely)?

Aside from package installation, this would also neatly prevent file name collisions (.fhir/packages/.hl7/my.package#1.2.3/some-new-file doesn't interfere with .fhir/packages/.firely/my.package#1.2.3/some-new-file) and means each tool just needs to implement concurrency within its own directory.

David Otasek2024-09-24T14:41:53Z

(deleted - accidental double post)

David Otasek2024-09-24T14:42:03Z

No idea why zulip posted that twice. Apologies.

David Otasek2024-09-24T14:49:40Z

can we live without packages.ini?

Grahame Grieve2024-09-24T15:12:19Z

as for indexing... I thought that we did that before install? can you check?

Grahame Grieve2024-09-24T15:12:30Z

I'm imagining a scenario where a pre-existing cache contains packages from previous implementations. How would we know that the packages are still compatible with the current way of doing things? packages.ini with a simple version is a good way of explicitly stating what particular interactions are supported in the cache.

David Otasek2024-09-24T15:21:52Z

that's true. There wouldn't really be contention around a packages.ini that only contained the cache version?

Grahame Grieve2024-09-24T15:22:53Z

I'll have to dig into the indexing as it was changed in recent merges, but my memory is that it generated missing indexes on package read, which was what necessitated re-arranging it.

David Otasek2024-09-24T15:23:24Z

If it only contains a package cache version, maybe it needs to not be 'packages.ini' at all.

David Otasek2024-09-24T15:24:49Z

but my memory is that it generated missing indexes on package read, which was what necessitated re-arranging it.

we can change it to only do it before the package is renamed.

If it only contains a package cache version, maybe it needs to not be 'packages.ini' at all.

gonna be something though

Grahame Grieve2024-09-24T15:26:21Z

cache.version?

David Otasek2024-09-24T15:26:58Z

could be. I don't mind, but the name and format aren't germane to the locking discussion?

Grahame Grieve2024-09-24T15:27:30Z

we can change it to only do it before the package is renamed.

This assumes then, that all other tools will also index before renaming. It would require it, in fact, and that the indexes produced are always the same.

David Otasek2024-09-24T15:28:06Z

Which I think will guarantee headaches.

David Otasek2024-09-24T15:28:29Z

And yeah, I don't care about the name. All I'd care about is the existence of something to indicate cache version.

David Otasek2024-09-24T15:30:49Z

Well, I do care about the name, a lot actually, but that discussion doesn't need to be here

David Otasek2024-09-24T15:48:58Z

that the indexes produced are always the same

there is a spec for the index, but I do deviate from it :-(

Grahame Grieve2024-09-24T15:57:28Z

@Martijn Harthoorn maybe we should talk about that

Grahame Grieve2024-09-24T15:57:41Z

the documentation for the index file says:

Grahame Grieve2024-09-24T15:58:09Z

The files array contains an object for each resource in the package with the following properties:
* filename - the filename in the package directory that is being described
* resourceType
* id
* url
* version
* kind
* type
* supplements
* content

but i had to add:

  • valueSet
  • derivation
Grahame Grieve2024-09-24T15:59:35Z

So all of the above needs to be satisfied, and:

The .index.json file can be rebuilt at any time

I can imagine the pain of sushi generating a bad index (not to imply that sushi would be prone to this) and then some other component having to deal with that. Or doing something (like above with valueSet) that gets overwritten by some other tool.

David Otasek2024-09-24T16:08:54Z

Tagging @Chris Moesel at request

David Otasek2024-09-24T17:48:54Z

And @Marten Smits is currently maintaining the .NET packaging library, so I am adding him too.

Ewout Kramer2024-09-24T18:03:17Z

SUSHI does not generate its own packages. We only cache packages that we have pulled from a registry or from the build server (for #current builds). When we do so, we follow the approach that Josh suggested, unzipping the tgz into a temporary folder and then moving it to the correct location in the cache. We don't modify anything in the package, except fixing up the folder structure in a few old packages (as described here). SUSHI doesn't generate, modify, or even read .index.json files.

Chris Moesel2024-09-24T19:19:50Z

thx

Grahame Grieve2024-09-24T19:23:18Z

:+1: for the temp folder approach. That indexing (or lack of indexing) behaviour is probably why Validator / IG Publisher builds its own, right Grahame?

David Otasek2024-09-24T19:23:27Z

builds its own what?

Grahame Grieve2024-09-24T19:23:42Z

Indexes. If it finds a package installed by sushi, without indexes, thats when it would build them.

David Otasek2024-09-24T19:24:09Z

@David Otasek - Generally speaking, I think that packages have a .index.json file in their distribution package, so when we cache the unzipped package, it usually already has a .index.json in it. That said, I don't know when that started happening, so I guess any packages prior to that wouldn't have one.

Chris Moesel2024-09-24T19:31:05Z

that's the case - it was about 5 years ago

Grahame Grieve2024-09-24T19:58:00Z

@Chris Moesel yes, that's my understanding as well. Sushi is doing a very literal install of the package, while the core libs are 'enhancing' it for optimization purposes. My proposition above was to do what Sushi does, and if .index.json or whatever is generated from another tool, it should go in .fhir/packages/.tool-id/to keep the package install idempotent.

David Otasek2024-09-24T19:58:53Z

why need to do that if the index is generated prior to renaming?

Grahame Grieve2024-09-24T20:07:29Z

That would have to be a requirement for every tool, then.

David Otasek2024-09-24T20:11:16Z

or we could delete and reinstall the package. Though that's not really the idea

Grahame Grieve2024-09-24T20:12:16Z

I'm not excited about that idea. Though not exactly the same, that has the same feel as the package clearing that was causing us grief.

David Otasek2024-09-24T20:15:16Z

With the .fhir/packages/.tool-id approach, I'm mostly attracted to the idea that the package will always be the same, and that different tools will have their own sandbox to do whatever they want. If I recall correctly someone mentioned they were maintaining some additional data of their own, which is exactly what we don't want.

David Otasek2024-09-24T20:18:44Z

that's firely - @Ewout Kramer

Grahame Grieve2024-09-24T20:21:29Z

That sounds right.

David Otasek2024-09-24T20:23:46Z

Yes, we Firely also generate a .firely.index.json file which contains a bunch of stuff we add for optimizing our tooling. We also still generate the .index.json as described by the spec. We used to add our own stuff there too a couple years ago, but I decided to keep that just as described by the spec so that other tools still work.

Marten Smits2024-09-26T11:53:11Z

@Marten Smits what do you add? Can we converge?

Grahame Grieve2024-09-26T11:54:06Z

Let me check.

Marten Smits2024-09-26T11:54:34Z

First of all, we put our index file at the root (so next to the package, example, and 'other' folder). So we have one index file for the entire package.

We add the following extra fields:

  • filepath (string): that's the relative path from the root to the file
  • hasSnapshot (bool): to check whether a profile has a snapshot already
  • hasExpansion (bool): to check whether a ValueSet already has an expansion
  • valuesetCodeSystem (string): which indexes implicit valuesets
  • conceptMapUris (complex):
    * source (string): conceptMap source
    * target (string): conceptMap target
  • namingSystemUniqueId (array of strings): lists the unique id's of NamingSystem.

Most of these we use the make resolving files from the packages faster.

Marten Smits2024-09-26T12:02:59Z

sounds like we can converge on that

Grahame Grieve2024-09-26T12:03:52Z

You've added

  • valueSet
  • derivation
    For what purpose?
Marten Smits2024-09-26T12:06:45Z

valueSet is CodeSystem.valueSet - again, for resolving things

Grahame Grieve2024-09-26T12:11:05Z

I can't see that I make use of derivation. So I don't know why I added it

Grahame Grieve2024-09-26T12:12:46Z

oh no, I do. I use it to find/explore the type hierarchy without having to load all the structure definitions

Grahame Grieve2024-09-26T12:13:53Z

Ok, that's easy enough indeed to align.
Do you want to keep having an index file per folder? Or no problem with moving it to the root?

Marten Smits2024-09-26T12:17:25Z

I think I put it in each folder because we didn't say, and it seemed the most conservative option. But it does matter to me - I don't load examples unless examples are being looked for, for example

Grahame Grieve2024-09-26T12:23:47Z

Sure, we can work around our root scope I guess.
Do we need to file a Jira ticket to change the index.json spec?

Marten Smits2024-09-26T12:48:12Z

yes we do need one

Grahame Grieve2024-09-26T13:02:40Z

For clarity, the full proposal here is that every tool installing a package to the package cache will:

  • Ensure any package they install has a conformant .index.json file, as defined by the spec mentioned (which will be updated)
  • Install packages to a temp directory first, generate indexes, and then rename that directory, to solve concurrency issues.
  • Support a packages.ini file (or similar) with a specification that includes package cache version.
David Otasek2024-09-26T14:53:41Z

I'll go on record as saying I wanted tools to keep their dirty work to their own directories (.firely, .hl7-core, .sushi), but I can be on board with the above if that's the consensus.

David Otasek2024-09-26T14:55:00Z

@David Otasek I'm not sure, but if you're proposing adding requirements on how packages are created too, we'll need some FHIR-I tickets to update the requirements on https://hl7.org/fhir/packages.html

Ward Weistra2024-09-26T20:32:14Z

For now .index.json and package.ini are not mandator (or described in the latter case). But perhaps you are not proposing to make them mandatory in publishing, but in that case maybe you could update the proposal wording above to reflect that :thank_you:

Ward Weistra2024-09-26T20:33:42Z

Yes, this is restricted to tools writing to the package cache, and I updated the proposal above. I think that falls out of FHIR spec territory. I believe .index.json will still remain optional, and Grahame has stated that we will need a Jira ticket to make changes to that spec.

David Otasek2024-09-26T20:37:54Z

even though they are not mandatory, I always populate them when publishing

Grahame Grieve2024-09-26T20:44:13Z

Well, actually the language in the package spec is intentional at saying tools can modify these indices at any time. Fine as long as they aren't in the package cache. If they're in the package cache, there will be a VERY specific point at which they can be changed, and then must remain static unless completely deleted.

I don't like that the package spec says something which is immediately contradicted in the package cache docs, but doesn't otherwise mention it. Maybe a note saying: "there are stricter rules regarding regenerating indices when utilizing a package cache".

David Otasek2024-09-26T22:29:37Z

At least a breadcrumb.

David Otasek2024-09-26T22:33:17Z

We don't support package.ini I think. Can someone explain what's its purpose?

Marten Smits2024-09-30T08:56:44Z

it has two purposes - one to mark the version of the overall repository. that's currently 1

Grahame Grieve2024-09-30T09:25:42Z

and second to track the last use date of packages, so a user can see which packages haven't been used.

Grahame Grieve2024-09-30T09:26:02Z

but that's not really doing anything about the moment

Grahame Grieve2024-09-30T09:26:11Z
The discussion centers around the inappropriate use of the "Experimental" flag in value sets and code systems in Implementation Guides (IGs), with participants expressing concerns that it leads to confusion among implementers. Suggestions include improving validation mechanisms and clarifying the definitions of "experimental," "draft," and other statuses to ensure proper usage in future IG publications.
54 comments

In reviewing the Sept 2024 ballot I have found value sets and code systems in IGs intended for implementation with the "Experimental" flag set to true. Granted they are early in development, but looking at the content represented in the value set it is clear that the codes can be used and are expected to be used. A Code system example of this is Healthcare Capacity Reporting Code System. A particularly egregious occurrence of this can be seen in the Information Recipient Extension that binds the Clinical Document Participant Types Value set value set REQUIRED but the value set is marked Experimental.

In both the code system example and the value set example the use of the Experimental flag only confuses implementers. I suspect the "information" intended to be conveyed is already communicated by the maturity of the resource and the fact that this is an early IG.

I'd like others to comment if they agree with me on this and would like to push IG authors to stop using Experimental when the content is actually just an early initial attempt at real stuff. @Grahame Grieve @Lloyd McKenzie could we put in publisher warnings on experimental code systems and value sets? Particularly when publishing. Particularly when bound REQUIRED?

Robert McClure2024-09-16T20:21:28Z

I noticed this on some other resources. I think authors are incorrectly using experimental=true to mean really, really draft (or even the same as draft), rather than the defined meaning of "for test purposes."

Elliot Silver2024-09-16T20:34:56Z

ShareableValueSet and ShareableCodeSystem profiles had it mandatory, so several authoring tools have insisted having it filled in with something. A draft value set is not automatically experimental, but authors mark it as such "just in case". And then it gets forgotten.

Rutt Lindström2024-09-16T20:41:47Z

I think nothing should get into THO with "experimental=true". The only things in other IGs where it would be true is if it's an example and not intended for real use.

Lloyd McKenzie2024-09-16T21:29:26Z

So, add warning for experimental resources and a FMG/TSMG waiver needed?

Elliot Silver2024-09-16T22:02:18Z

I would say that THO should error on experimental. Other IGs should error on experimental that isn't marked as an example, and warn on examples that aren't marked as experimental.

Lloyd McKenzie2024-09-16T22:53:08Z

hmm. I thought I already had a warning when something not experimental refers to an experimental value set

Grahame Grieve2024-09-16T23:08:52Z

. would like to push IG authors to stop using Experimental when the content is actually just an early initial attempt at real stuff.

I think there's cases where content or even the value set it self is experimental, even while it's clearly in the space of something that is intended to be implemented, so I suspect that we shouldn't have hard policies about that

Grahame Grieve2024-09-16T23:10:18Z

and I don't think that they should be errors, or if so, not until later in the process, and we aren't executing on IG maturity yet

Grahame Grieve2024-09-16T23:10:48Z

If it is an error, I would request that be done in the HL7 template, rather than IGPublisher or the base template. I can imagine people wanting to publish experimental resources even if we don't agree with that decision.

Elliot Silver2024-09-16T23:18:27Z

I can do errors that are driven by HL7 policy in the validator, there's already a few like that, where the rules don't apply to content published by other organizations

Grahame Grieve2024-09-16T23:26:39Z

Oh, I thought those were driven by the template. That works for me too.

Elliot Silver2024-09-16T23:39:35Z

so it turns out that the validator has not been checking the experimental flag on bindings, so from the next version:

Grahame Grieve2024-09-17T00:11:15Z
Grahame Grieve2024-09-17T00:35:43Z

Grahame Grieve said:

image.png

Is that warning for any binding to an Experimental flagged value set that is not experimental? If so that is fine but far from meeting my concerns. We should be warning on all experimental value sets and code systems in ballots and published IGs. And an error when a required binding to an experimental value set.

Robert McClure2024-09-17T11:25:10Z

a warning when binding to an experimental value set from a profile that's not experimental

Grahame Grieve2024-09-17T13:00:11Z

I don't believe that it should be an error - it's not always wrong

Grahame Grieve2024-09-17T13:00:21Z

Grahame Grieve said:

I don't believe that it should be an error - it's not always wrong

It would be wrong when the binding is required.

Robert McClure2024-09-17T13:01:12Z

really? always wrong? why does binding strength make a difference to whether it's experimental?

Grahame Grieve2024-09-17T13:02:22Z

Perhaps in part we are quibbling over where to communicate "experimental", a required binding to something that is never to used in a real system seems like technical testing, not standards IG. I just think that type of combination is a nonsense thing for an HL7 IG. By that I mean more than something purely for technical work. I'd like to hear from others on this.

Robert McClure2024-09-17T15:09:35Z

It's totally fine for an experimental profile to have a required binding to an experimental value set (and code system). I.e. you just have something made up as an example for all three.

Lloyd McKenzie2024-09-17T15:42:40Z

'experimental' should jive with 'example'.

Lloyd McKenzie2024-09-17T15:43:09Z

There’s two levels here. First, should there be non-example experimental resources. Second, should a non-experimental resource be able to reference an experimental resource (value set, profile, extension,…).

I think the validator discussion above is only addressing (part of) the second. Is there a validation warning (HL7 error?) of the first?

Elliot Silver2024-09-17T17:25:00Z

I don't think non-example experimental makes sense. You could have 'draft' non-examples if you want to say "this is intended for real use, but isn't ready yet". But if it's not an example and it's not draft, I don't think it has any business being experimental.

I suppose you could have an example binding to an experimental value set. I.e. "Here's a set of codes to give you an idea of what kinds of concepts you could represent, but you shouldn't actually use these codes". That's the only use-case I can think of.

Lloyd McKenzie2024-09-17T17:36:35Z

I am still not clear on the difference between experimental, draft, and FMM. For example, I might argue that everything that is not a release publication should be marked experimental because they are not intended for production use.

Do we just have too many ways of saying the same thing?

Gino Canessa2024-09-17T18:31:59Z

Experimental = not for real use (now or ever)
Draft - in development, not yet ready for use
FMM 0 - should be same as status = draft
FMM 1+ (status should be active or retired) and indicates the degree of adoption and stability of this thing that is ready for use
status of retired = this thing should no longer be used

Lloyd McKenzie2024-09-17T18:41:04Z

Something that's experimental shouldn't have an FMM

Lloyd McKenzie2024-09-17T18:41:17Z

Well, I can see why everyone is confused at least. Having a structure with a flag experimental and the short of For testing purposes, not real usage, gave me the expectation that it aligned with my use of the term experimental: that something is not ready for production yet.

I am not sure reading the longer descriptions that there is anything to actually indicate that meaning. I definitely cannot see anything that indicates we can never change the value (e.g., in a future version).

Gino Canessa2024-09-17T18:48:44Z

experimental vs draft really does need to be made more clear.

John Moehrke2024-09-17T18:58:46Z

I definitely cannot see anything that indicates we can never change the value

We have never said that

Grahame Grieve2024-09-17T19:14:34Z

Lloyd McKenzie said:

Experimental = not for real use (now or ever)

I assume I am misreading that then - what is the intention?

Gino Canessa2024-09-17T19:22:42Z

Gino Canessa said:

Well, I can see why everyone is confused at least. Having a structure with a flag experimental and the short of For testing purposes, not real usage, gave me the expectation that it aligned with my use of the term experimental: that something is not ready for production yet.

I think the idea behind experimental is that you want to be able to send it to a system for test purposes and be able to quarantine it.

Elliot Silver2024-09-17T19:24:38Z

However, why canonical resources are special in this regards, compared to regular resources which don't have the experimental flag, I'm not sure.

Elliot Silver2024-09-17T19:25:21Z

I assume I am misreading that then - what is the intention?

the intention of the author is that it won't change. Unless the author changes their mind. We would expect that to be unlikely, but not wrong

Grahame Grieve2024-09-17T19:25:56Z

Elliot Silver said:

I think the idea behind experimental is that you want to be able to send it to a system for test purposes and be able to quarantine it.

I was under the impression the best practice for that was using the Core Security Label of HTEST.

Gino Canessa2024-09-17T19:31:02Z

Grahame Grieve said:

I assume I am misreading that then - what is the intention?

the intention of the author is that it won't change. Unless the author changes their mind. We would expect that to be unlikely, but not wrong

Fair enough - it sounds like the intention for experimental is a classification-type element (like abstract or kind) and not a status element (like status), and thus explicitly not a lifecycle state that will end in a production structure?

I think we definitely need a ticket to clarify - has someone filed one already?

Gino Canessa2024-09-17T19:37:54Z

thus explicitly not a lifecycle state that will end in a production structure

yes, that's the intent

Grahame Grieve2024-09-17T19:39:06Z

and I agree with @Robert McClure that it's not being used correctly in these cases. I have added two things:

  • a warning any time an experimental value set is used from a non-experimental profile
  • an IG Parameter that makes all experimental content into error
Grahame Grieve2024-09-17T19:40:29Z

If I say "this is experimental" then you should assume "there's no intention I'll ever use this in production", not "it's not yet ready for production". If I change my mind and decide "you know what, I think this actually should be used in production", then I could drop the experimental flag. That's very different from draft non-experimental which is saying "I intend this to be used in production, but it's not ready yet".

Lloyd McKenzie2024-09-17T19:41:29Z

Lloyd my confusion is that 'experimental', in my experience in software, is a status. It is equivalent to saying something is alpha/beta/etc.. E.g., something that is not ready for production yet (not that any such labelling actually prevents it from being production - to the consternation of software developers everywhere :-)

I even have a branch in a repo named experimental that I am merging into the main branch this week. It was experimental while we figured out if it could work, and since it does it is no longer experimental =). The intention was to see if something would work - but the intention was always to promote it if it did.

My understanding through this thread is that StructureDefinition.experimental is classifying a structure as a type of definition that is never expected to move into production. That is new to me, and given that this thread is about overuse, I assume will be new to many others.

*edit: to clarify - I am familiar with 'experimental' things that are just Proof of Concepts or other such terms. This is just not language I associate that way (and assume others have not either).

Gino Canessa2024-09-17T19:52:00Z

I agree that the element name isn't the best for what it represents, but we're past the point where we can change it.

Lloyd McKenzie2024-09-17T20:08:53Z

Agreed - we should update the descriptions to clarify and was wondering if anyone in the thread has filed a ticket already (was discussed) or if I should.

Gino Canessa2024-09-17T20:12:20Z

Not I :smile:

Lloyd McKenzie2024-09-17T20:16:34Z
Gino Canessa2024-09-17T20:24:53Z

Lloyd McKenzie said:

I don't think non-example experimental makes sense. You could have 'draft' non-examples if you want to say "this is intended for real use, but isn't ready yet". But if it's not an example and it's not draft, I don't think it has any business being experimental.

I suppose you could have an example binding to an experimental value set. I.e. "Here's a set of codes to give you an idea of what kinds of concepts you could represent, but you shouldn't actually use these codes". That's the only use-case I can think of.

Can I ask that we don't have a Warning when we have example binding strength with an experimental valueset? We created some ValueSets as experimental and used example binding for two three reasons:
a) give the community an idea of what we are looking for
b) get feedback
c) there is not a definitive list of codes that we can find or agree on just yet

By using example, I feel we are saying 'we really don't know if this is right yet, but maybe these work, give us some feedback please'? So flagging that as a Warning seems wrong.

Kevin Power2024-09-18T22:04:29Z

After reading this thread CG is not sure on what element to use to flag ValueSets or CodeSystems which could change in the future.
One example is our TBD Codesystem which contains all concepts/codes which do not have a loinc (or other external terminology) code (yet).

Patrick Werner2024-09-25T17:58:06Z

This CodeSystem is actively used inside the IG and is implemented by several stakeholders.
So experimental seems to be the wrong element to represent this. We discussed in the WG the option of using the draft status or the SDStandardsStatus Extension with the trial-use code.

Patrick Werner2024-09-25T18:02:59Z

Downside of draft would be that some tooling, e.g. hapi, only loads active resources from an IG.

Patrick Werner2024-09-25T18:03:36Z

Your TBD Codesystem seems like it is something which you intend to be temporary. The concepts themselves won't be temporary, but the actual code system as it currently exists will not. The official policy from TSMG (https://confluence.hl7.org/display/TSMG/Terminology+Expectations+for+IG+Developers) is that something like your use case SHOULD be marked as experimental.

Marc Duteau2024-09-25T18:17:41Z

Thanks for the guidance.

Patrick Werner2024-09-25T18:19:46Z

Marc Duteau said:

Your TBD Codesystem seems like it is something which you intend to be temporary. The concepts themselves won't be temporary, but the actual code system as it currently exists will not. The official policy from TSMG (https://confluence.hl7.org/display/TSMG/Terminology+Expectations+for+IG+Developers) is that something like your use case SHOULD be marked as experimental.

Interesting. I had expected that the CodeSystem itself would be active, with individual concepts would be retired as they get migrated into other systems.

Elliot Silver2024-09-25T18:26:36Z

Elliot Silver said:

Interesting. I had expected that the CodeSystem itself would be active, with individual concepts would be retired as they get migrated into other systems.

The code system described is active even if marked as Experimental. Experimental is not a status. I agree we should consider giving guidance that when the concept represented in the temporary is "transitioned" to a the 'real' intended code system (like LOINC or SCT) the concept in the temporary code system could be retired to reduce user confusion: IE - stop using this code system representation of the concept.

Robert McClure2024-09-25T18:39:53Z

Agree, but I don't see a reason to indicate it as experimental. The code system isn't for test purposes. It represent a real code system, even if the concepts in it aren't long lived.

Elliot Silver2024-09-25T19:35:03Z

@Elliot Silver Good point. The code system apparently has a persistent useful domain therefore the code system described is not temporary, just the concepts within it are.

Robert McClure2024-09-25T19:54:25Z
During a discussion about the International Patient Summary (IPS) at FHIR Connectathon 37, participants outlined various perspectives on the data that should be included in a patient summary, emphasizing different regional implementations and specific use cases, particularly in Canada and Australia. Key points included the identification of essential data elements like medications, allergies, and health history, as well as the need for clear guidelines on how to filter and present this information effectively while acknowledging the variability in requirements based on local contexts.
50 comments
KL

This is a topic from FHIR Connectathon 37 IPS Track, but expected to run past the event. The IPS sepcification sets a minimal baseline of data expected for a summary (e.g. you must include active, allergies, meds, problems see https://build.fhir.org/ig/HL7/fhir-ips/Generation-and-Data-Inclusion.html#data-included-in-ips-documents). The IPS does not intend to give programmatic guidance to all the relevant data in a summary and this is left up to implementers / use case.

We're inviting connectathon participants (e.g. @Allana Cameron ) and other on Zulip to contribute here any rules or guidance that they may have in regards to what should be in a summary. We could use this in the future to update the list of external links in the guide in the future, although we do not plan to include any direct guidance for what to include in the near future.

John D'Amore2024-09-22T13:45:22Z

In Canada, we currently have three provinces who have worked with their clinical working groups to determine how much content to include within each of their selected data domains. I have sent emails today to confirm their final content and to retrieve permission to share with this community. I'll keep you posted.

Allana Cameron2024-09-22T13:47:29Z

When we did some of the original work with HAPI, we developed a very coarse set of rules to filter out some information for the summary. These are shown here and further refined/editable in the HAPI documentation

John D'Amore2024-09-22T13:50:24Z

Yes. The rules in HAPI are a starting point. It's expected and desired to have further discussion and contributions to this, as we all are learning from our various implementation experiences.

Rob Hausam2024-09-22T15:51:35Z

From the Australian perspective, findings from Sparked Accelerator: Rural and Remote Health Equity Roundtable session 17-18 July 2024:

Note: These findings need to be worked through in terms of specific data elements, terminology, and appropriateness for IPS.

Sparked priories for IPS

  • Portability (eg. GP to GP) - this is a use case more than content
  • GP to GP, GP to and from Aged Care
  • To, from and between Allied Health providers
  • Transfer of care
  • Chronic Decease management
  • Data elements that support Rural and Remote areas

Patient summary is being discussed for augmentation or replacement of for the following:

  • Discharge summary
  • Transfer of care
  • Care plans
  • Aged care transfer summary
  • Summary for kids in out of home care
  • Summary from prisons

Top two priority data sets identified

  • Social Determinates of Health (SDOC); and
  • Social and Emotional Wellbeing (SEWB).

Across there two priorities, the following ranked list was obtained from the participants:

  1. Food and nutrition summary
  2. Housing summary
  3. Social network
  4. Personal safety summary
  5. Living arrangements
  6. Health access summary
  7. Alcohol consumption summary
  8. Communication capability
  9. Financial summary
  10. Literacy
  11. Substance use summary
  12. Transport summary
  13. Cultural burden
  14. Strength based behaviors
  15. Responsibilities
  16. Cultural security
  17. Tobacco smoking summary
  18. Oral health
  19. Interaction with justice system
  20. Education summary
  21. Disconnection/Connection
  22. Physical activity summary
  23. Vaping summary
  24. Assessments scores/scales
  25. Racism

Detailed notes from the Rural and Remote Health Equity Roundtable can be found here https://sparked.csiro.au/wp-content/uploads/2024/07/Sparked-Rural-Remote-Health-equity-Roundtable-July-2024-Workshop-Transcription-For-Publication.pdf

Ryan Mavin2024-09-22T16:31:11Z

@Ryan Mavin that's a very comprehensive list. I find it difficult to believe that anyone would ever actually populate all those usefully.

And to demonstrate that I'm just as guilty, there's nothing there about independence skills, which is very important for aged patients

Grahame Grieve2024-09-22T17:03:04Z

Grahame Grieve said:

Ryan Mavin that's a very comprehensive list. I find it difficult to believe that anyone would ever actually populate all those usefully.

And to demonstrate that I'm just as guilty, there's nothing there about independence skills, which is very important for aged patients

Agreed, my take away of the different emphasis in Rural and Remote areas as compared to the usual city locations, the ranking of what they see as most important (where we would get the most bang for our buck) and ideally where along the patient journey we can capture this so the consumer only has to tell us one.

Ryan Mavin2024-09-22T17:10:38Z

Actually, most of those squarely fit in the SDOH space, but not all of them are currently on the SDOH table. Are you talking to that project?

Grahame Grieve2024-09-22T17:16:26Z

What happened to the idea of an IPS being a general purpose summary? Have we given up on it being a limited focused document of the headlines for emergency care? Anyhow...

Several of those categories also fall within the PACIO PFE (personal functioning and engagement) and TOC (transitions of care) scope. It would be nice if there was international participation on those to move their scope beyond the US.

Elliot Silver2024-09-23T02:06:26Z

IPS is a good base for derivations that serve requirements more specific than the original 'unplanned cross-border care' use case. In NZ we're talking about using it as replacement for GP2GP (complete patient primary care record transfers) but that would require constraints on the original requirement ('give us everything') as well as addressing the question raised in the title of this thread.

Peter Jordan2024-09-23T13:38:54Z

I think it is hard to define "top down" what a summary should consist of, given the variety of purposes to which it might be put. IPS is a great container. How it is filled should be up to the person requesting it, given constraints of those providing data for the summary... For instance, if I want to create a summary with two years of lab data and five years of diagnoses, but the EHR instance I'm querying has only the last year's data, then I should know that the data I'm getting is less than I've requested. Similarly, if I request two years of lab data from a source that had a decade's worth, I should only receive two years.

That transparency in what I get, and how much of it, means more to me than a predefined list of resource types that comprise an overarching view of a "general summary for all purposes".

Bill Lober2024-09-23T15:22:31Z

Bill Lober said:

For instance, if I want to create a summary with two years of lab data and five years of diagnoses, but the EHR instance I'm querying has only the last year's data, then I should know that the data I'm getting is less than I've requested.

In terms of the depth of data, date filters alone might not be sufficient. Records that are marked as relevant to a patient's current health & wellness would be more useful.

From a breadth perspective, it also might be useful to see which elements are common between the various national CDI specifications (US, AU, CA, NZ, etc.). Certainly to analyse what's still missing in the core IPS IG (e.g. clinical notes from encounters).

Peter Jordan2024-09-23T18:16:41Z

Peter Jordan said:

In terms of the depth of data, date filters alone might not be sufficient. Records that are marked as relevant to a patient's current health & wellness would be more useful.

I agree re relevance! It seems to me that filtering (and understanding what happened when the source applied those filters) is kind of mechanical, whereas marking records (resources?) as relevant to a patient's current health and wellness would definitely be more useful - but labor-intensive and requiring some clinical judgement?

Bill Lober2024-09-24T02:58:27Z

maybe I'm not giving enough credit to the possibilities of an LLM-based determination of relevancy for a particular individual and a particular intended use - after all, this is the miracle age!

or maybe it's too late at night for clear thinking...!

Bill Lober2024-09-24T03:03:03Z

Are we still observing the difference between a) IPS, b) a FHIR document, and c) FHIR data?

Jose Costa Teixeira2024-09-24T12:07:40Z

Jose Costa Teixeira said:

Are we still observing the difference between a) IPS, b) a FHIR document, and c) FHIR data?

I'm not entirely sure what you mean (e.g. 'honouring' rather than 'observing'?), but this discussion is about content and could apply equally to the CDA representation of IPS.

Peter Jordan2024-09-24T13:26:09Z

yes, respecting / being aware of.

Jose Costa Teixeira2024-09-24T13:41:49Z

I see the discussion is about content but I think there is content that may be more appropriate to put outside of the IPS

Jose Costa Teixeira2024-09-24T13:42:43Z

Jose Costa Teixeira said:

I think there is content that may be more appropriate to put outside of the IPS

For sure - but the question being raised here is "what content". The basic use case for IPS is here but this is clearly being expanded by national derivations fed by local requirements.

Peter Jordan2024-09-24T14:16:04Z

sure, but national derivations may hink twice before making IPS the way to exchange any data any time.

Jose Costa Teixeira2024-09-24T14:18:21Z

i mean, IPS is not meant to be the representation of the EHR. It is an agreed subset. National patient summaries should not append IPS until there's a full EHR in there

Jose Costa Teixeira2024-09-24T14:19:14Z

(this is my opinion and justification for my point above).

Jose Costa Teixeira2024-09-24T14:19:38Z

If a national derivation says their IPS may include 2 years of data, not 6 months - that is fine.

Jose Costa Teixeira2024-09-24T14:21:23Z

we won't have an agreement of what is the best time window. and that is ok

Jose Costa Teixeira2024-09-24T14:21:45Z

but if we say we should add Tasks for the detailed execution of a procedure, or scheduling,... these are not "Summary" so I don't see the point in containing those in the IPS

Jose Costa Teixeira2024-09-24T14:23:03Z

Indeed - but the IPS IG is an extremely useful starting base. Certainly NZ implementers see it as an excellent candidate for replacing GP2GP (entire primary care record data transfers). Data filtering is required in that system - 12 years of implementation experience (using CDA) has certainly taught us that!

Peter Jordan2024-09-24T14:23:07Z

starting base for document-only data exchange - sure. But there's more than documents.

Jose Costa Teixeira2024-09-24T14:23:55Z

and there are other documents beyond IPS

Jose Costa Teixeira2024-09-24T14:24:07Z

and there should be

Jose Costa Teixeira2024-09-24T14:24:10Z

Documents as in a FHIR Composition - and/or Clinical Documents such as scanned documents and images?

Peter Jordan2024-09-24T14:24:59Z

documents as a composition. Much (most) of the data may be best transmited in REST, depending on the setting. Or messages if we want

Jose Costa Teixeira2024-09-24T14:30:02Z

most of that data doesn't need an authored, consistent, subsetted representation.

Jose Costa Teixeira2024-09-24T14:30:27Z

(but I think that has been largely discussed and agreed by now, so sorry if I am repeating it, it's just that that I am always concerned that IPS becomes the only envelope for sending any and all health data.)

Jose Costa Teixeira2024-09-24T14:31:47Z

Hello folks,

In Canada, we have a couple of implementations that have worked with their clinical working groups to determine how much content to include in their patient summary (PS). Please note that some jurisdictions are not putting filters on the data in their first limited product rollout (LPR) releases. They may re-visit this after their LPR learnings are collected. Here is a summary of what we know so far:

Medication Summary

Jurisdiction 1:
To be included in the PS:
·       Only include prescriptions that are not considered to be inactive, expired or closed
·       If duplicate prescriptions exist where Medication Name, Medication Dosage and Medication Frequency are the same, filter out all but the most recent
·       Only include prescriptions written within 18 months prior to the current date when the EMR scheduled process is running
·       Do not include prescriptions with no date or no name

To be grouped/sorted by:
·       By medication name (alphabetically), and then by Prescription Written Date, with most recent date first"

Jurisdiction 2:
To be included in the PS:
·       Last 15 months of prescribed medications,
To be sorted by:
·       most recent date

Allergies/Intolerances
To be included in PS:
·       Include all
To be grouped/sorted by:
·       Drug codes grouping first, followed by group without drug code

Problems
To be included in PS:
• Conditions and diagnoses with no resolved date or where resolved date is no more than 11 years prior to the current date.
To be grouped/sorted by:
• Sorted by Active or current first followed by other statuses.

History of Procedures
To be included in PS:
• Include all
To be sorted by:
• By date with most recent first, in descending order. Partial dates are sorted as though they are as early as possible (e.g. 2019-01 is treated as earlier than 2019-01-20 and later than 2018-06-17). Blank dates appear last.

Vital Signs
To be included in PS:
·       Include last six (6) dates that contain at least one (1) vital measurement. For each of those dates, include the last recorded vital measurement for each vital element.
To be sorted by:
·       By date with most recent first, in descending order.

Immunizations
To be included in PS:
·       Available publicly funded immunizations
To be sorted by:
·       Most recent received date

Results:
Lab Results: Last 12 months of laboratory tests, sorted by recent test collection date.
Imaging Reports: Last 12 months of medical imaging tests, sorted by most recent imaging test date.

Allana Cameron2024-09-24T16:01:02Z

Elliot Silver said:

What happened to the idea of an IPS being a general purpose summary? Have we given up on it being a limited focused document of the headlines for emergency care? Anyhow...

Several of those categories also fall within the PACIO PFE (personal functioning and engagement) and TOC (transitions of care) scope. It would be nice if there was international participation on those to move their scope beyond the US.

Maybe this comment is useful in the context of the discussion of different summary types... Seems like I've been having verbal conversations about this with different folks several times today!

Using TOC scope as an example of a type of summary, I think the diagram at this link lays out the TOC scope pretty nicely. (at least I've found it pretty helpful, though I'd be the first to say I lack a detailed understanding...)
https://paciowg.github.io/transitions-of-care-fsh/guidance.html

@Ravi Kafle and I were talking about this again today, so I figured I'd drag him in!

When I look at the _categories_ of information on the TOC diagram, the (well thought out) utility for transitions is clear to me. It seems like many of those categories are also part of IPS (and other composition-based summaries - eCR, etc.). There are a few areas that don't overlap, but doesn't it seem that a specific patient's summary could satisfy both some near-future version of TOC scope _and_ some near-future version of IPS? (especially if the underlying ISO spec to which I hear @John D'Amore and @Rob Hausam refer continues to evolve?)

If the content for different use cases overlaps, then wouldn't it make sense that a particular document built from that information might be useful for more than one use case? That's a little different than saying a particular document _is_ an IPS or _is_ a TOC, but rather that it could meet requirement _for use as_ an IPS, or as a TOC document.

I'm probably misusing the terms a bit, but when there are so many different variations of "the right information" for a particular use case, it seems useful to have a shorthand to talk about meeting one or more use cases, rather than a shorthand that says this document is one type _or_ another type.

@Allana Cameron has described an effort to understand commonalities in Canadian and provincial PSs. And maybe it's OK for the summary in one location to vary from the summary in another, just as a summary for one use might differ from that for another use. Yet a summary _could_ be sufficient to meet the requirements for more than one location, or more than one use.

Bill Lober2024-09-24T18:35:57Z

Hi Everyone,

In Australia, as part of Sparked, our FHIR accelerator, we have recently been looking at the IPS and patient summary and asked our clinical design group in a workshop of ~120 people, what they thought should be included in a patient summary as a first cut - considering feasibility, their own use cases, that this would be an iterative process, noting that at a minimum we should include the Required elements from IPS and they voted for the following

  • Problem/diagnosis (problem list)
  • Medication statement
  • Adverse reaction risk (allergies and intolerances)
  • Person information
  • Procedure completed (history of procedures)
  • Vaccination administration (immunisation)
  • Pregnancy
  • Past history of illness

We are working through the next level of detail to include in our AUCDI Release 2

Kylynn Loi2024-09-25T04:58:59Z

Jose Costa Teixeira said:

Are we still observing the difference between a) IPS, b) a FHIR document, and c) FHIR data?

and d) $summary. The IPS is extensible and it would be strange to forbid content, but $summary is just the currently defined IPS content

Marc de Graauw2024-09-25T10:36:53Z

$summary is a) Summary

Jose Costa Teixeira2024-09-25T11:58:15Z

I don't see the difference.

Jose Costa Teixeira2024-09-25T11:58:22Z

IPS is not forbidding content. It is a selection of agreed content

Jose Costa Teixeira2024-09-25T11:58:42Z

If I unilaterally extend, I am outside of the agreed content

Jose Costa Teixeira2024-09-25T11:58:57Z

and that should not forbidden, is just my own flavour of IPS where others may not understand my extras

Jose Costa Teixeira2024-09-25T12:02:19Z

and there may be options to exchange that data other than an IPS - other FHIR documents or just RESTful exchange of FHIR resources.

Jose Costa Teixeira2024-09-25T12:05:09Z

In the Netherlands our national PS (BgZ) contains:

  • Demographics
  • Financial information (insurance etc.)
  • Advance directives
  • Contact persons
  • Functional status
  • Problem list (active and past)
  • Social history (living situation, drugs, alcohol, tobacco, diet)
  • Alerts
  • Allergies
  • Medication (agreements, administration, use, contraindication)
  • Medical devices
  • Vaccinations
  • Vital signs (blood pressure, body weight and length)
  • Lab results
  • Procedures (past and planned)
  • Encounters
  • Care plan
  • Healthcare providers (those involved in active treatment)
Marc de Graauw2024-09-26T15:28:47Z

For labs, medication we use history of 4 months, items such as problems are either active or flagged as potentially still of concern in the EHR, and only exchanged if flagged or active

Marc de Graauw2024-09-26T16:37:01Z

It seems like some options to $summary to shape the query will be helpful, and also some way of the server conveying constraints it may have had in fulfilling the request (time period, data completeness, confidentiality restrictions, etc.,).

This seems like a problem that could have a wide variety of intricate solutions (a disaster!), but those who know FHIR better than I do might be able to point to an approach, particularly to the idea the server conveying back it's constraints with the data. That would be helpful even if the $summary operation had no query options.

Bill Lober2024-09-26T18:14:33Z

i think that is technically doable

Jose Costa Teixeira2024-09-26T19:50:15Z

I think it will be a good idea to have the IPS document be able to convey the selection criteria that were used in creating it (likely as a separate statement for each section). One of the challenges, though, will be if we can identify or create a standard way that can be used to express those selection criteria (it would at the least be sub-optimal for this to be done via non-standard text or various differing syntaxes).

Rob Hausam2024-09-26T20:17:32Z

Bill Lober said:

It seems like some options to $summary to shape the query will be helpful, and also some way of the server conveying constraints it may have had in fulfilling the request (time period, data completeness, confidentiality restrictions, etc.,).

This seems like a problem that could have a wide variety of intricate solutions (a disaster!), but those who know FHIR better than I do might be able to point to an approach, particularly to the idea the server conveying back it's constraints with the data. That would be helpful even if the $summary operation had no query options.

I agree with you, there should be a mechanism to indicate what rules need to be applied for a particular summary. Maybe the selection is configurable at the "big" solution level (e.g. HIE decides the rules) or perhaps determined by the user type (e.g. patient vs health professional(s)), amongst other options?

Federica Lanzo2024-09-27T03:40:21Z

In terms of "relevance" rules, has anyone thought of special clinical terms that, if available in the longitudinal patient record, should be called out in the patient summary?
Looking at procedures, for example, there might be some very old surgeries that time base rules would discard, but they would still be very important to know for a new carer/emergency doctor (e.g. appendix removed). Another area where I could see this been beneficial is medicines. This section is most likely to go through date filtering, having possibly a large volume of patient records. There might be medicine codes/class that are important to know as administered even if it was a long time ago.

Federica Lanzo2024-09-27T03:50:58Z
ICD-11 system URL
#implementers
In a recent discussion, participants explored the support for ICD-11 within existing tooling, noting that it is not yet supported and discussing potential interim solutions for its integration while considering licensing and technical requirements set by WHO. Grahame Grieve emphasized the need for a terminology service that aligns with WHO's standards, and various team members proposed strategies for temporary implementations, while expressing concerns about compliance with licensing restrictions.
45 comments
ML

I can't find any other updates - is there support for ICD-11 in the tooling yet?
If not, should we make a "terminology" IG that contains a subset of ICD-11 so that the VS expansion works?

Jose Costa Teixeira2024-08-09T07:37:46Z

What would be the ideal way to have this (maybe I can do some work there)?

Jose Costa Teixeira2024-08-09T07:38:28Z

@Grahame Grieve @Carl Leitner @Ritika Rawlani

Jose Costa Teixeira2024-08-09T07:38:41Z

ICD-11 is not supported yet. I've been meaning to chase this up with WHO

Grahame Grieve2024-08-09T09:03:58Z

it's on my backlog

Grahame Grieve2024-08-09T09:04:06Z

so, meanwhile, should we add a ICD-11 codesystem to a new/temporary terminology IG as a dependency?

Jose Costa Teixeira2024-08-09T11:59:18Z

no I don't think you should. very much not, for licensing reasons, but it's also a complex code system

Grahame Grieve2024-08-09T12:08:13Z

flagging for @Joe Amlung and @Jonathan Payne . The expansion would be needed for a WHO IG.

Carl Leitner2024-08-09T13:58:55Z

really, I need to talk to Robert Jakub and/or Can Celic

Grahame Grieve2024-08-09T13:59:20Z

first target is for the digital ICVP (yellow book). We can put it needed codes in a WHO IG as a stop-gap to allow resolution of vaccine codes and then transition to proper TS support later (via OCL/ICD-API)

Carl Leitner2024-08-09T14:00:55Z

I will flag technical bits for Can and team....

Carl Leitner2024-08-09T14:01:23Z

if it's a WHO IG, you can do what you want with regard to licensing. None of the rest of us can do that (I still don't think we can actually use ICD-11)

Grahame Grieve2024-08-09T14:02:34Z

Yeah, not worried on the licensing bit. As a stop gap, we can add in the ICD11 codes that we need for now in code system resource, but longer term to do it the right way. Something like this that would put in a "WHO TS" IG:
https://smart.who.int/ddcc/CodeSystem-DDCC-ICD11-CodeSystem.html
This will technically make the valueset expansion work, but is not something we want to keep up.

Carl Leitner2024-08-09T14:10:39Z

I think that what is needed to be done is in the common WHO/HL7 workplan for OCL, but maybe I misunderstood something. I haven't yet dived into the details on what the exact requirement that the IG Publisher has to support the expansion.

Carl Leitner2024-08-09T14:14:46Z

we need a terminology service that supports ICD-11. WHO intend to provide one, but it needs to meet our technical requirements, and I haven't heard that it will. And it appears that the licensing restrictions mean that I can't put it on tx.fhir.org. So I don't know where that leaves us

Grahame Grieve2024-08-09T14:25:26Z

what are the technical requirements specifically. i know there is some discussion around packaging but not sure this is the same

Carl Leitner2024-08-09T16:33:57Z

for the licensing restrictions on tx.fhir.org, can HL7 send something more formally around the concerns including me and Nat?

Carl Leitner2024-08-09T16:34:38Z

(i think it was related to redistribution / commercial use)

Carl Leitner2024-08-09T16:49:31Z

Open ICD-11 license (distributed under Creative Commons Attribution-NoDerivs 3.0 IGO license)

1.2.2.WHO does not consider incorporation of ICD-11 into a software product to be an “adaptation”, provided that you do not do any of the following:

  1. Reproduce ICD-11 in part or whole and distribute it under a different name or without attribution;
  2. Reproduce and distribute ICD-11 in part or whole without the ICD-11 codes;
  3. Reproduce ICD-11 in part or a whole without the ICD-11 URIs; or
  4. Reproduce and distribute ICD-11, in part or whole, with any combination of a-c above.

Does this or does this not allow producing a FHIR CodeSystem representation of ICD11? This is the key sticking point for us being able to support it.

Michael Lawley2024-08-10T01:52:40Z

What about previous versions of ICD?

Jens Villadsen2024-08-10T08:02:53Z

They are licensed differently

Michael Lawley2024-08-10T08:04:35Z

:thinking:

Jens Villadsen2024-08-10T08:07:24Z
  1. ok - we don't do anything without attribution
  2. ok - we don't reproduce anything without the codes
  3. that's the problem - we don't distribute the URIs in value sets. Are value sets 'reproducing or distributing ICD-11 in part'? We don't know and we asked for clarification, which I don't see that we got.
  4. (c) is the problem
Grahame Grieve2024-08-10T08:50:18Z

@Michael Lawley we could make the uri a property of the code system, and distribute it that way. So I didn't think that the code system representation was really the issue

Grahame Grieve2024-08-10T08:52:24Z

okay, then as long as a FHIR CodeSystem representation doesn't fall foul of:

  1. 1.2.1.To prevent the dilution of ICD’s purpose to provide a definitive standard for identifying health information, neither the Licensed Materials, nor any portion thereof, may be used for the purpose of developing or promulgating a different standard.

we should be okay, and then we need to work out how to identify Foundation vs any of the Linnearizations.

Michael Lawley2024-08-10T13:06:13Z

I am finding some strange things in WHO IGs and elsewhere:

THO has a content "not-present" version of http://id.who.int/icd/release/11/mms also with no hierarchyMeaning

Michael Lawley2024-08-10T13:19:42Z

then we need to work out how to identify Foundation vs any of the Linnearizations.

we've already agreed on the fundamentals with regard to that, and the WHO public API includes a FHIR API that expresses those agreements

Grahame Grieve2024-08-10T13:46:45Z

I have been scouring https://icd.who.int/icdapi and cannot find FHIR anything

Michael Lawley2024-08-11T03:06:47Z

As per Jose Teixeira, who I asked a months or so ago about incomplete icd-11 code systems in WHO FHIR implementation guides: these are just minimal placeholders (effectively a join of value sets required by a FHIR IG, promoted to a code system) whilst awaiting the full thing.

René Spronk2024-08-11T07:36:34Z

@Grahame Grieve do you know of any plans from WHO/ICD also having ICD-10 hosted on that same service?

Jens Villadsen2024-08-11T13:48:23Z

I have no information about that. but which ICD-10?

Grahame Grieve2024-08-11T13:48:45Z

ICD-10-WHO and ICD-10-DK

Jens Villadsen2024-08-11T14:10:41Z

@Michael Lawley @Grahame Grieve you're most welcome to look at the ICD-11 MMS Code System on Terminz and tell me if this exemplar is valid and legal. It uses the MMS linearization distribution and looks up the Foundation Properties using an API Key obtained from the WHO (the linearization distribution lacks additional designations and properties).

Peter Jordan2024-08-11T21:30:38Z

I tried a simple lookup on the WHO prerelease endpoint:
https://icdapi-fhir-prerelease.azurewebsites.net/fhir/CodeSystem/$lookup?code=XM68M6&system=http://id.who.int/icd/release/11/mms

{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "name",
      "valueString": "ICD-11 for Mortality and Morbidity Statistics"
    },
    {
      "name": "version",
      "valueString": "2024-01"
    },
    {
      "name": "display",
      "valueString": "COVID-19 vaccines"
    },
    {
      "name": "property",
      "part": [
        {
          "name": "code",
          "valueCode": "id"
        },
        {
          "name": "value",
          "valueCode": "http://id.who.int/icd/release/11/2024-01/mms/894585096"
        }
      ]
    },
    {
      "name": "property",
      "part": [
        {
          "name": "code",
          "valueCode": "parent"
        },
        {
          "name": "value",
          "valueCode": "http://id.who.int/icd/release/11/2024-01/mms/1347156717"
        }
      ]
    },
...

That's interesting - the code "XM68M6" has a parent with value "http://id.who.int/icd/release/11/2024-01/mms/1347156717"

If I then do a lookup of this code I get:

{
    "resourceType": "Parameters",
    "parameter": [
        {
            "name": "name",
            "valueString": "ICD-11 for Mortality and Morbidity Statistics"
        },
        {
            "name": "version",
            "valueString": "2024-01"
        },
        {
            "name": "display",
            "valueString": "Viral vaccines"
        },
        {
            "name": "property",
            "part": [
                {
                    "name": "code",
                    "valueCode": "id"
                },
                {
                    "name": "value",
                    "valueCode": "http://id.who.int/icd/release/11/2024-01/mms/1347156717"
                }
            ]
        },
        {
            "name": "property",
            "part": [
                {
                    "name": "code",
                    "valueCode": "code"
                },
                {
                    "name": "value",
                    "valueCode": "XM61M7"
                }
            ]
        },
...

so it looks like "XM61M7" and "http://id.who.int/icd/release/11/2024-01/mms/1347156717" are treated as equivalent in some way.

But then if I $lookup at their parent: "http://id.who.int/icd/release/11/2024-01/mms/164949870" I get

{
    "resourceType": "Parameters",
    "parameter": [
        {
            "name": "name",
            "valueString": "ICD-11 for Mortality and Morbidity Statistics"
        },
        {
            "name": "version",
            "valueString": "2024-01"
        },
        {
            "name": "display",
            "valueString": "Vaccines"
        },
        {
            "name": "property",
            "part": [
                {
                    "name": "code",
                    "valueCode": "id"
                },
                {
                    "name": "value",
                    "valueCode": "http://id.who.int/icd/release/11/2024-01/mms/164949870"
                }
            ]
        },
        {
            "name": "property",
            "part": [
                {
                    "name": "code",
                    "valueCode": "code"
                },
                {
                    "name": "value",
                    "valueCode": ""
                }
            ]
        },
...

the code is an empty string?

Michael Lawley2024-08-12T06:07:08Z

@Peter Jordan your code system is "not-present"?
I can at least say that it should be flagged as caseSensitive=true
Doing a $lookup as per above, only gives back minimal information; is there a way to pull back the hierarchy?

Michael Lawley2024-08-12T06:12:19Z

Michael Lawley said:

Peter Jordan your code system is "not-present"?
I can at least say that it should be flagged as caseSensitive=true
Doing a $lookup as per above, only gives back minimal information; is there a way to pull back the hierarchy?

Wouldn't you expect the value of CodeSystem.content to be "non-present"?
I'll update the caseSensitive value to "true"

Try this to see some nascent Code System properties (grabbed from the Foundation) - including parent and child...

https://terminz.azurewebsites.net/fhir/CodeSystem/$lookup?system=http://id.who.int/icd/release/11/mms&code=XM68M6&property=*&_format=json&_summary=data

I haven't tried anything trickier, such as $subsumes - that could involve a lot of API calls to the Foundation!

Peter Jordan2024-08-12T07:21:40Z

Ah, I'll give that a go - I had tried property=parent to no avail

Michael Lawley2024-08-12T07:28:36Z

Yeah - I haven't implemented $lookup requests for individual properties yet - just all.

Peter Jordan2024-08-12T07:48:44Z

@Peter Jordan Is there a way to do $lookup for the Foundation entity that was missing the code (mentioned above) i.e. so I guess something like (gives me "Code System not found"):
https://terminz.azurewebsites.net/fhir/CodeSystem/$lookup?system=http://id.who.int/icd/entity&code=http://id.who.int/icd/entity/164949870&property=*&_format=json&_summary=data

Kari Heinonen2024-08-12T08:03:48Z

@Kari Heinonen my server won't recognize that system uri - i.e. I don't have a CodeSystem resource that represents the ICD-11 Foundation and, last time I looked, it's not available to download.

Peter Jordan2024-08-12T08:10:11Z

And you don't treat the URIs like http://id.who.int/icd/release/11/2024-01/mms/164949870 as codes in the MMS?
@Kari Heinonen I think the main issue is that the MMS (linearization) doesn't have a parent code in that case.

I think this is one of the things yet to be sorted out regarding representing the MMS as a FHIR CodeSystem

Michael Lawley2024-08-12T08:14:12Z

OK, thank you, thought it must be something like that. Just being overly curious to what that "entity without code" looks like since the interactive ICD-11 browser seems to be aware of that hierarchy relation.

Kari Heinonen2024-08-12T08:29:09Z

@Daniel Vreeman fyi

Grahame Grieve2024-08-13T10:48:53Z

thanks all for the discussion and clarificiation. i am following up. hopefully we can clarify the valueset issue.

Carl Leitner2024-09-27T13:00:52Z
Brian Kaney inquired about the use and definition of Substance.instance in FHIR, expressing confusion over its relevance given that profiles are typically used for defining types of instances, while Rik Smithies explained that Substance.instance indicates whether the resource represents an actual substance or its type, and highlighted the distinction between substance instances and definitions within different FHIR resources. The conversation evolved into discussing potential changes in future FHIR releases regarding the need for the Substance.instance boolean and its implications for handling various resource types.
48 comments

Wondering how to interpret Substance.instance -- which is defined as "Is this an instance of a substance or a kind of one". I thought documenting a kind of a FHIR instance is what profiles are for?

Brian Kaney2024-09-17T18:37:29Z

hi Brian,
When the value is "instance" it means that this resource data (which could also be called a resource instance, but that is an unhelpful coincidence) represents an actual substance entity, that exists in the real world and could be touched (probably) e.g. an actual lump of sugar.
Alternatively it is a type (kind) of substance e.g. the concept of sugar.
Of which you could then have instances.
So kind means this resource (instance) is the wikipedia page about sugar. Sugar info.
Instance means this resource (instance) is about some sugar. Actual sugar.

Rik Smithies2024-09-17T22:18:57Z

Profiles are nice computable way to say how you want your "instances" of any resource to look. I suppose there are instances of resources (data), and kinds of resources (as in the FHIR spec), and then there are instances of substances (lumps etc.) and kinds of substances (types, definitions).

Rik Smithies2024-09-17T22:32:29Z

But wouldn't the concept of sugar be represented as a profile (which is an instance of a structure definition :)) where the code is set to mean sugar? Also noteworthy that as far as I am aware, this flag does not appear on other resource types (including Medication).

Brian Kaney2024-09-18T09:29:49Z

I bring this up because I am just noticing this was changed in R5.

We use profiles to describe how we want our instances to look (e.g. the concept of blood pressure is a profile, and the actual reading is an instance of Observation that conforms to that profile), and we also use R4 Substance + profiles. This new pattern of a boolean to modify the nature of the resource seems different than how it is handled in the rest of FHIR.

Brian Kaney2024-09-18T09:47:25Z

Only if you want to specify how a single resource should be in a profile. Sugar is one of a million substances. You don't want a profile for all of them, any more than you would have a profile of for patient John Smith. If there were 100 variations of Sugar, then you may want a "sugar substances profile", so that all varieties of sugar are done similarly, eg using the "international classification of sugar codes". But otherwise it doesn't make sense to have a profile for one single resource instance

Rik Smithies2024-09-18T09:48:35Z

You could have a profile of BP, it is true, because that is very common, and there are only 20 or so vital signs and we want all the millions of instances to all look the same. But equally, we don't have a profile for every clinical condition in the world (all the hundreds of thousands of SCT codes).

Rik Smithies2024-09-18T09:50:19Z

If you have lots of people making sugar instances and there is something special about them that differs from how salt is represented, then sure, make a profile. Bit this is a totally different issue to Substance.instance. They are not the same concept at all.

Rik Smithies2024-09-18T09:51:37Z

Profiles add documentation, essentially. Substance.instance is a property of the data, that tells people what sort of thing it refers to (like Patient.gender). It is nothing to do with profiles.

Rik Smithies2024-09-18T09:53:50Z

Okay. I am still not seeing how they are different. Or why this pattern then would not apply to Medication. Also, in CPG we use Structure Definitions as first class resources, not just documentation (Case Feature Definitions).

Brian Kaney2024-09-18T09:54:29Z

I think the same thing was considered for Medication, but it just didnt make it to be an actual property.

Rik Smithies2024-09-18T09:55:18Z

To be consistent, Medication could have one. We were doing some revision on Substance, and at that time the instance vs kind was being discussed and it seemed good to make it explicit. That didn't happen with Medication, but it could have.

Rik Smithies2024-09-18T09:56:27Z

Then also for Specimen, Body Structure, Claim, etc. they would all need this boolean right?

Brian Kaney2024-09-18T09:56:45Z

These 2 resources are the only ones that I can think of that can be both instances or kinds.

Rik Smithies2024-09-18T09:56:49Z

No because there is e.g. SpecimenDefinition

Rik Smithies2024-09-18T09:57:18Z

For some resources they can only be instances, and a different resource does the work of the definition. Substance (and Medication) are unusual in that respect.

Rik Smithies2024-09-18T09:58:22Z

Medication is somewhat different to Substance too. Medication can be stated at various levels of completeness. But I think using it as a true "definition" is less common, and not really needed. Because drugs tend to be defined by code systems (RxNorm etc), not resources.

Rik Smithies2024-09-18T10:00:18Z

And there is no perceived need for BodyStructure definition. there is only one body, I guess, and the medical knowledge about say, livers, is not typically captured in FHIR. That would be in the literature.

Rik Smithies2024-09-18T10:02:13Z

Substances are more of a changeable thing, and have electronic catalogues, with supporting data about each substance. You don't tend to get electronic catalogues of body part, except in terminology.

Rik Smithies2024-09-18T10:04:07Z

You could have Claim definitions I suppose. But who is making processable electronic definitions of claim types?

Rik Smithies2024-09-18T10:05:04Z

The point I was making is structure definitions allow us to define the definitions of types of resources already. I am still not seeing the need for that boolean, but will think about it more.

Brian Kaney2024-09-18T10:05:59Z

This is not meta data about a resource - which is what SD is for. This is perhaps meta data about a resource instance.

Rik Smithies2024-09-18T10:07:36Z

There is a clear distinction in the use. It is not possible to do the job of Substance.instance with a profile.

Rik Smithies2024-09-18T10:08:20Z

All an SD can do is say how to use the resource. This would be like trying to use a profile to say if an individual patient was male. Can't be done. Saying how male patients are represented can be done. Saying if a patient is male cannot be done.

Rik Smithies2024-09-18T10:09:40Z

Defining the concept of sugar can be done in a structure definition. Definition a real pile of sugar can be done with an instance of Substance that conforms to that profile?

Brian Kaney2024-09-18T10:12:03Z

Again, that's the approach we use in CPG (case feature definitions are structure definitions)

Brian Kaney2024-09-18T10:12:47Z

But you cannot change from a kind to an instance using a profile. Any more than a profile can flip male to female.

Rik Smithies2024-09-18T10:12:52Z

You could define a new whole resource using an SD e.g. SubstanceInstance, but that is not FHIR. Basically put the instance flag into the name of the resource.

Rik Smithies2024-09-18T10:13:57Z

A resource type can have resource instances. Maybe that is what you are thinking. But this is not that concept.

Rik Smithies2024-09-18T10:15:01Z

The phrase "definition of a real pile" is a little strange though. It would be an instance of a real pile. We don't tend to say "a definition of a patient John Smith".

Rik Smithies2024-09-18T10:17:25Z

By analogy with Patient, if there was a Patient.instance flag, set to type "kind" it might be used to define, say what "US citizens" were like. You could then make a FHIR data set of different nationalities, as actual FHIR resources, saying what the postal address would be (an address in the US probably).
It is true that you could do the same thing with FHIR profiles (and we do e.g. US Core).
But FHIR profiles are not user editable data. Substance catalogues are sets of user editable data about kinds of substances. New ones come along all the time. Users can add new substances to the catalogue.
But users cannot add a new type of patient. They cannot add "Tuvalu citizen". That can only be done as a profile, by standards makers, not by users.
Maybe that is where the similarity and confusion is.

Rik Smithies2024-09-18T10:28:56Z

Admittedly you could in theory use StructureDefinitions as end-user editable definitions and let users create new nationality profiles as FHIR instances. Then drive validation off those. FHIR does eat its own dogfood, so resource profiles are already resources.

But because national profiles are relative static, and more sophisticated, we (certain people) do this "offline" using profile tools and repositories.

Substance catalogues are not static though, and are meant to be end user edited. So they are good for being represented in (end-)user data, not profiles.

So FHIR does definitions in two ways I suppose, as resources (usually with a whole separate resource e.g. SpecimenDefinition, PlanDefinition etc, but not always - regrettably I would say), and as StructureDefinitions/profiles.

It was originally, methodologically, thought that having two resource "flavours" was overkill, I think. Later the paradigm of having both {Resource} and {Resource}Definition seemed to take hold e.g. ObservationDefinition is a relative newcomer. And exists even though we have plenty of BP profiles...

Rik Smithies2024-09-18T10:42:33Z

I agree there is tension/overlap/confusion between the patterns of (resourceType)Definition and Structure Definition. And as you said these definition resource types are a relative newcomer. But now this boolean for instance seem an even newer newcomer and now a third pattern to consider.

You could have a catalog of StructureDefinitions about Observations -- or a catalog of ObservationDefintions (same with SubstanceDefinitions or SDs about Substance). You could also have tools to make managing a catalog of SDs accessible, since structure definitions are data, and there is nothing in FHIR spec that restricts what kind of end-user can create structure definitions.

I did not have an assumption that certain resource types are off limits for users in the FHIR specification. In clinical reasoning, we create structure definitions as part of routine authoring, with tooling support, even though many of the teams we work with are not federal agencies. I am not sure the level of sophistication we have, but they are kinda sophisticated :)

Brian Kaney2024-09-18T11:06:09Z

It's not really all that new. This flag has around since the early days of R5. Almost 5 years. But the resource has had this feature since DSTU2 (and had an optional backbone about it). It could always be a kind or an instance. It just was not so explicit til R5.

Sure, some end users can create profiles. Nothing is off limits, no hard edges. Some create complex quality measures and plan definitions. But a list of substances with a few properties is sort of in a different category I suppose. They are not deeply FHIR oriented, unlike say a profile (though complexity can indeed be hidden).

Profiles are "FHIR like", they are about data constraints. Substance types are very much in user space (chemists).

Rik Smithies2024-09-18T11:57:50Z

I think one thing that is missing from this discussion is that whether an instance claims conformance to a profile or whether it is conformant to a profile, doesn't change the meaning of the resource. A Patient resource that meets the Tuvalu patient profile doesn't need to shout can do so without adding the claim that it meets that profile. And if it does claim that profile, it can't change the meaning of the resource.

The other thing is that profiles (realized in StructureDefinitions) can't be used most places that a Substance can be used. I can't just plop the sugar profile in somewhere that I want to say "use Dememera." Those places are looking for a Substance.

Elliot Silver2024-09-18T14:24:08Z

I think it is valid to say that if a Patient is conformant to US Core, it means it is a US Core Patient. And if an Observation conforms to blood pressure profile, that Observation means a blood pressure. In this sense, the structure definition uses conformance rules to express meaning, and the Patient or Observation are the instances of it.

I think you can make reference to a sugar profile by either an invariant rule or using the artifact-reference extension (as seen in CRMI, and the FHIR extension pack).

Brian Kaney2024-09-18T14:47:16Z

E.g. those places can be expressed as referring to a substance that means Sugar

Brian Kaney2024-09-18T14:50:20Z

But in R6 with SubstanceDefinition I am guessing the Substance.instance bool will go away? In this case the substance of sugar will be via SubstanceDefinition, and the case of a pile of sugar it will be Substance with instantiates[x] to that definition?

Brian Kaney2024-09-18T15:02:07Z

That is a possible way to do this. But SubstanceDefinition was not intended to totally replace Substance[instance=kind]. Personally I would quite like that, but the thinking was that for simpler and legacy systems that are using Substance for that already, they can keep doing that. SubstanceDefinition is for serious catalogues that need a lot of info. Substance is still there for simpler cases. I actually doubt that anyone is using Substance for that, but you never know. We already had a presumed legacy when the bigger requirements that led to SubstanceDefinition came along. We didn't want to fill up Substance with all the stuff in SubstanceDefinition, but some use cases do need it. So we have two worlds. I would consider deprecating Substance.instance, and making it always an instance. But it may break someone somewhere and stop them going to R6, without API level changes.

Rik Smithies2024-09-18T15:25:41Z

Brian Kaney said:

I think it is valid to say that if a Patient is conformant to US Core, it means it is a US Core Patient.

I like to think of a profile as one of those children's block toys, where you have various shaped blocks and various shaped holes to push them through. If an instance conforms to a profile, it meets all the constraints of the profile. If a block can go through the hole, it meets the constraints of the hole. Just because I can slide the cylinder though the square hole doesn't mean you can start calling it a cube.

Elliot Silver2024-09-18T15:44:57Z

Rik Smithies said:

Personally I would quite like that, but the thinking was that for simpler and legacy systems that are using Substance for that already, they can keep doing that.

Substance.instance data type changed drastically from R4 -> R5. Since practically speaking many are skipping 5 and will be going right to 6, it could be a good idea to remove that boolean in R6..

Brian Kaney2024-09-18T16:14:43Z

Elliot Silver said:

Just because I can slide the cylinder though the square hole doesn't mean you can start calling it a cube.

Sure you can ;) given the context of use - but if you care about the shape than your conformance would need to define it -- "a small cylinder means it fits in a hole" vs "a small cylinder means it fits in a hole, and that hole is round, and the edges of the cylinder are all equidistant from the hole edge".

Brian Kaney2024-09-18T16:22:11Z

re removing the flag, that would break any R4 data that used this resource for kinds of Substance. So while it may be good for some, it could be very bad for others. What's the big problem with the flag anyway?

Rik Smithies2024-09-18T21:37:27Z

In R4 https://hl7.org/fhir/r4/substance.html Substance.instance is a complex type:

image.png

Brian Kaney2024-09-19T11:05:46Z

Yes indeed. It's definitely a change. Is it hard to support do you think? Is it the fact that it's changed from a backbone to a plain attribute? Or is it that the concept of instance is not right for you.

Rik Smithies2024-09-19T11:26:43Z

Here are my thoughts:

  • In R4, instance it is a complex type, and the Substance resource type has dual role and could be either an instance or class.
  • In R5+, SubstanceDefinition has been introduced, but Substance.instance remains and the data type changed. I would have expected to simply remove this property.

I think it is confusing to support this property when I consider a migration from R4 -> R5 (it seems http://hl7.org/fhir/extensions/conversions-Substance.html is not valid). Here's my thoughts on how to migrate:

  • If (r4) Substance.instance present, create (r5) SubstanceDefinition
  • If (r4) Substance.instance not present, create (r5) Substance and set instance = true

I don't see a case where (r5) Substance.instance would ever be false, since that's what SubstanceDefinition is for.


In continuing research there seem to be inconsistently documented semantics and missing relationships that I would have expected to exist:

Resource Type Def Resource Type Semantics Relationships
Observation ObservationDefinition Defined Observation.instantiates[x]
Condition ConditionDefinition Not Defined N/A
Medication MedicationKnowledge Not Defined Medication.definition
Substance SubstanceDefinition Not Defined N/A
Device DeviceDefinition Not Defined Device.definition
Brian Kaney2024-09-24T20:07:37Z

Some discussion in O&O yesterday. There is a growing feeling that it may be good to deprecate Substance as a definition. The main use of this is by Pharmacy WG for medication that is defined specially, using Medication.ingredient (which is relatively rare) but then not using a substance code, but a reference to Substance resource. That now appears to be vanishingly rare. It needs some discussion O&O, Pharmacy and BR&R to work this out. Co-chairs are aware.

Rik Smithies2024-09-24T21:06:49Z
Rik Smithies2024-09-25T21:31:00Z
The discussion revolves around implementing bearer token authentication in the HL7 Validator to enable the use of the Ontoserver for validation against Dutch SNOMED extension sets. Key participants, including Ardon Toonstra and Grahame Grieve, explore the current capabilities and future plans for integrating OAuth2 support, with ongoing contributions toward finalizing the necessary code updates for this functionality.
41 comments
ML
KS
PE

Hi @Grahame Grieve ,
The Netherlands now has a nice national terminology server (the Ontoserver)! We would like to use it for validation purposes as this would solve a lot of validator errors/warnings due to the Dutch SNOMED extension sets we use.
However, to use the Ontoserver we require authentication based on bearer tokens. I believe the HL7 validator currently does not support authentication? Are there any plans to add such a feature?

Ardon Toonstra2021-03-02T13:31:29Z

"HL7 Validator" also means "IG Publisher" in this context ;)

Pieter Edelman2021-03-02T13:34:06Z

@Mark Iantorno please add this to your list. and I would propose:

  • you can provide a bearer token in the parameters
  • or you can it in .fhir/validator.config or similar
Grahame Grieve2021-03-02T19:41:20Z

Okay, this will fit in with the other HTTP library work I want to do

Mark Iantorno2021-03-02T19:42:05Z

Nice! :D Thanks

Ardon Toonstra2021-03-03T11:48:26Z

+1 for this request , ie. hl7validator to support OAuth2 over HTTPS against a 3rd-party FHIR TX instance

supply the OAuth2 access token to the hl7validator - assuming it is obtained out-of-band in one of the OAuth2 flows

@Mark Iantorno @Grahame Grieve

David Simons2021-07-20T12:16:17Z

The core validator does token based auth as of now

Mark Iantorno2021-07-20T13:09:37Z

OAuth2 would be a little more difficult to set up

Mark Iantorno2021-07-20T13:10:04Z

Mark Iantorno said:

The core validator does token based auth as of now

Can you elaborate a bit more, please, what that means, or where documented? Glad to test drive!
(I did not see it under https://github.com/hapifhir/org.hl7.fhir.core )

If it means, supply the hl7validator CLI with an OAuth2 Bearer access token, obtained separately (out-of-band), like "MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3", and using it in the FHIR-REST calls to the TX, even without refresh, in the HTTP Authorization request header, that'd be great already!

David Simons2021-07-20T13:45:21Z

@Mark Iantorno - is there a feature branch we can look at / contribute to?

PS: are you our sick? get well soon!

David Simons2021-07-26T12:49:34Z

I was sick last week, feeling better now, thanks.

Mark Iantorno2021-07-26T13:58:56Z
Mark Iantorno2021-07-26T13:59:28Z

that one is for the website that hosts the validator

Mark Iantorno2021-07-26T14:00:05Z

actual validator is in the core library

Mark Iantorno2021-07-26T14:00:12Z
Mark Iantorno2021-07-26T14:00:22Z

@David Simons

Mark Iantorno2021-07-26T14:00:26Z

Thanks and yes - I scrutinized that latter repo - but could not find any use of the headers argument in the org.hl7.fhir.core\org.hl7.fhir.r4\src\main\java\org\hl7\fhir\r4\utils\client\ClientUtils.java, yet, for example, trickling down from the
org.hl7.fhir.validation\src\main\java\org\hl7\fhir\validation\cli\utils\Params.java

public <T extends Resource> ResourceRequest<T> issuePostRequest(URI resourceUri,
                                                                  byte[] payload,
                                                                  String resourceFormat,
                                                                  Headers headers,
                                                                  String message,
                                                                  long timeout)

e.g. a public static final String TERMINOLOGY_AUTH = "-txAuth"; for a bearer token to be ingested as a HTTP Authorization request header. :)

David Simons2021-07-26T15:06:36Z

created a DRAFT pull request https://github.com/hapifhir/org.hl7.fhir.core/pull/566/files - let me see how far I get myself :)

David Simons2021-07-27T11:56:53Z

was able to get the OAuth2 Bearer access token to be passed to TX, from CLI via parameter like-txAccessToken e5f81bb4-4cb8-47a7-9ee4-03b049dacbbb , on that branch/PR.

Now trying to overcome (customizing):

  • missing api-version: 1 HTTP header
  • missing CapabilityStatement from TX, upon metadata?_summary=true, and metadata?mode=terminology
  • java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one in the R4 ClientUtils on the httpclient.execute(request). This is probably related to the required work on the HTTP client in the hl7validator.
David Simons2021-07-30T07:58:20Z

Hopefully this work item to productize can be prioritized :) https://github.com/hapifhir/org.hl7.fhir.core/issues/588

David Simons2021-08-31T09:28:37Z

@Mark Iantorno yes but we need to get a new version out asap

Grahame Grieve2021-08-31T09:43:00Z

working on this today

Mark Iantorno2021-08-31T13:09:13Z

@Grahame Grieve do you mean you want me to publish a new version of the core before doing this

Mark Iantorno2021-08-31T13:09:37Z

or just do this, then publish a new version of the core?

Mark Iantorno2021-08-31T13:09:47Z

well, I'd really like to have you sort out your merge thing, then I can commit a bunch of code, and then we get a release out later today your time

Grahame Grieve2021-08-31T13:15:34Z

All my merges accept for the one I need James to assist with are closed?

Mark Iantorno2021-08-31T13:18:49Z

Which one do you mean?

Mark Iantorno2021-08-31T13:18:56Z

The validation one you said you had to merge with the code I committed on Friday

Grahame Grieve2021-08-31T13:20:22Z

I pushed the changes the PR you had made

Mark Iantorno2021-08-31T13:21:02Z

and merged that

Mark Iantorno2021-08-31T13:21:09Z

ok. I'll merge when I wake up tomorrow and we'll do a release

Grahame Grieve2021-08-31T13:22:16Z

sounds goood

Mark Iantorno2021-08-31T13:22:25Z

I'll start on the issue 588

Mark Iantorno2021-08-31T13:22:32Z

Did this (ability to supply bearer token via the CLI) ever properly land? I followed the tickets and got to https://github.com/hapifhir/org.hl7.fhir.core/issues/603 but that was auto-closed due to inactivity.

Michael Lawley2024-04-19T09:48:07Z

I think it's close. All the infrastructure is in place, but no one wanted to test it for us

Grahame Grieve2024-04-19T11:53:12Z

I have NHS people wanting this capability

Michael Lawley2024-04-24T05:06:31Z

well, you could consider doing a PR.

Roughly, org.hl7.fhir.convertors.txClient.TerminologyClientFactory.makeClient needs to take a parameters with additional headers to pass through to TerminologyClientR4 etc, and that needs to be called using org.hl7.fhir.utilities.settings.FhirSettings.getApiKey

Grahame Grieve2024-04-25T12:51:47Z

Thanks - I'll see what we can do

Michael Lawley2024-04-25T14:15:01Z

@Michael Lawley any positive progress you can share with us?

Ken Sinn2024-09-23T20:36:13Z

Totally untested, but from a quick look through the code I am thinking a patch like the following would work:

--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/client/network/FhirRequestBuilder.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/client/network/FhirRequestBuilder.java
@@ -27,6 +27,7 @@ public class FhirRequestBuilder {
   protected static final String HTTP_PROXY_USER = "http.proxyUser";
   protected static final String HTTP_PROXY_PASS = "http.proxyPassword";
   protected static final String HEADER_PROXY_AUTH = "Proxy-Authorization";
+  protected static final String HEADER_AUTHORIZATION = "Authorization";
   protected static final String LOCATION_HEADER = "location";
   protected static final String CONTENT_LOCATION_HEADER = "content-location";
   protected static final String DEFAULT_CHARSET = "UTF-8";
@@ -184,6 +185,11 @@ public class FhirRequestBuilder {
         return response.request().newBuilder()
           .header(HEADER_PROXY_AUTH, credential)
           .build();
+      } else if (FhirSettings.hasApiKey()) {
+        String credential = FhirSettings.getApiKey();
+        return response.request().newBuilder()
+          .header(HEADER_AUTHORIZATION, "Bearer: " + credential)
+          .build();
       }
       return response.request().newBuilder().build();
     };
Michael Lawley2024-09-24T03:38:22Z

@David Otasek can you look at this - thanks

Grahame Grieve2024-09-27T11:18:47Z
dialog item control
#questionnaire
Fikri Milano proposed adding a 'dialog' item control type for displaying choices in a pop-up dialog, particularly for mobile applications, and suggested it be an extension to allow for flexibility based on the renderer. The discussion included concerns about the implementation details, functionality, and whether introducing such a control would enhance or complicate the standard's usability across different renderers.
40 comments
YW

Is it possible to propose a new item control called 'dialog'? To specifically display choices in a pop up dialog.
https://hl7.org/fhir/extensions/CodeSystem-questionnaire-item-control.html

Fikri Milano2024-08-27T10:20:07Z

Sure, but when would you need a dialog box to display answer options for question?

Paul Lynch2024-08-27T20:51:25Z

For context:
It's simply a design decision, a client asked for a dialog.

And we're planning to use the 'dialog' control type in the Android FHIR SDK.

In the SDK, we have a hardcoded logic that says, if there are at least 10 options, then use a dialog. But we'd like to specifically use a dialog by declaring an item control type extension, so even if the options are less than 10, we can still use a dialog.

3d4abcf5-1a2a-4769-b269-421d7e8f1ec8.jpg

Fikri Milano2024-08-27T22:42:46Z

I would have said, if there are 10 options or more, use a drop down list, but maybe a dialog like that is right for the context of a phone app.

So, when you say "dialog", you mean specifically a dialog with checkboxes/radio buttons, and not a dialog showing a drop down list? I am just wondering if the dialog gets used for other control types sometimes.

Paul Lynch2024-08-28T13:45:29Z

In a phone you could make that decision anyway without having something in the item.
The UI hints are just that, and depending on the context/features/capabilities of the renderer and it's input mechanisms, those sorts of things could be done.

Brian Postlethwaite2024-08-29T04:44:16Z

To me they are declaring what could be appropriate, and in some cases not appropriate.
If you're saying an auto-complete, you're giving a pretty strong indication that it's probably not going to be good to use radios...

Brian Postlethwaite2024-08-29T04:45:26Z

So, when you say "dialog", you mean specifically a dialog with checkboxes/radio buttons

@Paul Lynch if options are defined, yes.

Fikri Milano2024-08-29T05:46:16Z

@Brian Postlethwaite
But it would also makes sense to use dialog control type to display something else.
Let's say if we add a dialog control type to a group, that means, whatever items are inside the group, will be displayed in a dialog. The trigger in showing that dialog can be a button.

Fikri Milano2024-08-29T09:18:44Z

There are an awful lot of complexities in that.

Brian Postlethwaite2024-08-29T09:21:57Z

This is an example in FHIR doc where it tries to display a content to a dialog, it's not possible to do that in all renderer, since the example is not really using anything similar to dialog control type.
https://build.fhir.org/ig/HL7/sdc/examples.html#using-contextexpression

I think defining dialog control type would allow other renderers to specifically display a dialog in such scenario, no?

Fikri Milano2024-08-29T09:23:13Z

Dialogue then needs buttons, what's on them, what's the behaviour when you click them, OK, cancel, does cancel throw away the data, does that mean you need a new copy of that part. When would dynamic expressions using that data be fired etc...

Brian Postlethwaite2024-08-29T09:25:21Z

I guess the question is where the line is drawn between what goes in the sdc ig and what is considered implementation. But I don't really feel dialog is a step forward in terms of "specificity" of the sdc ig - for example, we do have collapsible which is a very specific ui treatment.

Jing Tang2024-08-29T10:01:12Z

Fikri Milano said:

Brian Postlethwaite
But it would also makes sense to use dialog control type to display something else.
Let's say if we add a dialog control type to a group, that means, whatever items are inside the group, will be displayed in a dialog. The trigger in showing that dialog can be a button.

I think the benefit in displaying options or questions in a dialog is probably specific to phone UIs, but then probably other renderers could ignore it.

One concern I have is that currently itemControl's cardinality is 0..1, which means if you said an item was 'dialog', you couldn't say anything else about it (e.g., use checkboxes or a dropdown).

Paul Lynch2024-08-29T15:57:26Z

@Paul Lynch would it makes sense to you if we have the dialog as it's own extension?

So in an item, we can declare both the dialog extension and itemControl extension

Fikri Milano2024-09-16T13:09:00Z

I don't suppose you're coming to the connectathon on the weekend by chance @Fikri Milano

Brian Postlethwaite2024-09-17T03:49:16Z

I don't, how do I join?

Fikri Milano2024-09-17T05:03:57Z

It's an in-person event in Atlanta (USA)

Brian Postlethwaite2024-09-17T05:04:26Z

I couldn't join, too expensive '-'
I thought it's an online call.

Fikri Milano2024-09-17T05:08:03Z

Fikri Milano said:

Paul Lynch would it makes sense to you if we have the dialog as it's own extension?

So in an item, we can declare both the dialog extension and itemControl extension

In case anyone has comment about this, please let me know

Fikri Milano2024-09-17T05:09:04Z

We do have online calls on Thursday afternoons (5 Eastern), but not this week or next week due to travel and the meeting next week.

Lloyd McKenzie2024-09-17T05:33:11Z

Fikri Milano said:

Paul Lynch would it makes sense to you if we have the dialog as it's own extension?

So in an item, we can declare both the dialog extension and itemControl extension

Yes, that sounds better.

Paul Lynch2024-09-17T14:10:23Z

Lloyd McKenzie said:

We do have online calls on Thursday afternoons (5 Eastern), but not this week or next week due to travel and the meeting next week.

@Fikri Milano : https://www.hl7.org/concalls/CallDetails.cfm?concall=72728. "5 p.m. EST" should say "ET" (eastern time). It looks like you are 11 hours ahead of ET, so I can see that would be difficult time to meet for you, unfortunately.

Paul Lynch2024-09-17T14:13:34Z

Thanks all, it will be super early for me (4 AM), but I'll drop by if I do have the chance.

Fikri Milano2024-09-18T10:43:49Z

For the dialog extension, I'll create a jira ticket for now, and share the link here

Fikri Milano2024-09-18T10:45:43Z

Enjoy the event :D

Fikri Milano2024-09-19T06:16:11Z

Here's the Jira ticket https://jira.hl7.org/browse/FHIR-48350
cc @Jing Tang

Fikri Milano2024-09-22T00:59:07Z

It seems to me adding a 'dialog' code in the itemControl is a better solution. 'dialog' is essentially same as 'page' and 'tab-container' in that they are all containers of one or more items. They apply to the group items but not the question items.

Ye Wang2024-09-22T13:47:03Z

A message was moved here from #questionnaire > Connectathon track by Ye Wang.

Notification Bot2024-09-22T13:49:30Z

Yeah, that's what I initially thought, open for discussion. Feel free to leave a comment on the Jira ticket too

Fikri Milano2024-09-22T14:13:13Z

Dialog, to me, says "pop-up", and that's not what we're going for here...

Lloyd McKenzie2024-09-22T14:21:08Z

Right, the implementation of a dialog/pop-up will be tricky. A lot of more details are needed to decide when to bring up the dialog, how to reopen the dialog once it's closed, and whether it is modal or not, etc.

Ye Wang2024-09-22T20:34:10Z

And what happens if cancelled

Brian Postlethwaite2024-09-22T21:10:36Z

I understand your concerns.
Would having more indicators to the extension make it more possible to add the dialog to FHIR?

Fikri Milano2024-09-23T05:45:59Z

Lloyd McKenzie said:

Dialog, to me, says "pop-up", and that's not what we're going for here...

Is it because of the concerns mentioned by @Ye Wang and @Brian Postlethwaite ? Or is it something else?

Fikri Milano2024-09-23T05:48:41Z

If you mean you're looking to do choice items like that instead of combo boxes, you would be free to use that for your mobile interface without having specific extension to request it - outside combo-box.
But if you're looking more for sow these 5 items as a popup dialog to capture.
The item-control is the hint to indicate to the renderer what type of input mode is required to enter that field which would be most appropriate for the options.
it's not an explicit commandment that you MUST use that format.
Your rendering can be consistent with how the rest of your system does things and still retain the functionality of the form.
Usually the selection is based on how many options are available. e.g.

  • < 5 radio buttons is usually good
  • < 30 drop down/combo is usually good
  • more than this you're wanting some form of finder/search such as an auto-complete style

With mobile devices dropdown/combo can be awkward and a popup style selector which takes much of the screen is also common in other mobile forms engines.
However that style is not usually appropriate in a laptop/tablet environment.

Brian Postlethwaite2024-09-23T12:24:09Z

hint to indicate to the renderer what type of input mode is required to enter that field which would be most appropriate for the options.
it's not an explicit commandment that you MUST use that format.

@Brian Postlethwaite thanks, we can say that it's optional then, depending on the renderer. The input mode would makes sense for renderer A but not renderer B.

In renderer A, the dialog feature will be used, since it's a feature that only makes sense for renderer A.
In renderer B, the dialog feature wouldn't be used, since it wouldn't makes sense to use it. But the questionnaire should still works ok.

With that context, do you think it would makes sense to add the dialog extension to the specific renderer only? instead of trying to apply that to the whole FHIR standard.
I think that wouldn't affect interoperability by much, right?

Fikri Milano2024-09-27T03:55:58Z

So, other renderers will simply ignore that custom dialog extension, with a note to not sacrifice functionality of the Questionnaire.

Fikri Milano2024-09-27T03:58:14Z

That's the expectation, but I'm sure all of us would like to explore to see if it's something we'd want to do also. And be sure if it's in the spec, we all understand the functionality.

Brian Postlethwaite2024-09-27T06:30:25Z

Each of the current renderers have a few internal features that aren't in the standard, and that's ok.

Brian Postlethwaite2024-09-27T06:31:29Z

But it's also good to have consistency too.
Which is also what you're seeking.

Brian Postlethwaite2024-09-27T06:32:20Z
The discussion focused on improving the narrative linking within International Patient Summary (IPS) documents by using an id/idref pattern to better associate HTML elements with their corresponding resources, enhancing rendering and display capabilities. The participants agreed on the importance of incorporating clear examples into future IPS specifications while exploring ways to optimize the linking mechanism to facilitate smoother transitions during resource transformations.
36 comments

When rendering an IPS document, IPS viewers are able to do a much better job if there's a map between the section entry resources and the narrative html elements that represent it

Grahame Grieve2023-11-28T23:26:05Z

a typical situation might be that there's a list of items, which each item in the list is associated with an underlying allergyIntolerance resource

Grahame Grieve2023-11-28T23:26:45Z

or maybe there's a table of observations

Grahame Grieve2023-11-28T23:26:57Z

if a renderer knew which <li> or <tr> was associated with a particular resource, it could add links, mouse-overs etc that added reference, provenance information, or it could switch displays between consumer and clinician friendly, for interest

Grahame Grieve2023-11-28T23:28:15Z

NZ has a particular interest in this after the connectathon of the last two days. And the spec does describe how to do this in the Composition resource

Grahame Grieve2023-11-28T23:28:45Z
<div xmlns="....">
  <table class="grid">
   <tr idref="t1"><td>something...</td></tr>
   <tr idref="t2"><td>something else...</td></tr>
  </table>
</div>
Grahame Grieve2023-11-28T23:31:54Z

and then:

Grahame Grieve2023-11-28T23:32:00Z
  "section" : [{
    "title" : "Active Problems",
    "code" : {
    // snip
    },
    "text" : {
      // as above
    },
    "entry" : [{
      "id" : "t1",
      "reference" : "Condition/eumfh-39-07-1"
    }]
  },
  // etc
Grahame Grieve2023-11-28T23:33:09Z

@John D'Amore I'd like IPS to mention the pattern and have a worked example. (but not to require it; that belongs in IPS profiles)

Grahame Grieve2023-11-28T23:34:32Z
Notification Bot2023-11-29T00:20:27Z

@Grahame Grieve

Currently the IPS reference server uses a different pattern utilizing the narrativeLink extension to accomplish this (http://hl7.org/fhir/StructureDefinition/narrativeLink). We did it that way since that's how we read the narrative guidance around the narrativeLink and originalText extensions (https://build.fhir.org/narrative.html#linking). I agree we should incorporate examples of this into the next IPS release (note reference server was still a work in progress when 1.1 came out).

We do reference back indirectly to the base FHIR spec somewhat in this section (https://build.fhir.org/ig/HL7/fhir-ips/design.html#narrative-and-language-translation), but also agree we could clarify that further.

John D'Amore2023-11-29T00:50:33Z

hmm. it's the same use case? Got an example?

Grahame Grieve2023-11-29T00:57:58Z

I didn't use that because it's a reference from a resource to a composition, and it'll be different for each occurrance of the same resource in different IPS documents, even if the resource hasn't otherwise changed .

Grahame Grieve2023-11-29T00:58:55Z

and because you sure don't want to update .meta.lastUpdated but you kind of need to.

Grahame Grieve2023-11-29T00:59:15Z

the id/idref solution is neater in that it's all in the composition

Grahame Grieve2023-11-29T00:59:32Z

through I agree it's what the spec describes more clearly

Grahame Grieve2023-11-29T01:03:42Z

This is just a random example from the IPS reference server hosted by HL7, not necessarily a good example: https://hl7-ips-server.hl7.org/fhir/Patient/49/$summary

John D'Amore2023-11-29T01:55:05Z

It does follow the pattern of placing the ID in the <tr> which is a practice used by a lot of CDA examples gong back awhile. I agree that the section.entry.id pattern looks cleaner (i.e. it's not stuck in an extension). I'll try to raise this for discussion on next IPS weekly call

John D'Amore2023-11-29T01:56:49Z

Yes, let's talk about this. The next call is in just over 2 hours from now.

Rob Hausam2023-11-29T13:56:18Z

another reason for me to prefer the id/idref model: there might be multiple references in the narrative to the same resource (different language sections), and it's cleaner this way too

Grahame Grieve2023-11-29T17:49:51Z

yet another: the example document you referred to has multiple matching targets for the narrativeLink extensions.

Grahame Grieve2023-12-01T05:40:16Z

This topic was extensively discussed at the FHIR Connectathon 37. I'll tag participants in this post, but the consensus was that id/idref patterns should be the preferred mechanism for narrative linking in IPS generation. A few consequences/considerations of this decision:

  • Narrative linking is not required in IPS and there's no plan to require it. This is just a preferred mechanism for those who want to link narrative between individual resources and the Composition.text/Composition.section.text
  • The HAPI reference implementation of IPS currently uses the alternative linking mechanism of the narrativeLink extension. Based on this decision, we should work to change the HAPI pattern for references
  • We will work over the weekend to create an example of this linking pattern before the end of the connectathon.

THanks to those who contributed in the discussion. @Peter Jordan @Giorgio Cangioli @Rob Hausam @Darren Liu @Martin Kaye @Andrew Liu @Hanhong Lu @Abigail Nicolas @James Agnew

John D'Amore2024-09-21T14:16:42Z

@Lisa Nelson this is your answer, I think

Grahame Grieve2024-09-21T14:37:28Z

do we have an example?

Grahame Grieve2024-09-21T14:37:34Z
John D'Amore2024-09-21T14:55:50Z

ok I'll check it shortly

Grahame Grieve2024-09-21T15:05:57Z
{
    "resourceType": "Bundle",
    "id": "NZ-IPS-20231009024857",
    "language": "en-NZ",
    "identifier": {
        "system": "urn:oid:2.16.724.4.8.10.200.10",
        "value": "59f51f0b-2005-485c-858e-3d3ae9657287"
    },
    "type": "document",
    "timestamp": "2023-10-09T02:48:57.4219686+00:00",
    "entry": [
        {
            "fullUrl": "https://terminz.azurewebsites.net/fhir/Composition/d2d5d4dd-4e86-41c6-98d2-e412882e9b4c",
            "resource": {
                "resourceType": "Composition",
                "id": "d2d5d4dd-4e86-41c6-98d2-e412882e9b4c",
                "meta": {
                    "versionId": "1"
                },
                "language": "en-NZ",
                "text": {
                    "status": "generated",
                    "div": "<div xmlns='http://www.w3.org/1999/xhtml' lang='en-NZ' xml:lang='en-NZ'>International Patient Summary for <span idref=\"AAA1234\">James Judge</a></div>"
                },
                "identifier": {
                    "system": "urn:oid:2.16.840.1.113883.2.18.7.2",
                    "value": "59f51f0b-2005-485c-858e-3d3ae9657287"
                },
                "status": "final",
                "type": {
                    "coding": [
                        {
                            "system": "http://loinc.org",
                            "code": "60591-5",
                            "display": "Patient summary Document"
                        }
                    ]
                },
                "subject": {
                    "reference": "Patient/AAA1234"
                },
                "date": "2021-05-03",
                "author": [
                    {
                        "reference": "Organization/03993b0c-87ae-478b-8556-8c52a68c3486"
                    }
                ],
                "title": "International Patient Summary",
                "confidentiality": "N",
                "attester": [
                    {
                        "mode": "professional",
                        "time": "2021-05-03",
                        "party": {
                            "reference": "PractitionerRole/1153dc30-cf69-402f-9522-132ec9ec14ac"
                        }
                    }
                ],
                "custodian": {
                    "reference": "Organization/15d2d767-48ba-4222-a1ca-8fa34393aed4"
                },
                "relatesTo": [
                    {
                        "code": "transforms",
                        "targetIdentifier": {
                            "system": "urn:oid:2.16.840.1.113883.2.18.7.2",
                            "value": "59f51f0b-2005-485c-858e-3d3ae9657287"
                        }
                    }
                ],
                "event": [
                    {
                        "code": [
                            {
                                "coding": [
                                    {
                                        "system": "http://terminology.hl7.org/CodeSystem/v3-ActClass",
                                        "code": "PCPR"
                                    }
                                ]
                            }
                        ],
                        "period": {
                            "end": "2021-05-03"
                        }
                    }
                ],
                "section": [
                    {
                        "title": "Allergies and Intolerances",
                        "code": {
                            "coding": [
                                {
                                    "system": "http://loinc.org",
                                    "code": "48765-2",
                                    "display": "Allergies and adverse reactions Document"
                                }
                            ]
                        },
                        "text": {
                            "status": "generated",
                            "div": "<div xmlns='http://www.w3.org/1999/xhtml' lang='en-NZ' xml:lang='en-NZ'>There is no information available regarding the subject's allergy conditions.</div>"
                        },
                        "entry": [
                            {
                                "reference": "AllergyIntolerance/d46cc177-5660-46cc-9f55-6c28e1bc3bba"
                            }
                        ]
                    },
                    {
                        "title": "Problem List",
                        "code": {
                            "coding": [
                                {
                                    "system": "http://loinc.org",
                                    "code": "11450-4",
                                    "display": "Problem list - Reported"
                                }
                            ]
                        },
                        "text": {
                            "status": "generated",
                            "div": "<div xmlns='http://www.w3.org/1999/xhtml' lang='en-NZ' xml:lang='en-NZ'>There is no information available about the subject's health problems or disabilities.</div>"
                        },
                        "entry": [
                            {
                                "reference": "Condition/20a587fa-239f-49c2-a3c8-ff2f2a18b654"
                            }
                        ]
                    },
                    {
                        "title": "Medication Summary",
                        "code": {
                            "coding": [
                                {
                                    "system": "http://loinc.org",
                                    "code": "10160-0",
                                    "display": "History of Medication use Narrative"
                                }
                            ]
                        },
                        "text": {
                            "status": "generated",
                            "div": "<div xmlns='http://www.w3.org/1999/xhtml' lang='en-NZ' xml:lang='en-NZ'>There is no information available about the subject's medication use or administration.</div>"
                        },
                        "entry": [
                            {
                                "reference": "MedicationStatement/4e348646-0375-486a-a33d-d19801e6c7f7"
                            }
                        ]
                    },
                    {
                        "title": "Immunizations",
                        "code": {
                            "coding": [
                                {
                                    "system": "http://loinc.org",
                                    "code": "11369-6",
                                    "display": "History of Immunization Narrative"
                                }
                            ]
                        },
                        "text": {
                            "status": "generated",
                            "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">\r\n  <table>\r\n    <thead>\r\n      <tr>\r\n        <th>Vaccine</th>\r\n        <th>Status</th>\r\n        <th>Occurance</th>\r\n        <th>Route</th>\r\n        <th>Dose #</th>\r\n        <th>Series</th>\r\n      </tr>\r\n    </thead>\r\n    <tbody>\r\n      <tr>\r\n        <td>Influenza, seasonal, injectable</td>\r\n        <td>Completed</td>\r\n        <td>2020-07-03</td>\r\n        <td>Injection, intramuscular</td>\r\n        <td>2</td>\r\n        <td>45y (Eligible condition (Influenza))</td>\r\n      </tr>\r\n      <tr>\r\n        <td>Influenza, seasonal, injectable</td>\r\n        <td>Completed</td>\r\n        <td>2019-06-03</td>\r\n        <td>Injection, intramuscular</td>\r\n        <td>1</td>\r\n        <td>45y (Eligible condition (Influenza))</td>\r\n      </tr>\r\n    </tbody>\r\n  </table>\r\n</div>"
                        },
                        "entry": [
                            {
                                "reference": "Immunization/c5efb4c3-91cf-4f63-b176-a697215d727a"
                            },
                            {
                                "reference": "Immunization/f58b2627-eeac-4280-8475-195ae422aa2d"
                            }
                        ]
                    }
                ]
            }
        },
        {
            "id" : "AAA1234",
            "fullUrl": "https://terminz.azurewebsites.net/fhir/Patient/AAA1234",
            "resource": {
                "resourceType": "Patient",
                "id": "AAA1234",
                "text": {
                    "status": "generated",
                    "div": "<div xmlns='http://www.w3.org/1999/xhtml' xml:lang='en-NZ'>Name: James Judge</div>"
                },
                "identifier": [
                    {
                        "system": "https://standards.digital.health.nz/ns/nhi-id",
                        "value": "AAA1234"
                    }
                ],
                "name": [
                    {
                        "use": "usual",
                        "family": "Judge",
                        "given": [
                            "James"
                        ]
                    }
                ],
                "telecom": [
                    {
                        "system": "phone",
                        "value": "tel:+6478532279",
                        "use": "home"
                    }
                ],
                "gender": "male",
                "birthDate": "1985-04-25",
                "address": [
                    {
                        "use": "home",
                        "type": "physical",
                        "line": [
                            "Bleak House",
                            "3 Worcester Drive",
                            "Rototun
Grahame Grieve2024-09-21T15:19:28Z

Here is a link to an example using id/idref pattern adapted from @Peter Jordan server. I will go ahead and file a task for the validator to be updated since this does add a new warning since the idref is not contained in the resource which it references (but it is an the bundle) https://raw.githubusercontent.com/jddamore/IPSviewer/refs/heads/main/samples/connectathon_samples/NZ_Peter_Jordan_AAA1234.json

John D'Amore2024-09-21T15:33:00Z

Discussed and JIRA tracker added here: https://jira.hl7.org/browse/FHIR-48338 @Grahame Grieve will make a task to update the validator behavior which currently returns a warning when including idref inside composition to a resource.id in the Bundle

John D'Amore2024-09-21T15:44:37Z

I added a test case to the validator test cases for this yesterday:

Grahame Grieve2024-09-22T12:41:17Z

there's two links in there, one is AAA1234, which is valid. The other is AAA1234X which is not (it is a validator test case). Both are on line 23 (@Lisa Nelson )

Grahame Grieve2024-09-22T12:43:39Z

Grahame Grieve said:

there's two links in there, one is AAA1234, which is valid. The other is AAA1234X which is not (it is a validator test case). Both are on line 23 (Lisa Nelson )

@Grahame Grieve @John D'Amore Thanks. This was just what I needed. I've got it working and even figured out a way to make the ID elements in my CDA mimic this approach nicely. But I have one concern. I don't want to have to rebuild these narrative text linking ID's when I transform the CDA document into its FHIR counterpart. Is there some way these narrative text linking id's could be a special type of identifier rather than an actual Resource id? There's no way we'll know what id the created FHIR Resource is going to have and my transformation process will be very difficult if we have to re-establish all these links with new id's in them as part of the transformation from CDA to FHIR. As the document gets moved around from place to place, the id/idref information would need to change to utilize different id's for these resources on different servers. I'd prefer to set-em and forget-em. Is there a way to make this work by referencing an identifier on the resource rather than its id?

Lisa Nelson2024-09-24T03:05:47Z

Is there some way these narrative text linking id's could be a special type of identifier rather than an actual Resource id?

oh. it is. It refers to Bundle.entry.id, which is whatever you want it to be. I just reused the id of the resource because I'm lazy; it totally can be any valid id you want

Grahame Grieve2024-09-24T09:00:47Z

Grahame Grieve said:

Is there some way these narrative text linking id's could be a special type of identifier rather than an actual Resource id?

oh. it is. It refers to Bundle.entry.id, which is whatever you want it to be. I just reused the id of the resource because I'm lazy; it totally can be any valid id you want

Perfect! Thank you @Grahame Grieve .

Lisa Nelson2024-09-24T11:35:25Z
The discussion centers on the decision to use contained versus referenced resources within a document Bundle, highlighting that contained resources are appropriate only when they lack independent existence and identity from their parent resource. Participants provide various use cases and clarifications on how sending and receiving systems should manage these resources without compromising data integrity based on sender preferences.
19 comments

@Grahame Grieve , I've been thinking deeply about the question of contained resources for representing a document. Do you have any advice on how to make that decision? When would it be right to make the entries contained resources rather than free floating entries in the document Bundle. I sort liked the document Bundle with referenced Resources because it gives the flexibility to handle the resources independently, but you don't force a recipient system to have to instantiate them because they can just let them sit there in the confines of their Bundle. Do you see any reason I should be considering to make them fully contained within the Composition, or is containing them withing the Bundle sufficient "containment" of sorts?

Lisa Nelson2024-09-24T11:37:36Z

DomainResource.contained is only intended for use when the resource doesn't have an independent existence or identity from its parent. i.e. in the source system, the resource isn't referenced by (and can't be referenced by) anything other than the parent. As an example, you might have a system that captures the details of a compounded medication as part of the prescription rather than as a shared structure. It might do the same with the name and phone number of the prescriber. In that case, the MedicationRequest would reasonably have Medication and Practitioner as 'contained' resources. On the other hand, if the system allows for multiple prescriptions to point to the same drug 'recipe' and prescribers are always pointers to an internal registry of possible clinicians, then it would not be appropriate to 'contain' those resources - they have independent identity.

We don't use 'contained' as a handy packaging mechanism to avoid needing to transmit separate resource instances.

Lloyd McKenzie2024-09-24T11:55:18Z

@Lloyd McKenzie Thanks for that clarification. I'd like to extrapolate from the example you provided to my specific situation. You explained, "As an example, you might have a system that captures the details of a compounded medication as part of the prescription rather than as a shared structure. It might do the same with the name and phone number of the prescriber. In that case, the MedicationRequest would reasonably have Medication and Practitioner as 'contained' resources." In my case, I have a portable medical order which may have been authored by a doctor who is not in any way involved with he healthcare provider/system where that advance healthcare directive is being shared. That organization doesn't want to create PractitionerRole, Organization, or Practitioner resources on their recipient system. I was thinking this might be a good example of when to include this information about the PMO authoring physician's information as contained resources?

Lisa Nelson2024-09-24T13:19:19Z

What the receiving system wants to do (or doesn't want to do) isn't the sender's problem. If the sender says "these things have independent identity", then they should be transmitted that way. What the receiver chooses to do is up to them. We don't want the sender to adjust how they send data based on how a particular receiver might want to store the data. The sender can't reasonably split data into separate identified resources if it has no clue whether "Dr. Bob" on prescription 1 is the same "Dr. Bob" as is on prescription 2. But if it does know that, it should be reflected in the data being shared. If the receiver wants to collapse the data together, it can (though obviously there's information loss when it does so).

Lloyd McKenzie2024-09-24T13:23:25Z

We're considering a different use case. We want to share the date a Condition was last updated by a clinician. Our EHR vendors can provide that since it's in their db structure, say: SELECT date_updated FROM Problem WHERE Problem.id = 123, which can be wrapped in Provenance. Of course, date_updated has no independent existence: once Problem 123 is deleted, it is gone too, but it could be independently identified since this is a 1:1 relationship (say Provenance/problem123dateupdated would be a unique id). We haven't decided how to implement this yet, but can the general rule be reversed: if there is no independent existence, it is better to use a contained resource? @Lloyd McKenzie

Marc de Graauw2024-09-24T15:00:45Z

If there is no independent existence and no independent identity, then from a RESTful perspective, you pretty much have to use contained. The way you expose data in a document should be consistent with how you'd expose it restfully if you had a restful interface.

Lloyd McKenzie2024-09-24T15:15:18Z

@Marc de Graauw Since Provenance.target points to this Condition resource instead of the other way around: are you able to use Condition.contained at all? Do you add an additional extension on Condition that points to Provenance to satisfy that the parent shall point to the contained resource? (circular reference)

Alexander Henket ⚒️2024-09-24T17:22:12Z

So long as there’s a connection one way or the other, containment is still possible

Lloyd McKenzie2024-09-24T17:32:43Z

If Condition is resolvable, you could put an absolute uri in .target. Alternatively, use an identifier. Seems indeed one can point to a contained resource using a relative uri (#) but cannot point to the containing resource in a similar way (i.e. use '..' or something)

Marc de Graauw2024-09-24T17:34:45Z

Note on invariant dom-3:

STU3:
If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource

R4 and later:
If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource or SHALL refer to the containing resource

For IPS you are good. For our Dutch BgZ which is STU3 you would technically run into the issue that Condition has no native way to point to Provenance.

Alexander Henket ⚒️2024-09-24T17:50:25Z

but I do not enforce that in STU3

Grahame Grieve2024-09-24T18:08:06Z

If we would use Provenance contained in Condition in STU3 then that probably deserves a solid note in the IG

Alexander Henket ⚒️2024-09-24T18:58:18Z

yes, please do. The R4 dom-3 rule was the intention all along.

John Moehrke2024-09-24T20:36:19Z

It is my understanding that contained resources do not nest i.e. all relevant such resources form a flat list within (the outermost) containing resource, correct ?

Does the dom-3 rule prohibit transitive references from "tangling resources" ? So I'm searching for clearly worded, authoritative guidance for contained resources that a) do not reference the containing resource directly and b) instead reference some other contained resource that (in turn) satisfy dom-3 (or not) ? And to me the main unclear issue is that b) should actually cover reference chains leading to contained resource that can be tested to fulfill dom-3.

And yes, I'm aware that this kind of "closure" validation for contained resources is computationally rather heavy and there's probably no practical way to actually enforce it.

Kari Heinonen2024-09-25T07:44:57Z

the validator checks it

Grahame Grieve2024-09-25T08:33:26Z

and it is rather a challenge in big bundles

Grahame Grieve2024-09-25T08:33:41Z

but yes: flat, and contained resources can reference other contained resourcdes

Grahame Grieve2024-09-25T08:34:47Z

Thank you for confirmation, so transitive reference chains in contained resources do satisfy dom-4.

Some background for the curious: For cross-border use of medication information it is necessary to describe the medical product explicitly by its attributes (since there's no global identification schema, nor product characteristics database, etc. currently in use). Hence, one (and by no means the only one) way to achieve this is to use a (very) limited subset of the FHIR definitional resources for medications (especially for R5 and above). Which do natively tend to have their reference links "backwards" from the point of view using them as contained resources. And they can form multi-step chains if the definitional resources for substances/ingredients, "abstract medical products" etc. are fully taken into account. This is also a use case where it kind-of makes sense to use contained resources, just maybe.

Kari Heinonen2024-09-25T09:22:21Z

Interesting example

Marc de Graauw2024-09-25T10:26:31Z
Michael Lawley expresses frustration with the artifact-versionAlgorithm extension due to its inability to handle version sorting challenges, particularly when different format versions coexist or when dealing with non-standard date formats like MMDDYYYY. Several participants, including Grahame Grieve and Brian Postlethwaite, acknowledge the complexities of comparing versions across varying conventions, and emphasize the importance of ensuring consistency in version format to effectively resolve sorting issues.
14 comments
ML
AP
JS

I have recently come across two version sorting challenges that the artifact-versionAlgorithm extension provides no help with (leading me to think it adds almost no value except as documentation).

The first is a CodeSystem that has changed strategies from semver to datestamp; how can I sort these without special-case knowledge. The extension doesn't help with this - what do I do with two CodeSystem instances with the same URI but each declaring their version conforms to a different format?

The second is RxNorm using MMDDYYYY format ! (https://terminology.hl7.org/RxNorm.html). Firstly, this is not easily sortable without explicit parsing, but then I need to know the format, and none of the format types for the extension include this one. In fact the closest "ISO Date", (I assume meaning ISO 8601), but that is strictly "descending notation".

I am left wondering if we would have been better off (for sorting purposes) with an order-like extension.

Michael Lawley2024-09-25T09:47:57Z

leading me to think it adds almost no value except as documentation

I'e always thought that

Grahame Grieve2024-09-25T10:04:36Z

Isn't there a fhirpath option for the sorting?
So you should be able to use that to do the comparison.
https://hl7.org/fhir/structuredefinition-definitions.html#StructureDefinition.versionAlgorithm_x_

However I do agree that you'd need to update the old version instance with the change to make them consistent for things to really work.

My facade project does the resolution like this, and has error when inconsistent
https://github.com/brianpos/fhir-net-web-api/blob/51a514e5d15b90d9e314da5a6823a179a67dad31/src/Hl7.Fhir.DemoFileSystemServer/CanonicalResourceService.cs#L75

Brian Postlethwaite2024-09-25T11:14:15Z

So you should be able to use that to do the comparison.
https://hl7.org/fhir/structuredefinition-definitions.html#StructureDefinition.versionAlgorithm_x_

That still doesn't help - different resources are disagreeing about the algorithm. You can't resolve that in the resources themselves - it's a system property

Grahame Grieve2024-09-25T11:23:43Z

Yup, that's why my code complains and reports an error if the algorithm is different between the instances being considered.
And you'd need to fix the data to perform it in the service.

Brian Postlethwaite2024-09-25T11:26:28Z

(manually tell the system which should be used by updating all with the canonical to be consistent)

Brian Postlethwaite2024-09-25T11:27:02Z

image.png
Can someone clarify the difference between these two library IGs?

Julia Skapik2024-09-25T13:23:03Z

Julia Skapik said:

image.png
Can someone clarify the difference between these two library IGs?

There’s actually a third one though at least it’s obviously an older version (0.0.1 instead of 1.0.0). US-PHPL https://build.fhir.org/ig/HL7/fhir-us-phpl/

Marc Duteau2024-09-25T17:34:31Z

Yup, that's why my code complains and reports an error if the algorithm is different between the instances being considered.

Interesting. Although it's not necessarily the case that different algorithms are incompatible. integer, alpha, date, and natural should all give the same order for datestamps in "descending notation" with consistent syntax (eg all YYYYMMDD or all YYYY-MM-DD).

Ontoserver's approach is to break the version strings into a sequence of tokens whenever there's a switch from digit to non-digit. Then tokens that are all-digits are sorted as numbers, and other tokens are alpha sorted. The token sequences are compared pair-wise left to right so that 2.3.4 and 2.3 can be compared.

Michael Lawley2024-09-25T22:29:44Z
Anil Patel2024-09-26T12:24:17Z

@Anil Patel Yes, but version is a string, so there's no type checking for valid semantic versioning or a particular date/time format. usually people will use either semVer or a YYYYMMDD/YYYY-MM-DD, but that's not guaranteed to be the case.

René Spronk2024-09-26T14:02:35Z

And sometimes with random suffixes (-RC1, final, alpha, mjl-mod-1, etc), and sometimes prefixed with v, V, ver, etc or even 1st Ed, 2nd Ed, ...
And, even in FHIR / THO code systems, switching from one scheme to another.

Michael Lawley2024-09-26T21:16:02Z

we did that? where?

Grahame Grieve2024-09-26T21:18:08Z

Not the example I'm thinking of (semver -> datestamp) - I'm still trying to git it up, but the stub CodeSystem for LOINC has version 3.1.0, but it should follow the LOINC naming convention - e.g., 2.78 (which is smaller/older in semver terms!) - see https://jira.hl7.org/browse/UP-591

Michael Lawley2024-09-26T21:29:35Z
The discussion revolves around the challenges of incorporating FHIR system URLs into the CDA II.root, particularly for URLs that do not have a straightforward OID mapping, prompting considerations for algorithmic solutions like URL encoding and lookup tables. Participants express concerns about the practicality and standardization of these solutions in different jurisdictions, with a focus on balancing FHIR and CDA interoperability while addressing existing length restrictions and user expectations.
16 comments

Including FHIR Identifier.system URL's in CDA II.root can be hard. If the system uri is urn:oid: or urn:uuid:, it's easy. If it's an http(s) URL one could try to look it up in one of the registries which map URLs to OIDs, but if this does not work you're out of luck. We still need FHIR<->CDA conversion for some time don't want to loose identifiers.

In the Netherlands we're considering an algorithmic solution: urlencode the URL, get the ascii value for each character, append after '2.16.840.1.113883.2.4.3.46.30.' (or some other agreed upon OID) and use that. So 'http://example.org' would become '2.16.840.1.113883.2.4.3.46.30.104.116.116.112.58.47.47.101.120.97.109.112.108.101.46.111.114.103' etc. and store that in II.root. A drawback is OIDs can get long (some jurisdictions have length restrictions for II.root) but it's a generic round-trippable solution. Same of course could be used for CD.codeSystem etc. (Although those would sooner be expected to be expected to be in some registry, and that OID should take precedence.)

Any problems or comments? @Tom de Jong @Alexander Henket ⚒️

Marc de Graauw2024-09-25T17:49:25Z

What about (unless you are required to use @root):
Fhir .system is oid, uuid, ruid -> CDA @root
Fhir. system is url with no known oid conversion -> CDA @assigningAuthorityName
Fhir .system is a url with a known oid -> CDA @assigningAuthorityName, @root (known oid).

CDA back to FHIR, prefer @assigningAuthorityName over @root.

Daniel Venton2024-09-25T19:19:23Z

That's an alternative. It tweaks the definition of assigningAuthorityName

This name may be provided solely for the convenience of unaided humans interpreting an II value and can have no computational meaning.

Which may or may not be a problem. If it's only FHIR to CDA and back it's no problem but in a mixed environment parties may not expect this.

Marc de Graauw2024-09-25T19:37:12Z

CD does not have an attribute like II.assigningAuthorityName.

But even if it did: what do you put in @root or @codeSystem? There is no system in use today in our realm that would understand an @extension or @code without a @root or @codeSystem.

Note that contrary to string-to-codepoints() and codepoints-to-string() we currently forbid systems in NL to send urls of their own making and use oids instead. This is the only way we know how to have a working hybrid ecosystem.

Obviously: where applicable we define system urls for known code systems and identifier systems so there is a workable 1-to-1 mapping in those cases

Alexander Henket ⚒️2024-09-25T19:46:33Z

Alternative #2:
Instead of url encoding the url and getting the ascii value to create oid with 100's of segments. Just create a lookup table for all new .system values you come across.
2.16.840.1.113883.2.4.3.46.30.1 = https://first.com
2.16.840.1.113883.2.4.3.46.30.2 = http://somebodyunknown.org
2.16.840.1.113883.2.4.3.46.30.3 = http://someotherplace.edu
...
solves the length problem and is reversible.

Daniel Venton2024-09-25T19:49:08Z

That doesn't quite work in production.

  • You first need to encounter it and that would be seen by very specialized people inspecting system logs
  • They then would need to realize that they need a new mapping and request an oid somewhere
  • This would be done by every communication partner individually so hospital A and B would have a different oid as counter id for the same url
  • They would then need to update their mapping
  • All that time the communication is stalled
Alexander Henket ⚒️2024-09-25T19:52:06Z

It's no different than making up a new oid based on the ascii values of the .system value.

Daniel Venton2024-09-25T19:53:30Z

Yes it is ... the result of string-to-codepoints(), a well known function, is the same regardless of the hospital you apply it in.

Alexander Henket ⚒️2024-09-25T19:54:19Z

They don't know the .system value now, can't know because they can't do fhir. Why would they want to undo the oid into the .system value that they have no use for?

Daniel Venton2024-09-25T19:55:17Z

They do know the @root and @codeSystem today because in NL:

  • You SHALL send the url that FHIR defines and we can convert those into a valid oid back and forth
  • You SHALL send the url that HL7 NL defines and we can convert those into a valid oid back and forth
  • You SHALL NOT send a url, but SHALL send an oid if it does not fall in those categories

Hence: today we always can populate @root and @codeSystem with the appropriate oid

Alexander Henket ⚒️2024-09-25T19:57:57Z

But ... we sometimes get pushback from FHIR native systems because they like creating their own urls and to be fair: FHIR does nudge you in that direction.

We would not be pushing back on urls if V3 compatibility wasn't a requirement. So ... how do other countries handle this? There must be more places where CDA meets FHIR for example

Alexander Henket ⚒️2024-09-25T20:00:42Z

Undoing the OID may be useful when you receive FHIR, convert to v3, then send some v3 to some other party who does understand FHIR system URL and wants to reconstitute the original .system URL.

Marc de Graauw2024-09-25T20:01:18Z

In the Netherlands we require urn:oid as in @Alexander Henket ⚒️ bullet 3, but that is a national, not an international solution, which is less desirable

Marc de Graauw2024-09-25T20:05:45Z

The lookup table is required anyway ... there is no V3 system in the world that would handle:

<code code="327671006" codeSystem="104.116.116.112.58.47.47.115.110.111.109.101.100.46.105.110.102.111.47.115.99.116"/>

the only useful way would be:

<code code="327671006" codeSystem="2.16.840.1.113883.6.96"/>
Alexander Henket ⚒️2024-09-25T20:09:42Z

That long thing in the first <code/> is string-join(string-to-codepoints('http://snomed.info/sct'), '.')

Alexander Henket ⚒️2024-09-25T20:11:10Z

But ... if we hadn't had length restrictions in our realm ... the string-to-codepoints() solution would certainly be a valid solution for urls without a 1-to-1 mapping to an oid. Hope to learn how other realms approached this.

Alexander Henket ⚒️2024-09-25T20:14:27Z
The discussion focuses on guidelines for using contained resources versus full resources in FHIR, highlighting that contained resources should only be utilized when sufficient identifying information is not available. Participants shared scenarios illustrating appropriate use cases, emphasizing that contained resources are often necessary for unspecified data to avoid confusion and duplication.
10 comments

Hello - when is it appropriate to use contained resources vs. creating a full resource? Is there any guidance on when to use contained resources. I see this in the description comments for the 'contained' data element on each resource: "This should never be done when the content can be identified properly, as once identification is lost, it is extremely difficult (and context dependent) to restore it again"

Can anyone share example scenarios of when they used contained resources vs. creating a full resource?

Thanks!

Angie Benoit2024-09-24T15:50:13Z

a typical scenario for using a contained resource is when converting from v2 or CDA to FHIR, and the only information you have for the Practitioner details is 'Mr John Smith' - you don't know which john smith. This is unidentified, and therefore you have to use contained resources

Grahame Grieve2024-09-24T16:01:16Z

iif you don't have to, you shouldn't

Grahame Grieve2024-09-24T16:01:28Z

when you don't have sufficient detail to fill out that resource usefully or causing noise. In my case I am decomposing a lab result, I have the various lab measurement types and values; but I don't have any business identifier to keep me from generating alot of duplicate Observations data. Thus it is saved as a contained Observation within the DiagnosticReport, as I do have a business identifier of the lab report.

John Moehrke2024-09-24T16:10:00Z

I don't wish to confuse things, but if all you know is the single data point "Mr John Smith" (as a string) isn't that suitable for putting in reference.display, and not need a contained? I think that is a legitimate use. If you know another data point (e.g. phone), then that would require contained.

Rik Smithies2024-09-24T16:13:40Z

I always use the maxim of "does the resource have a lifecycle of its own? then don't put it as a contained resource."

Many implementers and IG authors use contained as a way to get around the FHIR reference mechanism. If you manage a resource's state and have an id for it, it should not be contained.

Jean Duteau2024-09-24T16:27:02Z

One thing I've heard on here is, using a contained questionnaire on a questionnaireresponse resource to indicate the questions as they were when answered.

Daniel Venton2024-09-24T17:06:53Z

The QuestionnaireResponse.item.text already does that. The only use case I’m aware of for contained Questionnaires is for adaptive forms where the Questionnaire is built on the fly for that specific response

Lloyd McKenzie2024-09-24T17:35:35Z

There are some resources - like Location, that require only 'name', which could be anything. Seems like this would definitely be a candidate for a contained resource. I have not seen these in the wild yet, so not sure what will be populated in them. But I question how useful they are as stand alone resources.

Angie Benoit2024-09-24T18:51:06Z

Similar discussion with some other use cases here: #IPS > Contained vs Referenced Resources in a document Bundle

Marc de Graauw2024-09-24T18:56:01Z
Brian Postlethwaite and David Hay are exploring definition-based extraction in FHIR questionnaires, aiming to set output resource values without requiring specific profiles or unnecessary hidden fields. They propose using an extension to dynamically populate extracted resource content, while discussing potential issues with transaction bundles and the need for collaboration on a reference implementation.
13 comments
IB
DH

@David Hay and I have been playing with the definition based extraction functionality and creating samples and a test environment and have come across one limitation and a possible way to work around it.

How can we set a value in the output resource without needing a specific profile to set the value, or have a pointless hidden field in the questionnaire that serves no purpose except for the extraction.

What we came up with is the following:

"extension": [
    {
        "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemExtractionValue",
        "extension": [
            {
                "url": "definition",
                "valueCanonical": "http://hl7.org/fhir/StructureDefinition/Patient#Patient.extension.url"
            },
            {
                "url": "fixed-value",
                "valueString": "http://example.org/Str ..."
            }
        ]
    }
],

This extension will be able to go on any item (or root) in the questionnaire and if that item is answered, then the values in the extension will also be set into the output resource.

A second variation of this would be instead of the fixed-value would have an expression-value that has for it's value an Expression type that would be evaluated at that point and if there are any results - those would be set into the identified definition property in the output resource.
These expressions would have a limitted number of variables available, and most significantly would NOT have access to the launch context variables, as they are unlikely to be available in many places this would be evaluated.
However it does have access to the QR.subject/QR.author which is usually what comes from the launch context anyway.

Thoughts?

Brian Postlethwaite2024-09-18T05:25:17Z

To provide another example, here would be how we could populate the obseravation's patient reference from the QR:

"extension": [
    {
        "url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemExtractionValue",
        "extension": [
            {
                "url": "definition",
                "valueCanonical": "http://hl7.org/fhir/StructureDefinition/Observation#Observation.patient"
            },
            {
                "url": "dynamic-value",
                "valueExpression": {
                      "language": "text/fhirpath",
                      "expression": "%resource.subject"
                 }
            }
        ]
    }
],
Brian Postlethwaite2024-09-18T05:29:58Z

Putting it in simplest terms this extension is for:

  • Any content in an extracted resource that is not directly set by a value that the user entered into an answer in the QR - and doesn't come from a fancy profile
Brian Postlethwaite2024-09-18T05:41:46Z

I've implemented the fixed-value portion of this in my demo server (will get a live example posted during the week - unless David beats me to it)

Brian Postlethwaite2024-09-22T21:13:11Z

I've also noted that we've documented that the output of the operation is a transaction bundle, however we've not defined how to populate the fullUrl field, or request fields to drive method=PUT/POST or ifnone match etc.
Is that something I've just missed, or shall I log this?
(also applies to observation based)

Brian Postlethwaite2024-09-22T21:17:06Z

Would be good to support conditional create / update...

David Hay2024-09-23T04:37:30Z

I am just wondering why people are still exploring poor ways of doing extraction such as definition and observation based while a real good way of doing it doesn't move forward https://jira.hl7.org/browse/FHIR-39498 ?

Ilya Beda2024-09-23T05:02:40Z

That's on my list for the week after next.

Brian Postlethwaite2024-09-23T11:31:10Z

Here's a new sample covering the proposed new fixed-value extension.
https://dev.fhirpath-lab.com/Questionnaire/tester?tab=csiro%20renderer&id=https%3A%2F%2Ffhir.forms-lab.com%2FQuestionnaire%2Fcanshare-myPatientNoProfile
It shows the new issue we found trying it out - which I added to the tracker item.

Brian Postlethwaite2024-09-23T14:17:08Z

Brian Postlethwaite said:

Putting it in simplest terms this extension is for:

  • Any content in an extracted resource that is not directly set by a value that the user entered into an answer in the QR - and doesn't come from a fancy profile

Looks like calculatedExpression extension fits this case? We use it to set subject when extracting Conditon or MedicationStatement

Stas Buldakov2024-09-24T10:43:19Z

Which would then replicate the subject into another field in the response.
Which is what this approach is seeking to avoid.

Brian Postlethwaite2024-09-24T10:46:16Z

Brian Postlethwaite said:

That's on my list for the week after next.

I am happy to collaborate and build a reference implementation with python.

Ilya Beda2024-09-24T23:10:39Z

When I get back home I'll reach out and we can iterate together.

Brian Postlethwaite2024-09-24T23:35:56Z
In a discussion about the experimental tool notebooklm.google.com, participants explore its ability to convert Zulip threads into podcasts while noting its tendency to generate additional context not originally present in the conversations. The tool's capability sparks a humorous debate about the identities of key figures in the FHIR community, reflecting on the implications of AI-generated content.
10 comments
ML

If y'all haven't seen notebooklm.google.com it's pretty fun. It can take zulip threads like #terminology > Overuse of the Experimental flag and turn them into, um... podcasts ;-)

Example Output: vocab2.mp3

Josh Mandel2024-09-25T22:01:38Z

That’s fascinating. It’s interesting how it’s pulling in all kinds of info not actually present in the conversation.

Elliot Silver2024-09-26T04:50:33Z

Yeah, intrigued as to how much additional context you added in

Michael Lawley2024-09-26T06:24:34Z

What I did was to curl the zulip message history of this stream, using the zulip json format, and I literally pasted that json into notebook LM as a source document. And then I clicked the button.

Note that the json stream does have details on names, timestamps, etc. but for sure when it calls Grahame "Grieves" the "grandfather of FHIR," that did not appear anywhere in the json.

Josh Mandel2024-09-26T11:20:01Z

It is a weird but prescient little experimental tool. It Is mostly about asking questions of your source documents, but the source documents selection page exposes a little "generate audio" button with zero configuration or prompt control.

Josh Mandel2024-09-26T11:28:45Z

Grahame "Grieves"

thereby demonstrating a very human like mode of thought

Grahame Grieve2024-09-26T11:53:25Z

"what could be more exciting that developers arguing about standards". Awesome

Grahame Grieve2024-09-26T11:54:41Z

it is a weird piece of performance art, I have to say. And us humans are doomed.

Grahame Grieve2024-09-26T11:56:50Z

Grahame Grieve said:

"what could be more exciting that developers arguing about standards". Awesome

When I heard that my first thought was, "did I just get dissed by an AI?"

Elliot Silver2024-09-26T12:34:03Z

Josh Mandel said:

Note that the json stream does have details on names, timestamps, etc. but for sure when it calls Grahame "Grieves" the "grandfather of FHIR," that did not appear anywhere in the json.

Which makes me wonder who is the father, or certainly the mother :smiley:

Robert McClure2024-09-26T20:19:27Z
Jonathan Hallee is struggling to understand the relationship between the FHIR entities Medication and MedicationKnowledge while building medication data on a FHIR server, and he is particularly frustrated by the limitations of search parameters for associating these entities. Daniel Venton and Kari Heinonen provide guidance on the use of search parameters, the potential for using MedicationKnowledge independently of Medication, and suggest resources for further exploration.
11 comments

Hey,

We are currently building our medication data in our FHIR server (Azure Health Data Services) (R4). I am having a hard time understanding the relation between Medication and MedicationKnowledge. It seems like the 2 entities have a clear parent-child relationship however I find it hard to search with the available search parameters.

Example: I expected to be able to search the list of medications and then _include the MedicationKnowledge:associatedMedication however it is not in the search parameters. The only way I can find to do this is possibly with the code? I assume we always expect the code to be the same between the medication and medication knowledge?

To note: We are a canadian company and are loosely following us core & canada profiles but not enforced them since this integration is not meant to be used with external clients.

It seems a lot of info are duplicated between medication and medication knowledge and medication is kind of an empty shell and we should just use medication knowledge. Can we use medication knowledge without medication object? Does it make sense? Thanks

Jonathan Hallee2024-09-27T13:26:34Z

If you are searching Medications. Then MedicationKnowledge:associatedMedication is a _revInclude.
Medication describes a bottle of pills, for example.

And of course, the MedicationKnowledge does have to have populated references to Medication instances.

Daniel Venton2024-09-27T13:34:10Z

When I do this I have the following error:

The search parameter 'associatedMedication' is not supported for resource type 'MedicationKnowledge'.

Here is the search query I am using (note I am using the firely dotnet sdk):

var searchParams = new SearchParams();
searchParams.Add("_id", medicationId);
searchParams.Add("_revinclude", "MedicationKnowledge:associatedMedication");

var bundle = await client.SearchAsync<Medication>(searchParams);
Jonathan Hallee2024-09-27T13:46:13Z

You are correct, there is no "associatedMedication" search param on MedicationKnowledge. Submit a jira ticket that says, it'll be very useful to have such. Then if/when such a search parameter is defined, you'll be able to do your include functionality (assuming your server has implemented it).

Until then you'll need a solution that doesn't require the server to implement the join for you.

Daniel Venton2024-09-27T13:57:33Z

Could I manually add a search parameter that does that in the meantime? I have added a couple search params on custom extensions i'm assuming I could do the same here?

Or i'm thinking perhaps the link between the 2 is expected to be the code (SNOMED Code?) I assume this would be unique per medication?

Jonathan Hallee2024-09-27T14:01:53Z

If the server you are talking to allows you to add a reference type search param and it propagates into the include dictionary, go ahead. I can't tell you the capabilities of the FHIR server you are using.

Daniel Venton2024-09-27T14:04:37Z

Re using MedicationKnowledge without Medication (and their logical relation)

Quite possible (see Scope and Usage chapter for MedicationKnowledge) but the answer remains "it depends". As other relevant resources in FHIR are mostly using references to Med (not to MedKnow), so not having them might quickly become a problem.

To further complicate matters, if the intent is to build a full, stand-alone medicinal product database a) there's a Medication Definition module in FHIR and b) R4 might not be the absolutely best choice to do that. For going deeper down that rabbit hole, Zulip has a dedicated Medication stream and ISO IDMP data model (and definitional module in R5) might be useful to be slightly familiar with.

In a way, one could think MedicationKnowledge as clinical workflow oriented, drastically simplified "version" or "summary-of-sorts" of the much bigger, very detailed, regulatory medicinal product data model.

Kari Heinonen2024-09-27T14:34:43Z

@Kari Heinonen could you share links for the zulip medication stream you are talking about? This is all brand now to me thanks!

R5 for now is not really an option for us due to the server we are using doesn't support it

Jonathan Hallee2024-09-27T14:46:15Z

Here you go #Medication

Kari Heinonen2024-09-27T14:47:27Z

Thanks will ask there :)

Jonathan Hallee2024-09-27T14:51:11Z

Yes, I did assume that R5 would not be an option. IMHO it might be still useful to take a peek at R5 and IDMP stuff anyway to "see where the river is taking us". And the R4 definitional resources I mentioned are listed as the very last group, bottom of page on
https://hl7.org/fhir/R4/resourcelist.html

And as it happens Medication data modelling related issues are quite relevant for EU currently (and me personally, hailing from Finland). I think I can answer (albeit always associated with big disclaimer :smile:) some more specific questions if you have any.

Kari Heinonen2024-09-27T15:11:17Z
Async Javascript
#javascript
Grahame Grieve encountered an issue with his JavaScript code where calling an asynchronous function returned a Promise instead of the expected JSON data. Josh Mandel explained that the solution involves making the `go()` function asynchronous and using `await` to ensure it properly retrieves the data before displaying it, while Brian Postlethwaite suggested using the `.then()` method as an alternative approach.
8 comments

it's a little while since I worked with javascript, and I'm bamboozled by something

Grahame Grieve2024-09-28T14:54:25Z

I execute this javascript:

Grahame Grieve2024-09-28T14:54:34Z
function go(id, ver) {
  var div = document.getElementById('target');
  if (div != null) {
    var json = getJson();
    div.innerHTML = '<p>'+json+'</p>';
  }
}

async function getJson() {
    const url = "some-document.json";
    try {
        const response = await fetch(url);
        if (response.ok) {
          return await response.json();
        } else {
          return null;
        }
    } catch (error) {
        return null;
    }
}
Grahame Grieve2024-09-28T14:55:10Z

that seems straight forward to me from the documentation, but when I run this, I get [object Promise] as the output, not the actual json. What am I doing wrong?

Grahame Grieve2024-09-28T14:56:17Z

I'm not being snarky, language models are just better than I am an answering these questions.


Explanation of Asynchronous JavaScript and Promise Handling

The issue you're experiencing is a common confusion when dealing with asynchronous JavaScript. Let's break down what's happening and how to fix it:

The Problem

In your original code:

function go(id, ver) {
  var div = document.getElementById('target');
  if (div != null) {
    var json = getJson();
    div.innerHTML = '<p>'+json+'</p>';
  }
}

async function getJson() {
    const url = "some-document.json";
    try {
        const response = await fetch(url);
        if (response.ok) {
          return await response.json();
        } else {
          return null;
        }
    } catch (error) {
        return null;
    }
}

getJson() is an asynchronous function, but you're calling it synchronously in the go() function. When you do this, JavaScript returns a Promise object instead of the actual JSON data, which is why you're seeing [object Promise].

The Solution

To fix this, you need to make the go() function asynchronous as well and use await when calling getJson(). Here's how to modify the go() function:

  1. Add the async keyword to the go() function declaration.
  2. Use await when calling getJson().
  3. Use JSON.stringify() to convert the JSON object to a string for display.

Here's the corrected go() function:

async function go(id, ver) {
  var div = document.getElementById('target');
  if (div != null) {
    var json = await getJson();
    div.innerHTML = '<p>' + JSON.stringify(json) + '</p>';
  }
}

This change allows the function to properly wait for the JSON data to be fetched before trying to display it.

Additional Considerations

When you call go() from elsewhere in your code, you'll need to handle the fact that it's now an asynchronous function. For example:

go().catch(error => console.error('Error in go():', error));

Or if you're calling it from another async function:

await go();

Explanation

In asynchronous JavaScript, functions that perform operations that might take some time (like fetching data from a server) return a Promise. A Promise is an object representing the eventual completion or failure of an asynchronous operation.

When you use the await keyword, you're telling JavaScript to pause the execution of the function until the Promise is resolved (or rejected). This allows you to write asynchronous code that looks and behaves more like synchronous code, making it easier to understand and manage.

By making these changes, you ensure that your code waits for the JSON data to be fetched before trying to display it, resolving the issue of seeing [object Promise] instead of the actual JSON data.

Josh Mandel2024-09-28T15:46:13Z

thanks.

Grahame Grieve2024-09-28T16:07:37Z

the alternative is to use then(.....) rather than propogating the async up the call graph.
Which usually stops at the event handler.

Brian Postlethwaite2024-09-28T21:13:27Z
synthea
#social
Jens Villadsen praises the Synthea team for their excellent tool for generating synthetic data, highlighting the useful flexporter feature. Jason Walonoski and Dylan Hall respond positively, discussing potential enhancements like adding support for loading JavaScript libraries in the flexporter.
7 comments
DH

I just wanna give a big-axx salute to the synthea team for making an awesome tool for generating synthetic data that is easily extendable and without a sxxt-load of magic. You guys nailed it!

Jens Villadsen2024-09-09T09:46:16Z

Thanks @Jens Villadsen , we appreciate the praise, and we're glad you find it useful.

Jason Walonoski2024-09-09T13:17:44Z

Especially the flexporter feature is a nice addon

Jens Villadsen2024-09-09T13:20:16Z

@Jason Walonoski - btw - one of my colleagues asked if adding/loading js libs could be an option so that one could use js util functions for different cases upon generation in the flexporter

Jens Villadsen2024-09-09T14:01:56Z

@Jens Villadsen thanks for the kind words!
Re: flexporter support for loading JS libraries, this is something we've explored a little but it wasn't super user friendly and I wasn't sure how far down the rabbit hole to go at that point. Limited support does exist if things are in the right place but it's not currently exposed via the mapping file. https://github.com/synthetichealth/synthea/blob/master/src/main/java/org/mitre/synthea/export/flexporter/FlexporterJavascriptContext.java#L21

I just opened https://github.com/synthetichealth/synthea/issues/1505 for this feature request, please chime in with any thoughts or specifics you might want to see

Dylan Hall2024-09-09T14:57:12Z

Thats good enough for us to play around with. Perfect!

Jens Villadsen2024-09-09T16:02:39Z

(deleted)

Althaf Pattan2024-09-24T21:37:22Z
Luud Slagter raised a question about the absence of a dateTime option for the .condition.onset element in the FamilyMemberHistory resource, suggesting it would allow for better mapping of onset dates to FHIR data types. Michelle Moseman Miller advised that a change request with use cases should be logged, and Slagter is awaiting feedback from the logical model team before proceeding.
6 comments
LS

Hi! In the FamilyMemberHistory resource the .condition.onset element has possible data types Age, Range, Period and string. Why hasn't the option dateTime been added here as well? Especially, since .procedure.performed includes dateTime as one of its allowed data types, and the familymemberhistory-abatement extension includes the date data type for its value, and I'd expect similar data types to be present for these three elements.

Background of the question: in the logical model that I need to map to FHIR, the condition of the family member has a start and end date (the onset and abatement date, respectively). In order to map the start date properly to FHIR, it is currently necessary to use the Period data type, and then add guidance on how to fill the .onsetPeriod.end element (as leaving it empty implies an ongoing onset period, which is not (necessarily) true).

Luud Slagter2024-04-15T16:37:10Z

@Michelle (Moseman) Miller

Lloyd McKenzie2024-04-15T17:10:30Z

Patient Care briefly discussed this today and would welcome a change request (JIRA) be logged with example use cases that would warrant onset precision of date or dateTime.

Michelle (Moseman) Miller2024-04-18T21:41:10Z

Thanks @Michelle (Moseman) Miller! I have asked the team that is responsible for the logical model to supply some use cases. Afterwards I'll create a change request accordingly.

Luud Slagter2024-04-19T07:23:35Z

Luud Slagter said:

Thanks Michelle (Moseman) Miller! I have asked the team that is responsible for the logical model to supply some use cases. Afterwards I'll create a change request accordingly.

Hi!
What's the status of this? Im facing the same problem with trying to store onsetAge.value: 0
and I think that the possibility of storing date can solve this.

Oren Banda2024-08-26T08:55:34Z

Hi @Oren Banda! Unfortunately I've not yet received any example use cases from the logical model team, hence I haven't created a change request yet.

Luud Slagter2024-09-30T06:15:26Z
Powered by Health Samurai | 2022