{
  "apiVersion": 56,
  "label": "Credits — Notify Approver on Assignment",
  "description": "Approval-notification Flow (proposal §0 Phase 3 item 2). Invoked ONLY by the approval lifecycle bridge via ProcessAction ActionType='Flow' rows bound to the Submit and StepApproval events of both Credits chains — it has no record trigger by design (the approval-notification sandbox rejects triggered Flows). Recipients come from the bridge-injected Approval.ApproverUserIds variable, which carries the POST-GATING newly-assigned approver ids (nextActorIDs on step advance; step-1 assignees on Submit), so a conditionally-skipped step (e.g. the dormant Finance gate) never receives a notification. Dual channel per the item-2 requirement: one email via resolveEmailRecipients + sendEmail (template emailtmpl_credits_approver_assigned_20260713, seeded by credits-approvals.seed.json), and one in-app bell notification per assigned approver via a Loop over Approval.ApproverUserIds calling sendNotification (Credits chains assign exactly one approver per step, so the loop normally runs once). Requires the sendNotification actionCall (upstream NX PR#3627, nexuscrm >= 6f611b75) AND the executeLoop []string collection fix — the bridge injects ApproverUserIds as a Go []string, which executeLoop's collection switch rejects (fails closed) on every invocation until that upstream gap is fixed; do not bind this Flow before BOTH land in the stack ref. sendEmail carries a faultConnector to the loop so an email failure (unresolvable recipient / render error) never suppresses the bell leg. Bell link is /approvals (the recipient's approvals queue) — object-agnostic and valid for both the Credits__c and Credits_Topup__c chains; Notification.link is a required (NOT NULL) field, so the bell insert fails validation without it. The scalar SObject variable 'Approval' is declared ONLY to satisfy the install-time metadata program check (programchecker): the approval bridge injects Approval as flow context at runtime, but the static checker resolves the loop collectionReference 'Approval.ApproverUserIds' only when its root is a declared non-collection loose (SObject/Unknown) variable — do NOT remove it. At runtime initializeFlowContext overrides the injected map onto this key, so the empty declaration never shadows the real approver ids.",
  "processType": "AutoLaunchedFlow",
  "status": "Active",
  "start": {
    "connector": {
      "targetReference": "Resolve_To_Recipients"
    },
    "locationX": 0,
    "locationY": -120
  },
  "variables": [
    {
      "name": "Approval",
      "dataType": "SObject"
    },
    {
      "name": "ApprovalEmail_To_Recipients",
      "dataType": "String",
      "isCollection": true
    },
    {
      "name": "Current_Approver_Id",
      "dataType": "String"
    }
  ],
  "actionCalls": [
    {
      "name": "Resolve_To_Recipients",
      "label": "Resolve Approver Emails",
      "locationX": 0,
      "locationY": 0,
      "actionName": "resolveEmailRecipients",
      "actionType": "resolveEmailRecipients",
      "inputParameters": [
        {
          "name": "userIds",
          "value": {
            "elementReference": "Approval.ApproverUserIds"
          }
        }
      ],
      "outputParameters": [
        {
          "name": "emails",
          "value": "ApprovalEmail_To_Recipients"
        }
      ],
      "connector": {
        "targetReference": "Send_Email_Notification"
      }
    },
    {
      "name": "Send_Email_Notification",
      "label": "Email Assigned Approver",
      "locationX": 0,
      "locationY": 120,
      "actionName": "sendEmail",
      "actionType": "sendEmail",
      "inputParameters": [
        {
          "name": "templateId",
          "value": {
            "stringValue": "emailtmpl_credits_approver_assigned_20260713"
          }
        },
        {
          "name": "to",
          "value": {
            "elementReference": "ApprovalEmail_To_Recipients"
          }
        }
      ],
      "connector": {
        "targetReference": "Notify_Each_Approver"
      },
      "faultConnector": {
        "targetReference": "Notify_Each_Approver"
      }
    },
    {
      "name": "Send_InApp_Notification",
      "label": "Bell Notification for Approver",
      "locationX": 240,
      "locationY": 240,
      "actionName": "sendNotification",
      "actionType": "sendNotification",
      "inputParameters": [
        {
          "name": "recipientUserId",
          "value": {
            "elementReference": "Current_Approver_Id"
          }
        },
        {
          "name": "title",
          "value": {
            "stringValue": "Approval requested: a Credits request awaits your review"
          }
        },
        {
          "name": "body",
          "value": {
            "elementReference": "$Record.Name"
          }
        },
        {
          "name": "link",
          "value": {
            "stringValue": "/approvals"
          }
        },
        {
          "name": "notificationType",
          "value": {
            "stringValue": "approval_assignment"
          }
        }
      ],
      "connector": {
        "targetReference": "Notify_Each_Approver"
      }
    }
  ],
  "loops": [
    {
      "name": "Notify_Each_Approver",
      "label": "For each assigned approver",
      "locationX": 0,
      "locationY": 240,
      "collectionReference": "Approval.ApproverUserIds",
      "assignNextValueToReference": "Current_Approver_Id",
      "nextValueConnector": {
        "targetReference": "Send_InApp_Notification"
      }
    }
  ]
}
