Aufgaben verteilen: der Knopf ist nie mehr tot, und die Bewerbung steht im Formular

screen1 -- „dogfather, die rechte hand und die linke hand sollen immer
noch aufgaben werden teilen können plus die option dass die modis sich
für aufgaben bewerben können. weil gerade hängt das und weiß nicht
wieso."

WAS WIRKLICH LOS WAR -- gemessen, nicht geraten

Auf entwicklung.html stand oben „Aufgabe verteilen · Wähl LINKS
jemanden aus", und der Knopf war so lange abgeschaltet. Im Browser
nachgemessen (1420 px, als DogFather):

    Band          oben 284 px, linke Kante 130 px
    Personenwahl  oben 490 px, linke Kante 130 px
    -> UNTER dem Band, 127 px darunter, gleiche linke Kante

Links war nichts. Wer der Anweisung folgte, schaute auf eine leere
Fläche und hatte einen Knopf, der nicht ging. Das Recht selbst war die
ganze Zeit richtig: `darfAufgabenVerteilen` = Leitung oder Hand, also
DogFather, rechte Hand UND linke Hand -- alle drei mit
`darf_verteilen: true` gemessen.

Kurz: Die Regel stimmte, der Weg dorthin nicht.

WAS JETZT ANDERS IST

1. DER KNOPF IST IMMER BENUTZBAR. Er öffnet das Formular, auch ohne
   vorherige Auswahl.
2. DIE FRAGE „für wen" STEHT IM FORMULAR, als erste Zeile, mit allen
   Personen zur Wahl. Wer unten eine Kachel angeklickt hat, findet sie
   angehakt wieder -- beide Wege führen zum selben Ziel.
3. EINE LISTE STATT ZWEIER. „Noch jemanden dazunehmen" ist weg. Es
   waren zwei Bedienungen für dieselbe Frage -- und die
   Bewerbungs-Option steckte ausgerechnet in der zugeklappten
   zweiten: Sie war nur zu finden, wenn man erst aufklappte UND dort
   jemanden ankreuzte. Eine Möglichkeit, die man nicht findet, gibt es
   nicht.
4. DIE BEWERBUNG STEHT DA, sobald zwei Leute angehakt sind: „Wer
   zuerst Zeit hat, übernimmt. Sie bewerben sich, du nimmst an oder
   lehnst ab."

ZWEI FEHLER, DIE DABEI AUFFIELEN

* Nach dem Anlegen wurde `fuerPerson` auf null gesetzt und DANACH
  `aufgabenZeigen(fuerPerson, …)` aufgerufen -- die Liste, die zeigen
  soll, was gerade entstanden ist, blendete sich damit aus. Die Namen
  werden jetzt festgehalten, bevor `reset()` sie abräumt.
* Die Bestätigung sagte immer „steht jetzt bei ihm" -- `fuerName` wird
  nur beim Klick auf eine Kachel gefüllt. Sie sagt jetzt, was wirklich
  passiert ist, und bei einem Pool, dass eine Bewerbung kommt.
* `e-mehr-art` heisst `e-art`: Der Name sagte „gehört zu ‚noch
  jemand'", und das gibt es nicht mehr. Dieselbe Sorte Falle wie
  `tperson__namen` heute Nachmittag.

DIE PRÜFUNG HATTE MEINEN FEHLER FESTGESCHRIEBEN

`pruef-bewerbung-aufgaben.mjs` enthielt wörtlich:

    ok(vorher.aus === true,
      "und ist aus, solange niemand gewaehlt ist");

Sie lief, sie war grün, und sie hat den toten Knopf verteidigt. Das
ist die unangenehmste Sorte: nicht übersprungen, nicht kaputt --
sondern eine Bestätigung meines Entwurfs statt der Sache. Jetzt wird
das Gegenteil verlangt.

Dazu zwei neue Abschnitte (84 -> 101 Prüfungen, 0 Fehler):
  6b  verteilen OHNE vorherige Auswahl, als Pool, samt Nachweis am
      Server (verteilart=pool, zwei Leute darin) und der Meldung, die
      nicht „bei ihm" sagen darf
  6c  alle drei Rollen am Bildschirm: DogFather, rechte Hand, linke
      Hand -- mit Gegenprobe, dass ein Modi das Band NICHT sieht

