Approvals — how it works

Approvals are node-native: two NodeTypes the mesh compiles live from Source/, plus a node that contributes the menu entry. Nothing here is a compiled module, so installing or removing the package changes the mesh immediately — no image, no restart.

The three moving parts

Node What it is
Approvals/Approval The satellite TYPE. One approval = one {document}/_Approval/{id} node: who asked whom, what for, by when, and the decision. Its Overview shows the record (with Approve / Reject for the named approver of a pending request); its Thumbnail is the card the inline list renders.
Approvals/Desk + Approvals/Workspace The document-anchored surfaces — RequestApproval (the form) and Approvals (the live list). The ONE Approvals/Workspace instance serves every document; the target arrives per render.
Approvals/RequestApprovalMenu A UiContribution node: the Request Approval entry on every node's menu, contributed as DATA.

Why one desk instead of every hub

The retired module registered its form, its list and its menu entry onto every per-node hub of the mesh (ConfigureDefaultNodeHub) — something no in-mesh type can do, and something that put a mesh-wide feature in the platform's build graph.

The desk needs none of it. Each area resolves its document per render:

  1. an explicit ?doc=Space/Path,
  2. else the layout-area reference id an embedding page passes — Controls.LayoutArea("Approvals/Workspace", "Approvals", documentPath),
  3. else the desk node's own documentPath.

So a document page embeds the approvals list, and the menu entry links to the form with the current node in ?doc=. Precedence and normalization are pinned by ApprovalDeskTests.

Embedding the list on another type

Controls.LayoutArea(ApprovalDocs.DeskPath, ApprovalDeskAreas.ApprovalsArea, documentPath)
    .WithShowProgress(false)

Probe first if the package may be absent — a query-index existence check on Approvals/Workspace, never a hub probe of a missing node (which costs the full activation timeout). The platform's markdown overview does exactly this.

What stays platform-level

The Approval record and the _Approvalannotations satellite mapping live in the platform (MeshWeaver.Mesh.Contract). Storage placement is resolved from the path SEGMENT, not from the node type, so approvals land in the right table and keep deserializing on a mesh where this package is not installed. Access is the platform's ordinary path-based check: an approval sits inside its document's partition and is readable exactly where the document is.

Invariants worth knowing

Run the Tests area on either type to execute the suites (CI asserts them green).

Reconnecting…
The server was updated. Reloading the page to pick up the latest version.