Skip to content

Commit 7e43b8a

Browse files
Domantasclaude
andcommitted
docs(triggers): order and breakOnError on trigger saves, with a body test for all four save methods
The gateway added two optional fields to every trigger: order (whole number, lower runs first) and breakOnError (stop the later triggers of the same event when this one fails). The save methods send the caller's map, so the fields already reach the gateway; this documents them and proves it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent c0bf39d commit 7e43b8a

3 files changed

Lines changed: 76 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ A trigger action (`save_schema_trigger`, `save_files_trigger`,
197197
`initiatorId` (who the send is attributed to) on Email, Push and SMS actions.
198198
Two related calls:
199199

200+
- `trigger.order` (whole number, lower runs first) and `trigger.breakOnError`
201+
(stop the later triggers of the same event when this one fails) set the queue
202+
of one event's triggers — see [docs/hub/triggers.md](./docs/hub/triggers.md).
200203
- `norbix.hub.triggers.get_triggers_needing_attention(triggerType="Schema")` —
201204
triggers that need a fix (for example, their provider is gone); `{"items": [...]}`.
202205
- `norbix.hub.account.check_project_languages(project_id, languages=["en", "de"])` —

‎docs/hub/triggers.md‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,31 @@ norbix.hub.database.save_schema_trigger(
4141
```
4242

4343
Everything here is asserted in `tests/hub/test_triggers.py`.
44+
45+
## Order and "break on failure"
46+
47+
When several triggers fire for the same event, they run one after the other.
48+
Two optional fields on `trigger` decide that queue (all four save methods):
49+
50+
- `order` — a whole number, 0 or more. Lower runs earlier; a trigger without
51+
an order runs after every numbered one; equal places run by name.
52+
- `breakOnError` — `True` stops the triggers after this one when this
53+
trigger's action fails. Default `False`: the others still run.
54+
55+
```python
56+
norbix.hub.membership.save_membership_trigger(
57+
trigger={
58+
"type": "Membership",
59+
"name": "welcome first",
60+
"when": "OnRegistered",
61+
"isEnabled": True,
62+
"order": 1,
63+
"breakOnError": True,
64+
"action": {"type": "Email", "integrationId": "int_email", "templateId": "tpl_123"},
65+
}
66+
)
67+
```
68+
69+
Both come back on `get_*_trigger` and on every row of `get_*_triggers`. A
70+
negative `order` is refused with `CM-ERRORS-TRIGGERS-008`.
71+

‎tests/hub/test_trigger_order.py‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
"""Trigger "order" and "break on failure" reach the gateway on every save.
2+
3+
The four save methods send the caller's map as the body, so `trigger.order`
4+
and `trigger.breakOnError` must arrive exactly as given (gateway task
5+
trigger-order-break: the fields were added to every trigger kind).
6+
"""
7+
8+
import json
9+
10+
import pytest
11+
12+
from tests.helpers import make_client
13+
14+
TRIGGER = {
15+
"name": "welcome first",
16+
"isEnabled": True,
17+
"order": 0,
18+
"breakOnError": True,
19+
"action": {"type": "WebhookCall"},
20+
}
21+
22+
23+
@pytest.mark.parametrize(
24+
("module", "method", "kind", "path"),
25+
[
26+
("membership", "save_membership_trigger", "Membership", "/membership/triggers"),
27+
("database", "save_schema_trigger", "Schema", "/database/schemas/triggers"),
28+
("files", "save_files_trigger", "Files", "/files/triggers"),
29+
("payments", "save_payments_trigger", "Payments", "/payments/triggers"),
30+
],
31+
)
32+
def test_save_trigger_sends_order_and_break_on_error(module: str, method: str, kind: str, path: str) -> None:
33+
client, transport = make_client(account_id=None)
34+
35+
getattr(getattr(client.hub, module), method)(trigger={"type": kind, **TRIGGER})
36+
37+
assert transport.last_request is not None
38+
assert transport.last_request["method"] == "POST"
39+
assert transport.last_request["url"].endswith(path)
40+
sent = json.loads(transport.last_request["body"])["trigger"]
41+
assert {k: sent[k] for k in ("type", "order", "breakOnError")} == {
42+
"type": kind,
43+
"order": 0,
44+
"breakOnError": True,
45+
}

0 commit comments

Comments
 (0)