Entwicklung: der Mensch sieht, was seine Aufgabe ist

VanVan im Support: „wenn ich … Aufgaben an einen Modi zutrage und
auch bewerte, dann sieht der Modi zwar die Auswertung im Bereich
Entwicklung, aber bei ihm taucht nichts im Bereich eure Aufgaben
unten in der Karte auf."

IHR FALL NACHGESTELLT (server/mess-vanvan-karte.mjs): VanVan traegt
einem Modi zwei von 68 Punkten zu und bewertet sie, Filipe bewertet
nichts -- genau wie bei ihr.

  vorher   seine Karte: fertig=0 von 68, alles „offen",
           Punktzeilen sichtbar: 0
           Kennt sie das Wort „zugetragen"?  NEIN
  nachher  Abschnitt „Deine Aufgaben (2)" mit beiden Titeln

ZWEI DINGE WAREN EINS, DIE GETRENNT GEHOEREN

  Was er TUN soll   die Zuteilung. Die gibt es, bevor jemand etwas
                    bewertet, und sie gehoert ihm.
  Was man SIEHT     die Bewertung. Die erscheint erst, wenn alle
                    hingesehen haben.

`meine-karte` kannte nur das Zweite. War die Bewertung noch nicht
vollstaendig, stieg die Anzeige mit `return` aus -- und damit sah er
gar nichts, obwohl ihm zwei Aufgaben zugetragen waren. Das ist die
falsche Reihenfolge: Wer seine Aufgabe erst sieht, wenn sich zwei
Leute ueber ihre Ausfuehrung einig sind, kann sie nicht angehen.

Die Regel fuer die Bewertung bleibt unveraendert. Eine einzelne
Meinung soll bei einem Menschen nicht als Urteil des Teams ankommen.

UND DIE ANDERE HAELFTE: NIEMAND SAGTE ES IHR

VanVan hatte gesetzt, es kam nicht an, und nichts auf ihrem
Bildschirm erklaerte das. Ein Mensch, der das zweimal erlebt, hoert
auf zu setzen. An einem Punkt, den sie bewertet hat, steht jetzt
leise: „Er sieht das noch nicht -- es fehlt noch eine Einschaetzung."
Ohne Namen: Wer fehlt, waere eine Aufforderung, jemanden
anzutreiben.

IHRE ZWEITE BEOBACHTUNG, EBENFALLS GEMESSEN

„bei jedem Punkt läuft obwohl auch wenn die Aufgaben darüber gar
nicht zugetragen wurde." Stimmt: Die vier Bewertungsknoepfe („✓
Läuft ↗ Wächst ! Da hakt es – Kann ich nicht sagen") stehen an allen
68 Punkten, auch an den nicht zugetragenen. Beim Durchscrollen liest
man deshalb ueberall „Läuft".

DIE 68 BLEIBEN. Filipe am 25.09.2026 ausdruecklich: „dogfather und
die rechte hand sollen immer noch die 68 sachen sehen wie vorher …
unsere sicht soll sich nicht aendern." Also kein Ausblenden und
keine neue Vorgabe, sondern ein Knopf mehr in der Leiste, die es
schon gibt: „Zugetragen · 2". „Alle" bleibt, was beim Aufmachen
gilt. Gemessen grenzt er auf 2 Punkte ein, Kopf „2 / 2".

NEBENBEI ZUSAMMENGEFUEHRT
* `beurteilerZahl()` an einer Stelle -- beide Enden stellen dieselbe
  Frage, zwei Abschriften saegten irgendwann Verschiedenes ueber
  denselben Punkt.
* `antwortReihe()` und `punkteGefiltert()` ebenso.
* Die Abfrage stand zuerst je Punkt in der Schleife: 68
  Datenbankfragen fuer eine Zahl, die sich nicht aendert.

