diff --git a/assets/img/app-symbole/workspace-1024.png b/assets/img/app-symbole/workspace-1024.png
new file mode 100644
index 00000000..6773ea36
Binary files /dev/null and b/assets/img/app-symbole/workspace-1024.png differ
diff --git a/server/pruef-ampel.mjs b/server/pruef-ampel.mjs
index 8b062b84..ab4bcdfa 100644
--- a/server/pruef-ampel.mjs
+++ b/server/pruef-ampel.mjs
@@ -11,6 +11,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-ampel-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4206, "pruef-ampel");
process.env.PORT = "4206";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -20,6 +26,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-aufgaben-vorlagen.mjs b/server/pruef-aufgaben-vorlagen.mjs
index 2f72c92b..30b8ebff 100644
--- a/server/pruef-aufgaben-vorlagen.mjs
+++ b/server/pruef-aufgaben-vorlagen.mjs
@@ -20,6 +20,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-aufv-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4211, "pruef-aufgaben-vorlagen");
process.env.PORT = "4211";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -29,6 +35,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(240_000, "pruef-aufgaben-vorlagen");
await new Promise((r) => setTimeout(r, 700));
diff --git a/server/pruef-aufgabenbrett.mjs b/server/pruef-aufgabenbrett.mjs
index 1a94a347..8fd5333a 100644
--- a/server/pruef-aufgabenbrett.mjs
+++ b/server/pruef-aufgabenbrett.mjs
@@ -35,6 +35,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-brett-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4216, "pruef-aufgabenbrett");
process.env.PORT = "4216";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -44,6 +50,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-bereiche-lesend.mjs b/server/pruef-bereiche-lesend.mjs
index f5c15f9b..9456965c 100644
--- a/server/pruef-bereiche-lesend.mjs
+++ b/server/pruef-bereiche-lesend.mjs
@@ -13,9 +13,16 @@
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
+import { portMussFreiSein } from "./helfer-port.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-bereiche-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4183, "pruef-bereiche-lesend");
process.env.PORT = "4183";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
diff --git a/server/pruef-betreuung.mjs b/server/pruef-betreuung.mjs
index fd42a520..6ba4b7f1 100644
--- a/server/pruef-betreuung.mjs
+++ b/server/pruef-betreuung.mjs
@@ -12,9 +12,16 @@
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
+import { portMussFreiSein } from "./helfer-port.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-betreuung-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4189, "pruef-betreuung");
process.env.PORT = "4189";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
diff --git a/server/pruef-buehne.mjs b/server/pruef-buehne.mjs
index f4d19445..261bcf02 100644
--- a/server/pruef-buehne.mjs
+++ b/server/pruef-buehne.mjs
@@ -100,6 +100,12 @@ console.log(`Zeitrahmen: ${Math.round((100_000 + SEITEN_ZEIT) / 1000)} s.`);
const ordner = mkdtempSync(join(tmpdir(), "ws-buehne-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4193, "pruef-buehne");
process.env.PORT = "4193";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -110,6 +116,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-checkliste.mjs b/server/pruef-checkliste.mjs
index d33cb3ee..19d811a4 100644
--- a/server/pruef-checkliste.mjs
+++ b/server/pruef-checkliste.mjs
@@ -19,6 +19,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-check-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4207, "pruef-checkliste");
process.env.PORT = "4207";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -28,6 +34,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-code.mjs b/server/pruef-code.mjs
index bfd41d67..5fe68c83 100644
--- a/server/pruef-code.mjs
+++ b/server/pruef-code.mjs
@@ -25,6 +25,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-code-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4195, "pruef-code");
process.env.PORT = "4195";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -35,6 +41,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-content-ansicht.mjs b/server/pruef-content-ansicht.mjs
index bc9d8a6b..441b9f53 100644
--- a/server/pruef-content-ansicht.mjs
+++ b/server/pruef-content-ansicht.mjs
@@ -6,6 +6,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-content-b-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4185, "pruef-content-ansicht");
process.env.PORT = "4185";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -16,6 +22,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-content.mjs b/server/pruef-content.mjs
index 74d84e1a..6bb76ddf 100644
--- a/server/pruef-content.mjs
+++ b/server/pruef-content.mjs
@@ -5,9 +5,17 @@
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
+import { portMussFreiSein } from "./helfer-port.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-content-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* BEIDE PORTS, nicht nur einer (nachgeruestet 19.09.2026). Diese
+ Datei startet ZWEI Server nacheinander -- 4184 fuer den Hauptlauf,
+ 4194 fuer die Gegenprobe. Nur den ersten zu pruefen hiesse, die
+ Gegenprobe ungeschuetzt zu lassen, und die ist der Teil, dem man
+ glaubt. */
+await portMussFreiSein(4184, "pruef-content");
+await portMussFreiSein(4194, "pruef-content (Gegenprobe)");
process.env.PORT = "4184";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
diff --git a/server/pruef-crew-adresse.mjs b/server/pruef-crew-adresse.mjs
index 51075f9a..cc89fde2 100644
--- a/server/pruef-crew-adresse.mjs
+++ b/server/pruef-crew-adresse.mjs
@@ -29,6 +29,12 @@ import { request } from "node:http";
const ordner = mkdtempSync(join(tmpdir(), "ws-crew-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4371, "pruef-crew-adresse");
process.env.PORT = "4371";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -38,6 +44,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-crew-adresse");
await new Promise((r) => setTimeout(r, 700));
diff --git a/server/pruef-crew-wand-bild.mjs b/server/pruef-crew-wand-bild.mjs
index 745a1a23..5f580d46 100644
--- a/server/pruef-crew-wand-bild.mjs
+++ b/server/pruef-crew-wand-bild.mjs
@@ -27,12 +27,19 @@ import { fileURLToPath } from "node:url";
const ordner = mkdtempSync(join(tmpdir(), "ws-crewbild-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4373, "pruef-crew-wand-bild");
process.env.PORT = "4373";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00";
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-crew-wand-bild");
await new Promise((r) => setTimeout(r, 700));
diff --git a/server/pruef-formulare.mjs b/server/pruef-formulare.mjs
index 2d2cd48f..3cf7f21b 100644
--- a/server/pruef-formulare.mjs
+++ b/server/pruef-formulare.mjs
@@ -21,6 +21,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-form-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4203, "pruef-formulare");
process.env.PORT = "4203";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -30,6 +36,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-freie-namen.mjs b/server/pruef-freie-namen.mjs
index 80bced68..c0435eb5 100644
--- a/server/pruef-freie-namen.mjs
+++ b/server/pruef-freie-namen.mjs
@@ -26,6 +26,12 @@ import { heuteLokal, tagLokal } from "./helfer-zeit.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-frei-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4192, "pruef-freie-namen");
process.env.PORT = "4192";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -36,6 +42,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-glocke.mjs b/server/pruef-glocke.mjs
index d42b9b80..23648217 100644
--- a/server/pruef-glocke.mjs
+++ b/server/pruef-glocke.mjs
@@ -391,11 +391,61 @@ melde("\n=== Anmelden und wieder abmelden ===");
const zahl = () => p.prepare("SELECT COUNT(*) AS n FROM push_anmeldungen").get().n;
ok(zahl() === 0, `vorher ${zahl()} Anmeldungen in der Datenbank`);
+ /* ==== "BEI DIR KLINGELT NICHTS" (19.09.2026) ======================
+
+ Gemessen an diesem Tag auf dem echten Server: Von elf Zugaengen
+ hatten SIEBEN kein einziges Geraet angemeldet. Bei ihnen kommt
+ nichts an, solange die Seite zu ist -- keine Aufgabe, kein Termin,
+ kein Anruf.
+
+ Die Glocke sagt das seit jeher korrekt. Nur tippt sie niemand an:
+ Sie ist ein stiller Schalter in einer Leiste. Deshalb steht es
+ jetzt auch dort, wo man hinsieht -- in "Was ist dran?".
+
+ DIE GEGENPROBE IST DER EIGENTLICHE PUNKT: Der Hinweis muss
+ VERSCHWINDEN, sobald ein Geraet da ist. Eine Warnung, die immer
+ kommt, ist keine Warnung mehr -- und bei sieben von elf Leuten
+ stuende sie sonst dauerhaft ueber den echten. */
+ const hinweise = async () => (await seite.evaluate(async () => {
+ const a = await fetch("/workspace/api/hinweise", { credentials: "same-origin" });
+ return a.json();
+ })).hinweise || [];
+
+ {
+ const vorher = await hinweise();
+ const h = vorher.find((x) => x.art === "kein_geraet");
+ ok(!!h, "ohne Geraet steht der Hinweis in „Was ist dran?“");
+ ok(h?.ziel === "anruf-probe.html",
+ `und er fuehrt auf die Seite, die sagt warum (${h?.ziel})`);
+ ok(h?.stufe === "offen",
+ `als offener Punkt, nicht als Warnung (${h?.stufe}) — sonst stuende er `
+ + "dauerhaft ueber den echten Warnungen");
+ /* Und auf dem Bildschirm steht er ohne die "1" davor: Er zaehlt
+ nichts, er beschreibt einen Zustand. */
+ const sichtbar = await seite.evaluate(() =>
+ [...document.querySelectorAll(".dran__punkt")]
+ .map((li) => li.textContent.trim()).find((t) => /klingelt nichts/.test(t)) || "");
+ ok(/klingelt nichts/.test(sichtbar) && !/^\s*1/.test(sichtbar),
+ `auf der Seite steht er ohne Zahl davor: „${sichtbar.replace(/\s+/g, " ").slice(0, 60)}“`);
+ }
+
await seite.click("#glocke");
await seite.waitForTimeout(1200);
ok(zahl() === 1, `nach dem Klick: ${zahl()} Anmeldung`);
+ /* GEGENPROBE: Jetzt muss der Hinweis weg sein. */
+ {
+ /* OHNE NEULADEN. Der erste Anlauf lud die Seite neu -- danach war
+ das Test-Doppel fuer den Push-Dienst weg, der Glockenknopf stand
+ wieder auf "aus", und die drei folgenden Pruefungen meldeten
+ Fehler, die es nicht gab. Die Schnittstelle antwortet ohnehin
+ live; eine neue Seite braucht es dafuer nicht. */
+ const nachher = await hinweise();
+ ok(!nachher.some((x) => x.art === "kein_geraet"),
+ "mit einem angemeldeten Geraet ist der Hinweis weg — nichts zu quittieren");
+ }
+
const eintrag = p.prepare("SELECT * FROM push_anmeldungen").get();
ok(eintrag?.person_id === idDogi && /^https:\/\//.test(eintrag?.endpunkt || ""),
`sie gehört der richtigen Person und hat eine https-Adresse`);
diff --git a/server/pruef-grosscheck.mjs b/server/pruef-grosscheck.mjs
index 2234d6de..75fe9373 100644
--- a/server/pruef-grosscheck.mjs
+++ b/server/pruef-grosscheck.mjs
@@ -44,6 +44,12 @@ const REPO = join(dirname(fileURLToPath(import.meta.url)), "..");
const ordner = mkdtempSync(join(tmpdir(), "ws-gross-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4218, "pruef-grosscheck");
process.env.PORT = "4218";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -54,6 +60,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-handy.mjs b/server/pruef-handy.mjs
index 42bba8c9..17ad6a2f 100644
--- a/server/pruef-handy.mjs
+++ b/server/pruef-handy.mjs
@@ -28,6 +28,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-handy-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4198, "pruef-handy");
process.env.PORT = "4198";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -37,6 +43,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-kalender.mjs b/server/pruef-kalender.mjs
index e5a25baf..9faa6896 100644
--- a/server/pruef-kalender.mjs
+++ b/server/pruef-kalender.mjs
@@ -13,6 +13,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-kal-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4188, "pruef-kalender");
process.env.PORT = "4188";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -23,6 +29,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-kopf-messen.mjs b/server/pruef-kopf-messen.mjs
index ad50e20a..f37a0dc2 100644
--- a/server/pruef-kopf-messen.mjs
+++ b/server/pruef-kopf-messen.mjs
@@ -26,6 +26,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-messen-"));
process.env.WORKSPACE_DB = join(ordner, "pruef.sqlite");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4179, "pruef-kopf-messen");
process.env.PORT = "4179";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -36,6 +42,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-lesbarkeit.mjs b/server/pruef-lesbarkeit.mjs
index b40e7511..29e8cf33 100644
--- a/server/pruef-lesbarkeit.mjs
+++ b/server/pruef-lesbarkeit.mjs
@@ -28,6 +28,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-lese-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4214, "pruef-lesbarkeit");
process.env.PORT = "4214";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -37,6 +43,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-manager-sicht.mjs b/server/pruef-manager-sicht.mjs
index e03733fa..a4a559f8 100644
--- a/server/pruef-manager-sicht.mjs
+++ b/server/pruef-manager-sicht.mjs
@@ -38,6 +38,12 @@ import { heuteLokal, tagLokal } from "./helfer-zeit.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-msicht-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4199, "pruef-manager-sicht");
process.env.PORT = "4199";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -48,6 +54,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-modi-checkliste.mjs b/server/pruef-modi-checkliste.mjs
index a43cf987..e787fbce 100644
--- a/server/pruef-modi-checkliste.mjs
+++ b/server/pruef-modi-checkliste.mjs
@@ -26,6 +26,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-mcheck-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4369, "pruef-modi-checkliste");
process.env.PORT = "4369";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -35,6 +41,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-modi-checkliste");
await new Promise((r) => setTimeout(r, 800));
diff --git a/server/pruef-modi-ideen.mjs b/server/pruef-modi-ideen.mjs
index f1658849..bc4a3214 100644
--- a/server/pruef-modi-ideen.mjs
+++ b/server/pruef-modi-ideen.mjs
@@ -31,6 +31,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-ideen-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4365, "pruef-modi-ideen");
process.env.PORT = "4365";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -96,6 +102,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-modi-ideen");
await new Promise((r) => setTimeout(r, 900));
diff --git a/server/pruef-modi-katalog.mjs b/server/pruef-modi-katalog.mjs
index f7cd9a0e..03b70cb3 100644
--- a/server/pruef-modi-katalog.mjs
+++ b/server/pruef-modi-katalog.mjs
@@ -22,6 +22,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-kat2-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4363, "pruef-modi-katalog");
process.env.PORT = "4363";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -33,6 +39,7 @@ express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(
import { notbremse } from "./helfer-notbremse.mjs";
import { ersatzschreibungen } from "./helfer-deutsch.mjs";
import { fileURLToPath } from "node:url";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-modi-katalog");
await new Promise((r) => setTimeout(r, 700));
diff --git a/server/pruef-modi-kategorien.mjs b/server/pruef-modi-kategorien.mjs
index 60443448..df0a08b5 100644
--- a/server/pruef-modi-kategorien.mjs
+++ b/server/pruef-modi-kategorien.mjs
@@ -23,6 +23,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-kat-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4361, "pruef-modi-kategorien");
process.env.PORT = "4361";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -32,6 +38,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-modi-kategorien");
await new Promise((r) => setTimeout(r, 700));
diff --git a/server/pruef-modi-livecheck.mjs b/server/pruef-modi-livecheck.mjs
index 521b215a..518034dc 100644
--- a/server/pruef-modi-livecheck.mjs
+++ b/server/pruef-modi-livecheck.mjs
@@ -27,6 +27,12 @@ import { tagLokal } from "./helfer-tag.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-live-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4367, "pruef-modi-livecheck");
process.env.PORT = "4367";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -36,6 +42,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-modi-livecheck");
await new Promise((r) => setTimeout(r, 800));
diff --git a/server/pruef-modi-verborgen.mjs b/server/pruef-modi-verborgen.mjs
index 532a5c25..8a08084e 100644
--- a/server/pruef-modi-verborgen.mjs
+++ b/server/pruef-modi-verborgen.mjs
@@ -23,6 +23,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-modi-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4359, "pruef-modi-verborgen");
process.env.PORT = "4359";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -32,6 +38,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* NACH index.js: Der Server haengt dort zwei Auffangnetze ein, die
einen Absturz nur protokollieren. Fuer den Betrieb richtig, fuer eine
diff --git a/server/pruef-personen-formular.mjs b/server/pruef-personen-formular.mjs
index 0f0f2372..a542bff8 100644
--- a/server/pruef-personen-formular.mjs
+++ b/server/pruef-personen-formular.mjs
@@ -24,6 +24,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-pform-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4198, "pruef-personen-formular");
process.env.PORT = "4198";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -34,6 +40,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-personen-liste.mjs b/server/pruef-personen-liste.mjs
index 9938bb19..0899a68c 100644
--- a/server/pruef-personen-liste.mjs
+++ b/server/pruef-personen-liste.mjs
@@ -18,6 +18,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-personen-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4187, "pruef-personen-liste");
process.env.PORT = "4187";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -28,6 +34,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-personen-loeschen.mjs b/server/pruef-personen-loeschen.mjs
index 7f8f134a..3c14d289 100644
--- a/server/pruef-personen-loeschen.mjs
+++ b/server/pruef-personen-loeschen.mjs
@@ -8,9 +8,16 @@
import { mkdtempSync, rmSync, readdirSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
+import { portMussFreiSein } from "./helfer-port.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-loeschen-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4188, "pruef-personen-loeschen");
process.env.PORT = "4188";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
diff --git a/server/pruef-protokoll-klappe.mjs b/server/pruef-protokoll-klappe.mjs
index be1852ea..4d663341 100644
--- a/server/pruef-protokoll-klappe.mjs
+++ b/server/pruef-protokoll-klappe.mjs
@@ -10,6 +10,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-klappe-"));
process.env.WORKSPACE_DB = join(ordner, "pruef.sqlite");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4180, "pruef-protokoll-klappe");
process.env.PORT = "4180";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -20,6 +26,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-protokoll-loeschen.mjs b/server/pruef-protokoll-loeschen.mjs
index 56d91618..9d0c49b2 100644
--- a/server/pruef-protokoll-loeschen.mjs
+++ b/server/pruef-protokoll-loeschen.mjs
@@ -31,6 +31,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-prot-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4197, "pruef-protokoll-loeschen");
process.env.PORT = "4197";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -41,6 +47,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-rollen.mjs b/server/pruef-rollen.mjs
index 17ade5df..548200d0 100644
--- a/server/pruef-rollen.mjs
+++ b/server/pruef-rollen.mjs
@@ -33,6 +33,12 @@ import { heuteLokal, tagLokal } from "./helfer-zeit.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-rollen-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4193, "pruef-rollen");
process.env.PORT = "4193";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -43,6 +49,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
@@ -194,7 +201,31 @@ const ROLLEN = [
const { chromium } = await import(
"file:///C:/Users/qciga/Documents/Obelix/Analyse/node_modules/playwright/index.mjs");
-const browser = await chromium.launch();
+
+/* ==== EIN BROWSER JE ROLLE, NICHT EINER FUER ALLE (19.09.2026) ========
+
+ DER BEFUND: Dieser Lauf ist bei der fuenften Rolle abgestuerzt --
+ "Target crashed", nach 234 gruenen Pruefungen. Kein Fehlschlag,
+ sondern ein toter Browser: Der Renderer-Prozess wird vom System
+ beendet, wenn ihm der Speicher ausgeht.
+
+ Nachgemessen gegen den Stand VOR den Aenderungen dieses Tages
+ (Commit 0b73fbb) -- dort stuerzt er genauso ab, an derselben Stelle.
+ Er war also schon vorher rot, und zwar ohne dass es jemandem
+ aufgefallen ist: Von aussen sieht ein abgestuerzter Browser aus wie
+ ein Programmfehler, und die 234 gruenen Zeilen davor lesen sich wie
+ ein fast bestandener Lauf.
+
+ DIE URSACHE IST DIE MENGE: fuenf Rollen mal sechzehn Seiten, jede
+ mit Hintergrundbild, Schriften und Skripten -- rund achtzig
+ Seitenaufbauten in EINEM Browserprozess. Die Kontexte wurden zwar
+ je Rolle geschlossen (`kontext.close()`), der Prozess darunter lief
+ aber durch und gab den Speicher nicht zurueck.
+
+ Ein Prueflauf, der abstuerzt, beweist nichts -- er ist schlimmer als
+ einer, der scheitert, weil das Ergebnis nach Programmfehler aussieht.
+ Deshalb bekommt jede Rolle ihren eigenen Browser, und der wird am
+ Ende der Runde beendet. Kostet ein paar Sekunden je Rolle. */
/* Fehler, die nichts mit uns zu tun haben. Bewusst kurz gehalten: Jede
Ausnahme hier ist eine Stelle, an der eine echte Panne durchrutschen
@@ -208,9 +239,19 @@ const istEgal = (t) => EGAL.some((r) => r.test(t));
const berichte = [];
for (const r of ROLLEN) {
+ const browser = await chromium.launch();
const kontext = await browser.newContext({ viewport: { width: 1440, height: 1000 } });
const seite = await kontext.newPage();
+ /* EIN ABGESTUERZTER BROWSER MUSS SICH MELDEN, nicht schweigen.
+ Ohne diesen Zuhoerer faellt der Absturz erst beim naechsten
+ Zugriff auf -- als Zeitueberschreitung irgendwo weiter unten,
+ Hunderte Zeilen von der Ursache entfernt. */
+ seite.on("crash", () => {
+ console.error(` ABSTURZ: Der Browser ist bei "${r.name}" gestorben.`);
+ console.error(" Das ist kein Befund am Code -- meist fehlender Speicher.");
+ });
+
const konsole = [];
const schlechteAntworten = [];
seite.on("console", (m) => { if (m.type() === "error" && !istEgal(m.text())) konsole.push(m.text()); });
@@ -324,10 +365,9 @@ for (const r of ROLLEN) {
await seite.screenshot({ path: `pruef-rollen-${r.rolle}.png`, fullPage: false });
await kontext.close();
+ await browser.close();
}
-await browser.close();
-
/* ---------- Abschluss --------------------------------------------------- */
console.log("");
diff --git a/server/pruef-schulung.mjs b/server/pruef-schulung.mjs
index 1e30b4e4..706e14d9 100644
--- a/server/pruef-schulung.mjs
+++ b/server/pruef-schulung.mjs
@@ -18,6 +18,12 @@ import { createHash } from "node:crypto";
const ordner = mkdtempSync(join(tmpdir(), "ws-schul-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4205, "pruef-schulung");
process.env.PORT = "4205";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -27,6 +33,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-scout-zuteilung.mjs b/server/pruef-scout-zuteilung.mjs
index 9ff3d203..1e8242a6 100644
--- a/server/pruef-scout-zuteilung.mjs
+++ b/server/pruef-scout-zuteilung.mjs
@@ -26,6 +26,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-zut-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4217, "pruef-scout-zuteilung");
process.env.PORT = "4217";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -35,6 +41,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-serien.mjs b/server/pruef-serien.mjs
index 2c021f4f..0f9606f3 100644
--- a/server/pruef-serien.mjs
+++ b/server/pruef-serien.mjs
@@ -29,6 +29,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-serien-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4189, "pruef-serien");
process.env.PORT = "4189";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -39,6 +45,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-sicherung.mjs b/server/pruef-sicherung.mjs
index d93332e0..9f2b02fd 100644
--- a/server/pruef-sicherung.mjs
+++ b/server/pruef-sicherung.mjs
@@ -15,9 +15,16 @@ import { tmpdir } from "node:os";
import { join } from "node:path";
import { createRequire } from "node:module";
import { pathToFileURL } from "node:url";
+import { portMussFreiSein } from "./helfer-port.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-sicherung-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4181, "pruef-sicherung");
process.env.PORT = "4181";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
diff --git a/server/pruef-sicht.mjs b/server/pruef-sicht.mjs
index 6a6d9997..237738be 100644
--- a/server/pruef-sicht.mjs
+++ b/server/pruef-sicht.mjs
@@ -26,6 +26,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-sicht-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4215, "pruef-sicht");
process.env.PORT = "4215";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -35,6 +41,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-sprung.mjs b/server/pruef-sprung.mjs
index b8ba9cd1..adc078bb 100644
--- a/server/pruef-sprung.mjs
+++ b/server/pruef-sprung.mjs
@@ -32,6 +32,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-sprung-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4212, "pruef-sprung");
process.env.PORT = "4212";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -41,6 +47,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-start-ansicht.mjs b/server/pruef-start-ansicht.mjs
index 8a39fafb..25ec7ece 100644
--- a/server/pruef-start-ansicht.mjs
+++ b/server/pruef-start-ansicht.mjs
@@ -6,6 +6,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-start-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4186, "pruef-start-ansicht");
process.env.PORT = "4186";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -16,6 +22,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-steckbrief.mjs b/server/pruef-steckbrief.mjs
index 50876d7b..4c91fb11 100644
--- a/server/pruef-steckbrief.mjs
+++ b/server/pruef-steckbrief.mjs
@@ -11,6 +11,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-sb-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4196, "pruef-steckbrief");
process.env.PORT = "4196";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -20,6 +26,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-tagesruf.mjs b/server/pruef-tagesruf.mjs
index ec80fa9d..fb79bc99 100644
--- a/server/pruef-tagesruf.mjs
+++ b/server/pruef-tagesruf.mjs
@@ -39,6 +39,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-start-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4186, "pruef-tagesruf");
process.env.PORT = "4186";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -49,6 +55,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-team-ampel.mjs b/server/pruef-team-ampel.mjs
index 9a7cc017..3eff0291 100644
--- a/server/pruef-team-ampel.mjs
+++ b/server/pruef-team-ampel.mjs
@@ -31,6 +31,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-ampel-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4385, "pruef-team-ampel");
process.env.PORT = "4385";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00";
@@ -39,6 +45,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-team-ampel");
await new Promise((r) => setTimeout(r, 700));
diff --git a/server/pruef-team-stufen.mjs b/server/pruef-team-stufen.mjs
index b22e7000..84650311 100644
--- a/server/pruef-team-stufen.mjs
+++ b/server/pruef-team-stufen.mjs
@@ -27,6 +27,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-stufen-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4375, "pruef-team-stufen");
process.env.PORT = "4375";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00";
@@ -35,6 +41,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
notbremse(180_000, "pruef-team-stufen");
await new Promise((r) => setTimeout(r, 700));
diff --git a/server/pruef-uebersicht-browser.mjs b/server/pruef-uebersicht-browser.mjs
index 1c1f4950..5b92f95e 100644
--- a/server/pruef-uebersicht-browser.mjs
+++ b/server/pruef-uebersicht-browser.mjs
@@ -12,6 +12,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-uebersicht-b-"));
process.env.WORKSPACE_DB = join(ordner, "pruef.sqlite");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4177, "pruef-uebersicht-browser");
process.env.PORT = "4177";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -24,6 +30,7 @@ express.response.cookie = function (name, wert, opt) {
return echteCookie.call(this, name, wert, { ...(opt || {}), secure: false });
};
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-uebersicht.mjs b/server/pruef-uebersicht.mjs
index c3bb0cb3..d83a0d9e 100644
--- a/server/pruef-uebersicht.mjs
+++ b/server/pruef-uebersicht.mjs
@@ -10,9 +10,16 @@
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
+import { portMussFreiSein } from "./helfer-port.mjs";
const ordner = mkdtempSync(join(tmpdir(), "ws-uebersicht-"));
process.env.WORKSPACE_DB = join(ordner, "pruef.sqlite");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4176, "pruef-uebersicht");
process.env.PORT = "4176";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
diff --git a/server/pruef-verborgen.mjs b/server/pruef-verborgen.mjs
index 1ee01f92..6b870c74 100644
--- a/server/pruef-verborgen.mjs
+++ b/server/pruef-verborgen.mjs
@@ -6,6 +6,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-start-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4186, "pruef-verborgen");
process.env.PORT = "4186";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -16,6 +22,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-wissen-neu.mjs b/server/pruef-wissen-neu.mjs
index e8aef5f6..ca4d9b68 100644
--- a/server/pruef-wissen-neu.mjs
+++ b/server/pruef-wissen-neu.mjs
@@ -15,6 +15,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-wissen-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4201, "pruef-wissen-neu");
process.env.PORT = "4201";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -24,6 +30,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-workspace-seiten.mjs b/server/pruef-workspace-seiten.mjs
index 7039e619..938effa3 100644
--- a/server/pruef-workspace-seiten.mjs
+++ b/server/pruef-workspace-seiten.mjs
@@ -7,6 +7,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-kopf-"));
process.env.WORKSPACE_DB = join(ordner, "pruef.sqlite");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4178, "pruef-workspace-seiten");
process.env.PORT = "4178";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -19,6 +25,7 @@ express.response.cookie = function (n, w, o) {
return echteCookie.call(this, n, w, { ...(o || {}), secure: false });
};
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/pruef-zustand-ansicht.mjs b/server/pruef-zustand-ansicht.mjs
index 5e219343..7c918f7e 100644
--- a/server/pruef-zustand-ansicht.mjs
+++ b/server/pruef-zustand-ansicht.mjs
@@ -8,6 +8,12 @@ import { join } from "node:path";
const ordner = mkdtempSync(join(tmpdir(), "ws-zustand-"));
process.env.WORKSPACE_DB = join(ordner, "workspace.db");
+/* DER PORT MUSS MEINER SEIN (nachgeruestet 19.09.2026).
+ Ohne diese Zeile startet der eigene Server bei belegtem Port
+ STILL nicht -- und alles Folgende misst gegen einen fremden
+ Stand. Das ist der dritte Ausgang: belegt ist etwas anderes
+ als kaputt. */
+await portMussFreiSein(4182, "pruef-zustand-ansicht");
process.env.PORT = "4182";
process.env.SITE_ACCESS_SECRET = "lokaler-test";
process.env.SITE_ACCESS_CODE_DOGI = "DOGI-TEST-1";
@@ -18,6 +24,7 @@ const express = (await import("express")).default;
const ec = express.response.cookie;
express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); };
import { notbremse } from "./helfer-notbremse.mjs";
+import { portMussFreiSein } from "./helfer-port.mjs";
await import("./index.js");
/* DIE NOTBREMSE. Muss NACH index.js stehen: Der Server haengt dort
zwei Auffangnetze ein, die einen Absturz nur protokollieren --
diff --git a/server/rechte.js b/server/rechte.js
index bf03ca39..bf73aa67 100644
--- a/server/rechte.js
+++ b/server/rechte.js
@@ -298,9 +298,24 @@ export const SEITEN = {
/* DIE ANRUF-PROBE (19.09.2026). Sie sagt einem Menschen in seinem
eigenen Browser, warum es nicht klingelt -- die Frage, die sich
von aussen nicht beantworten laesst. Sie ruft niemanden an und
- zeigt nichts ueber andere; deshalb steht sie allen offen, die
- ueberhaupt telefonieren koennen. */
- "/workspace/anruf-probe.html": ["admin", "hand", "modi"],
+ zeigt nichts ueber andere.
+
+ ERWEITERT AM 19.09.2026, nachmittags, nach einer Messung: Von
+ elf Zugaengen hatten SIEBEN kein einziges Geraet angemeldet -- bei
+ ihnen klingelt nichts und es kommt keine Erinnerung an, solange
+ die Seite zu ist. Fuenf der sieben sind Creator, Scout oder Spicy
+ Media und durften diese Seite gar nicht oeffnen.
+
+ Das war die falsche Einschraenkung: Die Seite prueft nicht nur
+ Anrufe, sondern die ganze Kette bis zur angemeldeten Geraete-Kennung
+ -- und die traegt auch jede Aufgaben- und Terminerinnerung. Wer
+ Erinnerungen bekommen kann, muss nachsehen koennen, warum sie
+ ausbleiben.
+
+ OHNE "gast". Die Community bekommt keine Erinnerungen, und eine
+ Seite mit sieben Prueftpunkten ueber etwas, das es fuer sie nicht
+ gibt, waere nur Verwirrung. */
+ "/workspace/anruf-probe.html": [...ALLE],
/* DIE ANFRAGE FUER MODI (17.09.2026).
diff --git a/server/workspace-hinweise.js b/server/workspace-hinweise.js
index f178e7b6..9b37c29e 100644
--- a/server/workspace-hinweise.js
+++ b/server/workspace-hinweise.js
@@ -336,6 +336,44 @@ hinweisRouter.get("/workspace/api/hinweise", (req, res) => {
"neue Anfrage für Modi", "bewerbungen.html",
zaehle("SELECT COUNT(*) n FROM bewerbungen WHERE zustand = 'neu'", []));
+ /* ==== BEI DIR KLINGELT NICHTS (19.09.2026) =======================
+
+ Gemessen an diesem Tag: Von elf Zugaengen hatten SIEBEN kein
+ einziges Geraet angemeldet. Bei ihnen kommt keine einzige
+ Erinnerung an, solange die Seite zu ist -- keine Aufgabe, kein
+ Termin, kein Anruf.
+
+ Die Glocke oben rechts sagt das seit jeher korrekt ("Benach-
+ richtigungen aus") und kennt sogar den iPhone-Sonderfall. Nur
+ tippt sie niemand an: Sie ist ein stiller Schalter in einer
+ Leiste, kein Hinweis. Deshalb steht es jetzt dort, wo man
+ hinsieht.
+
+ DIESER HINWEIS GEHT NUR AN DIE PERSON SELBST, nicht an die
+ Sicht. `req.person` und nicht `person`: Wenn DogFather die Lage
+ eines Scouts ansieht, waere "bei DIR klingelt nichts" eine
+ Aussage ueber den falschen Menschen -- und eine, die er nicht
+ loesen kann.
+
+ STUFE "offen", NICHT "warnung". Es ist kein Ausfall, sondern
+ etwas, das man einmal einrichtet. Ein rotes Warnzeichen, das
+ bei sieben von elf Leuten dauerhaft oben steht, waere nach
+ einer Woche unsichtbar -- und mit ihm die echten Warnungen
+ daneben.
+
+ ER VERSCHWINDET VON SELBST, sobald ein Geraet angemeldet ist.
+ Nichts zu quittieren, nichts, was veralten kann -- Regel 1
+ dieser Datei. */
+ if (req.person?.id) {
+ const geraete = zaehle(
+ "SELECT COUNT(*) n FROM push_anmeldungen WHERE person_id = ?", [req.person.id]);
+ if (!geraete) {
+ dazu("kein_geraet", "offen",
+ "Bei dir klingelt nichts – kein Gerät angemeldet",
+ "anruf-probe.html", 1);
+ }
+ }
+
hinweise.sort((x, y) => (RANG[x.stufe] - RANG[y.stufe]) || (y.anzahl - x.anzahl));
res.json({ hinweise, stand: new Date().toISOString() });
} catch (fehler) {
diff --git a/tools/workspace-symbol.mjs b/tools/workspace-symbol.mjs
index 6928d779..ad750ee8 100644
--- a/tools/workspace-symbol.mjs
+++ b/tools/workspace-symbol.mjs
@@ -61,8 +61,19 @@ for (const q of [HUSKY, CHILI]) {
}
const alsDaten = (p) => "data:image/webp;base64," + readFileSync(p).toString("base64");
-/* Die Groessen, die Manifest und HTML tatsaechlich anfordern. */
+/* Die Groessen, die Manifest und HTML tatsaechlich anfordern.
+
+ 1024 KOMMT AM 19.09.2026 DAZU, und zwar nicht fuer das Haus: TikTok
+ verlangt fuer die Anmeldung der Display-API ein Symbol in
+ 1024 x 1024. Vorhanden war 512.
+
+ HIER EINGETRAGEN UND NICHT VON HAND HOCHSKALIERT: Ein hochgerechnetes
+ 512er-Bild ist an den Kanten weich, und ausgerechnet das Gesicht des
+ Huskys lebt von harten Kanten. Diese Datei rendert die Groesse
+ frisch -- und die drei Gegenproben unten (Streuung, Gesicht, Chili)
+ gelten fuer sie damit genauso wie fuer alle anderen. */
const GROESSEN = [
+ { n: 1024, endung: "1024", voll: true },
{ n: 512, endung: "512" },
{ n: 192, endung: "192" },
{ n: 512, endung: "512-maskable", maskable: true },
@@ -76,7 +87,7 @@ const GROESSEN = [
erzeugte Bild mit und ohne -- sind beide gleich, war der Bestandteil
nie zu sehen. Eine Pruefung, die nur "es steht etwas drauf" sagt,
haette den Fleck von gestern anstandslos durchgewunken. */
-function html(n, maskable, husky, chili, weglassen = "") {
+function html(n, maskable, husky, chili, weglassen = "", voll = false) {
/* KLEIN = alles unter 64 px. Dort faellt die GESICHTSZEICHNUNG weg,
nicht die Chili. Achtfach vergroessert nebeneinandergelegt: Mit
Zeichnung ist der Kopf bei 32 px ein dunkler Fleck, als reine
@@ -92,7 +103,18 @@ function html(n, maskable, husky, chili, weglassen = "") {
liegt alles Wesentliche im Sicherheitskreis mit 80 % Durchmesser,
den Android als einziges garantiert. */
const g = Math.round(n * (maskable ? 0.72 : 0.94));
- const ecke = maskable ? "" : `border-radius:${rand}px;`;
+ /* `voll` heisst: KEINE abgerundeten Ecken (19.09.2026).
+
+ Fuer die 1024er-Fassung, die an ein Portal geht. Die Aufnahme hat
+ keinen Alphakanal -- was ausserhalb der Rundung liegt, wird also
+ nicht durchsichtig, sondern WEISS. Auf TikToks hellem Hintergrund
+ faellt das nicht auf, auf einem dunklen sieht es aus wie vier
+ abgeschnittene Ecken.
+
+ App-Portale wollen ohnehin das volle Quadrat: Die Rundung macht
+ das Betriebssystem selbst, und eine zweite darunter ergibt einen
+ hellen Saum. */
+ const ecke = (maskable || voll) ? "" : `border-radius:${rand}px;`;
/* ALLE REGELN TRAGEN DENSELBEN VORSATZ `.gruppe > i`.
@@ -213,9 +235,9 @@ let gebaut = 0;
const maengel = [];
/* Eine Fassung aufnehmen. `weglassen` steuert die Gegenprobe. */
-async function aufnehmen(n, maskable, weglassen = "") {
+async function aufnehmen(n, maskable, weglassen = "", voll = false) {
await seite.setViewportSize({ width: n, height: n });
- await seite.setContent(html(n, maskable, husky, chili, weglassen),
+ await seite.setContent(html(n, maskable, husky, chili, weglassen, voll),
{ waitUntil: "networkidle" });
return await seite.screenshot({ omitBackground: false });
}
@@ -264,7 +286,7 @@ async function unterschied(a, b) {
}
for (const g of GROESSEN) {
- const bild = await aufnehmen(g.n, !!g.maskable);
+ const bild = await aufnehmen(g.n, !!g.maskable, "", !!g.voll);
writeFileSync(join(ZIEL, `workspace-${g.endung}.png`), bild);
gebaut++;
@@ -276,8 +298,10 @@ for (const g of GROESSEN) {
aussieht wie mit ihr, dann war die Zeichnung nie zu sehen -- und
genau das war der Fehler der alten Fassung, die trotzdem gruen war. */
const klein = g.n < 64;
- const ohneZeichnung = await unterschied(bild, await aufnehmen(g.n, !!g.maskable, "zeichnung"));
- const ohneChili = await unterschied(bild, await aufnehmen(g.n, !!g.maskable, "chili"));
+ const ohneZeichnung = await unterschied(bild,
+ await aufnehmen(g.n, !!g.maskable, "zeichnung", !!g.voll));
+ const ohneChili = await unterschied(bild,
+ await aufnehmen(g.n, !!g.maskable, "chili", !!g.voll));
if (klein) {
/* Unter 64 px ist die schlichte Silhouette Absicht. Geprueft wird,
diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html
index d0cf7af8..cd4a1fd8 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`. -->
-
-
+
+
-
+