Relay Implementation
Full implementation plan for turning the stub Lambda handler into a working configurable webform relay.
What it does
Webform Relay accepts HTTP POST submissions at /api/v1/submit/{form-name},
maps the input fields according to a YAML config, and fans out the result to
one or more output targets — all without redeployment when the config changes.
Architecture
Browser
│ POST /api/v1/submit/{form-name}
▼
API Gateway
│
▼
Lambda (Go container)
├── Load config from S3 (TTL cache, default 30s)
├── Route to named form
├── Validate input fields
├── Apply field mapping
└── Fan-out to output targets
├── HTTP POST (GitLab issue form, any webhook)
├── Email (Amazon SES)
└── Salesforce Web2LeadConfig
Config is a YAML file stored in S3. The Lambda reads CONFIG_BUCKET and
CONFIG_KEY from environment variables, caches the parsed config in memory
for CACHE_TTL seconds, and re-fetches on cache expiry. No container
rebuild or redeployment is needed to change config — update the S3 file and
wait for the TTL.
cache_ttl: 30s
forms:
contact:
fields:
- name: name
required: true
- name: email
required: true
type: email
- name: message
required: true
type: textarea
outputs:
- type: email
to: hello@example.com
subject: "New contact: {{.name}}"
mapping:
from_name: name
body: message
static:
source: website
- type: http_post
url: https://gitlab.example.com/api/v4/projects/1/issues
headers:
Authorization: "Bearer {{env.GITLAB_TOKEN}}"
mapping:
title: name
description: message
newsletter:
fields:
- name: email
required: true
outputs:
- type: salesforce_web2lead
url: https://webto.salesforce.com/servlet/servlet.WebToLead
mapping:
email: email
static:
oid: "00Dxxxxxxxxxxxxxxx"
retURL: https://example.com/thanksOutput targets
| Type | What it does |
|---|---|
http_post | Posts mapped fields as application/x-www-form-urlencoded to any URL |
email | Sends via Amazon SES |
salesforce_web2lead | Posts to the Salesforce Web-to-Lead endpoint |
Multiple outputs per form are all attempted on every submission (fan-out).
CLI
A webform-relay binary is built by task build:cli. It reads a local
config file (not S3) and is used for development and CI.
webform-relay form html contact # print the HTML form to stdout
webform-relay form list # list all configured form names
webform-relay config validate # validate the config fileDevelopment process
Each internal package is built with a strict Red-Green cycle:
- Opus writes failing tests that define the interface and behaviour.
- Sonnet implements until the tests are green.
- Haiku runs
task test:alland confirms. - Opus reviews the implementation assuming it is wrong and lists issues.
- Sonnet fixes every issue.
- Haiku confirms tests are still green.
Components are completed in this order:
internal/config— structs, YAML parsing, S3 loader, TTL cacheinternal/form— validation, HTML rendererinternal/mapping— field rename + static value injectioninternal/relay/http— HTTP POST targetinternal/relay/email— SES email targetinternal/relay/salesforce— Salesforce Web2Lead targetinternal/relay— fan-out coordinatorinternal/handler— Lambda handler + routingcmd/cli— CLI binary