Compare celebration stamps as whole entries; queue events

Child ids sharing a prefix no longer suppress each other (split and
compare entries for equality), and queued mode keeps a second child's
day-complete event from being dropped while the first notify runs.
This commit is contained in:
2026-09-19 14:50:59 -04:00
parent bf84793a1c
commit f6166f25d9
2 changed files with 26 additions and 5 deletions
@@ -60,7 +60,7 @@ blueprint:
filter:
- domain: input_text
mode: single
mode: queued
variables:
celebrate: !input celebrate
@@ -74,12 +74,17 @@ conditions:
- condition: template
value_template: "{{ celebrate | bool }}"
# Once-per-child-per-day dedupe: celebrate only when THIS child has
# no entry for today in the helper. An unset or missing helper reads
# as '' and celebrates.
# no equal entry for today in the helper. Entries compare as whole
# comma-separated tokens — a substring check would wrongly suppress
# child 1 after child 11 was celebrated. An unset or missing helper
# reads as '' and celebrates.
- condition: template
value_template: >-
{{ (trigger.payload.child_id ~ ':' ~ now().strftime('%Y-%m-%d'))
not in (states(last_celebrated_helper) or '') }}
not in ((states(last_celebrated_helper) or '')
.split(',')
| select('ne', '')
| list) }}
actions:
- action: !input notify_target
+17 -1
View File
@@ -255,4 +255,20 @@ def test_celebration_never_hard_codes_notify_target() -> None:
assert re.search(r"notify\.[a-z_]+", target_description), (
"the input description should show a placeholder example"
)
assert bp["actions"][0]["action"] == BlueprintInput("notify_target")
assert bp["actions"][0]["action"] == BlueprintInput("notify_target")
def test_celebration_dedupe_entry_equality_not_substring() -> None:
"""Child ids sharing a prefix must not suppress each other: after
child 11 is celebrated, child 1 still celebrates (whole-entry
comparison, not substring)."""
assert render_dedupe("11:2026-09-19", child_id=11) == "False"
assert render_dedupe("11:2026-09-19", child_id=1) == "True", (
"child 1's entry must not be found inside child 11's entry"
)
assert render_dedupe("1:2026-09-19", child_id=11) == "True"
def test_celebration_mode_is_queued() -> None:
"""Two children completing at nearly the same time must both be
processed: queued mode does not drop the second event."""
assert celebration()["mode"] == "queued"