Portal Community

Role-Targeted Delivery Flow

1

Role Resolution

Server resolves role:finance-managers to [usr_alice, usr_bob, usr_carol]. Three separate publish calls go to their individual interaction topics.

2

All Three Receive the Interaction

Alice, Bob, and Carol all see the interaction in their HIL inboxes. The interactionId is the same for all three.

3

Bob Responds First

Bob clicks Approve. His InteractionResponse arrives at the server. The pipeline atomically claims the interaction. Bob's response is accepted.

4

Alice and Carol Receive Dismissal

The pipeline publishes a dismissal signal to interactions.dismiss.{aliceId} and interactions.dismiss.{carolId}. Their clients remove the interaction from the inbox with a "Responded by another team member" message.

5

Concurrent Response Attempt (Rejected)

If Alice tries to respond in the same moment as Bob, her response is rejected with InteractionAlreadyRespondedException. Her client shows an error and dismisses the interaction.

Dismissal Signal Format

// Received on interactions.dismiss.{userId}
interface InteractionDismissalSignal {
  interactionId: string;
  reason: 'responded_by_other' | 'timed_out' | 'cancelled';
  respondedBy?: string; // present when reason is 'responded_by_other'
  message?: string;     // human-readable dismissal message
}

Client Handling of Dismissal Signals

// InteractionSubscriber also listens to the dismiss topic
edgeStreamClient.subscribe(`interactions.dismiss.${userId}`, (msg) => {
  const dismissal = JSON.parse(msg.body) as InteractionDismissalSignal;

  // Remove from queue
  queue.dismiss(dismissal.interactionId, dismissal.reason);

  // Notify the UI
  if (dismissal.reason === 'responded_by_other') {
    toast.info(`Interaction responded to by ${dismissal.respondedBy}`);
  } else if (dismissal.reason === 'timed_out') {
    toast.warning('An interaction expired without a response.');
  }
});

Viewing Who Responded (Audit)

The InteractionResponse.RespondedBy field identifies which role member responded. The audit log records this for every interaction, allowing you to see the full history of who responded to role-targeted interactions:

FieldValue (example)
interactionId8f4a91bc-...
targetUserIdrole:finance-managers
respondedByusr_bob
outcomeapproved
Dismissed usersusr_alice, usr_carol