Stream: subscriptions
Topic: Resource Trigger Query Criteria
Grahame Grieve (Sep 10 2020 at 19:28):
ok @Gino Canessa yet another question:
image.png
Grahame Grieve (Sep 10 2020 at 19:28):
I don't understand requireBoth.
Grahame Grieve (Sep 10 2020 at 19:28):
if previous is present, isn't it required?
Grahame Grieve (Sep 10 2020 at 19:28):
if previous is not present, what does it mean if 'requireBoth' is true?
Grahame Grieve (Sep 10 2020 at 19:29):
is it actually about and/or and only applivable if both current and previous are present?
Grahame Grieve (Sep 10 2020 at 19:29):
oh it is. duh
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?
Gino Canessa (Sep 10 2020 at 19:33):
I'd need to think on that.
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;
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)
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'
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.
Grahame Grieve (Sep 10 2020 at 19:43):
I think that's what my code does
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)
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
Gino Canessa (Sep 10 2020 at 19:46):
Yes, the code looks right to me
Grahame Grieve (Sep 10 2020 at 19:46):
Gino, I have to handle both cases
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
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
}
Josh Mandel (Sep 10 2020 at 19:48):
What's your preferred way to express this?
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...
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?).
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
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
...
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))
)
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.
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.
Grahame Grieve (Sep 10 2020 at 20:46):
it's easier to do this that indulge in speculative evaluation against a missing resource
Josh Mandel (Sep 10 2020 at 20:49):
Agreed!
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?
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