GEPRUEFT
pruef-entwicklung 79/0 (9 neue, mit Gegenproben in beide Richtungen:
ein nicht zugetragener Punkt traegt die Marke nicht, und sobald der
zweite Beurteiler setzt, geht es durch). mess-vanvan-karte ohne
ACHTUNG. pruef-werdegang 103/0, pruef-entwicklung-kacheln 34/0,
pruef-deutsche-texte, pruef-css-klassen, pruef-zwischenspeicher 34/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-30 16:48:24 +02:00
co-authored by Claude Opus 5
parent a3ec558127
commit 51c47e1c07
50 changed files with 1391 additions and 701 deletions
+56
View File
@@ -2731,3 +2731,59 @@
@media (prefers-reduced-motion: reduce) {
.e-punkt__auftrag { transition: none; }
}
/* =====================================================================
VANVANS MELDUNG AUS DEM SUPPORT (30.09.2026)
Zwei neue Zeilen, beide leise. Was hier dazukommt, ist eine
Auskunft, kein Alarm -- und es steht neben 68 anderen Punkten.
===================================================================== */
/* „Er sieht das noch nicht." Steht direkt unter „von dir am ...", in
derselben Schriftgroesse und demselben Ton wie die Nachbarzeilen --
es gehoert zu dem, was ich gesetzt habe, und nicht daneben.
KEINE WARNFARBE. Es ist kein Fehler und nichts, was jemand falsch
gemacht hat: Es fehlt schlicht noch eine zweite Einschaetzung. Ein
rotes Schild an dieser Stelle waere ein Vorwurf an den, der gerade
richtig gehandelt hat -- und nach dem dritten Mal klickt man es
weg wie jede Warnung, die immer kommt. */
.e-punkt__wartet {
margin: 4px 0 0;
font-size: .78rem;
line-height: 1.5;
color: var(--text-leise);
display: flex;
gap: 7px;
align-items: baseline;
}
.e-punkt__wartet::before {
content: "";
flex: none;
width: 6px; height: 6px;
margin-top: 1px;
border-radius: 50%;
/* Gedeckter Bernstein, derselbe Ton wie das Anlassfeld nebenan --
„liegt an", nicht „kaputt". */
background: color-mix(in srgb, #c99a62 62%, transparent);
}
/* ---- Die eigenen Aufgaben auf der Karte des Menschen --------------
Der Abschnitt steht GANZ OBEN auf seiner Karte, vor den
Beobachtungen. Das ist die Reihenfolge der Sache: Eine Aufgabe gibt
es, bevor sie beurteilt wird.
Er traegt eine Kante links -- dieselbe Sprache wie die Marke an den
zugetragenen Punkten der Leitung, damit beide Seiten dasselbe
meinen, wenn sie dasselbe zeigen. */
.e-block--auftrag {
padding-left: 16px;
border-left: 3px solid color-mix(in srgb, var(--akzent) 70%, transparent);
}
.e-block--auftrag .e-block__text {
margin: 4px 0 14px;
font-size: .82rem;
line-height: 1.55;
color: var(--text-still);
}
+157 -29
View File
@@ -194,9 +194,7 @@
UNGEFILTERTE Zahl zurueck -- der Kopf sagte dann "3 / 14",
waehrend vier Zeilen darunter stehen. Und man zweifelt an der
Zahl, nicht am Filter. */
const punkte = stufenFilter
? b.punkte.filter((pt) => pt.stufe === stufenFilter)
: b.punkte;
const punkte = punkteGefiltert(b.punkte);
const n = punkte.filter((pt) => pt.meins).length;
const haktHier = punkte.filter((pt) => pt.meins?.stufe === 'hakt').length;
const stand = abschnitt.querySelector('.e-block__stand');
@@ -1651,11 +1649,38 @@
stufenLeiste.setAttribute('role', 'group');
stufenLeiste.setAttribute('aria-label', 'Nach Stufe filtern');
const allePunkte = r.bloecke.flatMap((b) => b.punkte);
const stufenWahl = [{ schluessel: '', name: 'Alle', text: '' }, ...(r.erwartung || [])];
/* ==== UND EIN KNOPF FÜR DAS ZUGETRAGENE (30.09.2026) ==========
VanVan aus dem Support: „steht in der Karte bei jedem Punkt
läuft obwohl auch wenn die Aufgaben darüber gar nicht
zugetragen wurde."
Gemessen stimmt das: Die vier Bewertungsknöpfe („✓ Läuft
↗ Wächst ! Da hakt es – Kann ich nicht sagen") stehen an allen
68 Punkten, auch an denen, die niemandem zugetragen sind. Wer
durchscrollt, liest deshalb an jedem Punkt das Wort „Läuft".
DIE 68 BLEIBEN. Filipe am 25.09.2026 ausdrücklich: „dogfather
und die rechte hand sollen immer noch die 68 sachen sehen wie
vorher … unsere sicht soll sich nicht ändern." Also kein
Ausblenden und keine neue Vorgabe — ein Knopf mehr in der
Leiste, die es schon gibt. „Alle" bleibt, was beim Aufmachen
gilt.
ER STEHT VORNE, gleich hinter „Alle": Es ist die Frage, die man
am häufigsten hat, wenn man eine bestimmte Person ansieht. */
const stufenWahl = [
{ schluessel: '', name: 'Alle', text: '' },
{ schluessel: 'zugetragen', name: 'Zugetragen',
text: 'Nur die Punkte, die diesem Menschen als Aufgabe gegeben wurden.' },
...(r.erwartung || []),
];
for (const e of stufenWahl) {
const wieViele = e.schluessel
? allePunkte.filter((pt) => pt.stufe === e.schluessel).length
: allePunkte.length;
const wieViele = e.schluessel === 'zugetragen'
? allePunkte.filter((pt) => pt.zugetragen).length
: e.schluessel
? allePunkte.filter((pt) => pt.stufe === e.schluessel).length
: allePunkte.length;
const k = el('button', 'e-stufen__knopf');
k.type = 'button';
k.dataset.erwartung = e.schluessel;
@@ -1681,9 +1706,7 @@
Zeilen, zeigte der Kopf weiterhin „3 / 14", während vier
Punkte darunter stehen. Genau diese Sorte Unstimmigkeit
lässt einen an der Zahl zweifeln statt am Filter. */
const punkte = stufenFilter
? b.punkte.filter((pt) => pt.stufe === stufenFilter)
: b.punkte;
const punkte = punkteGefiltert(b.punkte);
/* EINE KATEGORIE OHNE TREFFER WIRD GANZ AUSGELASSEN. Ein
Abschnitt mit „0 / 0" ist kein Ergebnis, sondern ein
Hindernis zwischen den echten. */
@@ -1937,6 +1960,34 @@
if (pt.meins) {
z.append(el('p', 'e-punkt__wann',
`von dir am ${datum(pt.meins.am)}${pt.meins.verblasst ? ' – älter als 90 Tage' : ''}`));
/* ==== KOMMT DAS BEI IHM AN? (30.09.2026) ====================
VanVan aus dem Support: Sie hatte einem Modi Punkte
zugetragen und bewertet — und bei ihm tauchte nichts auf.
Der Grund ist die Regel drüben in seiner Karte: Ein Punkt
erscheint dort erst, wenn ALLE Beurteiler gesetzt haben. Die
Regel bleibt, sie hat einen guten Grund — eine einzelne
Meinung soll bei einem Menschen nicht als Urteil des ganzen
Teams ankommen.
Falsch war, dass es niemand DENEN sagt, die schon gesetzt
haben. Sie hat getan, was sie tun sollte, es kam nicht an,
und nichts auf ihrem Bildschirm erklärte das. Ein Mensch, der
so etwas zweimal erlebt, hört auf zu setzen.
KEIN NAME. Wer noch fehlt, steht hier nicht — das wäre eine
Aufforderung, jemanden anzutreiben. Dass etwas offen ist,
genügt; wer es ist, weiß man bei zwei Beurteilern ohnehin. */
const se = pt.sieht_er;
if (se && se.noetig > 1 && se.da < se.noetig) {
const hin = el('p', 'e-punkt__wartet',
`Er sieht das noch nicht – es fehlt noch eine Einschätzung.`);
hin.title = 'Eine Beobachtung erscheint bei der Person erst, wenn alle '
+ 'sie gesetzt haben. Eine halbe Karte wäre schlimmer als keine.';
z.append(hin);
}
}
/* ==== AUS DER BEOBACHTUNG WIRD EIN SCHRITT (15.09.2026) ==========
@@ -2030,6 +2081,40 @@
ohne den Menschen dazu — deshalb steht hier stattdessen der Satz,
dass man danach fragen soll. Ein Satz aus einer Notiz, aus dem
Zusammenhang gerissen, richtet mehr an, als er erklärt. */
/** Welche Punkte zeigt der Filter gerade?
*
* AN EINER STELLE, weil an zwei Stellen gefiltert wird: beim
* Zeichnen und beim Nachziehen der Zähler. Standen dort zwei
* Abschriften, zeigte der Kopf „3 / 14", während vier Punkte
* darunter stehen — genau die Sorte Unstimmigkeit, die einen an
* der Zahl zweifeln lässt statt am Filter. */
function punkteGefiltert(punkte) {
if (!stufenFilter) return punkte;
if (stufenFilter === 'zugetragen') return punkte.filter((pt) => pt.zugetragen);
return punkte.filter((pt) => pt.stufe === stufenFilter);
}
/** Die Antworten zu einem fertigen Punkt.
*
* ALS EIGENE FUNKTION, seit die Aufgaben oben dieselbe Reihe
* brauchen (30.09.2026). Zweimal abgeschrieben waere sie die, bei
* der eine Seite irgendwann anders aussieht als die andere. */
function antwortReihe(pt) {
const antw = el('div', 'e-meine__antworten');
for (const x of pt.antworten || []) {
const chip = el('span', 'e-meine__antwort', `${x.anzahl} × ${x.name}`);
chip.dataset.stufe = x.stufe;
antw.append(chip);
}
if (!pt.einig) {
const hin = el('span', 'e-meine__uneinig', 'darüber seid ihr euch nicht einig');
hin.title = 'Zwei Leute haben dasselbe verschieden gesehen. Das ist normal – '
+ 'und ein guter Anlass, danach zu fragen.';
antw.append(hin);
}
return antw;
}
async function meineKarte() {
let a;
try { a = await hole('/workspace/api/entwicklung/meine-karte'); } catch { return; }
@@ -2048,18 +2133,71 @@
+ 'da ist, steht hier etwas.';
return;
}
/* ==== ZUERST: WAS SIND MEINE AUFGABEN? (30.09.2026) ===========
VanVan aus dem Support: „dann sieht der Modi zwar die
Auswertung im Bereich Entwicklung, aber bei ihm taucht nichts
im Bereich eure Aufgaben unten in der Karte auf."
Nachgestellt und bestaetigt: Waren die Bewertungen noch nicht
vollstaendig, stieg diese Funktion hier mit `return` aus — und
damit sah er GAR NICHTS, obwohl ihm zwei Aufgaben zugetragen
worden waren.
DAS WAR DIE FALSCHE REIHENFOLGE. Eine Aufgabe gibt es, bevor
sie beurteilt wird. Wer sie erst sieht, wenn sich zwei Leute
ueber ihre Ausfuehrung einig geworden sind, kann sie nicht
angehen.
Die Regel fuer die BEWERTUNG bleibt: Ein Punkt erscheint erst,
wenn alle Beurteiler gesetzt haben. Eine einzelne Meinung soll
bei einem Menschen nicht als Urteil des Teams ankommen. */
const meine = r.bloecke.flatMap((b) => b.punkte).filter((pt) => pt.zugetragen);
if (meine.length) {
const auf = el('section', 'e-block e-block--auftrag');
auf.append(el('h3', 'e-block__titel',
meine.length === 1 ? 'Deine Aufgabe' : `Deine Aufgaben (${meine.length})`));
auf.append(el('p', 'e-block__text',
'Das ist dir zugetragen. Daran arbeitest du – unabhängig davon, '
+ 'ob schon jemand etwas dazu notiert hat.'));
for (const pt of meine) {
const zeile = el('article', 'e-punkt e-punkt--meine');
zeile.dataset.zugetragen = 'ja';
zeile.append(el('h4', 'e-punkt__titel', pt.titel));
if (pt.offen) {
/* „NOCH NIEMAND" UND „EINER VON ZWEIEN" SIND NICHT DASSELBE.
Das erste heisst, es hat noch keiner hingesehen; das
zweite, dass es laeuft. Eine ZAHL steht hier bewusst
nicht — sie machte aus einer Auskunft einen Countdown. */
zeile.append(el('p', 'e-punkt__wann', pt.davon_da
? 'Einschätzung läuft – sie erscheint, sobald alle hingesehen haben.'
: 'Noch nicht eingeschätzt.'));
} else {
zeile.append(antwortReihe(pt));
}
auf.append(zeile);
}
ziel.append(auf);
}
if (!r.fertig) {
/* EINE ZAHL IN EINEM SATZ MUSS SICH VORLESEN LASSEN. „wenn alle 1
sie gesetzt haben" ist keine Auskunft, sondern eine Rechnung --
und wer einen Satz liest, der falsch klingt, glaubt auch dem
Rest der Seite weniger. Derselbe Fall wie bei der Ampel und
beim Takt auf befinden.html. */
satz.textContent = r.beurteiler === 1
? 'Noch nichts fertig. Eine Beobachtung erscheint hier, sobald sie gesetzt ist '
+ '– eine halbe Karte wäre schlimmer als keine.'
: `Noch nichts fertig. Eine Beobachtung erscheint hier erst, `
satz.textContent = (r.beurteiler === 1
? 'Noch keine Einschätzung durch. Eine Beobachtung erscheint hier, sobald sie '
+ 'gesetzt ist – eine halbe Karte wäre schlimmer als keine.'
: `Noch keine Einschätzung durch. Eine Beobachtung erscheint hier erst, `
+ `wenn alle ${r.beurteiler} sie gesetzt haben – eine halbe Karte ist `
+ `schlimmer als keine.`;
+ `schlimmer als keine.`)
/* „DARUNTER" UND NICHT „OBEN". Der Satz steht ueber der Liste
(`karte-satz` vor `#meine-karte`) -- am Bildschirm
nachgesehen, nicht aus dem Quelltext geschlossen. Ein
Verweis in die falsche Richtung laesst einen an der
falschen Stelle suchen. */
+ (meine.length ? ' Was dir zugetragen ist, steht darunter.' : '');
return;
}
@@ -2068,7 +2206,9 @@
+ 'danebengeschrieben steht. Das gehört ins Gespräch: frag danach.';
for (const b of r.bloecke) {
const fertige = b.punkte.filter((pt) => !pt.offen);
/* WAS OBEN SCHON STEHT, STEHT NICHT NOCH EINMAL. Eine Aufgabe
zweimal auf derselben Seite liest sich wie zwei Aufgaben. */
const fertige = b.punkte.filter((pt) => !pt.offen && !pt.zugetragen);
if (!fertige.length) continue;
const abschnitt = el('section', 'e-block');
abschnitt.append(el('h3', 'e-block__titel', b.name));
@@ -2076,19 +2216,7 @@
const zeile = el('article', 'e-punkt e-punkt--meine');
if (pt.einig) zeile.dataset.stufe = pt.antworten[0].stufe;
zeile.append(el('h4', 'e-punkt__titel', pt.titel));
const antw = el('div', 'e-meine__antworten');
for (const x of pt.antworten) {
const chip = el('span', 'e-meine__antwort', `${x.anzahl} × ${x.name}`);
chip.dataset.stufe = x.stufe;
antw.append(chip);
}
if (!pt.einig) {
const hin = el('span', 'e-meine__uneinig', 'darüber seid ihr euch nicht einig');
hin.title = 'Zwei Leute haben dasselbe verschieden gesehen. Das ist normal – '
+ 'und ein guter Anlass, danach zu fragen.';
antw.append(hin);
}
zeile.append(antw);
zeile.append(antwortReihe(pt));
abschnitt.append(zeile);
}
ziel.append(abschnitt);