From a7eb91ac40cfa19703c8baccc3f6cc3530138ccd Mon Sep 17 00:00:00 2001 From: fds2610-bot Date: Wed, 23 Sep 2026 09:00:28 +0200 Subject: [PATCH] Buero-Visualisierung: PO-Agent unabhaengig von API-Erreichbarkeit immer anzeigen Der PO laeuft auf dem Monitoring-Server selbst und repraesentiert dessen interne Prozesse. Bisher wurde er als "abwesend" gezeichnet, sobald der Browser die API kurzzeitig nicht erreichen konnte (isLive=false) - obwohl der Server und seine Prozesse in diesem Fall weiterliefen. Der feste PO-Platz zeigt den PO jetzt unabhaengig von isLive. Schliesst #97 Co-Authored-By: Claude Sonnet 5 --- html/js/office-render.js | 29 +++++++++++++---------------- html/js/office-scene.js | 6 ++++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/html/js/office-render.js b/html/js/office-render.js index 19ac2e5..adb301d 100644 --- a/html/js/office-render.js +++ b/html/js/office-render.js @@ -776,8 +776,8 @@ function renderDesk({ deskIndex, agent }) { /** * @param {Array} desks - reguläre 8er-Raster-Plaetze (echte Agenten, F1). - * @param {object|null} poAgent - {name: "PO", role: "product_owner", pose} bei erreichbarer - * API, sonst null (dann zeigt der feste PO-Platz "frei", Issue #19). + * @param {object|null} poAgent - {name: "PO", role: "product_owner", pose}, immer gesetzt (der + * PO gilt unabhaengig von der API-Erreichbarkeit als anwesend, Issue #19/#97). * @param {() => void} onPoClick - oeffnet das Projekte-Modal (Issue #27). */ function renderDesks(desks, poAgent, onPoClick) { @@ -1241,17 +1241,15 @@ function repaintAgentsLayer() { // es nur einen PO - poState ist daher ein einzelner Zustand statt einer Map. // --------------------------------------------------------------------------------------- -let poIsLive = false; let poState = "idle"; let poVisitTimeoutId = null; // Issue #55: wird aufgerufen, sobald der laufende Besuch das Board erreicht - das ist der // richtige Zeitpunkt, um die bis dahin zurueckgehaltenen Ticket-Aenderungen sichtbar zu machen. let poOnArrived = null; +// Der PO gilt immer als anwesend (Issue #97, siehe Kommentar bei poDeskAgent in +// renderOfficeScene()), poPlacement() liefert daher ohne eigene Bedingung eine Platzierung. function poPlacement() { - if (!poIsLive) { - return []; - } const visual = resolveAgentVisualState(poState); return [ { @@ -1295,7 +1293,7 @@ function advancePoVisit() { // Laeuft bereits ein Besuch, gibt es dafuer keine eigene Animation mehr - onArrived wird dann // sofort aufgerufen, damit die zurueckgehaltene Aenderung nicht dauerhaft verborgen bleibt. function triggerPoVisit(onArrived) { - if (!poIsLive || poState !== "idle") { + if (poState !== "idle") { onArrived?.(); return; } @@ -1315,7 +1313,7 @@ function triggerPoVisit(onArrived) { // Ist der PO gerade anderweitig unterwegs (poState !== "idle"), wird kein zweiter Besuch // angestossen - die Aktion laeuft trotzdem, nur ohne eigene Animation. function triggerPoReloadVisit(action) { - if (!poIsLive || poState !== "idle") { + if (poState !== "idle") { action(); return; } @@ -2355,10 +2353,6 @@ export function renderOfficeScene(container, data = {}) { poState = "idle"; } - // Der PO gilt als anwesend, sobald die API erreichbar ist (isLive) - nicht ueber das - // is_present-Feld wie registrierte Agenten (Issue #19). - poIsLive = isLive; - // "Agenten"/"Online" (Issue #39) stehen vor den gemeldeten KPIs (F7), damit sie auf der // Wandkachel (MAX_KPI_TILES) immer sichtbar sind, statt von gemeldeten Kennzahlen verdraengt // zu werden. "Hooks" (Issue #38) reserviert sich zusaetzlich die letzte (rechte) Kachel - @@ -2420,10 +2414,13 @@ export function renderOfficeScene(container, data = {}) { agent && agent.role === "voice" ? { ...agent, pending_recordings: pendingRecordings } : agent ); const deskLayout = buildDeskLayout(deskAgents); - const poDeskAgent = isLive ? { name: PO_DISPLAY_NAME, role: "product_owner", pose: "idle" } : null; - // Auch ohne erreichbare API klickbar: das Modal sagt dann selbst, dass es die Projekte - // nicht laden konnte. Ein toter PO waere in genau der Lage, in der man nachsehen will, - // die schlechtere Antwort (Fehlerbericht zu Issue #27). + // Der PO laeuft auf dem Monitoring-Server selbst und repraesentiert dessen interne Prozesse + // (Sync/API) - er gilt deshalb immer als anwesend, unabhaengig davon, ob der Browser die API + // gerade erreichen kann (isLive). Vor Issue #97 verschwand der PO faelschlich mitsamt der + // Live-Szene, sobald ausgerechnet der eigene Client offline war, obwohl der Server selbst + // weiterlief. Auch ohne erreichbare API bleibt der Platz zudem klickbar: das Modal sagt dann + // selbst, dass es die Projekte nicht laden konnte (Fehlerbericht zu Issue #27). + const poDeskAgent = { name: PO_DISPLAY_NAME, role: "product_owner", pose: "idle" }; const desksGroup = renderDesks(deskLayout, poDeskAgent, openRepoConfigModal); const existingDesks = svg.querySelector(".desks"); if (existingDesks) { diff --git a/html/js/office-scene.js b/html/js/office-scene.js index 28b835e..df6c6b7 100644 --- a/html/js/office-scene.js +++ b/html/js/office-scene.js @@ -859,8 +859,10 @@ export function advanceDoorVisitStage(stage) { // Der PO ist keine echte Registrierung ueber POST /api/v1/agents, sondern repraesentiert die // Produktverantwortung des Systems selbst - er bekommt daher keinen dynamisch zugewiesenen // Schreibtisch aus dem 8er-Raster, sondern einen eigenen, festen Platz (siehe office-render.js, -// PO_DESK), und gilt als anwesend, sobald die API erreichbar ist (nicht ueber das -// is_present-Feld wie registrierte Agenten, siehe isAgentPresent()). +// PO_DESK), und gilt immer als anwesend (nicht ueber das is_present-Feld wie registrierte +// Agenten, siehe isAgentPresent()). Er laeuft auf dem Monitoring-Server selbst und +// repraesentiert dessen interne Prozesse - ob der Browser die API gerade erreichen kann, aendert +// daran nichts (Issue #97; bis dahin verschwand der PO faelschlich mit, sobald isLive false war). export const PO_AGENT_ID = "po"; export const PO_DISPLAY_NAME = "PO";