Render each notification where it belongs: the workspace for task links, the run origin for its starter

A notification now renders where it belongs, instead of inheriting whichever request happens to be running.

The bug

TaskNotificationDispatcher::send() minted the inbox link with Url::fromRoute('orchestra_inbox.inbox')->setAbsolute(), so its host came from the ambient request. A task is normally created by the request that started the process, which on a multi-domain install is the site the customer was using, so the operator's mail linked them there instead of to the back office.

Two places, named

  • Workspace: where people do the work. The inbox link belongs there whoever caused the task, and a parked interaction step is work too.
  • Origin: where the process was started. A Notify node is author-composed content, normally addressed to whoever started the run, so it renders where they were. The instance records it at start (a subprocess inherits its parent's), since by the time the message goes out the run may be advancing anywhere.

orchestra.notification_context exposes currentOrigin(), inOrigin() and inWorkspace(). The shipped implementation is a pure no-op: a site with one front end records no origin, both wrappers just call the callback, and nothing about its behavior changes. Orchestra never interprets the origin string.

On a Domain site

orchestra_domain decorates the service. The origin becomes domain:{id}, the record rather than a URL because several domains may share a hostname under path prefixes and a record survives a hostname change. The workspace is the domain flagged Orchestra workspace on its record, a third-party setting like the existing tenant binding, with a checkbox on the domain form that keeps at most one domain flagged. With none flagged, links stay wherever the request is, which is what a single-domain site wants.

The switching itself is delegated to Domain Extras' domain_render_context (drupal.org/project/domain_extras issue 3613716), which owns what a domain switch involves: per-domain configuration and the path prefix through the negotiation context, the host through the request context, and the active theme.

Tests

11 kernel tests across three classes, plus a hidden orchestra_context_test module providing a context that names a fixed place and records which wrapper each call site asked for:

  • InstanceOriginTest: a started run records its origin, nothing is recorded when there is no place to name, and a subprocess inherits its parent's even when spawned from somewhere else.
  • TaskNotificationPlaceTest: the inbox notification asks for the workspace, and not for the origin.
  • DomainNotificationContextTest: the origin is the negotiated domain; rendering in the origin from the back office yields the starting domain's site name and links and restores afterwards; the inbox link renders on the flagged domain while the request is on another; with no domain flagged nothing moves; an unknown or absent origin renders where it is.

Notes

Pre-release, so no update hook: the instance origin field is installed by hand with installFieldStorageDefinition().

Merge request reports

Loading