Wie geht es dir: achtzehn Fragen in sechs Feldern, eine Zusammenfassung

Sechs Fragen mehr (jetzt 18), und alle in sechs Feldern gegliedert:
Last & Erholung, Miteinander, Sinn & Anerkennung, Klarheit &
Rueckhalt, Grenzen & Sicherheit, Weiterkommen & Ausblick. Die Felder
sind nicht ausgedacht -- es sind die Gebiete, die die Forschung zu
belasteten Rollen durchgehend abfragt.

Die drei neuen Luecken, die sie schliessen: Schlaf (zeigt Erschoepfung
frueher als jede andere Frage), Widersprechen (der Kern dessen, was
psychologische Sicherheit heisst) und Mitreden (viel Anforderung bei
wenig Einfluss ist die Kombination, aus der Erschoepfung entsteht).
Jede neue Frage hat ihre belegte Einordnung -- eine Frage ohne
Grundlage ist eine Frage, die jemand gut fand.

DIE ROTATION MUSSTE NEU. Der Katalog ist nach Themen sortiert; wer
daraus drei aufeinanderfolgende nimmt, bekommt drei aus demselben
Feld. Jetzt wird der Ring vorher verzahnt -- erst je eine Frage aus
jedem Feld, dann je eine zweite. Ein Fenster trifft damit von selbst
verschiedene Felder.

Ein erster Anlauf reservierte feste Plaetze fuer die kernlosen
Felder. Begruendet mit einer Auswertung je Feld, die es gar nicht
gibt -- und er kostete: zwoelf Runden, bis jede Frage einmal gestellt
war, fast ein halbes Jahr. Gefunden hat das pruef-befinden.mjs, nicht
das Nachdenken. Mit dem verzahnten Ring und vier Plaetzen je Runde
sind es vier Runden.

DIE EINE ZUSAMMENFASSUNG AM ENDE, nicht eine je Kategorie. Sie sagt
in dieser Reihenfolge: die Lage in einem Satz, was traegt (benannt,
nicht als Zahl), hoechstens EINE Sache zum Hinschauen, ein Schluss,
der zur Lage passt. Umgekehrt waere es eine Maengelliste mit
Trostpflaster, und so etwas beantwortet man beim naechsten Mal nicht
mehr ehrlich.

ZUR FRAGE NACH DER BESTEN KOSTENLOSEN MOEGLICHKEIT: bewusst KEINE
KI. Das sind Gesundheitsdaten (wer nachts wach liegt, wer angefeindet
wird, wer ans Aufhoeren denkt) -- deshalb sind sie im ganzen Haus als
nurSelbst markiert. Kostenlose KI-Angebote bezahlt man mit den Daten.
Ein Sprachmodell erfindet ausserdem, und zwar ueberzeugend. Und ein
fremder Dienst faellt aus. Jeder Grund reicht einzeln. Die
Begruendung steht ausfuehrlich in workspace-befinden-resuemee.js.

Nebenbefund behoben: Die Zusammenfassung blieb direkt NACH einer
abgeschlossenen Runde leer -- da ist keine Antwort mehr "frisch".
Genau der Moment, in dem man sie sehen will.

Auch eine Pruefung korrigiert: Sie verbot den Text "entwicklung.js"
irgendwo in der Datei und schlug an einem Kommentar an, der die
Serverdatei benennt. Sie misst jetzt die Skript-Quellen.

pruef-befinden.mjs 112/0, pruef-resuemee.mjs 35/0 (neu).

