testPayload is the proof contract for this Business Entity. Certification, capacity E2E, and mapping checks read it. A green invoke is not enough when gold rows are set. Role Assistant search does not own numeric totals.
Prerequisites
- Configure data flow with operations enabled
- Configure metadata and identity with
primaryKeyset - Test tenant credentials for live E2E (not production)
Where it lives
| Layer | Location |
|---|---|
| Mapping + capacity fixtures | <datasourceKey>.json → testPayload (closed root) |
| Optional schema rules | validation when used |
| How to run the ladder | Connected System tests |
Manifest keys: validation, testPayload.
Builder MCP
| Manifest keys | validation, testPayload |
| Help topics | section, evidencePatterns, repairRules |
| Repair hooks | test |
How the contract works
Two proofs share one object. Do not mix them.
| Proof | Fields | What it asserts |
|---|---|---|
| Mapping (one record) | payloadTemplate + expectedResult |
Expressions resolve; one normalized record shape |
| Capacity E2E (rows) | scenarios[] + optional expectedRows |
CIP output rows after list, get, or a named viewpoint answer |
payloadTemplate is what mapping expressions read (often provider/raw shape). Write scenario input is the exposed shape a REST or MCP caller would send — not the vendor envelope.
expectedRows |
Meaning |
|---|---|
| Omitted | Success-only (invoke did not throw) |
[] |
Expect zero rows — zero is a fact, not unknown |
| One or more objects | Gold rows; identityKey required |
matchMode subsetIdentities (default) allows extra live rows — typical for a list probe. exactIdentities fails extra identities. Optional numericTolerance applies only to numbers. Viewpoint SQL remains the calculator.
listWindow (page / pageSize, default 1 / 5) is the capacity list probe. It does not change live paginate.maxPages.
How to set
- Repair test band when fixture output drifted.
--testrebuilds mappingpayloadTemplate/expectedResultfrom attributes. It keeps scenarioexpectedRows(andidentityKey/numericTolerance/matchMode). It does not invent gold rows from attributes:
aifabrix repair <systemKey> --test --dry-run
aifabrix repair <systemKey> --test
- Author
testPayloadbefore first E2E — identity, probe window, mapping gold, then scenarios:
{
"testPayload": {
"mode": "live",
"primaryKey": { "externalId": "e2e-fixture-001" },
"useCopyForMutations": true,
"listWindow": { "page": 1, "pageSize": 5 },
"payloadTemplate": {
"id": "e2e-fixture-001",
"name": "E2E Record"
},
"expectedResult": {
"externalId": "e2e-fixture-001",
"name": "E2E Record"
},
"scenarios": [
{ "operation": "list", "enabled": true },
{
"operation": "get",
"enabled": true,
"identityKey": "externalId",
"matchMode": "subsetIdentities",
"expectedRows": [
{ "externalId": "e2e-fixture-001", "name": "E2E Record" }
]
}
]
}
}
- Named viewpoint answers use the same
expectedRowscontract —identityKeyis that operation’s output field (for example a customer id on a revenue cut), not a dump type. - Writes:
inputis exposed fields. Gold persisted values on a followingget, not on create/update/delete. Disable mutating steps in shared tenants withenabled: false. - Validate then run the ladder — Connected System tests.
Defaults and examples
| Field | Default / practice |
|---|---|
mode |
live for certification; mock for offline mapping only |
listWindow |
page 1, pageSize 5 when omitted |
useCopyForMutations |
true when create runs — copy, do not destroy shared fixtures |
matchMode |
subsetIdentities |
numericTolerance |
0 (use a small absolute value for money/ratios only) |
Validate
aifabrix repair <systemKey> --test
aifabrix validate <systemKey>
aifabrix datasource test-e2e <datasourceKey> --app <systemKey>
A green invoke is not enough when expectedRows is set — the run must match gold identities and values.
Common mistakes
| Mistake | Fix |
|---|---|
Treating mapping expectedResult as SUM/COUNT |
Put gold on scenarios[].expectedRows |
Expecting repair --test to invent expectedRows |
Author gold yourself; repair keeps existing rows |
| Copying a capability and trusting cloned gold | Edit expectedRows — copied gold may be wrong for the new operation |
| Using Role Assistant search as numeric proof | Keep gold on this Connected System datasource |
Provider envelope on write input |
Send exposed fields only |
Omitting identityKey with non-empty expectedRows |
Set the output identity field |
Lowering live paginate.maxPages to speed tests |
Set listWindow instead |
| Production IDs in fixtures | Isolated test-tenant keys |
Limits
Root testPayload is closed — unknown keys fail validate. Nested payloadTemplate / expectedResult / row objects stay open. Live E2E needs credentials; skip mutating scenarios when only read certification is in scope. Document fixture ids in the integration README. Re-run validate after changing scenarios.