From c4bdc1c4c26058e31e368debb962f38515c48a33 Mon Sep 17 00:00:00 2001 From: Dogfather Date: Tue, 6 Oct 2026 22:23:22 +0200 Subject: [PATCH] Kapitel 04: der Knopf heisst "Hingehen" -- und das Datum war gar keins Zwei kleine Dinge aus dem Bauplan, Kapitel 04. Das zweite war ein echter Fehler, und er war auf dem Weg nach draussen. "AKTUALISIERT AM" -- UND DANN STUENDE DA EIN ZEITSTEMPEL `datumKurz` prueft mit einem Ausdruck, der ein `$` am Ende hatte. Die Stufenkarte schickt einen reinen Tag ("2026-10-13"), die Karte aber einen ganzen Zeitstempel ("2026-10-06T18:22:31.123Z", aus `new Date().toISOString()` -- siehe anleitung-tabellen.js und workspace-anleitung.js). Die zweite Form bestand die Pruefung nicht und waere UNVERAENDERT durchgereicht worden: Auf der Karte haette woertlich "aktualisiert am 2026-10-06T18:22:31.123Z" gestanden. Kein Fehler, kein Absturz, keine rote Meldung -- genau die Sorte Schaden, die `node --check` nicht sehen kann, und die hier auch niemand gesehen haette, weil die Zeile nur in der Pflege steht. Gefunden hat es keine Eingebung, sondern das Nachsehen, WAS der Server wirklich schickt. Die Pruefung fragt ihn jetzt selbst und rechnet nicht gegen eine Erinnerung. "HINGEHEN" STATT "ZUR KACHEL" So steht es im Plan, und es ist die Sprache der Seite: Sie duzt, begruesst mit Namen und sagt "Schoen, dass du da bist". "Kachel" ist das Wort, mit dem wir INTERN ueber die Dinge reden; wer neu ist, hat es noch nie gehoert. "AKTUALISIERT AM" STEHT NUR IN DER PFLEGE -- eine Entscheidung, die der Plan so nicht trifft. Fuer ein Mitglied beantwortet das Datum keine Frage; DASS sich etwas geaendert hat, sagt ihm die Marke "Neu" daneben, die von selbst wieder verschwindet. Fuer DogFather beantwortet es eine sehr konkrete: "Habe ich die schon angefasst?" Eine Zeile, die auf jeder der 34 Karten steht und niemanden angeht, zieht den Blick von den drei Zeilen darueber weg. .an-karte__stand ist deshalb klein und still -- --text-still, dieselbe Stimme wie die Schilder "Wozu"/"Merke", deren Kontrast auf dieser Flaeche schon geprueft ist. Keine neue, noch blassere Farbe, die niemand bemerkt, bis sie nicht mehr lesbar ist. AUSSERDEM: pruef-community-sicht war rot, und zwar zu Recht. Die handgefuehrte Liste COMMUNITY_SEITEN kannte die neue Einweisungsseite nicht und meldete "ZU VIEL: anleitung.html". Das ist kein Mangel der Liste, sondern ihr Zweck -- sie nennt die ueberzaehlige Seite selbst. anleitung.html ist jetzt eingetragen, mit Begruendung, und bei willkommen.html steht dran, dass sie nur noch weiterleitet. 13 -> 14 Seiten, gruen. GEPRUEFT (pruef-anleitung 188 -> 196): - der Weg-Knopf heisst "Hingehen" (1x), "Zur Kachel" nirgends (0x) - "aktualisiert am" haengt an der Pflege (1x), nicht an jeder Karte - .an-karte__stand ist wirklich gestaltet - der Server schickt "geaendert" als ganzen Zeitstempel (14 von 14) - ...und die Karte macht daraus einen lesbaren Tag (14 von 14) - der reine Tag der Stufenkarte bleibt richtig (13.10.2026) - Gegenprobe: was kein Datum ist, wird auch zu keinem gemacht Die Rechenvorschrift wird dafuer AUSGEFUEHRT und nicht mit einem Muster angesehen -- ein Muster waere eine zweite, ungenaue Nachbildung. Und die Voraussetzung ("der Server schickt wirklich einen Zeitstempel") wird gemessen, nicht angenommen; ohne sie waere die Zeile darunter eine Rechnung gegen eine Erinnerung, und die altert. GEGENPROBE GEFAHREN: `$` wieder eingebaut -> "...und die Karte macht daraus einen lesbaren Tag (0 von 14)", EXIT=1, und die Zahl bleibt 196. Eine Pruefung, die immer bestaetigt, bestaetigt nichts. Dazu gruen, gezielt und nicht als Gesamtlauf: pruef-css-klassen 4698 Klassenverwendungen, die neue Klasse ist gestaltet; 42 Stellen unter 11,5 px wie bisher (die neue Zeile ist 12,16 px) pruef-community-sicht 10 Pruefungen, 0 Fehler pruef-haus-trennung 107 geprueft, 0 Fehler -- das Agenturhaus bleibt von der geaenderten Client-Datei unberuehrt pruef-deutsche-texte 12 Pruefungen, 0 Fehler Co-Authored-By: Claude Opus 5 --- server/pruef-anleitung.mjs | 82 ++++++++++++++++++++++++++++++ server/pruef-community-sicht.mjs | 16 +++++- workspace/anleitung.html | 28 +++++----- workspace/anruf-probe.html | 10 ++-- workspace/app.webmanifest | 8 +-- workspace/assets/css/anleitung.css | 21 ++++++++ workspace/assets/js/anleitung.js | 46 +++++++++++++++-- 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 | 38 +++++++------- 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/wissen.html | 34 ++++++------- 50 files changed, 847 insertions(+), 690 deletions(-) diff --git a/server/pruef-anleitung.mjs b/server/pruef-anleitung.mjs index 67bd5023..3eabf484 100644 --- a/server/pruef-anleitung.mjs +++ b/server/pruef-anleitung.mjs @@ -1442,6 +1442,88 @@ melde("\n=== Die Pflegeleiste haengt an beiden Ausgaengen ==="); `…und es gibt genau diese zwei Ausgaenge (${ausgaenge})`); } +/* ===================================================================== + KAPITEL 04 — DER KNOPF UND DER STAND DER KARTE + --------------------------------------------------------------------- + Zwei kleine Dinge aus dem Bauplan, und beide koennen lautlos falsch + sein: + + 1. DER KNOPF HEISST „HINGEHEN". So steht es im Plan, und es ist die + Sprache der Seite: Sie duzt und begruesst mit Namen. „Zur Kachel" + ist unser internes Wort; wer neu ist, hat „Kachel" noch nie + gehoert. Geprueft wird die ZAHL (genau einmal da, altes Wort + keinmal), nicht das blosse Vorkommen -- sonst waere die Zeile auch + gruen, wenn beide Woerter nebeneinander im Code stuenden. + + 2. „AKTUALISIERT AM" MUSS EIN DATUM SEIN, KEIN ZEITSTEMPEL. + Das ist der eigentliche Grund fuer diesen Block. `datumKurz` + bekommt ZWEI Formen herein, die nur am Anfang gleich aussehen: + die Stufenkarte schickt einen reinen Tag ("2026-10-13"), die + Karte einen ganzen Zeitstempel ("2026-10-06T18:22:31.123Z"). Die + Rechenvorschrift hatte ein `$` am Ende und liess die zweite Form + deshalb UNVERAENDERT durch: Auf der Karte stuende dann woertlich + „aktualisiert am 2026-10-06T18:22:31.123Z". Kein Fehler, kein + Absturz, keine rote Meldung -- genau die Sorte Schaden, die ein + `node --check` nicht sehen kann. + + DIE VORAUSSETZUNG WIRD GEMESSEN, NICHT ANGENOMMEN: Dass der Server + wirklich einen Zeitstempel schickt, fragt diese Pruefung beim Server + nach (erste Zeile). Ohne das waere die Zeile darunter eine Rechnung + gegen eine Erinnerung -- und die altert. + ===================================================================== */ +melde("\n=== Kapitel 04: der Knopf und der Stand der Karte ==="); +{ + const quelle = readFileSync( + new URL("../workspace/assets/js/anleitung.js", import.meta.url), "utf8"); + const nurCode = quelle + .replace(/\/\*[\s\S]*?\*\//g, " ") + .replace(/(^|[^:])\/\/[^\n]*/g, "$1 "); + + const hin = (nurCode.match(/'an-karte__weg', 'Hingehen'/g) || []).length; + ok(hin === 1, `der Weg-Knopf heißt „Hingehen" (${hin}x)`); + const altesWort = (nurCode.match(/Zur Kachel/g) || []).length; + ok(altesWort === 0, `…und „Zur Kachel" steht nirgends mehr (${altesWort}x)`); + + const nurPflege = (nurCode.match(/pflegeAn && eintrag\.geaendert/g) || []).length; + ok(nurPflege === 1, + `„aktualisiert am" hängt an der Pflege und steht nicht auf jeder Karte (${nurPflege}x)`); + + const css = readFileSync( + new URL("../workspace/assets/css/anleitung.css", import.meta.url), "utf8"); + ok(/\.an-karte__stand\s*\{/.test(css), + "…und hat eine eigene, stille Schrift (.an-karte__stand in der CSS)"); + + /* Die Rechenvorschrift wird AUSGEFUEHRT, nicht mit einem Muster + angesehen -- ein Muster waere eine zweite, ungenaue Nachbildung. */ + const anfang = quelle.indexOf("const datumKurz = (iso) => {"); + const ende = anfang < 0 ? -1 : quelle.indexOf("\n };", anfang); + braucht(anfang >= 0 && ende > anfang, + "datumKurz ist in anleitung.js nicht mehr zu finden — die Prüfung kann ihre Rechnung nicht holen"); + const kiste = {}; + vm.createContext(kiste); + vm.runInContext(`${quelle.slice(anfang, ende + 5)}\nglobalThis.__dk = datumKurz;\n`, + kiste, { filename: "datumKurz" }); + const datumKurz = kiste.__dk; + braucht(typeof datumKurz === "function", + "datumKurz ließ sich nicht ausführen — die Rechnung ist nicht zu messen"); + + const probe = (await holen("gast", CREW_HOST)).j?.karten || []; + braucht(probe.length > 0, + `keine einzige Karte da — ohne sie ist die Form von „geaendert" nicht zu messen`); + const mitZeit = probe.filter( + (k) => /^\d{4}-\d{2}-\d{2}T\d{2}:/.test(String(k.geaendert || ""))).length; + ok(probe.length > 0 && mitZeit === probe.length, + `der Server schickt „geaendert" als ganzen Zeitstempel (${mitZeit} von ${probe.length})`); + const lesbar = probe.filter( + (k) => /^\d{2}\.\d{2}\.\d{4}$/.test(datumKurz(k.geaendert))).length; + ok(probe.length > 0 && lesbar === probe.length, + `…und die Karte macht daraus einen lesbaren Tag (${lesbar} von ${probe.length})`); + ok(datumKurz("2026-10-13") === "13.10.2026", + "der reine Tag der Stufenkarte bleibt richtig (13.10.2026)"); + ok(datumKurz("demnächst") === "demnächst" && datumKurz("") === "", + "Gegenprobe: was kein Datum ist, wird auch zu keinem gemacht"); +} + /* ---------- Abschluss ------------------------------------------------ */ try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ } console.log(`\n${fehler ? "FEHLER: " + fehler : "Alles in Ordnung"} — ${geprueft} Prüfungen`); diff --git a/server/pruef-community-sicht.mjs b/server/pruef-community-sicht.mjs index 518c68f9..1c82a375 100644 --- a/server/pruef-community-sicht.mjs +++ b/server/pruef-community-sicht.mjs @@ -97,6 +97,16 @@ melde("=== 1. Was ueberhaupt offensteht ==="); DAS IST DIESELBE BAUART wie die festgelegten Kachelfarben: nicht „ungefaehr so viele", sondern „genau diese, und hier steht warum". */ const COMMUNITY_SEITEN = [ + /* DIE EINWEISUNG kam am 06.10.2026 dazu (Bauplan „Willkommen & + Anleitung"). Sie ist fuer ein Mitglied die ERSTE Seite ueberhaupt: + Die Kachel „Willkommen & Anleitung" steht breit und vorne in der + Gruppe „Community" und fuehrt hierher. Was darauf steht, erklaert + genau die vierzehn Kacheln, die dieses Mitglied hat -- nichts + darueber hinaus; das misst pruef-anleitung in beide Richtungen. + + Diese Zeile hat gefehlt, und die Pruefung ist deshalb rot + geworden -- richtig so: Genau dafuer gibt es sie. */ + "anleitung.html", // Willkommen & Anleitung (seit 06.10.2026) "bereich.html", // die Bretter (Highlights, Anschlag, Wunschliste ...) "bewerben.html", // Mitmachen "chat.html", // der Treff @@ -119,7 +129,11 @@ const COMMUNITY_SEITEN = [ "treff-regeln.html", // die Regeln des Rudels "unsere-seiten.html", // Draussen "unterstuetzen.html", // Unterstuetzen - "willkommen.html", // die Begruessung + /* Die alte Adresse bleibt offen -- sie leitet seit dem 06.10.2026 + auf anleitung.html weiter. Ein Lesezeichen soll nicht an einer + Schranke enden; die Weiterleitung selbst misst + pruef-willkommen. */ + "willkommen.html", // leitet auf die Anleitung weiter ]; const zuViel = erlaubt.filter((s) => !COMMUNITY_SEITEN.includes(s)); const fehltDa = COMMUNITY_SEITEN.filter((s) => !erlaubt.includes(s)); diff --git a/workspace/anleitung.html b/workspace/anleitung.html index 7b2fbd0d..35facd46 100644 --- a/workspace/anleitung.html +++ b/workspace/anleitung.html @@ -7,17 +7,17 @@ - - - - - + + + + + - - + + @@ -289,16 +289,16 @@ Und anleitung.js braucht es doppelt: Symbol, Farbe, Name und Adresse jeder Karte kommen von dort, nicht vom Server. --> - + - - - - - - + + + + + + diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html index c8268bc5..a90b8487 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`. --> - - + + - +