Events
A static scope can react to its records changing in data.svc: a ticket is created, and the rules set its priority. data.svc delivers each change to rules.svc; rules.svc evaluates the record the change names, with apply, as the system user.
Declaring it
Section titled “Declaring it”scopes: - name: ticket-triage paths: [triage] sources: shop: { kind: data, datastore: main } data: over: { source: shop, entity: ticket, as: ticket, select: [id, subject, priority], key: id } writes: - { source: shop, entity: ticket, ops: [update], fields: [priority], concurrency: last-write-wins } on: - { ops: [create] }rule Urgent "an outage is urgent" salience 10 { when strings.IContains(in.Str("ticket.subject", ""), "outage") then act.Set("priority", "urgent");}
rule Normal "everything else is normal" salience 5 { when !strings.IContains(in.Str("ticket.subject", ""), "outage") then act.Set("priority", "normal");}{ "ticket": { "id": "t-1", "subject": "Checkout outage in EU", "priority": null } }{}[ { "op": "set", "field": "priority", "value": "urgent", "rule": "Urgent", "cycle": 1 } ]on needs data.over on a data source. Its ops are create, update and delete; a deleted
record has nothing to evaluate, so a delete triggers nothing. on.fields is checked but does not
narrow a trigger yet, because data.svc’s events do not say which fields changed.
Wiring data.svc to rules.svc
Section titled “Wiring data.svc to rules.svc”Three pieces, all required:
-
The entity declares its events in the product’s data model, so data.svc emits them:
- name: ticketevents:- name: changedoperations: [create, update] -
data.svc delivers them to rules.svc, as one of its event targets, signed with a shared secret:
# data.svc's configurationevents:targets:rules:url: https://rules.example.com/rules/eventssecret: "vault://…"timeout: 5stopics: [entity.ticket] -
rules.svc takes them, with the same secret and a system user:
# rules.svc's configurationrules:events:enabled: truesecret: "vault://…"systemuser:identity: rules-systempassword: "vault://…"
What a delivery does
Section titled “What a delivery does”- rules.svc checks the delivery’s signature against the shared secret and its timestamp against the clock (within five minutes). The route takes no token and no tenant headers: the tenant is the one the signed event names.
- It finds every static scope of that tenant whose
overentity is the event’s and whoseonlists the operation. - For each, it reads the record as the system user, with its related records and knowledge, runs
the rules, and applies what they propose, exactly as
evaluatewithapply: truedoes. The system user must holdapplyon the scope (Access); a scope it may not apply is skipped and logged.
A write rules.svc makes can itself be a change data.svc delivers. Two things end the chain:
- A write the system user made triggers nothing. rules.svc’s own work never re-triggers a scope.
- A decision applied twice writes nothing the second time. A field set to what it holds is dropped, so a record re-evaluated after a caller’s write settles.
Retries
Section titled “Retries”Delivery is at least once, and safe to repeat for the same reason. rules.svc answers each
delivery so the outbox knows what to do: data.svc delivers again after a 5xx, 408 or 429,
and never after any other 4xx.
| Answer | Means | data.svc |
|---|---|---|
204 | handled, or nothing to do: no scope reacts to it, the tenant is not served here, the system user wrote it | done |
503, with Retry-After | the system user or a source cannot be reached now | delivers again |
401 | not signed with the secret, or its timestamp is not within five minutes | drops it |
400 | not an event rules.svc can read: no tenant or entity, or a tenant that is not a customer:env:product:tenant key | drops it |
404 | rules.events.enabled is off | drops it |
A secret that differs between the two services, or events turned off in rules.svc while data.svc still delivers, loses those changes: check both when you rotate the secret.
Continue with
Section titled “Continue with”- Scopes:
on. - Evaluating records: what an evaluation applies.
- Configuration.