Filipe: „fuer die modis, rechte und linke hand und dogfather eine
kachel hinzufuegst, sie soll: Notizen, heissen. ich will dass du das
auch wie ein notizblock erstellst. ich will dass es uebelst geil und
einzigartig ist."
=================================================================
TEIL 1: DIE FARBE -- UND WAS DABEI AUFFIEL
=================================================================
Fuer die neue Kachel braucht es einen Ton. Beim Suchen fiel auf, dass
tools/kachelton-entzerren.mjs zwoelf der 45 Farben fuer FREI hielt.
Sie sind es nicht. bereicheFuer() gibt fuer die fuenf Rollen des
Agenturhauses null zurueck -- das heisst „nimm die Liste aus dem
Browser", und die steht in workspace/assets/js/bereiche.js. Dort
stehen die Toene 1 bis 22 und 44: Dashboard, Zahlen, Team-Lage,
Scout-Pipeline. Kacheln, die jeden Tag jemand ansieht.
pruef-kachelfarben hatte denselben blinden Fleck. Sie meldete seit
Wochen „33 benutzte Toene" und war gruen. Was sie dadurch NICHT sah:
* Der Farblauf von gestern Nacht hat zwoelf dieser Kacheln
verschoben und drei davon unter die Buntheitsgrenze gedrueckt.
Gruen geblieben.
* Ton 7, 16 und 22 lagen SEIT JEHER unter der Grenze (0,112 / 0,116
/ 0,068). Nie gemeldet.
Das ist die Sorte gruener Haken, vor der die Hausregel warnt: Er sagt
nur, dass die Bedingung erfuellt war -- nicht, dass sie das Richtige
angesehen hat.
BEHOBEN, und zwar an der Wurzel: Die REGELN (Kontrast, Buntheit)
gelten jetzt fuer jeden Ton, der irgendwo an einer Kachel steht --
gelesen aus denselben fuenf Dateien, die auch pruef-kachel-universum
liest. Dazu die Namen der Kacheln, damit „Ton 1 traegt Dashboard"
ueberhaupt pruefbar ist.
DIE PALETTE WURDE NEU GERECHNET, mit dem dritten Verfahren an einem
Tag -- die ersten zwei stehen als Fehler im Kopf des Werkzeugs:
1. Alle 45 neu verteilt. Lief ueber zwei ausdrueckliche Wuensche
hinweg (#ff1a1a, #a8d8ff).
2. Nur die Kollisionen, aber immer nur EINEN der beiden bewegt.
Ergebnis: Ton 1 sprang vom Tuerkis ins Altrosa, 0,197 weit.
3. BEIDE duerfen sich bewegen, und zwar beide nur ein bisschen.
Zwei Toene, die 0,02 auseinanderstehen und 0,09 brauchen, teilen
sich das -- jeder rueckt 0,045, und beide bleiben, was sie waren.
kleinster Abstand 0,0154 -> 0,0905
zu blass 4 -> 0
sichtbar veraendert 7 Kacheln (ueber 0,05)
kaum zu sehen 28 (13 zwischen 0,02 und 0,05, 15 darunter)
EINE AUSNAHME MIT ZAHL, keine mit Achselzucken: Ton 1 (Dashboard)
bleibt acht Tausendstel unter der Buntheitsgrenze. Gemessen ueber ALLE
16,7 Millionen sRGB-Farben ist die naechste, die alle Regeln haelt,
#7a75c8 -- ein Blauviolett, 0,113 entfernt. Tuerkis erreicht in sRGB
schlicht keine hoehere Buntheit, und das schmale Band teilen sich
schon sieben Toene. Eine Kachel, die ihre Farbfamilie behaelt, ist die
bessere Antwort auf „richtig geil und speziell" als eine, die acht
Tausendstel bunter ist und niemand wiedererkennt. blassBis sagt jetzt
bei jeder Ausnahme, WIE WEIT sie reicht -- vorher hiess blassErlaubt
schlicht „hier wird weggesehen".
DIE NEUE FARBE IST GRUEN UND WOLLTE BERNSTEIN SEIN. Gesucht war die
Farbe von Papier. Gemessen gibt es sie nicht mehr: Der beste Bernstein
im ganzen Farbraum haelt 0,0799 Abstand -- unter der Hausgrenze. Und
Platz schaffen hilft nicht: Setzt man ihn fest, muss ein warmer Ton
das Band verlassen (Ton 45 waere 0,212 weit ins Magenta gewandert).
Die groesste wirklich freie Luecke liegt im Gruen, bei 0,0917. Ein
linierter Block in Gruen ist Papier, seit es Papier gibt.
=================================================================
TEIL 2: DER BLOCK
=================================================================
DREI ENTSCHEIDUNGEN, AUS DENEN DER REST FOLGT:
1. ES GIBT KEINEN SPEICHERN-KNOPF. Nirgends. Wer einen Block
aufschlaegt und lostippt, drueckt hinterher nicht auf „sichern";
er klappt ihn zu. Gesichert wird 800 ms nach dem letzten
Tastendruck. Geht das nicht, bleibt der Text im Browser liegen und
wird nachgereicht -- und der Fuss sagt ehrlich „noch nicht
gesichert", statt einen Verlust zu melden, den man gerade nicht
verhindern kann.
2. DAS BLATT IST EIN SCHREIBFELD MIT EINER DECKSCHICHT. Das Feld
traegt Text und Cursor und ist unsichtbar; darueber zeichnet eine
zweite Schicht denselben Text noch einmal -- mit Kaestchen,
Ueberschriften, Strichen und Links.
DARAUS FOLGT EINE EISERNE REGEL, und sie steht dreimal im Code:
KEINE Auszeichnung darf die BREITE eines Zeichens aendern. Kein
Fettdruck, keine andere Groesse, keine Sperrung. Erlaubt sind nur
Farbe, Flaeche, Rahmen und Durchstreichen. Ein einziges
font-weight: 700 verschoebe den Umbruch, und ab der zweiten Zeile
stuende der sichtbare Text neben dem Cursor.
pruef-notizen misst das am echten Umbruch: eine Probe mit allen
Auszeichnungen und einer Zeile, die umbrechen MUSS. Sind beide
Schichten verschieden hoch, sitzt der Umbruch woanders. Mit
Gegenprobe -- Fettdruck auf der Deckschicht bricht die Deckung um
genau eine Zeile (30 px), und die Zeile wird rot.
3. DIE TASTATUR FUEHRT DIE LISTE FORT, NICHT EINE LEISTE. Ein
Spiegelstrich und Enter macht den naechsten Punkt, ein leeres
Kaestchen und Enter das naechste Kaestchen -- und ein GESETZTER
Haken wird dabei nicht mitgenommen, die naechste Aufgabe ist ja
noch nicht erledigt. Zweimal Enter beendet die Liste. Ein Klick
aufs Kaestchen hakt ab. Es gibt keine Werkzeugleiste, weil man beim
Schreiben nie den Stift wechselt.
UND: NIEMAND SIEHT DIE NOTIZEN EINES ANDEREN. Auch DogFather nicht.
Es gibt in workspace-notizen.js keinen siehtAlles()-Zweig, keinen
Umschalter, keine fremde Liste -- jede Abfrage hat person_id = ? fest
eingebaut. Die Kachel steht deshalb in „Fuer dich" und nicht in
„Taeglich": Die Gruppe sagt die wichtigste Eigenschaft, bevor man sie
anfasst.
NUR AUF DER TEAM-ADRESSE. Auf der Agenturadresse ist die Seite ein
404 -- auch fuer DogFather. Das ist dieselbe Trennung wie bei Chat,
Kalender und Aufgaben, und sie steht an zwei Stellen: in
GEHOERT_ZU_ADRESSE (die Datei) und in der Schnittstelle (die Daten).
Die Seite ist nur HTML; die Daten sind die Sache.
Dazu: sechs Papierfarben, Anheften, Suche mit Hervorhebung im Text,
Papierkorb mit dreissig Tagen und einem Eintrag in der
Aufbewahrungsliste (ohne den waere die Frist ein Satz in einem
Kommentar -- genau das ist dem Support am 24.09. passiert).
=================================================================
EIN FUND BEIM BAUEN, DER ALLEN GEHOERT
=================================================================
DELETE /workspace/api/notizen/:id gab es schon -- in
workspace-aufgaben.js, fuer die Notizen AN einer Aufgabe. Weil jener
Router frueher eingehaengt ist, hat er jeden Loeschversuch des Blocks
abgefangen und mit 404 beantwortet.
Von aussen sah das aus wie ein Fehler im neuen Modul: Anlegen ging,
Aendern ging, Loeschen nicht. Man sucht dann im eigenen Code, und dort
ist nichts. Express meldet so etwas nicht -- es nimmt die erste Route,
die passt, und schweigt ueber die zweite.
Der Block liegt jetzt unter /workspace/api/notizblock. Und
pruef-notizen geht seitdem den Routenbaum von express durch und meldet
jedes Paar aus Methode und Pfad, das zweimal vergeben ist. Gemessen:
307 Wege, keine Dublette. Die Pruefung gilt fuers ganze Haus, auch
wenn sie in dieser Datei steht -- hier ist sie gefunden worden.
Nebenbei berichtigt: pruef-crew-adresse verlangte von jedem Eintrag
der Haustafel HTTP 200 mit Inhalt. Das stimmte, solange dort nur
oeffentliche Dateien standen. notizen.html ist die erste Seite hinter
der Anmeldung -- sie antwortet mit 302, und das ist richtig. Gefragt
wird jetzt, was die Tafel wirklich meint: GIBT es das hier.
GEMESSEN, alles nach den Aenderungen:
pruef-notizen 76 Punkte, 0 Fehler (neu)
pruef-kachelfarben 31 Punkte, 0 Fehler (vorher 26)
pruef-kachel-universum 13 Punkte, 0 Fehler
pruef-crew-adresse 157 Punkte, 0 Fehler
pruef-buehne 230 Punkte, 0 Fehler -- notizen.html neu in
der Liste, schlechtester Kontrast 6,73:1,
also 50 % ueber der Grenze
pruef-rechtetafel, -haus-seiten, -struktur, -css-klassen,
-jeder-hat-eine-seite, -workspace-seiten, -kachelraster,
-rueckmeldung alle 0 Fehler
Co-Authored-By: Claude Opus 5 <[email protected]>
682 lines
32 KiB
JavaScript
682 lines
32 KiB
JavaScript
/* =====================================================================
|
|
Die eigene Adresse der Modi-App (10.09.2026)
|
|
|
|
crew.dogfather-universe.com
|
|
|
|
WARUM EINE EIGENE ADRESSE. Derselbe Grund, aus dem der Creator
|
|
Workspace am 06.09.2026 umgezogen ist (siehe workspace-umzug.js):
|
|
Auf einem Ursprung laesst sich genau EINE App installieren. Zwei
|
|
Manifeste mit verschachtelten Bereichen sind laut w3c/manifest
|
|
Nr. 1180 "strongly not recommended", und Chrome haelt sich daran --
|
|
der zweite Eintrag erscheint dann nur als Verknuepfung, nie als
|
|
eigene App. Filipe will fuer die Modis ausdruecklich eine eigene
|
|
App: "ich will dass es eine eigene app wird."
|
|
|
|
WAS SICH NICHT AENDERT: der Pfad /workspace/, der Dienst (4100), die
|
|
Datenbank, der Code. Getrennt wird ueber den HOSTNAMEN, nicht ueber
|
|
einen zweiten Prozess. Genau so machen es Hauptseite und Workspace
|
|
schon heute.
|
|
|
|
---------------------------------------------------------------------
|
|
DREI FALLEN, DIE MAN EINER BEDINGUNG NICHT ANSIEHT
|
|
---------------------------------------------------------------------
|
|
|
|
1. EIN MUSTER STATT EINER LISTE WAERE TOEDLICH.
|
|
/dogfather-universe\.com$/ passt auch auf
|
|
workspace.dogfather-universe.com -- und wuerde damit genau die
|
|
Adresse abschalten, die man schuetzen will. Deshalb hier zwei
|
|
feste Mengen und kein einziges Muster. (Dieselbe Ueberlegung
|
|
steht schon in workspace-umzug.js; sie hat dort einen Ausfall
|
|
verhindert und gilt hier unveraendert.)
|
|
|
|
2. "ALLES AUSSER crew." IST NICHT DASSELBE WIE "DIE ALTEN ADRESSEN".
|
|
Der naheliegende Satz waere: "Ein Modi darf ueberall rein, nur
|
|
nicht auf einer Adresse, die nicht crew heisst." Damit waeren
|
|
localhost, 127.0.0.1 und jede Pruefadresse eingeschlossen -- und
|
|
saemtliche Modi-Pruefungen wuerden ab sofort messen, dass ein
|
|
Modi nirgends hereinkommt, ohne dass irgendwo etwas rot wird.
|
|
Ein gruener Lauf, der nichts mehr prueft, ist schlimmer als ein
|
|
roter. Deshalb ist OHNE_MODI_HOSTS eine AUFZAEHLUNG der drei
|
|
echten Adressen. Wer eine vierte anlegt, traegt sie hier nach --
|
|
und pruef-crew-adresse.mjs sagt es ihm, wenn er es vergisst.
|
|
|
|
3. "FAENGT AN MIT /workspace" TRIFFT AUCH /workspaceXYZ.
|
|
Beim Workspace-Umzug waere das beinahe passiert. Hier gilt es
|
|
genauso, deshalb dieselbe Schreibweise: genau "/workspace" oder
|
|
alles unter "/workspace/", sonst nichts.
|
|
|
|
---------------------------------------------------------------------
|
|
WARUM DIE ALTE ADRESSE FUER MODIS ZUGEHT
|
|
---------------------------------------------------------------------
|
|
|
|
Ein Modi, der sich weiterhin auf workspace.dogfather-universe.com
|
|
anmelden koennte, haette zwei Anmeldungen, zwei Sitzungen und zwei
|
|
Apps auf dem Startbildschirm -- und der verborgene Zugang haette
|
|
damit eine zweite Spur genau dort, wo alle anderen arbeiten. Er
|
|
bekommt deshalb auf der alten Adresse KEINE Sitzung, sondern den
|
|
Hinweis auf die neue.
|
|
|
|
DASS DIESER HINWEIS DIE ADRESSE NENNT, IST KEIN LECK: Er erscheint
|
|
nur nach Eingabe eines gueltigen Modi-Codes. Wer den hat, ist Modi.
|
|
Fuer jeden anderen -- auch fuer jeden Manager mit gueltigem eigenen
|
|
Code -- veraendert sich an der alten Adresse ueberhaupt nichts.
|
|
|
|
---------------------------------------------------------------------
|
|
UND WARUM AUF DER NEUEN ADRESSE NUR MODIS HEREINKOMMEN
|
|
---------------------------------------------------------------------
|
|
|
|
Sonst waere crew. eine zweite, vollwertige Tuer in den Workspace --
|
|
und die erste Person, die sie zufaellig errät und ihren eigenen Code
|
|
eintippt, wuesste sofort, dass es hier noch etwas gibt. Ein fremder
|
|
Code bekommt dort deshalb dieselbe Antwort wie ein erfundener: die
|
|
Zugangswand sieht aus wie immer, und der Code stimmt nicht.
|
|
===================================================================== */
|
|
|
|
import { readdirSync } from "node:fs";
|
|
import { dirname, join } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
export const CREW_ADRESSE = "https://crew.dogfather-universe.com";
|
|
|
|
/** Und die Adresse des Agenturhauses.
|
|
*
|
|
* Sie stand bisher nur als Text in `anmeldeAdresseFuer` ganz unten.
|
|
* Seit die Wechselkachel in BEIDE Richtungen geht (24.09.2026), wird
|
|
* sie an zwei Stellen gebraucht -- und zwei gleiche Zeichenketten sind
|
|
* eine Umzugsadresse, die beim naechsten Umzug halb mitwandert. Das
|
|
* ist in diesem Haus schon passiert: Der Workspace ist am 06.09.2026
|
|
* umgezogen, und die Rueckmeldung an den Server lief danach ins Leere.
|
|
*
|
|
* KEINE ABLEITUNG AUS `OHNE_MODI_HOSTS`: Dort stehen drei Adressen
|
|
* (mit und ohne www, plus die Hauptseite). Welche davon die Tuer ist,
|
|
* waere geraten. */
|
|
export const WORKSPACE_ADRESSE = "https://workspace.dogfather-universe.com";
|
|
|
|
/* WELCHE SYMBOLGROESSEN HAT DIE CREW-APP EIGENS?
|
|
Abgeleitet aus dem Ordner, nicht aufgezaehlt: Fuer jede Datei
|
|
crew-<X>.png, zu der es auch workspace-<X>.png gibt, kann umgebogen
|
|
werden. Einmal beim Start gelesen -- pro Anfrage waere es ein
|
|
Dateisystemzugriff fuer eine Antwort, die sich nie aendert. */
|
|
const CREW_SYMBOLE = (() => {
|
|
try {
|
|
const ordner = join(dirname(fileURLToPath(import.meta.url)),
|
|
"..", "assets", "img", "app-symbole");
|
|
const da = new Set(readdirSync(ordner));
|
|
return new Set([...da]
|
|
.map((f) => f.match(/^crew-([0-9a-z-]+)\.png$/))
|
|
.filter(Boolean)
|
|
.map((m) => m[1])
|
|
.filter((x) => da.has(`workspace-${x}.png`)));
|
|
} catch { return new Set(); }
|
|
})();
|
|
|
|
/* =====================================================================
|
|
DAS TEAM VON DOGI -- WELCHE ROLLEN DAZUGEHOEREN
|
|
|
|
Blueprint V3.0, Kapitel 1.1 und 3.1: DogFather (Owner), die "rechte
|
|
Hand" (Deputy, eine Person, austauschbar) und die Modis. Die beiden
|
|
letzten leben ausschliesslich auf dieser Adresse und sind fuer die
|
|
Workspace-Welt unsichtbar. DogFather steht in beiden Welten und
|
|
gehoert deshalb NICHT in diese Menge -- sie beantwortet die Frage
|
|
"wer ist hier verborgen", nicht "wer gehoert zum Team".
|
|
|
|
WARUM SIE HIER STEHT UND NICHT IN workspace.js, wo das uebrige
|
|
Rollenmodell liegt: workspace.js importiert diese Datei. Stuende die
|
|
Menge dort, muesste diese Datei zurueckimportieren -- ein Kreis, den
|
|
Node zwar aufloest, aber mit halb gefuellten Modulen, und das faellt
|
|
erst zur Laufzeit auf. Diese Datei hat bewusst KEINE eigenen
|
|
Importe; sie ist damit der einzige Ort, an dem so etwas gefahrlos
|
|
stehen kann. workspace.js gibt sie fuer die Fachmodule weiter. */
|
|
/* Die linke Hand ist Team Dogi wie die rechte (21.09.2026) -- sie
|
|
fuehrt dieselben Leute durch denselben Tag. */
|
|
export const TEAM_DOGI_ROLLEN = new Set(["hand", "linke", "modi"]);
|
|
|
|
/* WER VON AUSSEN KOMMT (11.09.2026).
|
|
|
|
Die Community. Sie steht hier und nicht in workspace.js, weil diese
|
|
Datei von nichts abhaengt -- workspace.js importiert von hier, nicht
|
|
umgekehrt. Eine zweite Liste dort waere die, die auseinanderlaeuft.
|
|
|
|
Der Unterschied zu TEAM_DOGI_ROLLEN ist nicht die Verborgenheit,
|
|
sondern die Richtung: Das Team gehoert zum Haus und wird vor der
|
|
Agentur verborgen. Die Community gehoert NICHT zum Haus -- sie
|
|
bekommt nur, was ausdruecklich fuer sie da ist. */
|
|
export const AUSSEN_ROLLEN = new Set(["gast"]);
|
|
|
|
/* DER TREFF HAT KEINE EIGENE ADRESSE (Entscheidung Filipe, 11.09.2026:
|
|
"das soll keine app fuer sich sein, das soll in der crew seite
|
|
adaptiert werden").
|
|
|
|
Am Vormittag stand hier treff.dogfather-universe.com -- eine dritte
|
|
Tuer mit eigener Wand, eigenem Manifest, eigenen Buehnenbildern. Sie
|
|
ist wieder weg, und das gehoert aufgeschrieben, weil die Gruende
|
|
dafuer weiterhin gelten und beim naechsten Mal jemand dieselbe Idee
|
|
haben wird:
|
|
|
|
WAS DAFUER SPRACH: Auf einem Ursprung laesst sich genau EINE App
|
|
installieren. Und zwischen einem Mitglied der Community und den
|
|
Daten der Agentur stand damit ein Schloss mehr.
|
|
|
|
WAS DAGEGEN ENTSCHIEDEN HAT: Es waere ein drittes Haus gewesen --
|
|
mit eigener Wand, eigenem Namen, eigener App neben Team Dogi. Der
|
|
Treff ist aber kein drittes Haus, sondern ein Raum in Dogis.
|
|
|
|
WAS DER VERZICHT KOSTET, ehrlich benannt: Die Community steht jetzt
|
|
vor derselben Wand wie das Team und liest dort die Namen der drei
|
|
Team-Rollen (Filipes Entscheidung: vierte Kachel "Community" statt
|
|
gar keiner Kacheln). Und sie ist auf demselben Ursprung angemeldet
|
|
wie die Modis -- die Trennung haengt damit allein an der
|
|
Rechtetafel und an sitzungLesen(), nicht mehr zusaetzlich an der
|
|
Adresse. Das ist der Grund, warum pruef-treff seit heute NICHT
|
|
weniger prueft, sondern mehr: Was vorher die Adresse erledigt hat,
|
|
muss jetzt jede einzelne Regel halten. */
|
|
|
|
/* =====================================================================
|
|
DIE ZWEI HAEUSER -- WELCHE ROLLE WO WOHNT (24.09.2026)
|
|
=====================================================================
|
|
|
|
Filipe: „ich will dass du zuerst die komplette site vn der workspace
|
|
seite trennst. da soll nichts verknuepft sein. wenn ich bei der einen
|
|
was mache soll nichts bei der anderen passieren."
|
|
|
|
DAS KEHRT DIE ENTSCHEIDUNG VOM 10.09.2026 UM. Damals hiess es
|
|
ausdruecklich: „es soll trotzdem so bleiben dass ich die daten hier
|
|
und da sehe", und weiter unten in dieser Datei steht bis heute
|
|
„Getrennt wird also das AUSSEHEN, nicht der Bestand." Das gilt nicht
|
|
mehr. Wer den alten Satz liest, liest einen ueberholten Stand --
|
|
deshalb steht die Umkehr hier oben und nicht als Fussnote.
|
|
|
|
WARUM DIE MENGEN HIER STEHEN: Diese Datei hat keine eigenen Importe
|
|
und ist damit der einzige Ort, an dem eine Rollenmenge stehen kann,
|
|
ohne einen Kreis zu bauen. TEAM_DOGI_ROLLEN und AUSSEN_ROLLEN wohnen
|
|
aus demselben Grund hier.
|
|
|
|
DREI MENGEN UND NICHT ZWEI. „Alles ausser Team Dogi" waere die
|
|
naheliegende Formulierung fuer die Agentur -- und sie waere falsch,
|
|
denn DogFather gehoert in BEIDE Haeuser. Eine Bedingung durch
|
|
Ausschluss haette ihn stillschweigend der Agentur zugeschlagen. Genau
|
|
diese Bauart ist in dieser Datei schon dreimal schiefgegangen (siehe
|
|
Falle 2 im Kopf). Deshalb wird jede Rolle einzeln genannt.
|
|
|
|
UND EINE ROLLE MUSS IRGENDWO STEHEN: `hausVonRolle` gibt fuer eine
|
|
unbekannte Rolle `null` zurueck, nicht „beide" und nicht „agentur".
|
|
Ein `null` faellt auf -- `pruef-haustrennung` wird rot, sobald eine
|
|
Rolle in ROLLEN steht, die hier fehlt. Eine stille Voreinstellung
|
|
waere eine offene Tuer, die niemand bemerkt. */
|
|
|
|
/** Die Rollen, die ausschliesslich im Agenturhaus leben. */
|
|
export const AGENTUR_ROLLEN = new Set(["spicy", "manager", "scout", "creator"]);
|
|
|
|
/** Die Rollen, die in BEIDEN Haeusern arbeiten. Genau eine: DogFather.
|
|
* Als Menge und nicht als `rolle === "admin"`, damit die drei Mengen
|
|
* zusammen gegen ROLLEN geprueft werden koennen. */
|
|
export const BEIDE_HAEUSER_ROLLEN = new Set(["admin"]);
|
|
|
|
/**
|
|
* In welchem Haus wohnt diese Rolle?
|
|
*
|
|
* @returns {"crew"|"agentur"|"beide"|null} `null` heisst: unbekannte
|
|
* Rolle. Das ist ein Fehler, kein Standardfall.
|
|
*/
|
|
export function hausVonRolle(rolle) {
|
|
if (TEAM_DOGI_ROLLEN.has(rolle) || AUSSEN_ROLLEN.has(rolle)) return "crew";
|
|
if (AGENTUR_ROLLEN.has(rolle)) return "agentur";
|
|
if (BEIDE_HAEUSER_ROLLEN.has(rolle)) return "beide";
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Welche Rollen kommen in diesem Haus vor -- DogFather eingerechnet?
|
|
*
|
|
* ABGELEITET AUS DENSELBEN MENGEN, nicht abgeschrieben. Wer eine Rolle
|
|
* verschiebt, verschiebt damit jede SQL-Abfrage mit, die diese Funktion
|
|
* benutzt. Genau das Abschreiben hat am 24.09.2026 dazu gefuehrt, dass
|
|
* die „An wen"-Reihe sechs Leute zeigte und der Server vier belieferte.
|
|
*/
|
|
export function rollenImHaus(haus) {
|
|
const eigen = haus === "crew"
|
|
? [...TEAM_DOGI_ROLLEN, ...AUSSEN_ROLLEN]
|
|
: [...AGENTUR_ROLLEN];
|
|
return new Set([...eigen, ...BEIDE_HAEUSER_ROLLEN]);
|
|
}
|
|
|
|
/**
|
|
* Und welche Rollen gehoeren NUR dem anderen Haus?
|
|
*
|
|
* Das ist die Menge, nach der gefiltert wird -- nicht „welche gehoeren
|
|
* hierher". Der Unterschied ist DogFather: Er steht in beiden, also
|
|
* darf er in keiner der beiden Ausschlussmengen auftauchen. Eine Zeile,
|
|
* die „gehoert hierher" fragt, wuerde eine Aufgabe, die DogFather fuer
|
|
* einen Creator angelegt hat, ueber `erstellt_von` ins Team-Haus
|
|
* ziehen. Derselbe Gedanke steht bei ohneTeamDogi() in workspace.js.
|
|
*/
|
|
export function nurAnderesHaus(haus) {
|
|
return haus === "crew" ? new Set(AGENTUR_ROLLEN)
|
|
: new Set([...TEAM_DOGI_ROLLEN, ...AUSSEN_ROLLEN]);
|
|
}
|
|
|
|
/** Die Adresse von Team Dogi -- und seit 11.09.2026 auch die des
|
|
* Treffs. Feste Menge, kein Muster -- Falle 1. */
|
|
const CREW_HOSTS = new Set(["crew.dogfather-universe.com"]);
|
|
|
|
/** Die echten Adressen, auf denen ein Modi nichts verloren hat.
|
|
* Aufzaehlung und ausdruecklich NICHT "alles ausser crew" -- Falle 2. */
|
|
const OHNE_MODI_HOSTS = new Set([
|
|
"dogfather-universe.com",
|
|
"www.dogfather-universe.com",
|
|
"workspace.dogfather-universe.com",
|
|
]);
|
|
|
|
/** Nur der Name, ohne Port und in Kleinschreibung.
|
|
* Hostnamen sind laut RFC 4343 gross/klein-unempfindlich; ein Browser
|
|
* darf "Workspace.Dogfather-Universe.com" schicken. */
|
|
function nurHost(hostKopfzeile) {
|
|
return String(hostKopfzeile || "").toLowerCase().split(":")[0];
|
|
}
|
|
|
|
/** Kommt die Anfrage ueber die Adresse der Modi-App? */
|
|
export function istCrewAdresse(hostKopfzeile) {
|
|
return CREW_HOSTS.has(nurHost(hostKopfzeile));
|
|
}
|
|
|
|
/** Ist das eine der Adressen, auf denen Modis nicht mehr arbeiten? */
|
|
export function istOhneModiAdresse(hostKopfzeile) {
|
|
return OHNE_MODI_HOSTS.has(nurHost(hostKopfzeile));
|
|
}
|
|
|
|
/** Eine Pruefadresse -- localhost und die Nummern, unter denen die
|
|
* Pruefungen ihren eigenen Server starten.
|
|
*
|
|
* Sie steht hier als EIGENE Funktion und nicht als "alles, was keine
|
|
* der echten Adressen ist". Genau diese Formulierung durch Ausschluss
|
|
* hat am 11.09.2026 dazu gefuehrt, dass der verborgene Zugang auf der
|
|
* neuen dritten Wand mitgalt, ohne dass es jemand entschieden haette.
|
|
* Wer eine vierte Adresse baut, muss sie hier NICHT eintragen -- und
|
|
* bekommt dadurch von selbst das sichere Verhalten. */
|
|
export function istPruefAdresse(hostKopfzeile) {
|
|
const h = nurHost(hostKopfzeile);
|
|
return h === "localhost" || h === "127.0.0.1" || h.startsWith("127.")
|
|
|| h === "::1" || h === "[::1]";
|
|
}
|
|
|
|
/** Gehoert dieser Pfad zum Workspace-Teil? Genau "/workspace" oder
|
|
* alles darunter -- aber NICHT /workspaceXYZ (Falle 3). */
|
|
export function istWorkspacePfad(pfad) {
|
|
const p = String(pfad || "");
|
|
return p === "/workspace" || p.startsWith("/workspace/");
|
|
}
|
|
|
|
/* =====================================================================
|
|
WELCHE WAND GEHOERT ZU WELCHER TUER (11.09.2026)
|
|
=====================================================================
|
|
|
|
Drei Zugangswaende liegen als drei Dateien im selben Ordner, und
|
|
express.static liefert jede aus, die man beim Namen nennt. Ohne eine
|
|
Regel kann also jeder jede aufrufen: die Community die Wand von Team
|
|
Dogi, das Team die Wand des Treffs, und beide auf der Agenturadresse.
|
|
|
|
DAS WAR SCHON EINMAL EIN LOCH, und gefunden hat es nicht das Lesen,
|
|
sondern der Wortleck-Test, der ALLE ausgelieferten Dateien durchsucht.
|
|
Damals stand die Regel als EIN Sonderfall im Code ("auf den alten
|
|
Adressen gibt es crew-index.html nicht"). Bei der dritten Wand waeren
|
|
daraus drei Sonderfaelle geworden, bei der vierten sechs. Deshalb
|
|
steht hier jetzt eine Tafel: Jede benannte Wand nennt die Adresse,
|
|
auf die sie gehoert, und die Frage wird einmal beantwortet.
|
|
|
|
404 UND KEINE WEITERLEITUNG: "Gibt es nicht" verraet nichts. Eine
|
|
Weiterleitung wuerde sagen, dass es die Datei gibt, nur woanders.
|
|
|
|
/workspace/index.html STEHT ABSICHTLICH NICHT IN DER TAFEL. Sie ist
|
|
keine benannte Wand, sondern die Vorgabe -- jede Adresse biegt sie
|
|
auf ihre eigene um, bevor daraus eine Datei wird. Stuende sie hier,
|
|
bekaeme man auf crew. und treff. ein 404 statt der eigenen Wand.
|
|
|
|
AUF PRUEFADRESSEN GILT DIE TAFEL NICHT, und das ist dieselbe
|
|
Ueberlegung wie bei OHNE_MODI_HOSTS: Sonst koennten die Pruefungen,
|
|
die jede Wand im Browser ansehen, keine mehr oeffnen -- sie blieben
|
|
gruen und wuerden nichts mehr messen. Ein gruener Lauf, der nichts
|
|
mehr prueft, ist schlimmer als ein roter. */
|
|
/* Die Tafel bleibt eine Tafel und wird nicht wieder zum Sonderfall:
|
|
Sie ist der Ort, an dem der naechste Eintrag dazukommt, ohne dass
|
|
jemand drei Bedingungen umbauen muss.
|
|
|
|
---------------------------------------------------------------------
|
|
SEIT DEM 21.09.2026 STEHT HIER AUCH EINE STILVORLAGE
|
|
|
|
Im Kopf von crew-haus.css stand seit dem 10.09.: "Diese Datei wird
|
|
NUR auf crew.dogfather-universe.com ausgeliefert." Nachgemessen war
|
|
das falsch -- 27 806 Byte, HTTP 200, von der Agenturadresse, OHNE
|
|
Anmeldung. Die Weiche biegt `haus.css` auf diesen Namen um; wer den
|
|
Namen direkt nennt, kam an der Weiche vorbei.
|
|
|
|
Es war also wieder derselbe Befund: Ein Kommentar, der eine Absicht
|
|
beschreibt, erfuellt sie nicht. Und es war dieselbe Luecke wie bei
|
|
der Zugangswand am 10.09. -- express.static liefert jede Datei aus,
|
|
die man beim Namen nennt.
|
|
|
|
WAS DARIN STAND: das ganze Farbhaus von Team Dogi, mit seinen
|
|
Kommentaren -- darunter zweimal die Crew-Adresse im Klartext. Die
|
|
Adresse ist das eigentlich Verborgene; die Rollennamen stehen auf
|
|
der Zugangswand dort ohnehin offen (so gewollt: "3 rollen.
|
|
dogfather. rechte hand und modis"). Wer die Adresse hat, sieht sie.
|
|
Wer sie nicht hat, sollte sie nicht aus einer Stilvorlage der
|
|
Agenturseite erfahren.
|
|
|
|
DIE INTERNE UMBIEGUNG BLEIBT UNBERUEHRT, und das ist der Grund,
|
|
warum dieser Eintrag ueberhaupt funktioniert: Diese Tafel wird in
|
|
crewWeiche() ganz oben gefragt (Zeile ~323), die Umbiegung von
|
|
`haus.css` passiert weiter unten (~454). Auf crew. wird also nach
|
|
wie vor umgebogen -- dort ist die Datei zuhause --, und auf der
|
|
Agenturadresse gibt es sie beim Namen nicht mehr.
|
|
|
|
Nachgeprueft in pruef-crew-adresse: einmal, dass sie auf crew.
|
|
ankommt, und einmal, dass die Agenturadresse 404 sagt. Ohne die
|
|
zweite Haelfte waere der Eintrag eine Behauptung wie die, die er
|
|
ersetzt. */
|
|
export const GEHOERT_ZU_ADRESSE = [
|
|
{ datei: "/workspace/crew-index.html", zuhause: istCrewAdresse },
|
|
{ datei: "/workspace/assets/css/crew-haus.css", zuhause: istCrewAdresse },
|
|
/* DER NOTIZBLOCK (26.09.2026). Er gehoert zum Haus von Team Dogi,
|
|
und zwar vollstaendig: Auf der Agenturadresse gibt es die Seite
|
|
nicht -- auch nicht fuer DogFather, der in beiden Haeusern
|
|
arbeitet. Das ist dieselbe Trennung wie bei Chat, Kalender und
|
|
Aufgaben; ohne diesen Eintrag waere die Seite dort einfach
|
|
abrufbar, weil express.static jede Datei ausliefert, die man
|
|
beim Namen nennt. Die Schnittstelle prueft es ein zweites Mal
|
|
(nurTeamDogi in workspace-notizen.js) -- die Seite ist nur HTML,
|
|
die Daten sind die Sache. */
|
|
{ datei: "/workspace/notizen.html", zuhause: istCrewAdresse },
|
|
];
|
|
|
|
/** Wird hier eine Wand verlangt, die zu einer ANDEREN Tuer gehoert? */
|
|
export function istFremdeWand(hostKopfzeile, pfad) {
|
|
/* Mehrfache Schraegstriche zusammenziehen: express raeumt Punkt-
|
|
Segmente weg, doppelte Striche aber nicht -- und express.static
|
|
zieht sie danach selbst zusammen und liefert die Datei aus. Genau
|
|
daran ist am 04.09.2026 die Schranke des Workspace vorbeigelaufen. */
|
|
const p = String(pfad || "").toLowerCase().replace(/\/{2,}/g, "/");
|
|
const wand = GEHOERT_ZU_ADRESSE.find((w) => w.datei === p);
|
|
if (!wand) return false;
|
|
if (istPruefAdresse(hostKopfzeile)) return false;
|
|
const benannt = istOhneModiAdresse(hostKopfzeile) || istCrewAdresse(hostKopfzeile);
|
|
if (!benannt) return false;
|
|
return !wand.zuhause(hostKopfzeile);
|
|
}
|
|
|
|
/**
|
|
* Darf diese Person auf dieser Adresse angemeldet sein?
|
|
*
|
|
* Die eine Regel, aus der beide Richtungen folgen. Sie steht hier als
|
|
* eigene Funktion, damit sie ohne laufenden Server pruefbar ist -- und
|
|
* damit sie an GENAU EINER Stelle steht: sitzungLesen() in
|
|
* workspace.js. Jedes der 26 Fachmodule geht dort durch.
|
|
*
|
|
* @param {string} rolle Rolle der angemeldeten Person
|
|
* @param {string} hostKopfzeile Inhalt des Host-Kopffeldes
|
|
*/
|
|
export function sitzungPasstZurAdresse(rolle, hostKopfzeile) {
|
|
const team = TEAM_DOGI_ROLLEN.has(rolle);
|
|
/* AUSSENROLLEN GEHOEREN AUF GENAU EINE ADRESSE (11.09.2026).
|
|
|
|
Und die Bedingung steht in BEIDE Richtungen: Die Community kommt
|
|
NUR auf crew. herein (dort liegt der Treff), und auf den alten
|
|
Adressen kommt sie gar nicht herein. Ein Konto, das an zwei
|
|
Waenden funktioniert, ist eine Tuer, die man beim naechsten Umbau
|
|
uebersieht.
|
|
|
|
SEIT DEM 11.09.2026 IST DIESE ADRESSE crew. UND NICHT treff.
|
|
(Filipe: "das soll keine app fuer sich sein"). Die Richtung der
|
|
Regel hat sich dadurch umgedreht, die Regel selbst nicht: Es gibt
|
|
genau eine Adresse, auf der die Community angemeldet sein darf. */
|
|
const aussen = AUSSEN_ROLLEN.has(rolle);
|
|
/* crew.: das Team, die Community -- und DogFather, der in beiden
|
|
Welten arbeitet. */
|
|
if (istCrewAdresse(hostKopfzeile)) return team || aussen || rolle === "admin";
|
|
/* Die echten alten Adressen: alle ausser dem Team und der Community. */
|
|
if (istOhneModiAdresse(hostKopfzeile)) return !team && !aussen;
|
|
/* localhost, Pruefadressen: unberuehrt.
|
|
|
|
UND DAS GILT AUCH FUER DIE COMMUNITY (gemessen 11.09.2026). Der
|
|
erste Entwurf hatte hier ein "wer von aussen ist, kommt sonst
|
|
nirgends herein" stehen -- eine Bedingung durch AUSSCHLUSS, und sie
|
|
traf damit auch localhost. Ergebnis: Jede Pruefung des Treffs haette
|
|
ab sofort gemessen, dass ein Mitglied nirgends hereinkommt, und
|
|
waere gruen geblieben, ohne noch irgendetwas zu pruefen. Genau die
|
|
Falle, vor der oben in diesem Kopf Nummer 2 warnt -- und ich bin
|
|
am selben Tag zum dritten Mal hineingelaufen.
|
|
|
|
Jetzt nennt jede Zeile die Adresse, FUER DIE sie gilt. Wer eine
|
|
vierte baut, faellt hier unten heraus und bekommt "erlaubt" --
|
|
das ist auf einer Pruefadresse richtig und auf einer echten faellt
|
|
es sofort auf, weil pruef-crew-adresse jede echte Adresse
|
|
einzeln aufzaehlt. */
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Express-Zwischenschritt fuer die Adresse der Modi-App.
|
|
*
|
|
* Er macht zwei Dinge und ausdruecklich nichts mit Rechten -- die
|
|
* liegen in sitzungLesen():
|
|
*
|
|
* 1. NICHT INDIZIEREN. Die Adresse taucht heute in keinem oeffentlichen
|
|
* Zertifikatsprotokoll auf (nachgemessen am 10.09.2026: crt.sh
|
|
* kennt fuer dogfather-universe.com nur den Platzhalter-Eintrag).
|
|
* Eine Suchmaschine waere der zweite Weg, sie doch zu finden --
|
|
* der Kopf schliesst ihn. Er steht hier und nicht nur als
|
|
* <meta> im HTML, weil er dann auch fuer Bilder, Manifest und
|
|
* jede Antwort ohne HTML gilt.
|
|
*
|
|
* 2. NUR DER WORKSPACE. Auf crew. gibt es die Hauptseite nicht --
|
|
* sonst laege die komplette Dogfather-Website ein zweites Mal
|
|
* unter einer zweiten Adresse (doppelter Inhalt, und ein Weg,
|
|
* die Adresse ueber eine Suchmaschine zu finden). Alles ausserhalb
|
|
* von /workspace und /assets geht zur Zugangswand.
|
|
*
|
|
* Caddy tut Punkt 2 bereits mit derselben Weiche. Dass es hier ein
|
|
* zweites Mal steht, ist Absicht: Eine Schranke, die nur in einer
|
|
* Datei ausserhalb des Projekts existiert, faellt beim naechsten
|
|
* Serverumbau lautlos weg.
|
|
*/
|
|
export function crewWeiche(req, res, next) {
|
|
/* DIE FREMDE WAND -- fuer JEDE Adresse, auch fuer crew. selbst.
|
|
|
|
Sie steht vor der Weiche und nicht in ihrem Nein-Zweig. Dort stand
|
|
sie bis zum 11.09.2026, und das war richtig, solange es zwei Waende
|
|
gab: Die eigene kann man nicht "fremd" verlangen. Mit der dritten
|
|
stimmt das nicht mehr -- auf crew. ist die Wand des Treffs fremd,
|
|
und im Nein-Zweig waere diese Frage dort nie gestellt worden. */
|
|
if (istFremdeWand(req.get("host"), req.path)) {
|
|
return res.status(404).type("html").send("Nicht gefunden.");
|
|
}
|
|
|
|
if (!istCrewAdresse(req.get("host"))) return next();
|
|
|
|
res.setHeader("X-Robots-Tag", "noindex, nofollow");
|
|
|
|
/* DAS MANIFEST MACHT DIE APP (10.09.2026).
|
|
|
|
Beide Adressen liefern dieselben HTML-Dateien aus -- in jeder steht
|
|
<link rel="manifest" href="/workspace/app.webmanifest">. Auf der
|
|
Modi-Adresse soll dahinter aber ein anderes Manifest stehen: eigener
|
|
Name ("Team Dogi"), eigenes Symbol. Sonst hiesse die App auf dem
|
|
Startbildschirm eines Modis "Creator Workspace" und traege das
|
|
Zeichen mit der Chili -- die zu Spicy Media gehoert, nicht zu ihnen.
|
|
|
|
WARUM DIE ADRESSE UMGEBOGEN WIRD, STATT IN 30 HTML-DATEIEN EINE
|
|
ZWEITE ZEILE ZU SETZEN: Eine zweite Zeile muesste jemand bei jeder
|
|
neuen Seite mitschreiben, und wer sie vergisst, bekommt eine Seite,
|
|
die still zur falschen App gehoert. Hier steht es einmal.
|
|
|
|
ZWISCHENSPEICHER: Cloudflare nimmt den Hostnamen in den Schluessel
|
|
auf, die beiden Antworten koennen sich also nicht vermischen. Der
|
|
Browser ohnehin nicht -- fuer ihn sind es zwei Ursprunge. */
|
|
if (req.path === "/workspace/app.webmanifest") {
|
|
req.url = "/workspace/crew.webmanifest";
|
|
return next();
|
|
}
|
|
|
|
/* DAS SYMBOL AUF DEM IPHONE (22.09.2026) — DIE ZWEITE HAELFTE.
|
|
===================================================================
|
|
Der Block darueber ist seit dem 10.09. richtig, war aber nur die
|
|
halbe Miete, und seine eigene Begruendung sagt, warum: "Sonst
|
|
hiesse die App auf dem Startbildschirm eines Modis 'Creator
|
|
Workspace' und traege das Zeichen mit der Chili."
|
|
|
|
Genau das passierte -- auf dem iPhone. Android nimmt das Symbol
|
|
aus dem Manifest (also crew-192.png, richtig). iOS Safari nimmt
|
|
es NICHT von dort, sondern aus `<link rel="apple-touch-icon">`.
|
|
Und die Zeile steht in jeder HTML-Datei auf workspace-180.png.
|
|
|
|
Gemessen: crew-180.png und workspace-180.png sind verschiedene
|
|
Dateien (30 899 gegen 34 850 Byte). Ein Modi mit iPhone bekam die
|
|
Chili auf den Startbildschirm; derselbe Modi mit Android das
|
|
richtige Zeichen. Beim Blick auf den Bildschirm faellt so etwas
|
|
nie auf, weil kaum jemand beide Geraete nebeneinander hat.
|
|
|
|
DIESELBE LOESUNG WIE BEIM MANIFEST: umbiegen statt in 37 Dateien
|
|
eine zweite Zeile zu setzen. Wer eine Seite anlegt, schreibt
|
|
weiterhin workspace-*.png -- und bekommt auf crew. trotzdem das
|
|
richtige Symbol.
|
|
|
|
ABGELEITET, NICHT AUFGEZAEHLT: Umgebogen wird nur, wenn es die
|
|
Crew-Fassung wirklich gibt. workspace-1024.png (fuer TikTok) hat
|
|
keine, bleibt also unangetastet -- und eine kuenftige Groesse
|
|
kommt von selbst dazu, sobald jemand die Datei anlegt. */
|
|
const symbol = req.path.match(
|
|
/^\/assets\/img\/app-symbole\/workspace-([0-9a-z-]+)\.png$/);
|
|
if (symbol && CREW_SYMBOLE.has(symbol[1])) {
|
|
req.url = req.url.replace(
|
|
`/app-symbole/workspace-${symbol[1]}.png`,
|
|
`/app-symbole/crew-${symbol[1]}.png`);
|
|
return next();
|
|
}
|
|
|
|
/* DIE ZUGANGSWAND GEHOERT DOGI UND DEN MODIS (10.09.2026).
|
|
|
|
Filipe: "alles soll auf dogfather und die modis perfektionniert
|
|
werden auf der neuen modi seite."
|
|
|
|
Bis dahin stand hier die gewohnte Wand: Spicy-Media-Logo, "Creator
|
|
Workspace", fuenf Rollenkacheln -- fuer einen Modi war davon nichts
|
|
richtig. Jetzt liefert crew. eine eigene Seite mit eigener Buehne,
|
|
eigenem Namen und ohne Kachelreihe.
|
|
|
|
DAS KEHRT EINE FRUEHERE ENTSCHEIDUNG UM, und das gehoert
|
|
hierhergeschrieben: Vorher war die Wand absichtlich identisch --
|
|
wer die Adresse errat, sollte etwas Vertrautes sehen und nichts
|
|
ueber Modis erfahren. Filipe hat anders entschieden. Der Tausch
|
|
ist damit bewusst: Ein Ratender liest jetzt "Team Dogi". Alles
|
|
andere bleibt, wie es war -- sein Code funktioniert dort nicht.
|
|
|
|
ZWEI ADRESSEN, EINE DATEI: `/workspace/` und
|
|
`/workspace/index.html` fuehren beide zur Wand, also muessen beide
|
|
umgebogen werden. Die zweite zu vergessen waere nicht aufgefallen,
|
|
denn im Alltag tippt sie niemand. */
|
|
if (req.path === "/workspace/" || req.path === "/workspace/index.html") {
|
|
req.url = "/workspace/crew-index.html";
|
|
return next();
|
|
}
|
|
|
|
/* DIE BUEHNEN INNEN GEHOEREN AUCH DER MODI-APP (10.09.2026).
|
|
|
|
Filipe: "auch die hintergrund bilder vom crew espace sollen anderes
|
|
aussehen, der community angepasst wie die zugangscode seite die ist
|
|
mega."
|
|
|
|
Die neun Buehnen hinter den Seiten zeigen nicht bloss rotes Licht,
|
|
sondern das Spicy-Media-Logo selbst -- in `halle` und `arena` sogar
|
|
vielfach nebeneinander. Umfaerben haette daraus ein blaues fremdes
|
|
Logo gemacht, also etwas Schlimmeres. Es gibt jetzt eigene Motive
|
|
aus den Community-Bildern der Dogfather-Seite (tools/crew-buehnen.mjs).
|
|
|
|
WARUM DIE ADRESSE UMGEBOGEN WIRD UND NICHT DAS CSS: `start.css`
|
|
nennt die neun Bilder in neun Zeilen und wird an alle
|
|
ausgeliefert. Eine zweite Zeile je Szene fuer die Modi-App waere
|
|
achtzehn Zeilen, die zusammenpassen muessen -- und der Name der
|
|
Szene stuende dann doppelt da. Hier steht eine Regel.
|
|
|
|
UND SIE HAT KEIN FLACKERN: Das Bild wird beim ERSTEN Abruf schon
|
|
als das richtige geliefert. Eine Umschaltung per JavaScript haette
|
|
erst die Spicy-Buehne gezeigt und dann getauscht -- sichtbar, und
|
|
ausgerechnet auf der Seite, die niemand sehen soll. */
|
|
const buehne = /^\/workspace\/assets\/img\/(buehne-[a-z]+-(?:uhd|breit|schmal)\.webp)$/
|
|
.exec(req.path);
|
|
if (buehne) {
|
|
req.url = `/workspace/assets/img/crew-${buehne[1]}`;
|
|
return next();
|
|
}
|
|
|
|
/* DAS ZEICHEN IN DER KOPFLEISTE (10.09.2026).
|
|
|
|
`start.css` setzt links neben den Namen eine Chili -- als
|
|
CSS-Hintergrund, nicht als Bild im HTML. Auf der Modi-Adresse stand
|
|
damit oben links das Zeichen von Spicy Media, auf jeder Seite, den
|
|
ganzen Tag. Im Bildschirmfoto der Startseite war es das Erste, was
|
|
auffiel.
|
|
|
|
UEBER DIE ADRESSE UND NICHT UEBER JAVASCRIPT: Eine Umschaltung im
|
|
Browser haette erst die Chili gezeigt und sie dann getauscht --
|
|
sichtbar, und ausgerechnet an der Stelle, die man zuerst ansieht.
|
|
So kommt beim ersten Abruf schon der Husky.
|
|
|
|
Er liegt laengst da (marke-husky.webp) und wird auf der Zugangswand
|
|
und im App-Symbol ohnehin benutzt. Ein neues Bild waere eine Datei
|
|
mehr fuer dasselbe Zeichen. */
|
|
if (req.path === "/workspace/assets/img/marke-spicy.webp") {
|
|
req.url = "/workspace/assets/img/marke-husky.webp";
|
|
return next();
|
|
}
|
|
|
|
/* DAS HAUS (10.09.2026).
|
|
|
|
Filipe: "die leiste da und alles andere was noch rot ist auf team
|
|
dogi seite soll lila werden. richtig geiles lila und babyblau
|
|
mischung ueberall." Und davor: "ich will doch dass der eingang
|
|
hier getrennt ist von der workspace seite … aber es soll trotzdem
|
|
so bleiben dass ich die daten hier und da sehe."
|
|
|
|
Getrennt wird also das AUSSEHEN, nicht der Bestand. Dieselbe
|
|
Datenbank, dieselben Seiten, dasselbe Programm -- und zwei
|
|
Haeuser, die man nicht verwechseln kann.
|
|
|
|
Jede Seite laedt als LETZTE Stilvorlage `haus.css`. Auf der
|
|
Agenturadresse ist die leer, hier steht dahinter das ganze andere
|
|
Farbhaus. Warum ueber den Dateinamen und nicht ueber ein Attribut
|
|
am <html>: Ein Attribut muesste entweder JavaScript setzen (dann
|
|
laedt die Seite erst im falschen Ton und faerbt sich um -- auf
|
|
jeder Seite, bei jedem Aufruf) oder der Server muesste jede
|
|
HTML-Antwort umschreiben statt sie als Datei auszuliefern.
|
|
|
|
Der Dateiname reist mit einer Fassungsnummer (`?v=…`); die
|
|
Bedingung sieht deshalb nur auf den PFAD, nicht auf die ganze
|
|
Adresse. Genau daran waere sie sonst gescheitert -- lautlos, denn
|
|
ein nicht umgebogener Pfad liefert weiterhin eine gueltige
|
|
Datei. */
|
|
if (req.path === "/workspace/assets/css/haus.css") {
|
|
req.url = "/workspace/assets/css/crew-haus.css"
|
|
+ (req.url.includes("?") ? req.url.slice(req.url.indexOf("?")) : "");
|
|
return next();
|
|
}
|
|
|
|
if (istWorkspacePfad(req.path) || req.path.startsWith("/assets/")) return next();
|
|
return res.redirect(302, "/workspace/");
|
|
}
|
|
|
|
/** WO SICH JEMAND MIT DIESER ROLLE ANMELDET (19.09.2026).
|
|
*
|
|
* ANLASS: Beim Anlegen eines Zugangs zeigt die Verwaltung Name und
|
|
* Code -- aber nirgends, WELCHEN Link man dazuschicken muss. DogFather
|
|
* ruft den Code durchs Zimmer und der andere fragt "und wo?".
|
|
* Ausgerechnet der Kasten, der sagt "jetzt weitergeben", gab die
|
|
* Haelfte nicht mit, die man weitergeben muss.
|
|
*
|
|
* ABGELEITET AUS DENSELBEN MENGEN wie die Weiche selbst -- nicht aus
|
|
* einer zweiten Liste. Wer eine Rolle nach TEAM_DOGI_ROLLEN oder
|
|
* AUSSEN_ROLLEN verschiebt, verschiebt die Adresse mit. */
|
|
export function anmeldeAdresseFuer(rolle) {
|
|
return (TEAM_DOGI_ROLLEN.has(rolle) || AUSSEN_ROLLEN.has(rolle))
|
|
? CREW_ADRESSE
|
|
: WORKSPACE_ADRESSE;
|
|
}
|