From 3bab6d9fbf57ccf616b12a706894deffd9b9519d Mon Sep 17 00:00:00 2001 From: Dogfather Date: Sun, 6 Sep 2026 16:50:30 +0200 Subject: [PATCH] Der Knopf auf der Umzugsseite ist jetzt ein echter Verweis Hinweis von Filipe: Wenn etwas wie ein Knopf aussieht, muss man auch draufdruecken koennen. Er hatte recht. Meine urspruengliche Begruendung - die Adresse solle nur zum Lesen dastehen, damit niemand versehentlich ein Lesezeichen auf den alten Weg setzt - traegt nicht: Wer klickt, landet auf der NEUEN Adresse und setzt sein Lesezeichen genau dort. Ein Element, das wie ein Knopf aussieht und sich nicht wie einer verhaelt, ist eine Falle. Der Knopf hat jetzt einen Hover- und einen Tastatur-Fokuszustand, und beide Bewegungen entfallen bei prefers-reduced-motion. Die Pruefung geht dabei einen Schritt weiter als vorher: Sie prueft nicht mehr nur, WELCHE Anfragen zugeordnet werden, sondern ruft die Middleware wirklich auf und sieht sich die ANTWORT an. Denn die Zuordnung kann stimmen und die Seite trotzdem kaputt sein: - ein Platzhalter, der woertlich in der Seite steht statt eingesetzt zu werden - ein Knopf ohne Verweis (genau der Fall, den Filipe gemeldet hat) - HTML statt JSON fuer /workspace/api/ - ein noch offener Tab wuerde sonst die Hinweisseite als Daten zu lesen versuchen - und die wichtigste: dass die NEUE Adresse durchgelassen wird 31 Pruefungen, alle gruen. Gegenprobe gemacht: Dreht man den Knopf zurueck zu einem div ohne Verweis, meldet die Pruefung 2 Fehler - sie haette den gemeldeten Mangel also selbst gefunden. Co-Authored-By: Claude Opus 5 --- server/pruef-workspace-umzug.mjs | 46 +++++++++++++++++++++++++++++--- server/workspace-umzug.js | 23 +++++++++++----- 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/server/pruef-workspace-umzug.mjs b/server/pruef-workspace-umzug.mjs index 04c73f76..b34dc9c6 100644 --- a/server/pruef-workspace-umzug.mjs +++ b/server/pruef-workspace-umzug.mjs @@ -21,7 +21,7 @@ Aufruf: node server/pruef-workspace-umzug.mjs ===================================================================== */ -import { istAlteWorkspaceAdresse, NEUE_ADRESSE } from "./workspace-umzug.js"; +import { istAlteWorkspaceAdresse, workspaceUmzug, NEUE_ADRESSE } from "./workspace-umzug.js"; /* [Host, Pfad, erwartet, Begruendung] */ const FAELLE = [ @@ -66,6 +66,46 @@ for (const [host, pfad, erwartet, grund] of FAELLE) { } } +/* ---- Die tatsaechliche ANTWORT pruefen, nicht nur die Entscheidung ---- + Die Zuordnung oben kann stimmen und die Seite trotzdem kaputt sein: ein + nicht eingesetzter Platzhalter, ein Knopf ohne Verweis, HTML statt JSON + fuer die Schnittstelle. Deshalb wird die Middleware hier wirklich + aufgerufen -- mit nachgebildeten Anfrage- und Antwortobjekten. */ +const pruefe = (bedingung, was) => { geprueft++; if (!bedingung) fehler.push(was); }; + +function antwortHolen(host, pfad) { + const req = { get: (n) => (String(n).toLowerCase() === "host" ? host : undefined), path: pfad, originalUrl: pfad }; + const a = { code: null, art: null, koerper: null, weiter: false }; + const res = { + status(c) { a.code = c; return this; }, + type(t) { a.art = t; return this; }, + send(k) { a.koerper = k; return this; }, + json(k) { a.art = "json"; a.koerper = k; return this; }, + }; + workspaceUmzug(req, res, () => { a.weiter = true; }); + return a; +} + +const seite = antwortHolen("dogfather-universe.com", "/workspace/"); +pruefe(seite.code === 410, `Hinweisseite antwortet mit ${seite.code}, erwartet 410`); +pruefe(seite.art === "html", `Hinweisseite hat Art ${seite.art}, erwartet html`); +pruefe(String(seite.koerper).includes(NEUE_ADRESSE + "/workspace/"), + "Hinweisseite nennt die neue Adresse nicht als Ziel"); +pruefe(/]+class="adresse"[^>]+href=/.test(String(seite.koerper)), + "Der Knopf ist kein anklickbarer Verweis — er saehe nur aus wie einer"); +pruefe(!String(seite.koerper).includes("${"), + "Ein Platzhalter wurde nicht eingesetzt und steht woertlich in der Seite"); + +const api = antwortHolen("dogfather-universe.com", "/workspace/api/aufgaben"); +pruefe(api.code === 410, `Schnittstelle antwortet mit ${api.code}, erwartet 410`); +pruefe(api.art === "json", + "Schnittstelle liefert kein JSON — ein noch offener Tab wuerde HTML als Daten zu lesen versuchen"); +pruefe(api.koerper?.neueAdresse === NEUE_ADRESSE, "JSON nennt die neue Adresse nicht"); + +const durch = antwortHolen("workspace.dogfather-universe.com", "/workspace/"); +pruefe(durch.weiter === true, "NEUE Adresse wurde abgefangen — der Workspace waere tot"); +pruefe(durch.code === null, "NEUE Adresse bekam eine Antwort, statt durchgelassen zu werden"); + /* Gegenprobe: Kann diese Pruefung ueberhaupt "nein" sagen? Ein Fall, von dem wir wissen, dass er falsch ist, MUSS auffallen. */ const gegenprobe = istAlteWorkspaceAdresse("dogfather-universe.com", "/workspace/") === true @@ -77,8 +117,8 @@ const zielStimmt = NEUE_ADRESSE === "https://workspace.dogfather-universe.com"; geprueft++; if (!zielStimmt) fehler.push(`Ziel ist "${NEUE_ADRESSE}", erwartet https://workspace.dogfather-universe.com`); -const SOLL = FAELLE.length + 1; -console.log(`${geprueft} Faelle geprueft (erwartet ${SOLL}), ${fehler.length} Beanstandungen.`); +const SOLL = FAELLE.length + 11; +console.log(`${geprueft} Pruefungen gelaufen (erwartet ${SOLL}), ${fehler.length} Beanstandungen.`); console.log(`Gegenprobe (alt abgeschaltet, neu erreichbar): ${gegenprobe ? "ja" : "NEIN"}`); for (const f of fehler) console.log(" FEHL " + f); diff --git a/server/workspace-umzug.js b/server/workspace-umzug.js index 79db0c4b..2ef3fb04 100644 --- a/server/workspace-umzug.js +++ b/server/workspace-umzug.js @@ -71,9 +71,15 @@ export function istAlteWorkspaceAdresse(hostKopfzeile, pfad) { /* Kurze Seite statt einer nackten Fehlermeldung. Wer hier landet, hat einen alten Link oder eine alte Verknuepfung -- er soll erfahren, wohin der Workspace gezogen ist, statt vor einem leeren Fenster zu sitzen. - Bewusst ohne Verweis zum Anklicken: Die Adresse steht zum Lesen da, - damit niemand aus Versehen ein neues Lesezeichen auf den alten Weg - setzt. Augenschonend dunkel wie der Rest der Seite. */ + + Der Knopf ist ein echter Verweis (Korrektur 06.09.2026, Hinweis von + Filipe). Zuerst stand die Adresse nur zum Lesen da, mit der Begruendung, + niemand solle versehentlich ein Lesezeichen auf den alten Weg setzen. + Das Argument traegt nicht: Wer klickt, landet auf der NEUEN Adresse und + setzt sein Lesezeichen genau dort. Etwas, das wie ein Knopf aussieht, + muss sich auch wie einer verhalten -- alles andere ist eine Falle. + + Augenschonend dunkel wie der Rest der Seite. */ const HINWEIS = ` @@ -87,15 +93,20 @@ const HINWEIS = ` h1{font-size:1.5rem;margin:0 0 1rem;font-weight:650} p{color:#9aa6b2;margin:0 0 1rem} .adresse{display:inline-block;margin-top:.5rem;padding:.85rem 1.4rem; - background:#0674b9;color:#fff;border-radius:10px; - font-weight:600;letter-spacing:.01em;word-break:break-all} + background:#0674b9;color:#fff;border-radius:10px;text-decoration:none; + font-weight:600;letter-spacing:.01em;word-break:break-all; + transition:background .15s ease,transform .15s ease} + .adresse:hover,.adresse:focus-visible{background:#0a86d4;transform:translateY(-1px)} + .adresse:focus-visible{outline:3px solid #7fd0ec;outline-offset:3px} + @media (prefers-reduced-motion:reduce){.adresse{transition:none} + .adresse:hover,.adresse:focus-visible{transform:none}}

Der Creator Workspace ist umgezogen

Diese Adresse gibt es nicht mehr. Der Workspace hat jetzt eine eigene Adresse — dadurch lässt er sich als richtige App installieren.

Bitte künftig hier anmelden:

-
workspace.dogfather-universe.com
+ workspace.dogfather-universe.com
`; /** Express-Zwischenschritt: beantwortet die alte Adresse mit 410 Gone. */