Problem

The interaction dispatcher resolves "the step the instance is parked on" and renders its interaction. That is right while the visitor has something to do, but it falls short when the run moves through steps the visitor should see but not act on:

  • After a payment the run advances through "awaiting confirmation" then "confirmed" or "declined", with no visitor action in between, so the dispatcher only has a generic "nothing to do" message to show.
  • A run can end on a node that should show a final "thank you" screen, but an end node parks nothing.
  • A run can fan out, so "the parked step" is ambiguous: which branch's status does a visitor link show?

Proposed model

Give the engine a first-class notion of a visitor's journey through a run, and let nodes show content without parking.

Interaction kinds. A renderOnly flag on the #[Interaction] attribute (default false) splits interactions into interactive (payment, webform, redirect: the visitor acts, the flow parks) and render-only (message: just shows content, needs no parking, can live on any node including automatic and end nodes).

Chains. A chain is one interactive interaction plus the render-only messages and automatic steps that follow it, up to the next interactive interaction. A new interactive interaction starts a new chain. The chain is the unit a visitor sees: its own URL, its own aggregated messages, one stop on a progress bar.

Chain id. The chain id is the token id of the interactive interaction that starts the chain, reusing the pattern already used for the fork field (a token id promoted to a group root that descendants inherit). A token computes it on creation: chain_id = (node has an interaction AND not renderOnly) then token.id else parent.chain_id. The start token seeds its own id, so every token has a chain id, and the chain id doubles as a loadable handle to the originating interaction.

has_interaction. A boolean on the token, set when its node declares an interaction, so a chain's interactions are found with one query instead of scanning node config.

The visitor view. A chain URL is scoped to its chain. When the dispatcher resolves a chain it renders the parked interactive interaction if there is one, otherwise the chain's render-only messages aggregated, otherwise a neutral message.

Status vs sticky. Within a chain, render-only messages accumulate. A sticky flag on the message settings picks the behavior: default (no flag) is a status, shown only while it is the most recent message and superseded by a newer one; sticky is a milestone, always shown. Aggregation rule: show the latest render-only message in the chain, plus any earlier ones marked sticky, in chronological order.

Linking chains. Each chain records its predecessor (the chain id of the parent token), so chains form a linked list (a tree under forks) of loadable handles. This gives the journey and a progress bar's past and current. A per-workflow setting decides what an old chain URL does: isolated (default, shows only its own chain, privacy safe) or catch-up (forward-resolves to the visitor's current chain).

Progress (later). A progress bar needs author-declared ordered stages (a linear template over the graph, nodes tagged to stages); the chains supply position and past, the stages supply the best-effort future. Additive, on top of the chain model.

Worked example

The yoyaku booking flow after payment: n_paid "Payment completed" (sticky), n_validate "Awaiting confirmation" (status), n_confirm "Booking confirmed" (status), n_end_ko "Declined" (status). All one payment chain. The aggregation gives "Payment completed" plus the current booking status, with "Awaiting confirmation" superseded once "Booking confirmed" arrives. Only the milestone needs a flag.

Design doc

A full write-up lives in the module docs at docs/interaction-chains.md (Interaction chains).

Scope

Built already: per-interaction title, configurable message title, restricted rich-text message body. This issue covers the renderOnly flag and render-only interactions on any node; chain_id, has_interaction and the predecessor link on the token; chain-scoped dispatch and message aggregation; the sticky flag; the per-workflow old-link setting; and as a follow-up the author-declared stages and the progress bar.

Issue fork orchestra-3606902

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

  • mably committed d3c203d9 on 1.x
    feat: #3606902 Show a visitor their whole journey: interaction chains,...
mably’s picture

Status: Active » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.