Demo Scenario
1. Purpose
Section titled “1. Purpose”The demo is the product acceptance test.
It should prove that Wayscribe can reconstruct a complete entity journey and reveal where a data defect first appeared.
2. Services
Section titled “2. Services”demo-source
Section titled “demo-source”Simulates Salesforce sending an account webhook.
demo-integration
Section titled “demo-integration”Receives the webhook, transforms the account, writes PostgreSQL, and publishes a message.
demo-worker
Section titled “demo-worker”Consumes the message and sends the customer to the target API.
This may initially run in the same application repository but should be a distinct process.
demo-target
Section titled “demo-target”Simulates HubSpot and rejects customers without a phone number.
Wayscribe services
Section titled “Wayscribe services”- API
- web
- PostgreSQL
3. Test customer
Section titled “3. Test customer”{ "Id": "0018Z00002ABC", "Name": "Jorge Polanco", "Phone": "+1 919 555 1234", "Status__c": "Active"}Expected internal customer:
{ "externalId": "0018Z00002ABC", "name": "Jorge Polanco", "phone": "+1 919 555 1234", "status": "active"}4. Intentional defect
Section titled “4. Intentional defect”The transformation incorrectly reads:
phone: account.Phone__c ?? nullThe incoming payload uses Phone, so output becomes:
{ "phone": null}5. Journey identifiers
Section titled “5. Journey identifiers”Primary entity:
customer:0018Z00002ABCAliases added later:
salesforceAccountId = 0018Z00002ABCinternalCustomerId = 18492targetContactId = absent because creation failed6. Expected timeline
Section titled “6. Expected timeline”10:31:02 receive-salesforce-webhook10:31:04 transform-salesforce-account10:31:05 persist-customer10:31:06 publish-customer-updated10:31:07 consume-customer-updated10:31:09 deliver-customer-to-target failed10:31:39 retry-customer-delivery failed10:32:39 retry-customer-delivery failed10:34:38 move-message-to-dead-letter7. Expected transformation diff
Section titled “7. Expected transformation diff”The transformation maps a Salesforce account onto an internal customer, and every field is renamed in the process. The diff therefore shows the Salesforce fields leaving and the internal fields arriving:
| Field | Before | After |
|---|---|---|
Id |
"0018Z00002ABC" |
(absent) |
Name |
"Jorge Polanco" |
(absent) |
Phone |
"+1 919 555 1234" |
(absent) |
Status__c |
"Active" |
(absent) |
externalId |
(absent) | "0018Z00002ABC" |
name |
(absent) | "Jorge Polanco" |
phone |
(absent) | null |
status |
(absent) | "active" |
The defect is visible in the pair of rows for the phone number: Phone went in
carrying a value, and phone came out null. Every other field arrives with its
value intact, which is what makes that pair stand out.
This replaced an earlier version of this section that showed phone changing
from "+1 919 555 1234" to null with name unchanged, as though input and
output shared field names. That diff is not producible from this step: section 3
defines the input as the Salesforce shape and the output as the internal shape, so
an input-versus-output comparison can only ever report removals and additions.
What the earlier version depicted was expected output versus actual output: the
correct internal customer against the defective one. That is the replay comparison
in REPLAY_SPEC.md section 11, not the transformation diff. See ADR-030.
8. Expected target response
Section titled “8. Expected target response”{ "error": { "code": "phone_required", "message": "A phone number is required." }}HTTP status:
4229. Search acceptance cases
Section titled “9. Search acceptance cases”The journey should be found using:
0018Z00002ABC18492- journey ID
- queue message ID
- trace ID where present
10. Replay acceptance case
Section titled “10. Replay acceptance case”After correcting the transformation to:
phone: account.Phone ?? nullThe user replays the original source payload to a development replay endpoint.
Expected replay output:
{ "externalId": "0018Z00002ABC", "name": "Jorge Polanco", "phone": "+1 919 555 1234", "status": "active"}The comparison shows that the phone number is preserved.
11. Automated E2E test
Section titled “11. Automated E2E test”The test should:
- start the full Compose stack
- wait for readiness
- trigger the source webhook
- poll for journey completion or failure
- search by Salesforce ID
- verify the event count and order
- verify the phone diff
- verify target rejection
- verify retry events
- invoke replay against corrected endpoint
- verify replay result
- verify replay audit event
12. Demo command goal
Section titled “12. Demo command goal”The final developer experience should approach:
docker compose -f infrastructure/compose.yaml \ -f infrastructure/compose.demo.yaml up --build
pnpm demo:triggerThen open the web UI and search:
0018Z00002ABC