feat: surface new unknowns after graph updates

This commit is contained in:
2026-08-02 10:30:59 +01:00
parent 904aec7616
commit 72ef175971
16 changed files with 910 additions and 41 deletions
+100 -4
View File
@@ -113,11 +113,37 @@ function makeUpdateSuccess(overrides = {}) {
value: "1.9 complaints per 100 units",
unit: null,
},
{
id: "n-next-unknown",
label: "Commercial value definition",
description: "Need a definition because the decision depends on it.",
kind: "unknown",
status: "unknown",
confidence: "high",
value: null,
unit: null,
},
],
edges: [],
},
proposal: {
addedNodes: [],
addedNodes: [
{
id: "n-next-unknown",
label: "Commercial value definition",
description: "Need a definition because the decision depends on it.",
kind: "unknown",
status: "unknown",
confidence: "high",
value: null,
unit: null,
evidenceIds: [],
dependsOn: [],
affects: [],
parentId: null,
childIds: [],
},
],
updatedNodes: [
{ nodeId: "n-unknown", newStatus: "resolved", reason: "answered" },
],
@@ -125,6 +151,16 @@ function makeUpdateSuccess(overrides = {}) {
removedEdgeIds: [],
resolvedUnknownNodeIds: ["n-unknown"],
affectedNodeIds: ["n-conclusion"],
selectedQuestion: {
nodeId: "n-next-unknown",
question: "How should commercial value be defined for this decision?",
reason: "A narrower consequential uncertainty remains.",
},
},
selectedQuestion: {
nodeId: "n-next-unknown",
question: "How should commercial value be defined for this decision?",
reason: "A narrower consequential uncertainty remains.",
},
affectedNodeIds: ["n-conclusion"],
resolvedUnknownNodeIds: ["n-unknown"],
@@ -323,6 +359,20 @@ describe("graph-backed UI rendering", () => {
expect(html).toContain("Complaint rate denominator");
});
it("newly surfaced unknowns render", () => {
const html = renderToStaticMarkup(
<GraphUpdateView
updateResult={{
...makeUpdateSuccess(),
previousSituationGraph: makeGraphResult().situationGraph,
}}
/>,
);
expect(html).toContain("Newly surfaced unknowns");
expect(html).toContain("Commercial value definition");
});
it("affected nodes render", () => {
const html = renderToStaticMarkup(
<GraphUpdateView
@@ -337,11 +387,33 @@ describe("graph-backed UI rendering", () => {
expect(html).toContain("Quality deterioration");
});
it("no fake next question appears", () => {
it("renders validated next question when present", () => {
const html = renderToStaticMarkup(
<GraphUpdateView
updateResult={{
...makeUpdateSuccess({ newActiveUnknownNodeId: null }),
...makeUpdateSuccess(),
previousSituationGraph: makeGraphResult().situationGraph,
}}
/>,
);
expect(html).toContain(
"How should commercial value be defined for this decision?",
);
});
it("no fake next question appears when there is none", () => {
const html = renderToStaticMarkup(
<GraphUpdateView
updateResult={{
...makeUpdateSuccess({
newActiveUnknownNodeId: null,
selectedQuestion: null,
proposal: {
...makeUpdateSuccess().proposal,
selectedQuestion: null,
},
}),
previousSituationGraph: makeGraphResult().situationGraph,
}}
/>,
@@ -363,7 +435,31 @@ describe("graph-backed UI rendering", () => {
expect(html).toContain("Previous active unknown");
expect(html).toContain("Complaint rate denominator");
expect(html).toContain("New active unknown");
expect(html).toContain("Unknown node (ID: n-next-unknown)");
expect(html).toContain("Commercial value definition");
});
it("situation graph marks newly surfaced and active unknowns", () => {
const html = renderToStaticMarkup(
<SituationGraphView
situationGraph={makeUpdateSuccess().updatedSituationGraph}
selectedQuestion={makeUpdateSuccess().selectedQuestion}
newlySurfacedNodeIds={["n-next-unknown"]}
/>,
);
expect(html).toContain("newly surfaced unknown");
expect(html).toContain("active unknown");
expect(html).toContain("resolved unknown");
});
it("disabled follow-up form is shown only as prototype limitation", () => {
const html = renderToStaticMarkup(
<GraphUpdateView
updateResult={makeUpdateSuccess()}
/>,
);
expect(html).toContain("How should commercial value be defined for this decision?");
});
it("raw ids remain only in collapsed proposal details", () => {