Skip to main content

Traceability Matrix Widget

mu-traceability-matrix is a Lit custom element that renders the full requirement-to-rule traceability matrix for a workflow version. Each row maps one rule node to its linked requirements and test coverage state. The matrix is virtualized via @lit-labs/virtualizer for efficient rendering of large rule sets.

The component is the primary trace-jump target: mu-living-docs and mu-impact-list both dispatch living-docs-node-trace-requested, which you wire to this widget's filter-rule attribute to scroll directly to a specific rule.

Package

@muonroi/ui-engine-rule-components

Register all custom elements before using the component:

import { MRegisterRuleComponents } from "@muonroi/ui-engine-rule-components";
MRegisterRuleComponents();

Attributes

AttributeTypeDefaultRequiredDescription
api-base-urlstring""YesBase URL for the Living Docs read API (no trailing slash).
tenant-idstring""NoActive tenant ID for API scoping.
workflowstring""YesWorkflow identifier.
versionnumber0YesRule version number.
filter-rulestring""NoPre-filter to a single rule node by nodeId. This is the trace-jump target (D-11). Set programmatically from the living-docs-node-trace-requested event.
filter-coverage"all" | "none" | "dry-run-example-only" | "unit-test-linked""all"NoQuick-filter by coverage state. "all" shows every row.

The component auto-loads on connectedCallback when api-base-url, workflow, and version are all set. It re-fetches whenever api-base-url, workflow, or version changes. filter-rule and filter-coverage apply client-side without a new fetch.

API Endpoints

Full matrix

GET {api-base-url}/traceability/{workflow}/{version}

Returns the complete traceability matrix for the given workflow and version.

Response type: TraceabilityMatrixResponse

interface TraceabilityMatrixResponse {
rows: TraceabilityMatrixRow[];
workflow: string;
version: number;
}

Single-node trace

GET {api-base-url}/traceability/trace/{workflow}/{nodeId}

Returns traceability rows filtered to the given rule node. Entry point for the trace-jump from doc viewer or impact list (D-11).

Response type: TraceRuleResponse

interface TraceRuleResponse {
nodeId: string;
workflow: string;
rows: TraceabilityMatrixRow[];
}

Row shape

interface TraceabilityMatrixRow {
nodeId: string;
title: string;
nodeType: string; // "feel" | "decision-table" | "nrules" | etc.
requirements: RequirementRef[];
testCoverage: TestCoverageInfo; // { state, exampleId?, unitTestCode? }
decisionTable?: DecisionTableCellInfo; // Present only for decision-table nodes
}

React Wrapper

MuTraceabilityMatrixReact is the @lit/react-wrapped version, exported from @muonroi/ui-engine-react.

Event mapping:

React propDOM event
onFilterChangematrix-filter-change

Usage

Web Component

<script type="module">
import { MRegisterRuleComponents } from "@muonroi/ui-engine-rule-components";
MRegisterRuleComponents();
</script>

<mu-traceability-matrix
api-base-url="https://api.example.com/api/v1"
tenant-id="tenant-abc"
workflow="loan-approval"
version="5"
></mu-traceability-matrix>

React

import { MuTraceabilityMatrixReact } from "@muonroi/ui-engine-react";

export function MatrixPanel() {
return (
<MuTraceabilityMatrixReact
api-base-url="https://api.example.com/api/v1"
tenant-id="tenant-abc"
workflow="loan-approval"
version={5}
filter-coverage="unit-test-linked"
/>
);
}

Wiring Trace-Jump

mu-living-docs and mu-impact-list both dispatch living-docs-node-trace-requested with { nodeId: string } when the user clicks a trace (↗) button. Pass that nodeId into this component's filter-rule attribute to jump to the rule.

Vanilla JS

<mu-living-docs
api-base-url="https://api.example.com/api/v1"
workflow="loan-approval"
version="5"
></mu-living-docs>

<mu-traceability-matrix
id="matrix"
api-base-url="https://api.example.com/api/v1"
workflow="loan-approval"
version="5"
></mu-traceability-matrix>

<script>
document.querySelector("mu-living-docs").addEventListener(
"living-docs-node-trace-requested",
(e) => {
document.getElementById("matrix").setAttribute("filter-rule", e.detail.nodeId);
}
);
</script>

React (shared state)

import { useState } from "react";
import { MuLivingDocsReact, MuTraceabilityMatrixReact } from "@muonroi/ui-engine-react";

export function TraceableDocsPage() {
const [filterRule, setFilterRule] = useState("");

return (
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
<MuLivingDocsReact
api-base-url="https://api.example.com/api/v1"
workflow="loan-approval"
version={5}
onNodeTraceRequested={(e) => setFilterRule(e.detail.nodeId)}
/>
<MuTraceabilityMatrixReact
api-base-url="https://api.example.com/api/v1"
workflow="loan-approval"
version={5}
filter-rule={filterRule}
/>
</div>
);
}

The same pattern applies when mu-impact-list is the event source.

Coverage Filter Values

filter-coverage valueRows shown
"all" (default)All rows
"unit-test-linked"Rows where testCoverage.state === "UnitTestLinked"
"dry-run-example-only"Rows where testCoverage.state === "DryRunExampleOnly"
"none"Rows where testCoverage.state === "None"

See Also