Fuenfte Etappe: "abgebrochen" fehlte in der Pruefung

Die Live-Datenbank hat mir den Fehler gezeigt, nicht der Quelltext.
Nach dem Ausliefern ein Blick auf die echten Staende: erledigt 6,
offen 4 -- und abgebrochen 2. Die zwei standen in meiner Pruefung
nicht.

GRUND: Ich hatte die Etappen aus STATUS in workspace-aufgaben.js
abgeleitet, und dort stehen nur vier. "abgebrochen" fehlt dort
ABSICHTLICH, damit der normale Weg es nicht setzen kann -- es kommt
ueber eine eigene Route mit Pflichtbegruendung. Wer die Liste aus
STATUS ableitet, uebersieht also ausgerechnet den Endzustand, in dem
Aufgaben am laengsten liegen bleiben. Dieselbe Luecke hat in dieser
Datei schon einmal zwei Bedingungen erwischt, die nur gegen
'erledigt' prueften.

"In jeder etape" waere damit eine Zusage ueber vier von fuenf
Etappen gewesen.

Zwei Dinge dafuer nachgezogen:

  * Die Etappe wird jetzt aus der DATENBANK gelesen, nicht aus der
    Liste. Abgebrochene Aufgaben werden an mehreren Stellen bewusst
    ausgeblendet -- "Etappe steht wirklich" waere ueber die Liste
    gar nicht messbar gewesen.
  * Die Auskunft an die Oberflaeche wird nur verlangt, WENN die
    Aufgabe in ihrer Liste steht. Blendet das Haus eine Etappe aus,
    gibt es dort keinen Knopf zu zeigen; dann zaehlt allein der
    Server, und den misst der DELETE. Gemessen: Sie steht drin, und
    der Knopf wird auch dort angeboten.

pruef-verteilen 42 -> 44, jetzt 5/5 in allen Zaehlungen.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-10-03 15:01:44 +02:00
co-authored by Claude Opus 5
parent 95d68fd392
commit 7d56837049
+37 -7
View File
@@ -393,7 +393,21 @@ melde("\n=== 5. Die rechte Hand an ihren eigenen Aufgaben ===");
===================================================================== */
melde("\n=== 6. Loeschen: immer, in jeder Etappe ===");
{
const ETAPPEN = ["offen", "arbeit", "review", "erledigt"];
/* FUENF, NICHT VIER -- und die fuenfte hat mir die Live-Datenbank
gezeigt (03.10.2026).
Mein erster Satz war ["offen","arbeit","review","erledigt"], die
Liste aus `STATUS` in workspace-aufgaben.js. Beim Nachsehen auf
dem laufenden Server standen dort aber auch zwei Aufgaben auf
"abgebrochen". Der Grund: "abgebrochen" steht absichtlich NICHT
in STATUS, damit der normale Weg es nicht setzen kann -- es
kommt ueber eine eigene Route. Wer die Etappen aus STATUS
ableitet, uebersieht also ausgerechnet den Endzustand, in dem
Aufgaben am laengsten liegen bleiben.
Genau dieselbe Luecke hat in dieser Datei schon einmal zwei
Bedingungen erwischt, die nur gegen 'erledigt' prueften. */
const ETAPPEN = ["offen", "arbeit", "review", "erledigt", "abgebrochen"];
let konnteHand = 0, konnteDogi = 0, konnteLinkeNicht = 0, wirklichWeg = 0;
for (const stand of ETAPPEN) {
@@ -403,7 +417,12 @@ melde("\n=== 6. Loeschen: immer, in jeder Etappe ===");
const r = await ruf("/workspace/api/aufgaben", kDogi, "POST",
{ titel, verantwortlich_id: idModi, prioritaet: "mittel" });
const id = json(r).id;
if (stand !== "offen") {
if (stand === "abgebrochen") {
/* Eigener Weg mit Pflichtbegruendung -- per PATCH laesst sich
dieser Stand gar nicht setzen. */
await ruf(`/workspace/api/aufgaben/${id}/abbrechen`, kDogi, "POST",
{ grund: "Pruefung: Loeschen in jeder Etappe" });
} else if (stand !== "offen") {
await ruf(`/workspace/api/aufgaben/${id}`, kDogi, "PATCH", { status: stand });
}
return id;
@@ -416,16 +435,27 @@ melde("\n=== 6. Loeschen: immer, in jeder Etappe ===");
/* Steht die Etappe wirklich? Ohne das waeren alle vier Durchlaeufe
in Wahrheit viermal "offen" -- und die Pruefung gruen, ohne je
etwas anderes gesehen zu haben. */
const liste = json(await ruf("/workspace/api/aufgaben", kDogi)).aufgaben || [];
const echt = liste.find((a) => a.id === fuerHand);
/* AUS DER DATENBANK, NICHT AUS DER LISTE. Abgebrochene Aufgaben
werden an mehreren Stellen bewusst ausgeblendet -- die Liste
koennte sie also gar nicht zeigen, und "Etappe steht" waere
dann nicht messbar. Die Tabelle luegt nicht. */
const dS = new DatabaseSync(process.env.WORKSPACE_DB);
const echt = dS.prepare("SELECT status FROM aufgaben WHERE id = ?").get(fuerHand);
dS.close();
ok(echt?.status === stand, `Etappe "${stand}" steht wirklich (${echt?.status})`);
/* Und die Oberflaeche bekommt es auch gesagt -- sonst gaebe es den
Knopf gar nicht, egal was der Server erlaubt. */
const beiHand = (json(await ruf("/workspace/api/aufgaben", kHand)).aufgaben || [])
.find((a) => a.id === fuerHand);
ok(beiHand?.darf_loeschen === true,
` der rechten Hand wird Loeschen angeboten (${beiHand?.darf_loeschen})`);
/* Steht sie in IHRER Liste, muss auch der Knopf angeboten werden.
Blendet das Haus diese Etappe fuer sie aus, gibt es dort keinen
Knopf zu zeigen -- dann ist der Server allein zustaendig, und
den misst der DELETE zwei Zeilen weiter. */
ok(beiHand === undefined || beiHand.darf_loeschen === true,
beiHand === undefined
? ` (in dieser Etappe steht sie nicht in ihrer Liste -- nur der Server zaehlt)`
: ` der rechten Hand wird Loeschen angeboten (${beiHand.darf_loeschen})`);
if ((await ruf(`/workspace/api/aufgaben/${fuerHand}`, kHand, "DELETE")).code === 200) konnteHand++;
if ((await ruf(`/workspace/api/aufgaben/${fuerDogi}`, kDogi, "DELETE")).code === 200) konnteDogi++;
@@ -442,7 +472,7 @@ melde("\n=== 6. Loeschen: immer, in jeder Etappe ===");
}
const n = ETAPPEN.length;
ok(n === 4 && konnteHand === n,
ok(n === 5 && konnteHand === n,
`die rechte Hand loescht in allen ${n} Etappen (${konnteHand}/${n})`);
ok(konnteDogi === n, `DogFather ebenso (${konnteDogi}/${n})`);
ok(konnteLinkeNicht === n,