feat(demo): plain-language integration status, richer audit, reset integrity
Integration status badges across Dashboard/Automation now show honest plain-language labels instead of raw backend state strings (and fix a few states that had no matching CSS colour class at all). Audit trail gets a "view related events" action reusing the existing correlation_id filter. About page gains scope/architecture/security/testing sections and a guided-demo entry point. POST /api/v1/demo/reset now runs and records a server-side scenario-integrity check. Also fixes a second real race condition (caught by the return-review e2e test): the odometer scenario pre-fill now resolves before ReturnForm mounts instead of patching its value in after the fact.
This commit is contained in:
@@ -4,14 +4,7 @@ import type { AutomationRun, IntegrationStatus, KnowledgeHealth } from "../api/t
|
||||
import { StatusBadge } from "../components/Badge";
|
||||
import { useAuth } from "../context/AuthContext";
|
||||
import { ErrorState, IntegrationMark, LoadingState, PageHeader, SectionHeading } from "../components/PageChrome";
|
||||
|
||||
const N8N_STATE_LABEL: Record<IntegrationStatus["n8n"]["state"], string> = {
|
||||
disabled: "disabled",
|
||||
unavailable: "unavailable",
|
||||
degraded: "degraded",
|
||||
operational: "available",
|
||||
no_evidence: "no_events",
|
||||
};
|
||||
import { N8N_STATE_META, MCP_STATE_META } from "../data/integrationLabels";
|
||||
|
||||
export function Automation() {
|
||||
const { user } = useAuth();
|
||||
@@ -98,9 +91,38 @@ export function Automation() {
|
||||
: "Return events are committed locally first and then delivered through the outbox."}
|
||||
</p>
|
||||
</div>
|
||||
<StatusBadge status={integrationStatus ? N8N_STATE_LABEL[integrationStatus.n8n.state] : (runs?.[0]?.status ?? "no_events")} />
|
||||
{(() => {
|
||||
const meta = integrationStatus ? N8N_STATE_META[integrationStatus.n8n.state] : null;
|
||||
return (
|
||||
<StatusBadge
|
||||
status={meta?.statusClass ?? (runs?.[0]?.status ?? "no_events")}
|
||||
label={meta?.label}
|
||||
/>
|
||||
);
|
||||
})()}
|
||||
</article>
|
||||
<article>
|
||||
<IntegrationMark kind="rag" />
|
||||
<div>
|
||||
<span className="integration-kicker">Knowledge</span>
|
||||
<h2>Knowledge assistant</h2>
|
||||
<p>
|
||||
{knowledge
|
||||
? `${knowledge.provider === "ragcore" ? "RAGcore" : "Demo knowledge base"} · ${knowledge.document_count} procedures indexed in ${knowledge.collection}.`
|
||||
: "Health evidence is currently unavailable."}
|
||||
</p>
|
||||
</div>
|
||||
<StatusBadge
|
||||
status={knowledge?.available ? "available" : "unavailable"}
|
||||
label={
|
||||
knowledge?.available
|
||||
? knowledge.provider === "ragcore"
|
||||
? "Operational"
|
||||
: "Demo mode"
|
||||
: "Unavailable"
|
||||
}
|
||||
/>
|
||||
</article>
|
||||
<article><IntegrationMark kind="rag" /><div><span className="integration-kicker">Knowledge</span><h2>RAGcore</h2><p>{knowledge ? `${knowledge.document_count} procedures indexed in ${knowledge.collection}.` : "Health evidence is currently unavailable."}</p></div><StatusBadge status={knowledge?.available ? "available" : "unavailable"} /></article>
|
||||
<article>
|
||||
<IntegrationMark kind="mcp" />
|
||||
<div>
|
||||
@@ -109,10 +131,13 @@ export function Automation() {
|
||||
<p>
|
||||
{integrationStatus?.mcp_hub.registration_enabled
|
||||
? "Registration is enabled for this deployment."
|
||||
: "No active MobilityOps adapter is configured in this proof of concept."}
|
||||
: "Not yet connected — prepared for future controlled tool calls from the ITWorx MCP Hub."}
|
||||
</p>
|
||||
</div>
|
||||
<StatusBadge status={integrationStatus?.mcp_hub.state ?? "not_configured"} />
|
||||
{(() => {
|
||||
const meta = integrationStatus ? MCP_STATE_META[integrationStatus.mcp_hub.state] : null;
|
||||
return <StatusBadge status={meta?.statusClass ?? "not_configured"} label={meta?.label} />;
|
||||
})()}
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user