Offener Befund, aelter als diese Aenderung: pruef-entwicklung.mjs
meldet "ein Modi: keine Kachel fuehrt mehr ersatzweise auf die
Entwicklungsseite" -- auch ohne diese Commits.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-20 19:45:14 +02:00
co-authored by Claude Opus 5
parent 1bdeccc054
commit 2719bd9b88
8 changed files with 1387 additions and 167 deletions
+241 -10
View File
@@ -61,7 +61,7 @@
import express from "express";
import { db, sitzungLesen, protokolliere, echteIp } from "./workspace.js";
import {
ENTWICKLUNG_BLOECKE, ENTWICKLUNG_PUNKTE, ENTWICKLUNG_STUFEN,
ENTWICKLUNG_BLOECKE, ENTWICKLUNG_PUNKTE, ENTWICKLUNG_STUFEN, BEFINDEN_FELDER,
} from "./workspace-entwicklungs-punkte.js";
import { tabellen as entwicklungTabellen } from "./workspace-entwicklung.js";
@@ -78,15 +78,27 @@ export const RHYTHMUS_TAGE = 14;
/** Wie viele Zusatzfragen je Runde zum Kern dazukommen.
*
* DREI. Mit fünf Kernfragen macht das acht je Runde — die Quellen zu
* VIER. Mit fünf Kernfragen macht das neun je Runde — die Quellen zu
* Puls-Abfragen sagen übereinstimmend fünf bis fünfzehn, unter zwei
* Minuten. Acht liegt mittig und lässt Platz: Der Katalog kann auf
* zwanzig Fragen wachsen, ohne dass eine einzelne Runde länger wird.
* Minuten. Neun liegt mittig und lässt Platz: Der Katalog kann weiter
* wachsen, ohne dass eine einzelne Runde länger wird.
*
* Das ist der ganze Trick an Filipes zwei Wünschen, die sich zu
* widersprechen schienen — „viel mehr Fragen" und „kurz und knapp".
* Beides geht, nur nicht gleichzeitig in DERSELBEN Runde. */
export const ZUSATZ_PRO_RUNDE = 3;
* Beides geht, nur nicht gleichzeitig in DERSELBEN Runde.
*
* WARUM VIER UND NICHT DREI (geändert 20.09.2026, mit den Feldern).
* Drei war richtig, solange es sieben wechselnde Fragen gab. Mit
* dreizehn dauerte es bei drei je Runde ZEHN Runden, bis jede einmal
* gestellt war — fast ein halbes Jahr, in dem eine Frage im Katalog
* steht und nie jemandem begegnet. Bei vier sind es vier Runden, also
* acht Wochen. Gemessen, nicht geschätzt; die Zahl steht in keiner
* Behauptung, sondern in pruef-befinden.mjs.
*
* Dieselbe Rechnung wieder anstellen, sobald der Katalog wächst:
* ceil(wechselnde / ZUSATZ_PRO_RUNDE) ist die Zahl der Runden, und
* mehr als fünf davon sind zu viele. */
export const ZUSATZ_PRO_RUNDE = 4;
/** So viele frühere Antworten bekommt die Person zu sehen.
*
@@ -258,12 +270,89 @@ export function fragenFuer(personId, runden = null) {
return { kern, zusatz: rest, alle: [...kern, ...rest], runden: n };
}
let schritt = ZUSATZ_PRO_RUNDE;
while (ggt(schritt, rest.length) !== 1) schritt++;
/* =====================================================================
DER RING IM REISSVERSCHLUSS (20.09.2026)
const start = (n * schritt) % rest.length;
Seit die Fragen in sechs Felder gegliedert sind, reicht ein
einfacher Ring nicht mehr. Der Katalog ist nach Themen sortiert --
wer daraus drei AUFEINANDERFOLGENDE nimmt, bekommt meistens drei
aus demselben Feld. Eine Runde, die nur nach „Klarheit & Rueckhalt"
fragt, ist keine Befindensabfrage mehr, sondern ein Interview zu
einem Thema.
DER RING WIRD DESHALB VORHER VERZAHNT: erst je eine Frage aus
jedem Feld, dann je eine zweite, dann je eine dritte. Ein Fenster
von vier aufeinanderfolgenden Eintraegen trifft damit von selbst
vier verschiedene Felder -- ohne dass irgendwo eine Regel
nachrechnen muss, welche schon dran waren.
DIE FELDER OHNE KERNFRAGE STEHEN IM REISSVERSCHLUSS VORN. Sie sind
die einzigen, die eine Runde lang ganz fehlen KOENNTEN -- die
anderen sind ueber ihre Kernfrage ohnehin in jeder Runde dabei.
Gemessen ueber zwanzig Runden: 19 davon enthalten mindestens eine
Frage aus einem kernlosen Feld.
---------------------------------------------------------------------
WAS HIER VORHER STAND -- UND WARUM ES WEG IST
Der erste Anlauf reservierte JEDER Runde feste Plaetze fuer die
kernlosen Felder. Begruendet war das mit „sonst stuende in der
Auswertung nach Feldern ein leeres Kapitel, und das liest sich wie
Zustimmung".
Die Begruendung war falsch: Es gibt gar keine Auswertung je Feld.
Filipe wollte ausdruecklich EINE Zusammenfassung am Ende, nicht
eine je Kategorie -- und die sucht sich ihr Thema aus dem, was
tatsaechlich gefragt wurde. Ein Feld, das diese Runde nicht
drankam, behauptet also gar nichts.
Gekostet hat die Reservierung dafuer etwas Messbares: Zwei von
drei Plaetzen waren belegt, der Ring kam kaum voran, und bis jede
der 13 wechselnden Fragen einmal gestellt war, vergingen ZWOELF
Runden -- fast ein halbes Jahr. Gefunden hat das nicht das
Nachdenken, sondern `pruef-befinden.mjs`: Sie verlangt, dass ueber
wenige Runden jede Frage drankommt, und wurde rot.
Mit dem verzahnten Ring sind es vier Runden (acht Wochen), bei
gleichzeitig besserer Streuung. Beides gemessen, nicht geschaetzt.
===================================================================== */
const felderMitKern = new Set(kern.map((p2) => p2.feld).filter(Boolean));
/* Die Feldreihenfolge: kernlose zuerst, sonst wie im Katalog. Ein
stabiles Sortieren -- `sort` in JavaScript ist seit ES2019
garantiert stabil, die Katalogreihenfolge bleibt also innerhalb
der beiden Gruppen erhalten. */
const feldReihe = [...new Set(rest.map((p2) => p2.feld).filter(Boolean))]
.sort((a, b) => (felderMitKern.has(a) ? 1 : 0) - (felderMitKern.has(b) ? 1 : 0));
const koerbe = feldReihe.map((f) => rest.filter((p2) => p2.feld === f))
.filter((k) => k.length);
/* Fragen ganz ohne Feld kaemen sonst nie dran -- sie bekommen einen
eigenen Korb. Abgeleitet, nicht angenommen. */
const ohneFeld = rest.filter((p2) => !p2.feld);
if (ohneFeld.length) koerbe.push(ohneFeld);
const ring = [];
const tiefe = koerbe.reduce((m, k) => Math.max(m, k.length), 0);
for (let i = 0; i < tiefe; i++) {
for (const k of koerbe) if (k[i]) ring.push(k[i]);
}
/* Der Versatz muss zur Ringlaenge teilerfremd sein, sonst laeuft der
Kreis nie ganz durch -- dieselbe Ueberlegung wie vorher, nur jetzt
auf dem verzahnten Ring. */
let schritt = ZUSATZ_PRO_RUNDE;
while (ggt(schritt, ring.length) !== 1) schritt++;
const start = (n * schritt) % ring.length;
const zusatz = [];
for (let i = 0; i < ZUSATZ_PRO_RUNDE; i++) zusatz.push(rest[(start + i) % rest.length]);
const schonDrin = new Set();
for (let i = 0; i < ring.length && zusatz.length < ZUSATZ_PRO_RUNDE; i++) {
const w = ring[(start + i) % ring.length];
if (schonDrin.has(w.schluessel)) continue;
schonDrin.add(w.schluessel);
zusatz.push(w);
}
/* IN KATALOGREIHENFOLGE AUSGELIEFERT, nicht in Rotationsreihenfolge.
Der Katalog ist nach Thema sortiert; wer ihn jede Runde in einer
@@ -281,6 +370,8 @@ export function fragenFuer(personId, runden = null) {
DIE SEITE
===================================================================== */
import { resuemeeVon } from "./workspace-befinden-resuemee.js";
befindenRouter.get("/workspace/api/befinden", angemeldet, (req, res) => {
try {
const b = block();
@@ -350,9 +441,86 @@ befindenRouter.get("/workspace/api/befinden", angemeldet, (req, res) => {
};
});
/* ==== DIE EINE ZUSAMMENFASSUNG AM ENDE (20.09.2026) ==============
Filipe: "am ende von allen fragen will ich eine gesamte
zusammenfassung, nicht bei jeder frage oder kategorie eine,
sondern EINE gesamte am ende. eine motivierende zusammenfassung
fuer die person."
SIE WIRD AUS DEN FRISCHEN ANTWORTEN GERECHNET, nicht aus allen
in `entwicklung_stand`. Der Unterschied ist derselbe wie eine
Bildschirmseite weiter oben: Eine Zusammenfassung ueber alte
Antworten sagt nicht "so geht es dir", sondern "so ging es dir
irgendwann mal", und man merkt es nicht.
UND SIE BRAUCHT KEINE ZWEITE RUNDE. Die Musteranalyse darunter
schon (ein Punkt ist keine Entwicklung) -- diese hier ist die
Antwort auf das, was gerade dasteht, und die gibt es beim ersten
Mal genauso.
DIE VORIGE RUNDE KOMMT MIT, wenn es eine gibt: Nur dann kann
"hat sich gebessert" ueberhaupt gesagt werden, und nur fuer
Fragen, die BEIDE Male dran waren. Seit die Fragen rotieren,
waere "war letztes Mal nicht dabei" sonst eine Verbesserung. */
const frischeAntworten = Object.fromEntries(
punkte.filter((pt) => pt.frisch && pt.meins)
.map((pt) => [pt.schluessel, pt.meins.stufe]));
/* WELCHE ANTWORTEN DIE ZUSAMMENFASSUNG MEINT -- und hier steckte
ein Fehler, den die Pruefung gefunden hat, nicht das Nachdenken.
Erster Anlauf: nur die FRISCHEN, also die nach der letzten Runde
gesetzten. Das ist waehrend einer laufenden Runde richtig -- und
ausgerechnet in dem Moment falsch, in dem man die Zusammenfassung
sehen will: DIREKT NACH dem Abschliessen einer Runde ist keine
einzige Antwort mehr frisch. Man hat sie ja Sekunden vorher
gesetzt, also VOR dem Abschluss. Die Seite zeigte nach dem
Abschliessen: nichts.
(Derselbe Sachverhalt steht schon beim Hinweis „das war deine
Antwort beim letzten Mal" in befinden.js -- dort wurde er
beruecksichtigt, hier nicht. Eine Erkenntnis, die an einer
Stelle notiert ist, wirkt nicht von selbst an der anderen.)
RICHTIG IST BEIDES, in dieser Rangfolge:
laeuft gerade eine Runde -> die frischen Antworten
gerade abgeschlossen -> die letzte Runde aus dem Verlauf
Der Vergleich rutscht entsprechend mit: Wird die laufende Runde
gezeigt, ist die letzte abgeschlossene der Vergleich; wird die
letzte abgeschlossene gezeigt, die vorletzte. Sonst verglichen
wir eine Runde mit sich selbst -- und "nichts hat sich
geaendert" waere dann keine Auskunft, sondern ein Rechenfehler. */
const laeuftRunde = Object.keys(frischeAntworten).length > 0;
const fazitAntworten = laeuftRunde
? frischeAntworten
: (verlauf[0]?.antworten || {});
const fazitVergleich = laeuftRunde
? (verlauf[0]?.antworten || null)
: (verlauf[1]?.antworten || null);
/* DIE FRAGEN DAZU aus dem KATALOG, nicht aus `diese.alle`: Eine
abgeschlossene Runde kann andere Fragen enthalten haben als die,
die gerade dran waeren -- die Zusatzfragen wechseln ja. Wer
stattdessen die aktuellen nimmt, fasst Antworten zusammen, die es
zu diesen Fragen gar nicht gibt. */
const fazitPunkte = (ENTWICKLUNG_PUNKTE[b.schluessel] || [])
.filter((pt) => fazitAntworten[pt.schluessel]);
res.json({
block: b,
stufen: ENTWICKLUNG_STUFEN,
/* DIE FELDER. Sie stehen im Katalog, nicht im Browser -- eine
zweite Liste dort waere die, die beim siebten Feld vergessen
wird. */
felder: BEFINDEN_FELDER,
resuemee: resuemeeVon(fazitAntworten, fazitPunkte, BEFINDEN_FELDER,
fazitVergleich),
/* WORAUF SIE SICH BEZIEHT -- die Seite sagt das dazu. „Was das
zusammen heisst" ueber eine Runde von vorgestern ist etwas
anderes als ueber die, die man gerade ausfuellt, und wer das
nicht weiss, bezieht den Satz auf den falschen Tag. */
resuemee_stand: laeuftRunde ? "laufend" : (verlauf[0] ? "letzte" : "keine"),
rhythmus_tage: RHYTHMUS_TAGE,
rhythmus: takt,
punkte,
@@ -622,6 +790,69 @@ export const EINORDNUNG = {
hilft: "Die billigste Maßnahme überhaupt und die mit der besten Wirkung: "
+ "ausdrücklich danken, für etwas Bestimmtes, nicht allgemein.",
},
/* ---- Die sechs vom 20.09.2026 ------------------------------------
Sie schließen drei Lücken, die die Liste vorher hatte: Schlaf,
Widersprechen und Mitreden. Jede bekommt hier ihre Einordnung --
eine Frage ohne Grundlage ist eine Frage, die jemand gut fand, und
davon gibt es in Befindensabfragen genug. */
"e-ich-schlaf": {
welt: "Schlafstörungen sind in der Erschöpfungsforschung das Zeichen, das "
+ "AM FRÜHESTEN kommt – vor dem Leistungsabfall, vor dem Zynismus, vor "
+ "dem Gedanken ans Aufhören. Wer nachts wach liegt und an eine Schicht "
+ "denkt, hat das Problem noch nicht bei der Arbeit, aber schon im Kopf.",
hilft: "Nicht weniger arbeiten, sondern klarer aufhören: ein festes Ende, "
+ "Meldungen aus, und etwas dazwischen, das nichts mit dem Stream zu tun "
+ "hat. Das Gehirn braucht ein Signal, dass die Schicht vorbei ist – die "
+ "Uhrzeit allein ist keins.",
},
"e-ich-widersprechen": {
welt: "Ob man widersprechen kann, ohne dass es unangenehm wird, ist der Kern "
+ "dessen, was die Forschung psychologische Sicherheit nennt – der am "
+ "besten belegte Einzelfaktor dafür, ob ein Team gut arbeitet. Ein Team, "
+ "in dem niemand widerspricht, ist selten einig; meistens ist es still.",
hilft: "Es liegt fast nie an der Person, die schweigt. Was hilft: dass die "
+ "Leitung selbst widerspricht und widersprochen wird, sichtbar, und dass "
+ "ein Einwand einmal ausdrücklich gedankt wird statt nur abgehakt.",
},
"e-ich-mitreden": {
welt: "Viel Anforderung bei wenig Einfluss ist die Kombination, aus der "
+ "Erschöpfung entsteht – nicht viel Arbeit allein. Das Modell dahinter "
+ "(Job Demands-Resources) ist seit Jahrzehnten eines der am besten "
+ "geprüften der Arbeitspsychologie, und Einfluss ist darin die "
+ "wirksamste einzelne Entlastung.",
hilft: "Es muss nicht Mitbestimmung über alles sein. Es reicht meistens, "
+ "über das Eigene zu entscheiden: wann, wie lange, in welcher "
+ "Reihenfolge. Wer das abgibt, gibt wenig ab und nimmt viel Last.",
},
"e-ich-fehler-ok": {
welt: "Was zählt, ist nicht, ob Fehler passieren, sondern ob man sie "
+ "erfährt. In Teams, in denen Fehler teuer sind, werden sie nicht "
+ "seltener – sie werden unsichtbar, und die Folgekosten trägt der, dem "
+ "er passiert ist, allein.",
hilft: "Der erste Fehler, den jemand aus der Leitung selbst erzählt, wirkt "
+ "mehr als jede Zusage. Und: beim nächsten gemeldeten Fehler zuerst "
+ "fragen, was er über den ABLAUF sagt, nicht über die Person.",
},
"e-ich-dazugehoeren": {
welt: "Anschluss ans Team ist in den Untersuchungen zu Moderatoren-Belastung "
+ "der STÄRKSTE einzelne Schutzfaktor – stärker als kürzere Schichten und "
+ "stärker als bessere Werkzeuge. Nützlich zu sein und dazuzugehören sind "
+ "dabei zwei verschiedene Dinge, und nur das zweite hält.",
hilft: "Es entsteht neben der Arbeit, nicht in ihr: ein Kanal, in dem es "
+ "nicht um Schichten geht, ein gemeinsamer Termin ohne Zweck. Wer nur "
+ "zum Arbeiten da ist, geht, sobald die Arbeit unangenehm wird.",
},
"e-ich-stolz": {
welt: "Die einzige Frage der Liste, die zurückschaut. Wer sich an nichts "
+ "erinnert, hat selten nichts geschafft – es hat nur niemand benannt. "
+ "Das ist die gleiche Lücke wie bei der Anerkennung, nur von innen: "
+ "Moderationsarbeit besteht zum großen Teil aus dem, was NICHT passiert "
+ "ist, und daran erinnert sich niemand von selbst.",
hilft: "Aufschreiben, sobald es passiert – eine Zeile reicht. Im Workspace "
+ "ist dafür das Highlight-Brett da. Was nirgends steht, ist nach zwei "
+ "Wochen weg, auch wenn es gut war.",
},
};
/** Das Muster einer Frage ueber die Runden hinweg -- neueste zuerst. */