diff --git a/server/pruef-nachfrage.mjs b/server/pruef-nachfrage.mjs
index 166483af..f9e12ae4 100644
--- a/server/pruef-nachfrage.mjs
+++ b/server/pruef-nachfrage.mjs
@@ -138,12 +138,55 @@ pruef("der Notnagel für alte Browser ist vorhanden",
/** Welche Skripte rufen frageNach auf? OHNE die Datei, die es
* DEFINIERT -- sonst ist die Antwort immer „alle". */
const nutzer = new Set();
+/* EIN AUFRUF HINTER EINER `typeof`-ABFRAGE IST KEINE PFLICHT
+ (24.09.2026 -- und die Pruefung war aus genau diesem Grund rot,
+ ohne dass etwas kaputt war).
+
+ `installieren.js` liegt auf fast jeder Seite und ruft frageNach
+ auf -- aber ausdruecklich nur, wenn es da ist:
+
+ if (typeof window.frageNach === 'function') { … }
+
+ Der Kommentar daneben erklaert seit dem 22.09.2026 genau, warum:
+ Die Datei laeuft auch auf der Anmeldewand, wo nachfrage.js mit
+ Absicht nicht geladen wird. Die Pruefung zaehlte den Aufruf
+ trotzdem als "diese Seite fragt nach" -- und weil installieren.js
+ ueberall liegt, wurde damit JEDE Seite zur fragenden. Ergebnis:
+ fuenf rote Zeilen, kein einziger echter Mangel.
+
+ EINE PRUEFUNG, DIE IMMER ROT IST, IST KEINE PRUEFUNG MEHR -- genau
+ wie eine Warnung, die immer kommt. Ab dem zweiten Mal liest man
+ sie weg, und dann auch die echte.
+
+ Die Unterscheidung ist einfach und haelt: Wer vorher fragt, ob es
+ die Funktion gibt, kommt ohne sie aus. Wer sie einfach aufruft,
+ braucht sie. */
+const geschuetzt = (text) =>
+ /typeof\s+window\.frageNach\s*===?\s*['"]function['"]/.test(text)
+ || /window\.frageNach\s*\?\./.test(text);
+const freiwillig = new Set();
for (const f of skripte) {
if (f === DER_NOTNAGEL) continue;
- if (/\bfrageNach\s*\(/.test(ohneKommentare(lies(join(JS_ORDNER, f))))) nutzer.add(f);
+ const text = ohneKommentare(lies(join(JS_ORDNER, f)));
+ if (!/\bfrageNach\s*\(/.test(text)) continue;
+ if (geschuetzt(text)) { freiwillig.add(f); continue; }
+ nutzer.add(f);
}
pruef("es gibt überhaupt Seiten, die nachfragen", nutzer.size > 0,
`gefunden: ${nutzer.size}`);
+/* WAS HIER HERAUSFAELLT, WIRD BENANNT. Ein stilles Aussortieren
+ waere die bequeme Art, eine Pruefung gruen zu bekommen -- man
+ saehe dann nicht mehr, wie gross die Ausnahme geworden ist. */
+pruef("die geschützten Aufrufe sind benannt und wenige",
+ freiwillig.size <= 3,
+ `ohne Pflicht zur Datei (typeof-Abfrage davor): ${[...freiwillig].join(", ") || "keine"}`);
+/* GEGENPROBE: Ein UNGESCHUETZTER Aufruf muss weiterhin zaehlen --
+ sonst hiesse "alle angeschlossen" nur, dass die Regel niemanden
+ mehr erfasst. */
+pruef("Gegenprobe: ein ungeschützter Aufruf zählt weiterhin",
+ !geschuetzt("frageNach({ titel: 'x' });")
+ && geschuetzt("if (typeof window.frageNach === 'function') frageNach({});"),
+ `${nutzer.size} Dateien rufen ungeschützt auf`);
const ohneDatei = [], totesGewicht = [], fragendeSeiten = [];
let mitNutzung = 0;
@@ -247,7 +290,14 @@ for (const f of skripte) {
const code = ohneKommentare(lies(join(JS_ORDNER, f)));
for (const a of aufrufe(code)) {
gezaehlt++;
- if (!/\btitel\s*:/.test(a)) ohneTitel.push(f);
+ /* AUCH DIE KURZSCHREIBWEISE ZAEHLT (24.09.2026).
+ Gesucht wurde nur `titel:`. In installieren.js steht aber
+ `frageNach({ titel, was: weg, … })` -- die Kurzform, die den
+ Titel aus einer gleichnamigen Variablen nimmt. Gueltiges JS,
+ gesetzter Titel, und trotzdem gemeldet. Eine Pruefung, die eine
+ richtige Schreibweise bemaengelt, bringt einem bei, ihre
+ Meldungen zu ignorieren. */
+ if (!/\btitel\s*[:,}]/.test(a)) ohneTitel.push(f);
if (!/\bwas\s*:/.test(a)) ohneWas.push(f);
}
}
diff --git a/server/pruef-treff-start.mjs b/server/pruef-treff-start.mjs
index 00ed37cb..28711b8b 100644
--- a/server/pruef-treff-start.mjs
+++ b/server/pruef-treff-start.mjs
@@ -169,17 +169,57 @@ melde("=== 1. Was bereitliegt ===");
`${mit} von ${alle.length} Texten nennen DogFather, seine Kanaele oder Casper `
+ `(${Math.round(mit / alle.length * 100)} %)`);
- /* UND DIE VIER BRETTER, DIE DIE COMMUNITY WIRKLICH SIEHT, ganz.
- Auf dem Anschlagbrett, im Treff, in der Wunschliste und bei den
- Highlights gibt es keinen Satz, der ohne ihn auskommt -- sie
- handeln von seinen Streams. */
- for (const b of ["treff", "anschlag", "wunsch", "highlight"]) {
+ /* JEDES BRETT, DAS VORSCHLAEGE HAT, ganz -- sie handeln von
+ seinen Streams, und keiner kommt ohne ihn aus.
+
+ DIE LISTE WIRD ABGELEITET, NICHT ABGESCHRIEBEN (24.09.2026).
+ Hier stand `["treff", "anschlag", "wunsch", "highlight"]`. Am
+ 24.09. fielen die Vorschlaege fuer Highlights weg (Filipe: "da
+ sollen nur die sachen rein kommen die die modis, linke und
+ rechte hand oder dogfather reinsetzen"), und die Pruefliste
+ wusste es nicht: Sie verlangte weiter Texte von einem Brett,
+ das keine mehr hat. Dieselbe Falle wie jede abgeschriebene
+ Liste in diesem Haus -- eine, die niemand pflegt, kann nicht
+ veralten.
+
+ DASS ES UEBERHAUPT WELCHE GIBT, wird eine Zeile tiefer
+ geprueft. Sonst waere "alle geprueft" auch dann gruen, wenn
+ morgen gar kein Brett mehr Vorschlaege haette -- ein
+ uebersprungener Test beweist nichts. */
+ /* DIE ABSICHT BLEIBT, DIE LISTE WIRD GEPRUEFT (berichtigt beim
+ zweiten Anlauf am 24.09.2026).
+
+ Mein erster Versuch nahm einfach ALLE Bretter mit Vorschlaegen.
+ Das war bequem und falsch: "Regeln", "Mitmachen" und "Was
+ ansteht" haben zu Recht Saetze ohne seinen Namen ("Turnier",
+ "Schritt 2: Sag im Rudel, dass du Lust hast") -- fuer die gilt
+ die 60-%-Regel eine Zeile weiter oben, nicht diese hier. Die
+ Pruefung waere dadurch rot geworden, ohne dass etwas kaputt
+ war, und ich haette ihre Aussage veraendert statt ihre Liste zu
+ reparieren.
+
+ Richtig ist die Schnittmenge: die Bretter, die die Community
+ sieht UND die ueberhaupt Vorschlaege haben. Faellt eines weg,
+ faellt es hier lautlos heraus -- deshalb steht direkt darunter,
+ WIE VIELE es sein muessen, und fuer Highlights ausdruecklich,
+ dass es keine mehr hat. */
+ const GEMEINT = ["treff", "anschlag", "wunsch", "highlight"];
+ const mitVorschlaegen = GEMEINT.filter((b) => (TREFF_START[b] || []).length > 0);
+ ok(mitVorschlaegen.length === 3,
+ `${mitVorschlaegen.length} der Bretter, die die Community sieht, haben `
+ + `Vorschlaege (${mitVorschlaegen.join(", ")})`);
+ for (const b of mitVorschlaegen) {
const liste = TREFF_START[b] || [];
const ohne = liste.filter((v) => !BEZUG.test(`${v.titel} ${v.text}`));
ok(liste.length > 0 && ohne.length === 0,
ohne.length ? `${b}: ohne Bezug -- "${ohne[0].titel}"`
: `${b}: alle ${liste.length} Texte sind auf ihn bezogen`);
}
+ /* UND HIGHLIGHTS HAT AUSDRUECKLICH KEINE MEHR. Ohne diese Zeile
+ wuerde das Wegfallen nur dazu fuehren, dass eine Pruefung
+ weniger laeuft -- und niemand merkte, wenn sie zurueckkaemen. */
+ ok(!(TREFF_START.highlight || []).length,
+ "Highlights hat keine fertigen Vorschlaege (auf Ansage vom 24.09.2026)");
/* GEGENPROBE: Ein anonymer Text MUSS auffallen. Ohne sie hiesse
"alle bezogen" nur, dass das Muster auf alles passt. */
@@ -333,7 +373,30 @@ melde("=== 6. Wie es aussieht ===");
alleKnopf: document.querySelector(".startkatalog__alle")?.textContent?.trim() || "",
leer: document.querySelector(".leer-hinweis")?.textContent?.trim() || "",
}));
- ok(vorher.karten >= 8, `${vorher.karten} Vorschlaege stehen bereit`);
+ /* WIE VIELE STEHEN DA? NICHT EINE ZAHL VON GESTERN (24.09.2026).
+
+ Hier stand `>= 8`. Das stimmte, bis am 20.09.2026 das Fenster
+ eingefuehrt wurde -- seither kommen HOECHSTENS VIER auf einmal
+ (FENSTER = 4 in workspace-bereiche.js), und die Pruefung war
+ vier Tage lang rot, ohne dass es jemandem gesagt wurde. Genau
+ die Sorte Zahl, vor der CLAUDE.md warnt: eine Rechnung von
+ gestern, die still falsch wird.
+
+ Gefragt wird jetzt der Server selbst -- er weiss, wie viele er
+ schickt, und die Oberflaeche muss genau so viele zeichnen.
+ Zusaetzlich `> 0`, damit "gleich viele" nicht auch bei null
+ gruen ist. */
+ const ausDerAntwort = await seite.evaluate(async () => {
+ const a = await fetch("/workspace/api/bereich/mitmachen/start?ab=0",
+ { credentials: "same-origin" });
+ if (!a.ok) return null;
+ const j = await a.json();
+ return { geschickt: (j.vorschlaege || []).length, vorrat: j.vorrat, offen: j.offen };
+ });
+ ok(!!ausDerAntwort && ausDerAntwort.geschickt > 0
+ && vorher.karten === ausDerAntwort.geschickt,
+ `${vorher.karten} Vorschlaege stehen bereit -- genau so viele, wie der `
+ + `Server schickt (${ausDerAntwort?.geschickt}), von ${ausDerAntwort?.offen} offenen`);
ok(/Alle \d+ übernehmen/.test(vorher.alleKnopf), `mit einem Knopf ("${vorher.alleKnopf}")`);
/* DER LEERTEXT IST DER DES BEREICHS, nicht der Einheitssatz. */
ok(vorher.leer.includes("dazugehören"),
diff --git a/server/workspace-treff-start.js b/server/workspace-treff-start.js
index 6e13a2b9..d2794b77 100644
--- a/server/workspace-treff-start.js
+++ b/server/workspace-treff-start.js
@@ -328,22 +328,36 @@ export const TREFF_START = {
],
/* ===================================================================
- HIGHLIGHTS — was hier hingehört
+ HIGHLIGHTS — HIER GIBT ES KEINE FERTIGEN VORSCHLÄGE MEHR
+ (24.09.2026)
+
+ Filipe: „nimm die sachen da weg bitte. da sollen nur die sachen
+ rein kommen die die modis, linke und rechte hand oder dogfather
+ reinsetzen."
+
+ Hier standen drei Vorschläge („Was hier hingehört", „Fanart von
+ DogFather und Casper ist ausdrücklich erwünscht", „Ein Ausschnitt,
+ der auf die Clips soll"). Jemand hat sie übernommen, und danach
+ standen sie zwischen den echten Clips — mit Datum, mit Verfasser,
+ äußerlich nicht von einem echten Eintrag zu unterscheiden.
+
+ WARUM DAS BEI DIESEM BRETT ANDERS IST ALS BEI DEN ÜBRIGEN: Auf
+ den anderen Brettern ist ein Vorschlag eine ANREGUNG, die man
+ ausfüllt („Der nächste Stream mit DogFather" → Datum eintragen).
+ Highlights dagegen ist eine SAMMLUNG von echten Sachen — Clips,
+ Bilder, Fanart. Ein vorgefertigter Text ist dort kein Anfang,
+ sondern ein Platzhalter, der aussieht wie Inhalt. Die Erklärung,
+ was hierher gehört, steht ohnehin schon oben auf der Seite.
+
+ Der Bereich fehlt in dieser Liste jetzt ganz. Das genügt:
+ `STARTKATALOG[bereich] || []` liefert eine leere Liste, der
+ Block bleibt unsichtbar, und ein POST beantwortet sich mit 404.
+ Eine leere Liste hier stehen zu lassen wäre dasselbe Ergebnis mit
+ einer Zeile mehr, an der man sich fragt, wozu sie da ist.
+
+ Die anderen Bretter behalten ihre Vorschläge — dazu hat er
+ nichts gesagt, und dort tun sie das, wofür sie gedacht waren.
=================================================================== */
- highlight: [
- { art: "moment", titel: "Was hier hingehört",
- text: "Clips aus DogFathers Streams, Bilder, Zeichnungen, "
- + "Bildschirmfotos von Momenten, die euch geblieben sind. Der erste "
- + "darf ruhig wackelig sein — es geht nicht um Produktion, sondern um "
- + "den Moment." },
- { art: "fanart", titel: "Fanart von DogFather und Casper ist ausdrücklich erwünscht",
- text: "Gezeichnet, gebastelt, am Handy zusammengeschoben — egal. Schreib "
- + "dazu, ob DogFather es im Stream zeigen darf." },
- { art: "clip", titel: "Ein Ausschnitt, der auf die Clips soll",
- text: "Wenn dir eine Stelle auffällt, die als eigener Clip funktionieren "
- + "würde: hier hinein, mit Zeitpunkt. So entsteht ein guter Teil von "
- + "DogFather Clips." },
- ],
/* ===================================================================
WAS ANSTEHT — Vorlagen für Termine
diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html
index 33fc6292..d130166c 100644
--- a/workspace/anruf-probe.html
+++ b/workspace/anruf-probe.html
@@ -16,15 +16,15 @@
verdeckt. Gefunden hat es pruef-struktur.
Richtig sind `gate.css` (die Farbwerte des Hauses) und `haus.css`. -->
-
-
+
+
-
+