Companion film
From dirty rows to trusted data
Run four visible Dataset transforms, explicitly publish three clean rows to TrustedOrders, and verify the bound Table reads only that result.
30 secGrid 0.63.2
Open film page →Guided build · 12
Continue the live revenue build at its source boundary: admit one connector event, prove the existing dashboard settles exactly once, and prepare its production handoff.
You will finish with: A connector-backed revenue app with bounded ingress failure checks, idempotent delivery, downstream proof, and named production evidence.
This is the operational continuation of Build a live revenue dashboard. That build already created the Orders, Customers, and Products tables; filtered, joined, and grouped them; published four semantic KPIs; and bound those KPIs to Layout.
Here you will leave that model logic unchanged. You will hand the Orders source boundary to an operator-configured connector adapter, reject one deliberately misbound event, deliver the pending-to-paid change exactly once, prove the existing dashboard settles, and prepare the model for production handoff.
The included event is a deterministic local fixture. This tutorial does not claim that the public site has executed it or published a Runtime Host receipt.
Complete the live-revenue-dashboard build first. That predecessor ends after changing o4 to paid, so perform this explicit handoff before connector work:
o4.status from paid back to pending.TotalRevenue = 90000, TotalMargin = 63000, ActiveSegments = 2, and RevenueAlert = false in the model and Layout.export GRID_MODEL_ID="replace-with-the-completed-dashboard-model-id"
If the completed dashboard is not present in GET /api/model-summaries, use your host's supported publish/deploy handoff to place that completed model and its seeded source tables in the Server Build first. The public API does not document a portable stateful-table export command, so do not continue against a newly deployed empty starter model.
The API-addressable model must now have:
o4 stored in Orders with status pending;TotalRevenue = 90000, TotalMargin = 63000, ActiveSegments = 2, and RevenueAlert = false;You also need curl, jq, a public API token, a separate connector-ingress token, and the order-status-paid.json asset above.
Your operator must provision this exact adapter contract for the deployed model:
| Binding field | Required value |
|---|---|
| HTTP source ID | revenue-orders |
| Delivered symbol | order-upsert |
| Target model | exact value of GRID_MODEL_ID |
| Target | Orders table upsert adapter |
| Stable row key | value.order_id |
| Accepted fields | order_id, customer_id, product_id, amount, status |
The public API does not document a binding-creation route or a universal table-upsert adapter configuration. This tutorial starts after the operator has configured and tested that boundary on the exact deployment. Do not reinterpret connector ingress as arbitrary cell mutation.
export GRID_URL="http://localhost:3000"
export GRID_TOKEN="replace-with-your-api-token"
export GRID_INGRESS_TOKEN="replace-with-your-ingress-token"
Confirm the ID resolves to the intended resident model before the operator binds it:
curl --fail-with-body \
-H "Authorization: Bearer $GRID_TOKEN" \
"$GRID_URL/api/models/$GRID_MODEL_ID/manifest" \
| jq '{id, sourceHash, declaredOutputs, protectedMode}'
The returned id must exactly equal GRID_MODEL_ID, and the manifest must expose the four KPI symbols. Give that exact ID—not the tutorial's title—to the operator provisioning the binding.
All HTTP requests target Node. Runtime Host and GRID_RUNTIME_RPC_TOKEN remain private. Review connector ingress and production credentials before continuing.
Resolve the public KPIs without reading the connector fixture:
curl --fail-with-body \
-H "Authorization: Bearer $GRID_TOKEN" \
-H "Content-Type: application/json" \
-X POST "$GRID_URL/api/models/$GRID_MODEL_ID/symbols/resolve" \
--data '{"symbols":["TotalRevenue","TotalMargin","ActiveSegments","RevenueAlert"]}' \
| tee /tmp/live-revenue-before.json \
| jq '{
revenue: .TotalRevenue.value.value,
margin: .TotalMargin.value.value,
segments: .ActiveSegments.value.value,
alert: .RevenueAlert.value.value,
requestRev: .TotalRevenue.requestRev,
resolvedRev: .TotalRevenue.resolvedRev
}'
Expected checkpoint from the preceding build: revenue 90000, margin 63000, segments 2, and alert false. Revision numbers are server-owned; record them so you can prove the later result is newer.
If the values differ, stop and inspect o4, the exact API model ID, and its settled revision. Do not tune the connector event around unexplained starting state.
jq -e '
.sourceKind == "adapter" and
(.events | length) == 1 and
.events[0].sourceSymbol == "order-upsert" and
.events[0].value.order_id == "o4" and
.events[0].value.status == "paid" and
.events[0].sequence == 5 and
.events[0].idempotencyKey == "revenue-order-o4-status-5"
' order-status-paid.json
jq '.events[0] | {
sourceSymbol,
rowKey: .value.order_id,
status: .value.status,
sequence,
idempotencyKey
}' order-status-paid.json
Deterministic local checkpoint:
{
"sourceSymbol": "order-upsert",
"rowKey": "o4",
"status": "paid",
"sequence": 5,
"idempotencyKey": "revenue-order-o4-status-5"
}
This validates only the authored event. The binding and application counters must come from the live ingress response.
Create a disposable payload with a misspelled source symbol and a different event identity:
jq '
.events[0].sourceSymbol = "order-upsert-typo" |
.events[0].sequence = 4 |
.events[0].idempotencyKey = "revenue-order-o4-status-4-typo"
' order-status-paid.json > /tmp/order-status-unbound.json
curl --fail-with-body \
-H "Authorization: Bearer $GRID_INGRESS_TOKEN" \
-H "Content-Type: application/json" \
-X POST "$GRID_URL/api/pipes/sources/revenue-orders/events" \
--data-binary @/tmp/order-status-unbound.json \
| tee /tmp/order-status-unbound-response.json \
| jq '{sourceId, admitted, deduped, unbound, applied, stream}'
Expected failure signal: the typo event applies no table write and is reported as unbound by the configured adapter path. Resolve the KPIs again; they must remain at the baseline.
If the typo applies a write, stop. The deployment binding is broader than the contract above and must be reviewed before untrusted connector data is admitted.
Minimal repair is to restore the exact order-upsert symbol. Do not add a wildcard binding, route around ingress with a direct cell write, or reuse the typo event's identity for corrected content.
Send the unchanged checked fixture through the exact source ID:
curl --fail-with-body \
-H "Authorization: Bearer $GRID_INGRESS_TOKEN" \
-H "Content-Type: application/json" \
-X POST "$GRID_URL/api/pipes/sources/revenue-orders/events" \
--data-binary @order-status-paid.json \
| tee /tmp/order-status-paid-response.json \
| jq '{sourceId, admitted, deduped, coalesced, unbound, applied, stream}'
For the resident configured target, require unbound = 0 and confirm applied includes the Orders upsert. admitted alone is not downstream proof.
Resolve the KPIs again:
curl --fail-with-body \
-H "Authorization: Bearer $GRID_TOKEN" \
-H "Content-Type: application/json" \
-X POST "$GRID_URL/api/models/$GRID_MODEL_ID/symbols/resolve" \
--data '{"symbols":["TotalRevenue","TotalMargin","ActiveSegments","RevenueAlert"]}' \
| tee /tmp/live-revenue-after.json \
| jq '{
revenue: .TotalRevenue.value.value,
margin: .TotalMargin.value.value,
segments: .ActiveSegments.value.value,
alert: .RevenueAlert.value.value,
requestRev: .TotalRevenue.requestRev,
resolvedRev: .TotalRevenue.resolvedRev
}'
Expected downstream checkpoint after a confirmed application: revenue 170000, margin 111000, segments 3, and alert true. The returned settled revision must not be older than the baseline revision.
Open Dashboard and confirm its four existing tiles show the same values. No table query, KPI formula, or Layout configuration changes in this tutorial.
Send order-status-paid.json again byte for byte:
curl --fail-with-body \
-H "Authorization: Bearer $GRID_INGRESS_TOKEN" \
-H "Content-Type: application/json" \
-X POST "$GRID_URL/api/pipes/sources/revenue-orders/events" \
--data-binary @order-status-paid.json \
| jq '{admitted, deduped, applied, stream}'
Expected checkpoint: Grid reports the delivery as deduplicated or duplicate rather than creating a second logical upsert. The four KPI values remain unchanged.
Reusing the same idempotency key with different content can return 409. A new source observation needs a new stable sequence and idempotency key. Preserve Retry-After and retry only identical idempotent content after overload.
Before handing the model to operators, create monitors or release checks for:
/readyz status and every failing probe;429 and overloaded 503 responses with Retry-After;unbound, deduped, applied, and stream.batchStatus trends;Do not log event payloads blindly: they can contain customer or commercial data. Store only the minimum identity needed for diagnosis under your data-handling policy.
See connector failure diagnosis for exact counter meanings.
Use the operator's deployment-specific procedure to:
catalogSha256 from /api/capabilities.order-status-paid.json canary against an isolated staging model with a fresh identity./readyz is 200 with status: "ok".The public documentation does not provide a universal image pull, drain, adapter-provisioning, backup, or restore command. Record and test the exact mechanisms your deployment actually uses rather than inventing portable-looking commands.
GRID_MODEL_ID; no relational or Layout logic was recreated.unbound = 0 with a confirmed upsert.170000, 111000, 3, and true.Continue with Send connector events to Grid for route details and Run Grid in production for the supported Server Build boundary.