flowreview v1examples/review/temporal/review.flow · dandori doc
Jev scores an application and says how sure it is, and a rule decides whether the verdict is acted on at once or goes to a person for approval: approving at once asks more certainty than rejecting at once. Written for Temporal: the scoring is an activity dandori writes, which calls Jev with TypeSafe's key (TYPESAFE_API_KEY) on the workers of its own task queue, which may be written in another language, and so does the notice, an activity you write; the rule runs in the worker of the workflow; the approver's tool answers the callback by the update the generated client sends
flow| Line | Call | Calls | Retries | Timeout | When it fails |
|---|---|---|---|---|---|
| 49 | r = score(…) | jev · jev-1.13.0 | 2 times every 10 seconds (busy, overloaded) | 10 seconds | busy, overloaded, timeout, failure → line 50 |
| 51 | d = policy(…) | rule review_policy.rule | 2 times, after 1 second and 2 (failure) | — | timeout, failure → the workflow fails |
| 55 | a = ask_for_approval(…) | a task you write, answered by a callback | — | 3 days | timeout → line 56failure → the workflow fails |
| 57 | notify(…) | a task you write, idempotent | — | — | timeout, failure → the workflow fails |
| 59 | notify(…) | a task you write, idempotent | — | — | timeout, failure → the workflow fails |
| Line | End |
|---|---|
| 50 | fail Unscorable "Could not score application {application.id}" |
| 56 | fail NoAnswer "No approval in three days" |
| 58 | succeed verdict = approve |
| 60 | succeed verdict = r.verdict |
Pick a step to see what the checker knows there. Pick a scenario on the left to light up the way its run goes; the number beside a step is how often the run passes it.
review v1Jev scores an application and says how sure it is, and a rule decides whether the verdict is acted on at once or goes to a person for approval: approving at once asks more certainty than rejecting at once. Written for Temporal: the scoring is an activity dandori writes, which calls Jev with TypeSafe's key (TYPESAFE_API_KEY) on the workers of its own task queue, which may be written in another language, and so does the notice, an activity you write; the rule runs in the worker of the workflow; the approver's tool answers the callback by the update the generated client sends
application: Applicationverdict: policy.verdictexamples/review/temporal/review.flowr = score(…) line 4949 let r = score(purpose: application.purpose) 50 on failure => fail Unscorable "Could not score application {application.id}"
jev · jev-1.13.0busy, overloaded, timeout, failure → line 5024 # Jev places what the applicant wrote on the scale of verdicts, from the lowest level, and how 25 # sure it is of the verdict comes as a rate, for the rule to weigh. 26 task score(purpose: string) -> Score 27 jev 28 verdict score "How clearly is the money for running the business?" 29 reject "It is for something personal or speculative, or against the law" 30 hold "It is for the business, but the statement leaves unclear what it pays for" 31 approve "It pays for a named part of running the business, such as stock, equipment, staff or premises" 32 sure confidence of verdict 33 model "jev-1.13.0" 34 queue "scoring" 35 errors busy = 429, overloaded = 529 36 retry 2 times every 10 seconds on busy, overloaded 37 timeout 10 seconds
fail Unscorable line 50 50 on failure => fail Unscorable "Could not score application {application.id}"
d = policy(…) line 51 51 let d = policy(verdict: r.verdict, sure: r.sure)
review_policy.ruletimeout, failure → the workflow fails 4 use rule policy from "../rules/review_policy.rule"
match d.decision line 5252 match d.decision 53 approve, reject => pass 54 ask =>
a = ask_for_approval(…) line 5555 let a = ask_for_approval(application_id: application.id, amount: application.amount, sure: r.sure) 56 on timeout => fail NoAnswer "No approval in three days"
timeout → line 56failure → the workflow fails39 # Someone approves in a tool of their own, and the answer comes back with the callback's id. 40 task ask_for_approval(application_id: string, amount: int, sure: rate[step 1%]) -> Approval 41 callback 42 timeout 3 days
fail NoAnswer line 56 56 on timeout => fail NoAnswer "No approval in three days"
notify(…) line 57 57 notify(application_id: application.id, text: "{a.approver} approved application {application.id}")
idempotenttimeout, failure → the workflow fails44 task notify(application_id: string, text: string) 45 queue "notify" 46 idempotent
succeed verdict = approve line 58 58 succeed verdict = approve
notify(…) line 59 59 notify(application_id: application.id, text: "Application {application.id} was reviewed: {r.verdict}")
idempotenttimeout, failure → the workflow fails44 task notify(application_id: string, text: string) 45 queue "notify" 46 idempotent
succeed verdict = r.verdict line 60 60 succeed verdict = r.verdict
end: succeedsThe flow runs to its end, and the workflow succeeds.
r = score(…) okd = policy(…) okmatch d.decision → approve, rejectnotify(…) oksucceed verdict = r.verdictr = score(…) failure → on failurefail Unscorabler = score(…) busy okd = policy(…) failure failure failure → not handled herer = score(…) okr = score(…) okd = policy(…) okr = score(…) okd = policy(…) okmatch d.decision → approve, rejectnotify(…) failure → not handled herer = score(…) okd = policy(…) okmatch d.decision → aska = ask_for_approval(…) oknotify(…) oksucceed verdict = approver = score(…) busy okd = policy(…) okmatch d.decision → aska = ask_for_approval(…) timeout → on timeoutfail NoAnswerr = score(…) okd = policy(…) okmatch d.decision → aska = ask_for_approval(…) failure → not handled herer = score(…) okd = policy(…) okmatch d.decision → aska = ask_for_approval(…) okr = score(…) okd = policy(…) okmatch d.decision → aska = ask_for_approval(…) oknotify(…) failure → not handled here