wf-order-review-request
Purpose
Contour 2 of the review system: ask the customer, once, after the work is done.
One run finds one order that finished long enough ago, has a customer to write
to and has never been asked; mints its personal single-use review link in; and sends the ask through rp-reviews.lm-ses
Why this is a workflow
The question "which finished orders have not been asked yet" spans two services
that are forbidden to know about each other: does not know what arp-orders
review is, and holds rp-reviews as an opaque string. Putting the twoorderId
lists side by side is exactly what a flow is for — and is what makesrt.node
the link minting survive a restart without minting a second one.
Shape
read-settings → list-finished (completed, updatedAt ≤ now − delay)
→ list-invites (which of those were already asked)
→ create-invite → send-email → mark-sent | mark-failed
One mail per run, so a stuck address never blocks the queue behind it and the
schedule decides the rate. renders the mail and mints nothing: adryRun
rehearsal that left a live link behind would have the next real run skip that
order as already asked.
A refused mail comes back from as lm-ses, not as a throw,{ success: false }
so it is an ordinary branch that marks the invite — not an errorfailed
boundary.
Parameters
(required) — sender address.from(required) —ses.SesCredentials— filled intoshopNamein the templates.{{shopName}}— overridesdelayHoursfor a catch-up.ReviewSettings.requestDelayHours— render and stop.dryRun
Subject, body, link base and the delay come from , so thereviews.getSettings()
shop changes its own wording without touching this flow.
Direct module dependencies
g-ordersg-reviewsg-ses
Source
modules/workflows/wf-order-review-request