{
  "id": "FLOW-007",
  "name": "AfterSave recordUpdate with implicit-Id pattern updates NULL-field Account (PB null semantics)",
  "description": "Regression lock for issue #2132. Process Builder-generated AfterSave recordUpdate elements carry an 'implicit-Id' filter (field=Id, operator=EqualTo, processMetadataValues=[{name:implicit,booleanValue:true}]) that identifies the target record via a relationship lookup. Additional (non-implicit) criteria use NotEqualTo against a non-null value. SQL semantics evaluate NULL != 'x' as NULL (false), silently excluding rows whose field is NULL. Salesforce Process Builder runtime instead treats NULL as 'not equal to any non-null value' (TRUE). The fix detects the implicit-Id pattern and generates '(field != val OR field IS NULL)' for NotEqualTo conditions, matching PB runtime semantics. Test: creates a Contact linked to an Account whose Industry is NULL. The test flow fires on Contact AfterSave Create, runs a recordUpdate on Account with implicit-Id filter (Id = $Record.AccountId) + non-implicit filter (Industry != 'Technology'). Before the fix: NULL Industry excluded by SQL → Description stays NULL. After the fix: NULL Industry included → Description is set to 'pb_implicit_update_test'. Tenant-agnostic: standard SObjects (Account, Contact), standard fields (AccountId, Industry, Description). No __c business names.",
  "object": "Contact",
  "method": "POST",
  "endpoint": "/services/data/v63.0/sobjects/Contact",
  "setup": [
    {
      "type": "http",
      "name": "Create target Account with NULL Industry (the field the filter excludes pre-fix)",
      "method": "POST",
      "endpoint": "/services/data/v63.0/sobjects/Account",
      "payload": {
        "Name": "FLOW-007-PB-NullSemantics-Account"
      },
      "expects": {
        "status_code": 201
      },
      "extract": {
        "flow007_account_id": "id"
      }
    },
    {
      "type": "http",
      "name": "Create test Flow: Contact AfterSave → implicit-Id recordUpdate on Account with Industry!=Technology",
      "method": "POST",
      "endpoint": "/services/data/v63.0/tooling/sobjects/Flow",
      "payload": {
        "MasterLabel": "FLOW-007 PB Null Semantics Test",
        "ProcessType": "AutoLaunchedFlow",
        "Status": "Draft",
        "Metadata": {
          "apiVersion": "63.0",
          "label": "FLOW-007 PB Null Semantics Test",
          "description": "Test-only AfterSave flow that exercises the implicit-Id recordUpdate PB null semantics fix (#2132). Triggers on Contact Create; updates the linked Account Description when Id matches AccountId (implicit filter) and Industry is not 'Technology' (PB semantics: NULL industry counts as not-equal). Teardown deletes this flow version.",
          "status": "Draft",
          "processType": "AutoLaunchedFlow",
          "start": {
            "locationX": 50,
            "locationY": 0,
            "object": "Contact",
            "triggerType": "RecordAfterSave",
            "recordTriggerType": "Create",
            "connector": {
              "targetReference": "UpdateLinkedAccount"
            }
          },
          "recordUpdates": [
            {
              "name": "UpdateLinkedAccount",
              "label": "Update Linked Account",
              "locationX": 176,
              "locationY": 287,
              "object": "Account",
              "filterLogic": "and",
              "filters": [
                {
                  "field": "Id",
                  "operator": "EqualTo",
                  "processMetadataValues": [
                    {
                      "name": "implicit",
                      "value": {
                        "booleanValue": true
                      }
                    }
                  ],
                  "value": {
                    "elementReference": "$Record.AccountId"
                  }
                },
                {
                  "field": "Industry",
                  "operator": "NotEqualTo",
                  "processMetadataValues": [
                    {
                      "name": "implicit",
                      "value": {
                        "booleanValue": false
                      }
                    }
                  ],
                  "value": {
                    "stringValue": "Technology"
                  }
                }
              ],
              "inputAssignments": [
                {
                  "field": "Description",
                  "value": {
                    "stringValue": "pb_implicit_update_test"
                  }
                }
              ]
            }
          ]
        }
      },
      "expects": {
        "status_code": 201
      },
      "extract": {
        "flow007_version_id": "id"
      }
    },
    {
      "type": "http",
      "name": "Activate the test Flow so it fires on Contact AfterSave",
      "method": "POST",
      "endpoint": "/services/data/v63.0/tooling/sobjects/Flow/{flow007_version_id}/activate",
      "expects": {
        "status_code": 204
      }
    }
  ],
  "payload": {
    "LastName": "FLOW-007-PB-NullSemantics-Contact",
    "AccountId": "{flow007_account_id}"
  },
  "expects": {
    "status_code": 201
  },
  "query_after": {
    "object": "Account",
    "record_id": "{flow007_account_id}",
    "retry": 15,
    "delay_ms": 2000,
    "assertions": [
      {
        "field": "Description",
        "operator": "eq",
        "value": "pb_implicit_update_test"
      }
    ]
  },
  "teardown": [
    {
      "method": "DELETE",
      "endpoint": "/services/data/v63.0/sobjects/Contact/{id}"
    },
    {
      "method": "DELETE",
      "endpoint": "/services/data/v63.0/sobjects/Account/{flow007_account_id}"
    },
    {
      "method": "DELETE",
      "endpoint": "/services/data/v63.0/tooling/sobjects/Flow/{flow007_version_id}"
    }
  ],
  "priority": "P0",
  "bug_ref": "#2132",
  "scene": "flow"
}
