From ef911691b7deef0fe93d0695f0fab3600896a605 Mon Sep 17 00:00:00 2001 From: Dogfather Date: Sat, 3 Oct 2026 11:31:18 +0200 Subject: [PATCH] Der zweite Weg ist weg -- nicht nur sein Knopf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VanVan im Support, Meldung #8: „Wenn man auf ich fange an drueckt steht dort in Bearbeitung und wenn man auf fertig drueckt dann wird es zu erledigt. DIE AUFGABE BLEIBT ABER IM STATUS OFFEN STEHEN." GESTERN HABE ICH DIE HALBE ARBEIT GEMACHT und daneben eine Ausrede geschrieben. Die zwei Knoepfe kamen weg, und in den Kommentar kam: „Der Weg `/mein-stand` bleibt bestehen -- er ist die Schranke, falls ihn jemand direkt anspricht." Eine Route ist keine Schranke gegen sich selbst. Sie setzte weiterhin NUR `aufgaben_zuteilung.zustand` und liess `aufgaben.status` stehen -- also genau den Widerspruch, den VanVan beschrieben hat. Ich hatte ihn unsichtbar gemacht, nicht abgeschafft: kein Knopf mehr, das Verhalten unveraendert im System. GEFUNDEN BEIM NACHMESSEN AM LAUFENDEN SERVER, nicht beim Schreiben. Filipe hat auf den Screenshot gezeigt und gesagt, es sei noch nicht in Ordnung. Statt meine Pruefungen zu zitieren habe ich die Route gelesen -- und dort stand es. NACHGEMESSEN, BEVOR SIE WEGKAM: Kein einziger Aufruf mehr im ausgelieferten Browsercode (grep ueber alle JS- und HTML-Dateien des Workspace). Nur zwei Pruefungen benutzten sie. UND EINE DAVON NICKTE DEN FEHLER AB. In pruef-zuteilung stand: Bea setzt "in Bearbeitung" (HTTP 200) und danach "erledigt" (HTTP 200) Zwei gruene Haken ueber genau dem Verhalten, das gemeldet wurde -- weil sie nur den Rueckgabewert ansahen und nie den Aufgabenstatus daneben. Eine Pruefung, die nur eine Haelfte misst, kann den Widerspruch gar nicht finden. Jetzt steht dort: Bea setzt "in Bearbeitung" (HTTP 200) und BEIDES steht auf "in Arbeit" (Aufgabe arbeit, Zuteilung arbeit) — das war VanVans Befund und danach "erledigt" (HTTP 200) und wieder beides (Aufgabe erledigt, Zuteilung erledigt) WAS JETZT GILT: `PATCH /workspace/api/aufgaben/:id` mit `{ status }`. Er setzt den Status UND zieht die Zuteilung mit (`zuteilungenNachStatus`), kennt dieselbe Sperre fuer dauerhafte Aufgaben und dieselbe Rechtepruefung. Eine Frage, eine Antwort. ENTFERNT STATT AUSKOMMENTIERT -- dieselbe Entscheidung wie bei `/vorlagen/hilfe` am 01.09.: Eine Route, die niemand mehr aufruft, wird beim naechsten Mal fuer lebenden Code gehalten und mitgepflegt. EIN SCHRECKMOMENT UNTERWEGS, der sich als Messfehler herausstellte: Nach der Umstellung meldete pruef-bewerbung-aufgaben eine 404 beim Abhaken -- also der Verdacht, dass eine ZUGETEILTE Aufgabe ueber den Statusweg gar nicht erreichbar ist und ich gerade etwas kaputt gemacht haette. Nachgemessen statt geglaubt: Die Aufgabe steht in ihrer Liste, der PATCH antwortet 200. Die rote Zeile war eine DRITTE Stelle, die ich beim Umstellen uebersehen hatte und die noch auf die alte Route zeigte. Zwei Minuten Messung statt einer Stunde Suche an der falschen Stelle. GEPRUEFT pruef-zuteilung ok, mit zwei neuen Zeilen, die BEIDE Zustaende messen den zweiten Weg (mein-stand) gibt es nicht mehr (404) pruef-bewerbung-aufgaben 178 ok pruef-struktur 102 ok, 414 -> 413 Routen pruef-aufgabenbrett · pruef-modi-katalog 159 · pruef-aufgaben-vorlagen 60 Co-Authored-By: Claude Opus 5 --- server/pruef-bewerbung-aufgaben.mjs | 23 +++++---- server/pruef-zuteilung.mjs | 52 ++++++++++++++++---- server/workspace-zuteilung.js | 73 ++++++++++------------------- workspace/anruf-probe.html | 10 ++-- workspace/app.webmanifest | 8 ++-- workspace/assets/js/zuteilung.js | 16 ++++++- workspace/aufgaben.html | 38 +++++++-------- workspace/automation.html | 32 ++++++------- workspace/befinden.html | 34 +++++++------- workspace/bereich.html | 44 ++++++++--------- workspace/bewerben.html | 38 +++++++-------- workspace/bewerbungen.html | 36 +++++++------- workspace/buehne.html | 6 +-- workspace/calls.html | 34 +++++++------- workspace/chat.html | 40 ++++++++-------- workspace/content.html | 34 +++++++------- workspace/crew-index.html | 12 ++--- workspace/crew.webmanifest | 8 ++-- workspace/dateien.html | 34 +++++++------- workspace/entwicklung.html | 36 +++++++------- workspace/hilfe.html | 30 ++++++------ workspace/index.html | 10 ++-- workspace/kalender.html | 34 +++++++------- workspace/leistung.html | 32 ++++++------- workspace/manager-ziele.html | 28 +++++------ workspace/material.html | 32 ++++++------- workspace/notizen.html | 28 +++++------ workspace/personen.html | 32 ++++++------- workspace/profil.html | 36 +++++++------- workspace/reaktion.html | 38 +++++++-------- workspace/rechte.html | 34 +++++++------- workspace/report.html | 36 +++++++------- workspace/scouting.html | 32 ++++++------- workspace/start.html | 32 ++++++------- workspace/startcheck.html | 34 +++++++------- workspace/steckbrief.html | 36 +++++++------- workspace/support.html | 28 +++++------ workspace/tafel.html | 6 +-- workspace/talente.html | 36 +++++++------- workspace/team.html | 32 ++++++------- workspace/teamlage.html | 34 +++++++------- workspace/teilen.html | 30 ++++++------ workspace/treff-moderation.html | 32 ++++++------- workspace/treff-regeln.html | 32 ++++++------- workspace/uebersicht.html | 32 ++++++------- workspace/unsere-seiten.html | 30 ++++++------ workspace/unterstuetzen.html | 32 ++++++------- workspace/werdegang.html | 32 ++++++------- workspace/willkommen.html | 30 ++++++------ workspace/wissen.html | 34 +++++++------- 50 files changed, 779 insertions(+), 753 deletions(-) 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`. --> - - + + - +