SIENTIAPDE-2011: Compute query-time levels union / ignore_models_id intersection
Push level and model-exclusion filtering down to the Mongo query instead of fetching the full notification_queue unfiltered on every run. - Fix await ordering in load_notification_package so sending_configs (active receiver_groups) resolves before load_latest_data is called, letting the query filter be built from group data. - Add _compute_query_time_filter: unions active groups' `levels` (falls back to the workflow's default filter if any group has no restriction, since that group wants every level) and intersects their `ignore_models_id` (a model is only safe to drop from the fetch if every active group ignores it). - Add unit tests covering mixed groups, a model ignored by only one group (must not be excluded from the fetch), and the empty active-groups case. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,16 +32,19 @@ async def test_run(workflow_mock, load_notification_package):
|
||||
'base_data_filter': {'level': 'ERROR'},
|
||||
}
|
||||
|
||||
# Await order is now: last_timestamp -> sending_configs -> notification_package
|
||||
# (fixed ordering bug: sending_configs must resolve before load_latest_data is
|
||||
# called, so its levels/ignore_models_id can feed the query-time filter).
|
||||
workflow_mock.start_local_activity_method.side_effect = [
|
||||
'2023-01-01 12:00:00',
|
||||
[
|
||||
{
|
||||
'id': '1',
|
||||
'id_r': '1',
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
'id_r': '1',
|
||||
'id': '1',
|
||||
}
|
||||
],
|
||||
]
|
||||
@@ -158,7 +161,9 @@ async def test_run_has_data(workflow_mock, load_notification_package):
|
||||
'mail_type': 'test_mail_type',
|
||||
}
|
||||
|
||||
workflow_mock.start_local_activity_method.side_effect = ['2023-01-01 12:00:00', ['data'], []]
|
||||
# sending_configs (awaited 2nd) is empty here on purpose, to exercise the
|
||||
# early-return branch below regardless of notification_package having data.
|
||||
workflow_mock.start_local_activity_method.side_effect = ['2023-01-01 12:00:00', [], ['data']]
|
||||
|
||||
output = await load_notification_package.run(input_data)
|
||||
|
||||
@@ -169,3 +174,62 @@ async def test_run_has_data(workflow_mock, load_notification_package):
|
||||
}
|
||||
|
||||
workflow_mock.start_activity_method.assert_not_called()
|
||||
|
||||
|
||||
def test_compute_query_time_filter_empty_active_groups(load_notification_package):
|
||||
default_filter = {'level': 'ERROR'}
|
||||
|
||||
result = load_notification_package._compute_query_time_filter([], default_filter)
|
||||
|
||||
assert result == default_filter
|
||||
|
||||
|
||||
def test_compute_query_time_filter_mixed_groups_no_levels_restriction(load_notification_package):
|
||||
# One active group restricts levels/ignore_models_id, the other has neither set
|
||||
# (the common case today) -> that group wants everything, so no levels
|
||||
# restriction can be applied at query time; falls back to default_filter.
|
||||
sending_configs = [
|
||||
{'group_name': 'group_a', 'levels': ['ERROR'], 'ignore_models_id': ['model_a']},
|
||||
{'group_name': 'group_b'},
|
||||
]
|
||||
default_filter = {'level': 'ERROR'}
|
||||
|
||||
result = load_notification_package._compute_query_time_filter(sending_configs, default_filter)
|
||||
|
||||
assert result == {'level': 'ERROR'}
|
||||
|
||||
|
||||
def test_compute_query_time_filter_model_ignored_by_only_one_group_not_excluded(
|
||||
load_notification_package,
|
||||
):
|
||||
# model_a is ignored by group_a but group_b still wants it -> must stay in
|
||||
# the fetch (the per-group filter is what drops it for group_a specifically).
|
||||
sending_configs = [
|
||||
{'group_name': 'group_a', 'levels': ['ERROR'], 'ignore_models_id': ['model_a']},
|
||||
{'group_name': 'group_b', 'levels': ['ERROR'], 'ignore_models_id': []},
|
||||
]
|
||||
default_filter = {}
|
||||
|
||||
result = load_notification_package._compute_query_time_filter(sending_configs, default_filter)
|
||||
|
||||
assert result == {'level': {'$in': ['ERROR']}}
|
||||
assert 'model_id' not in result
|
||||
|
||||
|
||||
def test_compute_query_time_filter_union_levels_and_intersection_models(
|
||||
load_notification_package,
|
||||
):
|
||||
# Every active group restricts levels -> union of levels applies.
|
||||
# model_a is ignored by every active group -> safe to exclude at query time.
|
||||
sending_configs = [
|
||||
{'group_name': 'group_a', 'levels': ['ERROR'], 'ignore_models_id': ['model_a', 'model_b']},
|
||||
{'group_name': 'group_b', 'levels': ['WARNING', 'ERROR'], 'ignore_models_id': ['model_a']},
|
||||
]
|
||||
default_filter = {}
|
||||
|
||||
result = load_notification_package._compute_query_time_filter(sending_configs, default_filter)
|
||||
|
||||
assert result == {
|
||||
'level': {'$in': ['ERROR', 'WARNING']},
|
||||
'model_id': {'$nin': ['model_a']},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user