EIGENER MESSFEHLER, offen notiert: Mein erster Versuch, die Bewerbung
nachzustellen, meldete „kein Abruf, nichts passiert". Der Knopf öffnet
eine Rückfrage, und die hatte ich nicht beantwortet. Die Bewerbung war
nie kaputt -- meine Messung war es. Erst der zweite Anlauf zeigte den
ganzen Weg: POST /api/aufgaben/1/bewerben -> {"ok":true,"zustand":"beworben"}.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-22 20:18:35 +02:00
co-authored by Claude Opus 5
parent ba0e326585
commit 803750edbc
41 changed files with 963 additions and 663 deletions
+176 -2
View File
@@ -620,8 +620,26 @@ melde("=== 6. Am echten Bildschirm ===");
});
ok(vorher.istLink === false,
"der Knopf fuehrt nicht mehr auf eine andere Seite (kein Link mehr)");
ok(vorher.aus === true,
"und ist aus, solange niemand gewaehlt ist — er haette nichts zu verteilen");
/* HIER STAND `vorher.aus === true` (bis 22.09.2026 abends).
---------------------------------------------------------------
Die Pruefung hat damit MEINEN Entwurf bestaetigt, nicht die
Sache: Der Knopf war abgeschaltet, solange niemand gewaehlt
war, und daneben stand „Waehl links jemanden aus".
Gemessen steht die Auswahl aber gar nicht links, sondern
206 px WEITER UNTEN, bei derselben linken Kante (130 px). Wer
der Anweisung folgte, sah eine leere Flaeche neben einem
toten Knopf.
Filipe: „weil gerade hängt das und weiß nicht wieso."
Das ist die unangenehmste Sorte gruener Haken: Er lief, er war
gruen, und er hat den Fehler festgeschrieben. Jetzt wird das
Gegenteil verlangt -- der Knopf ist IMMER benutzbar, und die
Auswahl steht im Formular. */
ok(vorher.aus === false,
"und er ist benutzbar, auch ohne vorherige Auswahl — die Frage"
+ " nach der Person wird im Formular selbst gefragt");
ok(vorher.aufgabenBlock === false,
"ohne Person steht auch keine Aufgabenliste da");
@@ -667,8 +685,164 @@ melde("=== 6. Am echten Bildschirm ===");
/* GEGENPROBE: Die Aufgabe ist wirklich da, nicht nur im Bild. */
const ausDerListe = await finde(chef.keks, titel);
ok(!!ausDerListe, "sie steht auch wirklich in der Aufgabenliste des Servers");
/* =================================================================
6b. VERTEILEN OHNE VORHERIGE AUSWAHL -- und als Bewerbung
Filipe am 22.09.2026 abends: „dogfather, die rechte hand und
die linke hand sollen immer noch aufgaben werden teilen
können plus die option dass die modis sich für aufgaben
bewerben können. weil gerade hängt das und weiß nicht wieso."
Der Weg, der vorher tot war: Seite aufmachen, auf „Aufgabe
anlegen" druecken -- ohne unten jemanden angeklickt zu haben.
Frueher passierte dabei NICHTS.
Und im selben Formular muss die Bewerbung zu finden sein.
Vorher steckte sie hinter „Noch jemanden dazunehmen" und
erschien erst, wenn man dort jemanden ankreuzte -- eine
Moeglichkeit, die man nicht findet, gibt es nicht.
================================================================= */
await e.s.goto(`${SEITE}/workspace/entwicklung.html`, { waitUntil: "networkidle" });
await e.s.waitForTimeout(1800);
await e.s.click("#verteilen-knopf");
await e.s.waitForTimeout(600);
const direkt = await e.s.evaluate(() => ({
offen: !document.getElementById("e-neu")?.hidden,
zurWahl: document.querySelectorAll("#e-fuer-leute input[type=checkbox]").length,
artSichtbar: document.getElementById("e-art")
? !document.getElementById("e-art").hidden : null,
/* Die alte, zugeklappte zweite Liste darf es nicht mehr geben --
sonst stehen wieder zwei Bedienungen fuer dieselbe Frage da. */
alteZweiteListe: !!document.getElementById("e-mehr-auf"),
}));
ok(direkt.offen === true,
"das Formular geht auch ohne vorherige Auswahl auf — genau der Weg, der haengen blieb");
ok(direkt.zurWahl >= 2,
`und die Frage nach der Person steht darin, mit ${direkt.zurWahl} Personen zur Wahl`);
ok(direkt.alteZweiteListe === false,
"die zweite, zugeklappte Personenliste gibt es nicht mehr");
ok(direkt.artSichtbar === false,
"bei niemandem oder einer Person wird nicht nach der Verteilart gefragt");
/* Zwei anhaken -> jetzt MUSS die Frage kommen, und die
Bewerbung muss eine der Antworten sein. */
const angehakt = await e.s.evaluate(() => {
const k = [...document.querySelectorAll("#e-fuer-leute input[type=checkbox]")];
k[0].click(); k[1].click();
return k.length;
});
await e.s.waitForTimeout(500);
const zuZweit = await e.s.evaluate(() => ({
artSichtbar: !document.getElementById("e-art").hidden,
antworten: [...document.querySelectorAll('#e-art input[name="e-verteilart"]')]
.map((x) => x.value),
knopf: document.getElementById("verteilen-knopf")?.textContent.trim(),
}));
ok(angehakt >= 2 && zuZweit.artSichtbar === true,
"bei zwei Personen wird gefragt, wie es laufen soll");
ok(zuZweit.antworten.includes("pool"),
`und der Pool-Weg steht als Antwort da (${zuZweit.antworten.join(", ")})`);
ok(/2 Personen/.test(zuZweit.knopf || ""),
`der Knopf zaehlt mit („${zuZweit.knopf}")`);
const poolTitel = "Pool von der Entwicklungsseite";
await e.s.check('#e-art input[value="pool"]');
await e.s.fill("#e-titel", poolTitel);
await e.s.click("#e-neu-speichern");
await e.s.waitForTimeout(1800);
const poolFertig = await e.s.evaluate(() => ({
zu: document.getElementById("e-neu")?.hidden,
meldung: document.getElementById("fehler")?.textContent.trim(),
gut: document.getElementById("fehler")?.dataset.gut,
}));
ok(poolFertig.zu === true && poolFertig.gut === "ja",
`angelegt und als gute Nachricht gemeldet (${poolFertig.gut})`);
/* DIE MELDUNG DARF NICHT „steht jetzt bei ihm" SAGEN. Bei einem
Pool sitzt noch niemand daran -- das ist der ganze Punkt. */
ok(/bewirbt|bereit/i.test(poolFertig.meldung || "")
&& !/bei ihm/.test(poolFertig.meldung || ""),
`und die Meldung sagt, dass eine Bewerbung kommt („${poolFertig.meldung}")`);
const poolAufgabe = await finde(chef.keks, poolTitel);
ok(!!poolAufgabe, "die Pool-Aufgabe steht in der Liste des Servers");
ok(poolAufgabe?.verteilart === "pool",
`und sie ist wirklich ein Pool (${poolAufgabe?.verteilart})`);
ok((poolAufgabe?.zuteilung || []).length === 2,
`mit zwei Leuten darin (${(poolAufgabe?.zuteilung || []).length})`);
} finally { await e.ctx.close(); }
/* ===================================================================
6c. ALLE DREI, DIE VERTEILEN DUERFEN -- am Bildschirm
Filipe: „dogfather, die rechte hand und die linke hand sollen
immer noch aufgaben werden teilen können."
Der Server sagt das seit dem 22.09. ueber `darfAufgabenVerteilen`,
und Abschnitt 1 misst das dort auch. Hier geht es um die andere
Haelfte: ob es auf der SEITE ankommt. Genau diese Luecke war der
Fehler -- die Regel stimmte, der Knopf war trotzdem tot.
DIE DREI STEHEN IN EINER LISTE, und die Zahl der geprueften
Rollen steht in der Bedingung: Eine leere Schleife darf nicht
„in Ordnung" heissen.
=================================================================== */
const verteiler = [
["admin", "CODE-DOGI-0001", "DogFather"],
["hand", "CODE-HAND-0001", "die rechte Hand"],
["linke", "CODE-LINK-0001", "die linke Hand"],
];
let konnten = 0;
for (const [rolle, code, wer] of verteiler) {
const v = await seiteAls(rolle, code, 1180);
try {
await v.s.goto(`${SEITE}/workspace/entwicklung.html`, { waitUntil: "networkidle" });
await v.s.waitForTimeout(1700);
const stand = await v.s.evaluate(() => ({
band: document.getElementById("verteilen-band")
? !document.getElementById("verteilen-band").hidden : null,
aus: document.getElementById("verteilen-knopf")?.disabled,
darf: window.__ich?.darf_verteilen,
}));
if (stand.band === true && stand.aus === false && stand.darf === true) {
/* Nicht nur hinsehen -- einmal aufmachen. Ein Knopf, der
nicht abgeschaltet ist, muss noch lange nichts tun. */
await v.s.click("#verteilen-knopf");
await v.s.waitForTimeout(500);
const auf = await v.s.evaluate(() => ({
offen: !document.getElementById("e-neu")?.hidden,
leute: document.querySelectorAll("#e-fuer-leute input[type=checkbox]").length,
}));
if (auf.offen && auf.leute > 0) konnten++;
}
ok(stand.band === true && stand.aus === false,
`${wer} sieht das Verteilband und kann es bedienen`
+ ` (sichtbar=${stand.band}, aus=${stand.aus})`);
} finally { await v.ctx.close(); }
}
ok(konnten === verteiler.length,
`und alle ${verteiler.length} bekommen das Formular mit der Personenliste auf (${konnten})`);
/* GEGENPROBE: Ein Modi darf es NICHT. Ohne diese Zeile waere nicht
bewiesen, dass die drei oben etwas Besonderes koennen -- eine
Pruefung, die bei jedem gruen wird, misst keine Grenze. */
{
const m = await seiteAls("modi", "CODE-MODI-0001", 1180);
try {
await m.s.goto(`${SEITE}/workspace/entwicklung.html`, { waitUntil: "networkidle" });
await m.s.waitForTimeout(1700);
const stand = await m.s.evaluate(() => ({
band: document.getElementById("verteilen-band")
? !document.getElementById("verteilen-band").hidden : null,
darf: window.__ich?.darf_verteilen,
}));
ok(stand.band === false && stand.darf === false,
`Gegenprobe: ein Modi sieht das Verteilband nicht`
+ ` (sichtbar=${stand.band}, darf=${stand.darf})`);
} finally { await m.ctx.close(); }
}
ok(meckern.length === 0, meckern.length
? `der Browser meldet: ${meckern.slice(0, 3).join(" | ")}`
: "kein Absturz und keine Fehlermeldung im Browser");