FHIR Chat · Resource Trigger Query Criteria · subscriptions

Stream: subscriptions

Topic: Resource Trigger Query Criteria


view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:28):

ok @Gino Canessa yet another question:
image.png

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:28):

I don't understand requireBoth.

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:28):

if previous is present, isn't it required?

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:28):

if previous is not present, what does it mean if 'requireBoth' is true?

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:29):

is it actually about and/or and only applivable if both current and previous are present?

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:29):

oh it is. duh

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:30):

I guess I'm wanting an explicit statement that previous = absent means true. but what if there isn't a previous (create) and requireBoth = true?

view this post on Zulip Gino Canessa (Sep 10 2020 at 19:33):

I'd need to think on that.

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:34):

well, here's my code to help your thinking:

function TSubscriptionManagerR4.MeetsTopicQueryCriteria(topic : TFHIRSubscriptionTopicResourceTrigger; newRes, oldRes : TFHIRResource): boolean;
var
  prev, curr : boolean;
begin
  if (topic.queryCriteria = nil) then
    result := true
  else
  begin
    if topic.queryCriteria.previous = '' then
      prev = true
    else if oldRes = nil then
      prev := false
    else
      prev := meetsCriteria(topic.queryCriteria.previous, oldRes);

    if topic.queryCriteria.current = '' then
      curr = true
    else if newRes = nil then
      curr := false
    else
      curr := meetsCriteria(topic.queryCriteria.current, newRes);

    if topic.queryCriteria.requireBoth then
      result := prev and curr
    else
      result := prev or curr;
  end;
end;

view this post on Zulip Gino Canessa (Sep 10 2020 at 19:36):

Yes, but I'm thinking about saying that defining a 'previous' on Create or 'current' on Delete should just be invalid. I'm not sure what someone would be expecting by filling it out (e.g., user just filled out the wrong field)

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:38):

well, it would really arise if you didn't fill out the methodCriteria at all. Which I assume means 'any method'

view this post on Zulip Gino Canessa (Sep 10 2020 at 19:40):

In those situations, wouldn't a default of 'false' make more sense? E.g., if I have no method, but a previous and current that are required those methods do NOT meet the requirements.

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:43):

I think that's what my code does

view this post on Zulip Josh Mandel (Sep 10 2020 at 19:45):

One goal of these is to be able to explicitly capture certain transitions. Often it's enough just to identify that something changed into a state (e.g., "any time an Encounter enters the in-progress state", send a notification). But if you want to detect a specific transition (e.g. "any time an Encounter goes from in-progress directly to cancelled, send a notification") then you don't want to match null as a previous state.

So when we're talking about requireBoth, then

1) The topic had better populate filters for .previous and .current (this can be expressed in a constraint, so that requireBoth implies previous and current, more or less)
2) A resource instance that was null before a transition would only satisfy .previous if a null resource fits the logic (e.g., from my first example abovestatus:not=in-progress could match a null previous value, but from my second example status=in-progress would never match a null previous value)

view this post on Zulip Gino Canessa (Sep 10 2020 at 19:46):

Ahh, I read the original as in if the resource was missing, not if the field was missing

view this post on Zulip Gino Canessa (Sep 10 2020 at 19:46):

Yes, the code looks right to me

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:46):

Gino, I have to handle both cases

view this post on Zulip Grahame Grieve (Sep 10 2020 at 19:46):

status:not=in-progress could match a null previous value

please no. That's really really hard

view this post on Zulip Josh Mandel (Sep 10 2020 at 19:48):

That's what the Argonaut Encounter IG has said all along:

    "queryCriteria": {
      "previous": "status:not=in-progress",
      "current": "status=in-progress",
      "requireBoth": true
    }

view this post on Zulip Josh Mandel (Sep 10 2020 at 19:48):

What's your preferred way to express this?

view this post on Zulip Gino Canessa (Sep 10 2020 at 19:55):

Yeah, that slipped my mind.... only negative tests can result, so it may not be terrible though...

view this post on Zulip Gino Canessa (Sep 10 2020 at 20:01):

Hmm... it may be clearer to add an explicit null check to our syntax. Testing against null is overly complicated (e.g., does no value satisfy a '<' test?).

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:02):

yes. I decided that the only way I could really grasp how hard that would be is to program it. Starting to work on it now

view this post on Zulip Gino Canessa (Sep 10 2020 at 20:04):

That's what I was doing - my pascal is a bit rusty, but I started modifying your snippet.... it got ugly fast.

  • check for :not
  • check for ne
  • check for lt
    ...

view this post on Zulip Josh Mandel (Sep 10 2020 at 20:05):

But we'd want something like requireBoth vs requireBothOrTrueWhenNull (not a real name proposal).

requireBoth logic would be:

(
  (previous state exists and matches previous query)
  AND
  (current exists and matches current query)
)

requireBothOrTrueWhenNull logic would be:

(
  ((previous state exists and matches previous query)
     OR
    (previous state does not exist))
  AND
  (( current exists and matches current query)
    OR
    (current state does not exist))
)

view this post on Zulip Gino Canessa (Sep 10 2020 at 20:07):

I was just thinking of something like SubscriptionTopic.resourceTrigger.queryCriteria.previousNotFoundPasses=true|false (also not a suggestion for the name) so that it's up to the topic to explicitly define what the behavior is.

view this post on Zulip Josh Mandel (Sep 10 2020 at 20:09):

:thumbs_up: Yes, we're on the same page here. I like yours better for being decomposed into more separate properties.

view this post on Zulip Grahame Grieve (Sep 10 2020 at 20:46):

it's easier to do this that indulge in speculative evaluation against a missing resource

view this post on Zulip Josh Mandel (Sep 10 2020 at 20:49):

Agreed!

view this post on Zulip Gino Canessa (Sep 10 2020 at 20:51):

Adding to my notes - do we need to do anything on the FhirPath definitions for the same issue?

view this post on Zulip Josh Mandel (Sep 10 2020 at 21:00):

I think you can check for null explicitly in the fhirpath...


Last updated: Apr 12 2022 at 19:14 UTC