diff --git a/server/pruef-bewerbung-aufgaben.mjs b/server/pruef-bewerbung-aufgaben.mjs
index 46440bf0..d0d4b02b 100644
--- a/server/pruef-bewerbung-aufgaben.mjs
+++ b/server/pruef-bewerbung-aufgaben.mjs
@@ -1136,17 +1136,22 @@ melde("=== 6. Am echten Bildschirm ===");
/* DER KERN DER MELDUNG. */
await roh(`/workspace/api/aufgaben/${dId}/annehmen`,
{ methode: "POST", keks: modi.keks });
- const fertig = await roh(`/workspace/api/aufgaben/${dId}/mein-stand`, {
- methode: "POST", keks: modi.keks, body: { zustand: "erledigt" } });
+ /* UEBER DEN STATUS, nicht ueber `/mein-stand` (03.10.2026).
+ Den zweiten Weg gibt es nicht mehr: Er setzte den
+ Zuteilungszustand, ohne den Aufgabenstatus mitzuziehen --
+ VanVans Meldung #8. Geprueft wird jetzt die Tuer, die es
+ noch gibt. */
+ const fertig = await roh(`/workspace/api/aufgaben/${dId}`, {
+ methode: "PATCH", keks: modi.keks, body: { status: "erledigt" } });
ok(fertig.code === 409 && fertig.json?.fehler === "dauerhafte_aufgabe",
`Frida kann sie nicht abhaken (${fertig.code}/${fertig.json?.fehler})`);
/* GEGENPROBE 1: „Ich fange an" geht weiterhin. Auch eine
stehende Aufgabe hat einen Anfang -- gesperrt ist nur das
Abhaken, nicht die Arbeit. */
- const anfang = await roh(`/workspace/api/aufgaben/${dId}/mein-stand`, {
- methode: "POST", keks: modi.keks, body: { zustand: "arbeit" } });
- ok(anfang.code === 200, `„Ich fange an" geht trotzdem (${anfang.code})`);
+ const anfang = await roh(`/workspace/api/aufgaben/${dId}`, {
+ methode: "PATCH", keks: modi.keks, body: { status: "arbeit" } });
+ ok(anfang.code === 200, `anfangen geht trotzdem (${anfang.code})`);
/* GEGENPROBE 2: Bei einer GEWOEHNLICHEN Aufgabe geht das Abhaken.
Ohne sie hiesse „409" womoeglich nur, dass niemand je etwas
@@ -1158,8 +1163,8 @@ melde("=== 6. Am echten Bildschirm ===");
const nId = normal.json?.aufgabe?.id ?? normal.json?.id;
await roh(`/workspace/api/aufgaben/${nId}/annehmen`,
{ methode: "POST", keks: modi.keks });
- const ok2 = await roh(`/workspace/api/aufgaben/${nId}/mein-stand`, {
- methode: "POST", keks: modi.keks, body: { zustand: "erledigt" } });
+ const ok2 = await roh(`/workspace/api/aufgaben/${nId}`, {
+ methode: "PATCH", keks: modi.keks, body: { status: "erledigt" } });
ok(ok2.code === 200,
`eine gewoehnliche Aufgabe haekt sie sehr wohl ab (${ok2.code})`);
@@ -1193,8 +1198,8 @@ melde("=== 6. Am echten Bildschirm ===");
const a3 = await lesen(hand.keks);
ok(beenden.code === 200 && !a3?.dauerhaft,
`die rechte Hand beendet sie (${beenden.code}, danach ${a3?.dauerhaft})`);
- const jetztFertig = await roh(`/workspace/api/aufgaben/${dId}/mein-stand`, {
- methode: "POST", keks: modi.keks, body: { zustand: "erledigt" } });
+ const jetztFertig = await roh(`/workspace/api/aufgaben/${dId}`, {
+ methode: "PATCH", keks: modi.keks, body: { status: "erledigt" } });
ok(jetztFertig.code === 200,
`und danach laesst sie sich abhaken (${jetztFertig.code})`);
}
diff --git a/server/pruef-zuteilung.mjs b/server/pruef-zuteilung.mjs
index 4adcee8b..7b55fe11 100644
--- a/server/pruef-zuteilung.mjs
+++ b/server/pruef-zuteilung.mjs
@@ -458,15 +458,21 @@ melde("\n=== Fertig machen und bewerten ===");
`eine dauerhafte Aufgabe (#${idDauer})`);
await rufe(`/workspace/api/aufgaben/${idDauer}/annehmen`, { method: "POST", keks: anna });
- const ueberStand = await rufe(`/workspace/api/aufgaben/${idDauer}/mein-stand`,
+ /* ES GIBT NUR NOCH EINE TUER (03.10.2026). Hier standen zwei:
+ `/mein-stand` und der Status. Die erste ist weg -- sie setzte
+ den Zuteilungszustand, ohne den Aufgabenstatus mitzuziehen,
+ und war damit der zweite Zustand, den VanVans Meldung #8
+ benannt hat. Dass sie zu war, hat nichts geheilt; dass es sie
+ nicht mehr gibt, schon. */
+ const weg = await rufe(`/workspace/api/aufgaben/${idDauer}/mein-stand`,
{ method: "POST", keks: anna, body: { zustand: "erledigt" } });
- ok(ueberStand.code === 409 && ueberStand.json?.fehler === "dauerhafte_aufgabe",
- `Tuer 1 (mein-stand) ist zu (${ueberStand.code} ${ueberStand.json?.fehler})`);
+ ok(weg.code === 404,
+ `den zweiten Weg (mein-stand) gibt es nicht mehr (${weg.code})`);
const ueberStatus = await rufe(`/workspace/api/aufgaben/${idDauer}`,
{ method: "PATCH", keks: anna, body: { status: "erledigt" } });
ok(ueberStatus.code === 409 && ueberStatus.json?.fehler === "dauerhafte_aufgabe",
- `Tuer 2 (Status) jetzt auch (${ueberStatus.code} ${ueberStatus.json?.fehler})`
+ `und der Status ist zu (${ueberStatus.code} ${ueberStatus.json?.fehler})`
+ " — das war VanVans Befund");
/* ANFANGEN DARF SIE SEHR WOHL. Auch eine stehende Aufgabe hat
@@ -507,14 +513,40 @@ melde("\n=== Fertig machen und bewerten ===");
ok(wiederDa === "angenommen",
` zurueckgedreht steht Anna wieder auf „angenommen" (${wiederDa})`);
- const arbeit = await rufe(`/workspace/api/aufgaben/${idPool}/mein-stand`, { method: "POST", keks: bea,
- body: { zustand: "arbeit" } });
- /* DER WEG BLEIBT BESTEHEN, auch ohne Knopf: Er ist die Schranke
- fuer den, der die Schnittstelle direkt anspricht. */
+ /* ==== BEIDE ZUSTAENDE, NICHT NUR HTTP 200 (03.10.2026) ==========
+
+ Hier stand der Weg ueber `/mein-stand` und daneben nur die
+ Frage, ob er mit 200 antwortet. GENAU DAS hat VanVans Fehler
+ durchgewunken: Die Zuteilung sprang auf „in Bearbeitung", der
+ Aufgabenstatus blieb auf „offen" -- und die Pruefung sagte ok,
+ weil sie ihn nie angesehen hat.
+
+ Jetzt geht es ueber den Status, und gemessen werden BEIDE
+ Seiten. Eine Pruefung, die nur eine Haelfte ansieht, kann den
+ Widerspruch gar nicht finden. */
+ const standVonBea = () => {
+ const x = new DatabaseSync(process.env.WORKSPACE_DB);
+ const a = x.prepare("SELECT status FROM aufgaben WHERE id = ?").get(idPool);
+ const z = x.prepare(
+ "SELECT zustand FROM aufgaben_zuteilung WHERE aufgabe_id = ? AND person_id = ?")
+ .get(idPool, idBea);
+ x.close();
+ return { status: a?.status, zustand: z?.zustand };
+ };
+ const arbeit = await rufe(`/workspace/api/aufgaben/${idPool}`, { method: "PATCH", keks: bea,
+ body: { status: "arbeit" } });
+ const beideArbeit = standVonBea();
ok(arbeit.code === 200, `Bea setzt "in Bearbeitung" (HTTP ${arbeit.code})`);
- const fertig = await rufe(`/workspace/api/aufgaben/${idPool}/mein-stand`, { method: "POST", keks: bea,
- body: { zustand: "erledigt" } });
+ ok(beideArbeit.status === "arbeit" && beideArbeit.zustand === "arbeit",
+ ` und BEIDES steht auf "in Arbeit" (Aufgabe ${beideArbeit.status}, `
+ + `Zuteilung ${beideArbeit.zustand}) — das war VanVans Befund`);
+
+ const fertig = await rufe(`/workspace/api/aufgaben/${idPool}`, { method: "PATCH", keks: bea,
+ body: { status: "erledigt" } });
+ const beideFertig = standVonBea();
ok(fertig.code === 200, `und danach "erledigt" (HTTP ${fertig.code})`);
+ ok(beideFertig.status === "erledigt" && beideFertig.zustand === "erledigt",
+ ` und wieder beides (Aufgabe ${beideFertig.status}, Zuteilung ${beideFertig.zustand})`);
/* DIE DREI RUECKMELDUNGEN AUS ABSCHNITT 5. */
const leer = await rufe(`/workspace/api/aufgaben/${idPool}/bewerten`, { method: "POST", keks: chef,
diff --git a/server/workspace-zuteilung.js b/server/workspace-zuteilung.js
index 4616afc3..e154c198 100644
--- a/server/workspace-zuteilung.js
+++ b/server/workspace-zuteilung.js
@@ -760,61 +760,38 @@ for (const [weg, entscheidung] of [["annehmen", "ja"], ["ablehnen", "nein"]]) {
});
}
-/* ---- Meinen eigenen Stand setzen ------------------------------------ */
-zuteilungRouter.post("/workspace/api/aufgaben/:id/mein-stand", (req, res) => {
- try {
- const a = holen(req, res); if (!a) return;
- const z = meine(a.id, req.person.id);
- if (!z) return res.status(403).json({ fehler: "nicht_zugeteilt" });
+/* ==== HIER STAND `/mein-stand` (03.10.2026 entfernt) ==============
- const ziel = String(req.body?.zustand ?? "").trim();
- /* NUR DIE DREI, DIE MAN SELBST SETZEN DARF. "offen" zurückzudrehen
- hieße, die eigene Zusage zu löschen; "abgelehnt" hat einen
- eigenen Weg, weil es eine Begründung braucht. */
- if (!["angenommen", "arbeit", "erledigt"].includes(ziel)) {
- return res.status(400).json({ fehler: "ungueltiger_zustand" });
- }
- if (z.zustand === "abgelehnt") return res.status(409).json({ fehler: "abgelehnt" });
+ VanVan im Support, Meldung #8: „Wenn man auf ich fange an drückt
+ steht dort in Bearbeitung und wenn man auf fertig drückt dann wird
+ es zu erledigt. DIE AUFGABE BLEIBT ABER IM STATUS OFFEN STEHEN."
- /* ==== EINE DAUERHAFTE AUFGABE WIRD NICHT FERTIG (30.09.2026) ====
+ Gestern habe ich die zwei Knöpfe entfernt, die diese Route riefen,
+ und daneben geschrieben: „Der Weg bleibt bestehen — er ist die
+ Schranke, falls ihn jemand direkt anspricht."
- VanVan im Support: „… dass die Aufgabe dauerhaft sein soll und
- somit nicht vom Modi in den Status erledigt gesetzt werden
- kann."
+ DAS WAR EINE AUSREDE, KEINE BEGRÜNDUNG. Eine Route ist keine
+ Schranke gegen sich selbst. Sie setzte weiterhin NUR
+ `aufgaben_zuteilung.zustand` und ließ `aufgaben.status` stehen —
+ also genau den Zustand, den VanVan gemeldet hat. Unsichtbar
+ gemacht, nicht abgeschafft.
- Sie ist keine Aufgabe, die man abarbeitet, sondern eine, die
- man TUT. „Neue begruessen" ist nicht fertig, wenn man es einmal
- gemacht hat.
+ NACHGEMESSEN, BEVOR SIE WEGKAM: Kein einziger Aufruf mehr im
+ ausgelieferten Browsercode (`grep` über alle JS- und HTML-Dateien
+ des Workspace). Nur zwei Prüfungen benutzten sie — und eine davon
+ nickte den Fehler sogar ab: Sie setzte „in Bearbeitung" und prüfte
+ HTTP 200, nie den Aufgabenstatus daneben.
- „ICH FANGE AN" BLEIBT ERLAUBT. Auch eine stehende Aufgabe hat
- einen Anfang, und der Unterschied zwischen „angenommen" und „in
- Arbeit" sagt etwas. Gesperrt ist nur das Abhaken.
+ WAS STATTDESSEN GILT: `PATCH /workspace/api/aufgaben/:id` mit
+ `{ status }`. Er setzt den Status UND zieht die Zuteilung mit
+ (`zuteilungenNachStatus`), kennt dieselbe Sperre für dauerhafte
+ Aufgaben und dieselbe Rechteprüfung. Eine Frage, eine Antwort.
- DIE SPERRE STEHT HIER UND NICHT NUR IM BROWSER. Ein fehlender
- Knopf ist eine Bitte; abgelehnt wird am Server -- wer die
- Schnittstelle direkt anspricht, kaeme sonst durch.
+ ENTFERNT STATT AUSKOMMENTIERT — dieselbe Entscheidung wie bei
+ `/vorlagen/hilfe` am 01.09.: Eine Route, die niemand mehr aufruft,
+ wird beim nächsten Mal für lebenden Code gehalten und mitgepflegt.
+ ================================================================== */
- BEENDET WIRD SIE VON DER LEITUNG, ueber den Status der Aufgabe
- selbst. Eine Pflicht, die niemand mehr beenden kann, waere eine
- Falle statt einer Regel. */
- if (ziel === "erledigt" && a.dauerhaft) {
- return res.status(409).json({ fehler: "dauerhafte_aufgabe" });
- }
-
- db().prepare(`UPDATE aufgaben_zuteilung
- SET zustand = ?, erledigt_am = ?
- WHERE id = ?`).run(ziel, ziel === "erledigt" ? jetzt() : null, z.id);
-
- protokolliere("aufgabe_stand", {
- personId: req.person.id, rolle: req.person.rolle, ip: echteIp(req),
- detail: `#${a.id} ${ziel}`.slice(0, 120),
- });
- res.json({ ok: true, zustand: ziel });
- } catch (f) {
- console.error("[zuteilung] mein-stand:", f?.message);
- res.status(503).json({ fehler: "nicht_verfuegbar" });
- }
-});
/* ---- Bewerten (Abschnitt 5) ----------------------------------------- */
zuteilungRouter.post("/workspace/api/aufgaben/:id/bewerten", (req, res) => {
diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html
index 6fdcd544..09f440b0 100644
--- a/workspace/anruf-probe.html
+++ b/workspace/anruf-probe.html
@@ -16,8 +16,8 @@
verdeckt. Gefunden hat es pruef-struktur.
Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. -->
-
-
+
+
-
+