{
  "id": "workflow-action-lead-authorship-finalization",
  "title": "Set Campaign atomically creates a Lead with finalized HubSpot authorship",
  "kind": "hubspot_sync",
  "optional": true,
  "targetedAcceptance": {
    "schemaVersion": "hubspot-targeted-acceptance/v1",
    "reason": "Workflow-action Lead authorship finalization before outbound visibility."
  },
  "executionMode": "serial",
  "executionModeReason": "The case uses one synthetic unbound HubSpot contact identity so the workflow action, rather than an ordinary contact webhook, must own Lead creation and authorship finalization.",
  "caseTimeoutMs": 420000,
  "linkedIssues": [4166],
  "provenance": {
    "businessScenario": "补一个hubspot integration test case到l2",
    "reportedBy": "Amber",
    "capturedAt": "2026-07-21",
    "calibrated": "A signed Set Campaign workflow action for a unique remote contact identity that has never entered through the ordinary contact webhook must atomically create the Lead and finalize the exact HubSpot authorship before record-triggered PushLeadToHubSpotContact can observe its nonblank HubSpot_Id__c. It must not emit non-blank remote-id field HubSpot_Id__c has no matching authored inbound evidence."
  },
  "steps": [
    {
      "id": "create-campaign",
      "system": "nexuscrm",
      "authRole": "admin",
      "method": "POST",
      "path": "/services/data/v63.0/sobjects/Campaign",
      "body": {
        "Name": "IT Workflow Authorship Finalize {{__runId}}",
        "IsActive": true
      },
      "expectStatusRange": [200, 299],
      "assertions": [
        { "path": "response.body.id", "exists": true }
      ]
    },
    {
      "id": "build-synthetic-workflow-action-contact",
      "system": "tidb",
      "method": "GET",
      "sql": "SELECT CAST(8000000000000000 + CAST(CONV(SUBSTRING(SHA2('{{__runId}}', 256), 1, 10), 16, 10) AS UNSIGNED) AS CHAR) AS id, 'workflow-authorship-finalize-{{__runId}}@example.com' AS email",
      "expectStatus": 200,
      "assertions": [
        { "path": "response.body.records[0].id", "exists": true },
        { "path": "response.body.records[0].email", "exists": true }
      ]
    },
    {
      "id": "assert-synthetic-contact-is-unbound",
      "system": "tidb",
      "method": "GET",
      "sql": "SELECT (SELECT COUNT(*) FROM `Lead` WHERE HubSpot_Id__c = '{{steps.build-synthetic-workflow-action-contact.response.body.records[0].id}}' AND IsConverted = 0 AND IsDeleted = 0) AS LeadCount, (SELECT COUNT(*) FROM `Contact` WHERE HubSpot_Id__c = '{{steps.build-synthetic-workflow-action-contact.response.body.records[0].id}}' AND IsDeleted = 0) AS ContactCount, (SELECT COUNT(*) FROM `_System_ConnectorRemoteLink` WHERE ConnectorOwnerKey = 'pingcap-hubspot-companion' AND RemoteId = '{{steps.build-synthetic-workflow-action-contact.response.body.records[0].id}}' AND Status = 'finalized') AS FinalizedLinkCount",
      "expectStatus": 200,
      "assertions": [
        { "path": "response.body.records[0].LeadCount", "numericEquals": 0 },
        { "path": "response.body.records[0].ContactCount", "numericEquals": 0 },
        { "path": "response.body.records[0].FinalizedLinkCount", "numericEquals": 0 }
      ]
    },
    {
      "id": "execute-set-campaign",
      "system": "connector_action",
      "path": "/webhooks/hubspot-crm-connector/workflow-action",
      "forEach": "steps.build-synthetic-workflow-action-contact.response.body.records",
      "contactIdField": "id",
      "emailField": "email",
      "campaignId": "{{steps.create-campaign.response.body.id}}",
      "status": "Sent",
      "callbackIdPrefix": "authorship-finalize",
      "concurrency": 1,
      "assertions": [
        { "path": "response.body.failedCount", "numericEquals": 0 },
        { "path": "response.body.acceptedCount", "numericEquals": 1 }
      ]
    },
    {
      "id": "assert-workflow-action-terminal",
      "system": "tidb",
      "method": "GET",
      "sql": "SELECT COUNT(*) AS EventCount, SUM(CASE WHEN W.State = 'processed' THEN 1 ELSE 0 END) AS ProcessedCount, SUM(CASE WHEN W.State = 'dead' THEN 1 ELSE 0 END) AS DeadCount, MIN(E.CreatedDate) AS ActionCreatedAt, MAX(W.TerminalAt) AS ActionTerminalAt FROM `_System_ConnectorEvent` E JOIN `_System_ConnectorWorkItem` W ON W.EventId = E.Id WHERE E.Namespace = 'hubspot-crm-connector' AND E.EventKind = 'workflow.action.execute' AND E.SourceObjectID = '{{steps.build-synthetic-workflow-action-contact.response.body.records[0].id}}'",
      "expectStatus": 200,
      "poll": { "budgetMs": 300000, "intervalMs": 6000 },
      "onTimeout": "fail",
      "assertions": [
        { "path": "response.body.records[0].EventCount", "numericEquals": 1 },
        { "path": "response.body.records[0].ProcessedCount", "numericEquals": 1 },
        { "path": "response.body.records[0].DeadCount", "numericEquals": 0 },
        { "path": "response.body.records[0].ActionCreatedAt", "exists": true },
        { "path": "response.body.records[0].ActionTerminalAt", "exists": true }
      ]
    },
    {
      "id": "assert-workflow-action-authorship-finalized",
      "system": "tidb",
      "method": "GET",
      "sql": "SELECT P.Id AS LeadId, P.HubSpot_Sync_Enabled__c, P.HubSpot_Id__c, L.LinkKey, (SELECT COUNT(*) FROM `_System_ConnectorRemoteLink` X WHERE X.ConnectorOwnerKey = L.ConnectorOwnerKey AND X.RemoteId = L.RemoteId AND X.SourceObject = 'Lead' AND X.DestinationSlotId = 'hubspot-contact' AND X.Status = 'finalized') AS FinalizedLinkCount, (SELECT COUNT(*) FROM `_System_ConnectorInboundRemoteIDEvidence` E WHERE E.ConnectorOwnerKey = L.ConnectorOwnerKey AND E.SourceObject = L.SourceObject AND E.SourceRecordId = L.SourceRecordId AND E.RemoteId = L.RemoteId AND E.EvidenceStatus = 'consumed' AND E.ConsumedByLinkKey = L.LinkKey AND E.ActiveKey IS NULL) AS ConsumedEvidenceCount, (SELECT COUNT(*) FROM `CampaignMember` M WHERE M.CampaignId = '{{steps.create-campaign.response.body.id}}' AND M.LeadId = P.Id) AS CampaignMemberCount FROM `_System_ConnectorRemoteLink` L JOIN `Lead` P ON P.Id = L.SourceRecordId AND P.IsConverted = 0 AND P.IsDeleted = 0 WHERE L.ConnectorOwnerKey = 'pingcap-hubspot-companion' AND L.RemoteId = '{{steps.build-synthetic-workflow-action-contact.response.body.records[0].id}}' AND L.SourceObject = 'Lead' AND L.DestinationSlotId = 'hubspot-contact' AND L.Status = 'finalized' LIMIT 1",
      "expectStatus": 200,
      "poll": { "budgetMs": 300000, "intervalMs": 6000 },
      "onTimeout": "fail",
      "assertions": [
        { "path": "response.body.records[0].LeadId", "exists": true },
        { "path": "response.body.records[0].HubSpot_Sync_Enabled__c", "numericEquals": 1 },
        { "path": "response.body.records[0].HubSpot_Id__c", "equals": "{{steps.build-synthetic-workflow-action-contact.response.body.records[0].id}}" },
        { "path": "response.body.records[0].FinalizedLinkCount", "numericEquals": 1 },
        { "path": "response.body.records[0].ConsumedEvidenceCount", "numericEquals": 1 },
        { "path": "response.body.records[0].CampaignMemberCount", "numericEquals": 1 }
      ]
    },
    {
      "id": "assert-no-missing-authorship-error",
      "system": "tidb",
      "method": "GET",
      "sql": "SELECT COUNT(*) AS MissingAuthorshipErrorCount FROM `_System_FlowAuditLog` WHERE CreatedDate >= '{{steps.assert-workflow-action-terminal.response.body.records[0].ActionCreatedAt}}' AND CreatedDate <= DATE_ADD('{{steps.assert-workflow-action-terminal.response.body.records[0].ActionTerminalAt}}', INTERVAL 30 SECOND) AND ElementId = 'PushLeadToHubSpotContact' AND ErrorPayload LIKE '%non-blank remote-id field HubSpot_Id__c has no matching authored inbound evidence%'",
      "expectStatus": 200,
      "assertions": [
        { "path": "response.body.records[0].MissingAuthorshipErrorCount", "numericEquals": 0 }
      ]
    }
  ]
}
