From 2e46a623fb1668db1cb7c2682e22962ffe5f4afd Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Wed, 9 Sep 2026 02:03:53 +0200 Subject: [PATCH] fix(ui): move widget and page documentation into headings Verified with the coordinated workspace changes by devkit full run 2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed). This shared UI pass does not mark the individual module reviews complete. --- src/govoplan_ops/backend/manifest.py | 8 +++++++- tests/test_interface_documentation_contract.py | 4 +++- webui/src/features/ops/OpsHealthWidget.tsx | 5 ----- webui/src/features/ops/OpsPage.tsx | 4 ++-- webui/src/module.ts | 2 ++ 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/govoplan_ops/backend/manifest.py b/src/govoplan_ops/backend/manifest.py index 378c4c2..99d25da 100644 --- a/src/govoplan_ops/backend/manifest.py +++ b/src/govoplan_ops/backend/manifest.py @@ -152,7 +152,10 @@ manifest = ModuleManifest( id="ops.health-governance-and-sizing", title="Inspect platform health and deployment posture", summary="Ops combines module-owned health checks with deployment profile, governance inventory, worker assumptions, and sizing guidance.", - body="Read-only status distinguishes configured capabilities from healthy integrations. Worker and queue providers use a Core runtime-status contract, so Ops never imports a provider backend. The surface distinguishes intentionally disabled, unconfigured, starting, healthy with unsupported queue depth, measured idle, busy, degraded, stale, and unreachable states. It shows enabled/configured state, backend, workers, heartbeat age and stale threshold, queue depth, active/reserved work, and failures only when each value is actually reported; unavailable values are never rendered as zero or healthy. Local development treats intentionally disabled workers as expected, while production profiles require an enabled, configured, reachable provider before queue-backed work is accepted. Polling is bounded to one request, pauses while the page is hidden, and refreshes on return. When the deployment mounts a signed or locally generated non-secret infrastructure capability receipt, Ops shows whether PostgreSQL, Redis, SMTP, file storage, load balancing, and ingress are configured, externally supplied, available but unconfigured, or unavailable. Secret values never cross this boundary; only stable environment or credential-envelope references may be disclosed. Pending post-install tasks remain visible with a stable resume key. The separately authorized infrastructure-dependency endpoint asks enabled module providers for their current persisted configuration and data dependencies. Each provider returns only stable references, states, scopes, numeric metrics, and required migration actions; one failed provider marks the entire fresh inventory incomplete so the host deployer blocks a capability change. Authorized operators can run bounded probes; a probe must not perform unbounded business work or silently repair data. Use readiness and worker results when diagnosing a node, and use the deployment profile and sizing assumptions when planning horizontal capacity.", + body="Documentation books sit immediately beside the visible heading or contextual label for Ops " + "and health information, not among operational action buttons. Field help remains beside its " + "label. " + "Read-only status distinguishes configured capabilities from healthy integrations. Worker and queue providers use a Core runtime-status contract, so Ops never imports a provider backend. The surface distinguishes intentionally disabled, unconfigured, starting, healthy with unsupported queue depth, measured idle, busy, degraded, stale, and unreachable states. It shows enabled/configured state, backend, workers, heartbeat age and stale threshold, queue depth, active/reserved work, and failures only when each value is actually reported; unavailable values are never rendered as zero or healthy. Local development treats intentionally disabled workers as expected, while production profiles require an enabled, configured, reachable provider before queue-backed work is accepted. Polling is bounded to one request, pauses while the page is hidden, and refreshes on return. When the deployment mounts a signed or locally generated non-secret infrastructure capability receipt, Ops shows whether PostgreSQL, Redis, SMTP, file storage, load balancing, and ingress are configured, externally supplied, available but unconfigured, or unavailable. Secret values never cross this boundary; only stable environment or credential-envelope references may be disclosed. Pending post-install tasks remain visible with a stable resume key. The separately authorized infrastructure-dependency endpoint asks enabled module providers for their current persisted configuration and data dependencies. Each provider returns only stable references, states, scopes, numeric metrics, and required migration actions; one failed provider marks the entire fresh inventory incomplete so the host deployer blocks a capability change. Authorized operators can run bounded probes; a probe must not perform unbounded business work or silently repair data. Use readiness and worker results when diagnosing a node, and use the deployment profile and sizing assumptions when planning horizontal capacity.", documentation_types=("admin", "user"), audience=("operator", "system_admin"), related_modules=("audit", "docs", "notifications"), @@ -173,6 +176,9 @@ manifest = ModuleManifest( "title": "Plattformzustand und Bereitstellungsprofil prüfen", "summary": "Ops führt modulbezogene Zustandsprüfungen mit Bereitstellungsprofil, Governance-Inventar, Worker-Annahmen und Dimensionierungshinweisen zusammen.", "body": ( + "Dokumentationsbücher stehen unmittelbar neben der sichtbaren Überschrift oder " + "Kontextbezeichnung für Betriebs- und Zustandsinformationen, nicht zwischen ausführbaren " + "Aktionsschaltflächen. Feldhilfe bleibt neben der Feldbezeichnung. " "Der schreibgeschützte Status unterscheidet konfigurierte Fähigkeiten von funktionsfähigen Integrationen. " "Worker- und Warteschlangenanbieter verwenden einen Core-Vertrag für den Laufzeitstatus, sodass Ops niemals ein Anbieter-Backend importiert. " "Die Oberfläche unterscheidet bewusst deaktivierte, nicht konfigurierte, startende, gesunde, untätige, ausgelastete, beeinträchtigte, veraltete und nicht erreichbare Zustände; eine nicht unterstützte Warteschlangentiefe wird ausdrücklich ausgewiesen. " diff --git a/tests/test_interface_documentation_contract.py b/tests/test_interface_documentation_contract.py index a1ba1a9..c9a34b0 100644 --- a/tests/test_interface_documentation_contract.py +++ b/tests/test_interface_documentation_contract.py @@ -76,7 +76,9 @@ class OpsInterfaceDocumentationContractTests(unittest.TestCase): "TableActionGroup", ): self.assertIn(component, page) - self.assertIn("DocumentationHelpLink", widget) + contribution = (REPO_ROOT / "webui/src/module.ts").read_text(encoding="utf-8") + self.assertIn("documentation: OPS_DOCUMENTATION", contribution) + self.assertNotIn("DocumentationHelpLink", widget) self.assertIn("LoadingFrame", widget) diff --git a/webui/src/features/ops/OpsHealthWidget.tsx b/webui/src/features/ops/OpsHealthWidget.tsx index 9414c59..15dfe8f 100644 --- a/webui/src/features/ops/OpsHealthWidget.tsx +++ b/webui/src/features/ops/OpsHealthWidget.tsx @@ -3,7 +3,6 @@ import { MetricGrid } from "@govoplan/core-webui"; import { useEffect, useState } from "react"; import { DismissibleAlert, - DocumentationHelpLink, LoadingFrame, MetricCard, StatusBadge, @@ -11,7 +10,6 @@ import { type ApiSettings } from "@govoplan/core-webui"; import { fetchOpsStatus, type OpsStatus } from "../../api/ops"; -import { OPS_DOCUMENTATION } from "./interfacePatterns"; import { knownMetric, knownQueueDepthTotal, runtimeWorkTone } from "./runtimeStatus"; export default function OpsHealthWidget({ settings, refreshKey }: { settings: ApiSettings; refreshKey: number }) { @@ -42,9 +40,6 @@ export default function OpsHealthWidget({ settings, refreshKey }: { settings: Ap return ( {error && {error}} -
- -
diff --git a/webui/src/features/ops/OpsPage.tsx b/webui/src/features/ops/OpsPage.tsx index cbd48cc..ec8f390 100644 --- a/webui/src/features/ops/OpsPage.tsx +++ b/webui/src/features/ops/OpsPage.tsx @@ -173,14 +173,14 @@ export default function OpsPage({ settings, auth }: {settings: ApiSettings;auth: return ( } description="i18n:govoplan-ops.runtime_health_deployment_profile_worker_split_a.55340156" error={error} actions={ void load(), loading, disabledReason: loading ? OPS_I18N.loading : undefined }} - helpAction={} + primaryActions={} />} > diff --git a/webui/src/module.ts b/webui/src/module.ts index 67922c0..9f21bd8 100644 --- a/webui/src/module.ts +++ b/webui/src/module.ts @@ -1,6 +1,7 @@ import { createElement, lazy } from "react"; import type { DashboardWidgetsUiCapability, PlatformWebModule } from "@govoplan/core-webui"; import OpsHealthWidget from "./features/ops/OpsHealthWidget"; +import { OPS_DOCUMENTATION } from "./features/ops/interfacePatterns"; import { generatedTranslations } from "./i18n/generatedTranslations"; const OpsPage = lazy(() => import("./features/ops/OpsPage")); @@ -16,6 +17,7 @@ const dashboardWidgets: DashboardWidgetsUiCapability = { id: "ops.health", surfaceId: "ops.widget.health", title: "Operations health", + documentation: OPS_DOCUMENTATION, description: "Readiness, worker mode, and current warning count.", moduleId: "ops", category: "Operations",