signup-intake
Two inputs feed one pipeline: an http form at /in/signup-intake/form and a nightly schedule import. A map node cleans both the same way and records meta.input, the input each sign-up came through. The output is to: pipeline: every sign-up is handed to signup-store, exactly once, and delivered.check: downstream waits until signup-store has written and verified it.
bun pipo check examples # checks both ends of the chain together (P064)
bun pipo start examples/signup-store/signup-store.pipo
bun pipo start examples/signup-intake/signup-intake.pipo --listen 8790
curl -X POST localhost:8790/in/signup-intake/form -H 'content-type: application/json' -d '{"email": "Ada@Example.com", "name": "Ada"}'
bun pipo test examples/signup-intake
If signup-store isn't running, the hand-off is retried (output.on_error) and the sign-ups wait in signup-intake's journal.
signup-intake.pipo#
# Sign-ups come in two ways: a web form and a nightly import. Both are cleaned the same way, then handed to
# signup-store, which writes and verifies them (a chain, docs/spec.md §3.14). Several inputs, one output (§3.3.1).
# bun pipo start examples/signup-store/signup-store.pipo
# bun pipo start examples/signup-intake/signup-intake.pipo --listen 8790
# curl -X POST localhost:8790/in/signup-intake/form -H 'content-type: application/json' \
# -d '{"email": " Ada@Example.com ", "name": "Ada"}'
pipo: 1
name: signup-intake
description: Sign-ups from a web form and a nightly import, cleaned and handed to signup-store.
inputs:
form:
via: http
with: {path: /form}
validate:
- exists(data.email)
nightly:
via: schedule
with:
cron: "0 3 * * *"
payload: {email: import@example.com, name: Nightly import}
nodes:
clean:
from: [form, nightly]
transform: map
with:
data:
email: "${lower(trim(data.email))}"
name: "${trim(default(data.name, ''))}"
via: "${meta.input}"
output:
from: clean
to: pipeline
with: {pipeline: signup-store}
on_error: {retry: 10, backoff: exponential, delay: 1s, max_delay: 30s}
# Delivered only once signup-store has written and verified it, not just received it.
delivered:
check: downstream
within: 1m
on_fail: {then: dead_letter}
Source: examples/signup-intake.