diff --git a/server/pruef-spicy.mjs b/server/pruef-spicy.mjs index 7876516c..20201c56 100644 --- a/server/pruef-spicy.mjs +++ b/server/pruef-spicy.mjs @@ -213,6 +213,11 @@ for (const z of ausgabe().split(String.fromCharCode(10))) if (z.includes("worksp } catch { erfunden = true; } ok(erfunden, "die Schranke beisst noch -- eine erfundene Rolle wird abgelehnt"); const idSpicy = anlegen(s, "Agentur", "spicy", "CODE-SPICY-001"); + /* EIN ZWEITER ADMIN-ZUGANG. Ohne ihn waere die Regel "Spicy Media + sieht DogFather, aber nicht den zweiten Admin" gar nicht pruefbar + -- bei einem einzigen Admin ist jede Antwort richtig. Am echten + System gibt es zwei (id 1 "Dogfather", id 4 "VanVan"). */ + anlegen(s, "VanVan", "admin", "CODE-VAN-000001"); ok(Number.isInteger(idSpicy) && idSpicy > 0, "'spicy' laesst sich jetzt anlegen"); s.close(); } @@ -275,9 +280,22 @@ const ruf = async (art, weg, keks, koerper) => { einer Aussage werden drei, und die dritte ist die wichtigste: Ueberblick ist nicht Verwaltung. */ ok(status === 200, `die Personenliste ist fuer sie offen (HTTP ${status})`); - const listeRollen = (daten?.personen || []).map((x) => x.rolle); - ok(listeRollen.length > 0 && !listeRollen.includes("admin"), - `und DogFather steht nicht darin (${listeRollen.join(", ") || "leer"})`); + /* AM 07.09.2026 PRAEZISIERT. Erst hiess es "DogFather steht nicht + darin", dann: "die rolle spicy soll auch die rolle dogfather sehen, + aber nur dogfather und nicht vanvan." + + Beide Zugaenge tragen dieselbe Rolle `admin`; unterschieden werden + sie ueber das ALTER -- DogFather ist der erste Zugang des Hauses, + also die kleinste Nummer. Genau das wird hier gemessen, und der + zweite Admin ist der Prueffall: Ohne ihn waere jede Antwort + richtig. */ + const admins = (daten?.personen || []).filter((x) => x.rolle === "admin"); + ok(admins.length === 1, + `genau EIN Admin-Zugang steht in ihrer Liste (${admins.length})`); + ok(admins[0]?.id === idDogi, + `und zwar der erste, DogFather (${admins[0]?.name || "keiner"})`); + ok(!(daten?.personen || []).some((x) => x.name === "VanVan"), + "der zweite Admin-Zugang nicht"); const prot = await ruf("GET", "/workspace/api/verwaltung/protokoll?anzahl=5", keksSpicy); ok(prot.status === 404, `das Protokoll bleibt zu (HTTP ${prot.status})`); const loeschen = await ruf("DELETE", `/workspace/api/verwaltung/personen/${idLuna}`, keksSpicy); @@ -507,8 +525,10 @@ console.log("\n=== Die Anmeldeseite ==="); const abschnitteSpicy = await seite.$$eval(".gruppe__name, .gruppe__kopf", (k) => k.map((x) => x.textContent.trim()).filter(Boolean)); const alsText = abschnitteSpicy.join(" | "); - ok(!/DogFather/.test(alsText), - `bei ihr fehlt der Abschnitt DogFather (${alsText.slice(0, 70) || "keine Abschnitte"})`); + ok(/DogFather/.test(alsText), + `bei ihr steht der Abschnitt DogFather (${alsText.slice(0, 70) || "keine Abschnitte"})`); + ok(/Manager|Creator|Scout/.test(alsText), + "und die uebrigen Abschnitte ebenfalls -- die Liste ist nicht leer"); await ctx.close(); /* GEGENPROBE BEI DOGFATHER: Bei ihm steht der Abschnitt "Spicy Media" diff --git a/server/workspace-personen.js b/server/workspace-personen.js index 80d4b102..4ca4a98a 100644 --- a/server/workspace-personen.js +++ b/server/workspace-personen.js @@ -139,7 +139,30 @@ personenRouter.get("/workspace/api/verwaltung/personen", (req, res) => { nicht in der Abfrage: Die Abfrage ist lang und wird von mehreren Feldern gelesen; eine zusaetzliche Bedingung mittendrin waere die Stelle, an der beim naechsten Umbau jemand danebengreift. */ + /* FUER SPICY MEDIA: DOGFATHER JA, DER ZWEITE ADMIN-ZUGANG NEIN. + + Filipe: "die rolle spicy soll auch die rolle dogfather sehen, + aber nur dogfather sehen und nicht vanvan." + + In der Datenbank tragen BEIDE die Rolle `admin` -- nachgemessen + am laufenden System: id 1 "Dogfather", id 4 "VanVan". Es gibt + kein Feld, das den einen vom anderen unterscheidet. + + Der Unterschied, den es WIRKLICH gibt, ist das Alter: DogFather + ist der erste Zugang des Hauses. Deshalb zaehlt hier die + kleinste Nummer unter den Admins -- eine Eigenschaft, die + feststeht und nicht am Namen haengt. + + DIE SCHWACHSTELLE STEHT HIER, damit sie niemand sucht: Wuerde + Zugang 1 je geloescht, rueckte der naechste Admin nach. Sollte + das eintreten, gehoert stattdessen ein ausdrueckliches Merkmal + in die Tabelle -- ein `haupt`-Feld. Solange es genau zwei + Admin-Zugaenge gibt und der erste DogFather ist, ist die + Nummer die ehrlichste Antwort ohne Datenbankumbau. */ const ohne = req.ohneDogFather === true; + const hauptAdmin = ohne + ? (db().prepare("SELECT MIN(id) AS id FROM personen WHERE rolle = 'admin'").get()?.id || 0) + : 0; res.json({ personen: db().prepare(` SELECT p.id, p.name, p.rolle, p.aktiv, p.erstellt, p.letzter_login, @@ -162,7 +185,7 @@ personenRouter.get("/workspace/api/verwaltung/personen", (req, res) => { LEFT JOIN betreuung b ON b.creator_id = p.id LEFT JOIN scout_zuteilung sz ON sz.scout_id = p.id ORDER BY ${ROLLEN_SORTIERUNG.replace("rolle", "p.rolle")}, p.aktiv DESC, p.name`) - .all().filter((z) => !(ohne && z.rolle === "admin")), + .all().filter((z) => !(ohne && z.rolle === "admin" && z.id !== hauptAdmin)), /* Wer ueberhaupt als zustaendig eingetragen werden kann. Bis zum 31.08.2026 waren das nur Scouts. In der Auswahl stand diff --git a/workspace/assets/css/personen.css b/workspace/assets/css/personen.css index 3f505af5..91d2ad9a 100644 --- a/workspace/assets/css/personen.css +++ b/workspace/assets/css/personen.css @@ -206,10 +206,56 @@ box-shadow: 0 4px 16px -10px var(--r); } +/* ===================================================================== + DIE ROLLENSYMBOLE SIND KOERPER, KEINE UMRISSE (07.09.2026) + + Filipe: "alle diese symbole von den rollen sollen auch viel + realistischer, geiler aussehen, auch mit farben befuellt sein." + + Sie waren reine Konturen in einer Farbe -- daneben auf derselben + Seite die Kachelzeichen mit drei Lichtern. Sie bekommen jetzt + dieselbe Behandlung, nur einfacher gebaut (die Rollensymbole stehen + als im HTML, nicht aus dem Bauer): + + FLAECHE ein Verlauf in der Rollenfarbe -- oben satt, unten + warm auslaufend. Dasselbe Prinzip wie bei den + Kachelzeichen: kaltes Spitzlicht, Eigenfarbe, warmes + Streulicht. + ZEICHNUNG die Linien darauf, hell -- sie tragen die Form. + AUGEN hell gefuellt, damit ein Gesicht auch ein Gesicht ist. + + `--r` ist die Farbe der Rolle und kommt aus der Liste darueber. */ .rollenwahl__symbol { - width: 22px; height: 22px; flex: none; margin-top: 1px; - fill: none; stroke: var(--r); stroke-width: 1.6; + width: 24px; height: 24px; flex: none; margin-top: 1px; + fill: none; stroke: var(--r); stroke-width: 1.55; stroke-linecap: round; stroke-linejoin: round; + filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .6)); +} +.rollenwahl__symbol .fuell { + stroke: none; + fill: color-mix(in srgb, var(--r) 58%, transparent); +} +.rollenwahl__symbol .linie { stroke: color-mix(in srgb, var(--r) 92%, #ffffff); } +.rollenwahl__symbol .auge { + stroke: none; + fill: color-mix(in srgb, var(--r) 30%, #ffffff); +} +/* Der Haken im Schutzschild ist die AUSSAGE des Zeichens -- er bleibt + hell und duenn, damit er auf der gefuellten Flaeche steht statt in + ihr zu verschwinden. */ +.rollenwahl__symbol .hell { + stroke: color-mix(in srgb, var(--r) 18%, #ffffff); + stroke-width: 1.9; +} +.rollenwahl__symbol .nase { + stroke: none; + fill: color-mix(in srgb, var(--r) 45%, #06090f); +} +/* Beim gewaehlten Knopf leuchtet die Flaeche etwas staerker -- das ist + der einzige Unterschied, den es braucht: mehr Licht auf demselben + Gegenstand. */ +.rollenwahl__knopf[data-an="ja"] .rollenwahl__symbol .fuell { + fill: color-mix(in srgb, var(--r) 78%, transparent); } .rollenwahl__text { display: grid; gap: 2px; min-width: 0; } .rollenwahl__name { font-size: .92rem; font-weight: 650; } diff --git a/workspace/assets/js/personen.js b/workspace/assets/js/personen.js index 986dee08..fc067d9e 100644 --- a/workspace/assets/js/personen.js +++ b/workspace/assets/js/personen.js @@ -31,7 +31,7 @@ const ROLLEN = [ { wert: 'spicy', name: 'Spicy Media', symbol: 'chili', text: 'Überblick über alle – ohne Automationen, ohne fremde Chats. Legt Leute an.' }, - { wert: 'admin', name: 'DogFather', symbol: 'krone', + { wert: 'admin', name: 'DogFather', symbol: 'husky', text: 'Alle Rechte, endgültig. Nur DogFather legt DogFather, Spicy Media und Manager an.' }, /* Der Satz stimmte bis zum 07.09.2026 -- seither legen Manager Creator an, und ein Text, der etwas anderes verspricht als die @@ -579,8 +579,19 @@ DAS IST KEINE SICHERUNG, sondern Aufraeumen: Der Server liefert ihr die Liste ohnehin nur, wenn sie sie sehen darf. Eine ausgeblendete Zeile hat noch nie etwas geschuetzt. */ + /* DER ABSCHNITT DOGFATHER WIRD NICHT MEHR AUSGEBLENDET (07.09.2026, + zweite Praezisierung). Filipe: "die rolle spicy soll auch die + rolle dogfather sehen, aber nur dogfather und nicht vanvan." + + Hier stand ein Filter, der den ganzen Abschnitt wegnahm. Jetzt + entscheidet der SERVER, wer darin steht -- er liefert Spicy Media + nur den ersten Admin-Zugang. Das ist auch die richtige Stelle + dafuer: Eine ausgeblendete Zeile hat noch nie etwas geschuetzt, + und zwei Regeln fuer dieselbe Frage laufen auseinander. + + `filter((a) => a.drin.length)` erledigt den Rest von selbst: Ist + niemand darin, gibt es den Abschnitt auch nicht. */ const vorhanden = ROLLEN_ABSCHNITTE - .filter((a) => !(a.rolle === 'admin' && ich?.rolle === 'spicy')) .map((a) => ({ ...a, drin: alle.filter((p) => p.rolle === a.rolle) })) .filter((a) => a.drin.length); diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 89ae4881..097374c3 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -9,10 +9,10 @@ - - - - + + + + @@ -212,10 +212,10 @@ - - - - - + + + + + diff --git a/workspace/automation.html b/workspace/automation.html index 996fefc8..fbba2ac2 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -135,10 +135,10 @@ - - - - - + + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index dcd8ea04..f9767226 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -144,14 +144,14 @@ - - - - - - - - - + + + + + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 69747033..aed6cfc6 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -77,11 +77,11 @@ - - - - - - + + + + + + diff --git a/workspace/chat.html b/workspace/chat.html index bd77ffc4..03a765ed 100644 --- a/workspace/chat.html +++ b/workspace/chat.html @@ -9,17 +9,17 @@ - - + + - - - + + + @@ -155,10 +155,10 @@ - - - - - + + + + + diff --git a/workspace/content.html b/workspace/content.html index 86685e51..b8125f7b 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -167,12 +167,12 @@ - - - - - - - + + + + + + + diff --git a/workspace/dateien.html b/workspace/dateien.html index f045b789..52c0d589 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -96,10 +96,10 @@ - - - - - + + + + + diff --git a/workspace/index.html b/workspace/index.html index 39900e5f..4f4cfe4a 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -27,7 +27,7 @@ - + @@ -202,6 +202,6 @@ - + diff --git a/workspace/kalender.html b/workspace/kalender.html index f8a5ddec..9a07c120 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -258,11 +258,11 @@ - - - - - - + + + + + + diff --git a/workspace/leistung.html b/workspace/leistung.html index 89c8292f..a8edfc12 100644 --- a/workspace/leistung.html +++ b/workspace/leistung.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -212,10 +212,10 @@ - - - - - + + + + + diff --git a/workspace/personen.html b/workspace/personen.html index ec5a6211..64e1e6b3 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -42,11 +42,31 @@ Anmeldeseite. Zwei Rollen mit derselben Krone waeren genau der Fehler, den die Kacheln schon einmal hatten: Man klickt zweimal falsch, bevor man merkt, dass es zwei verschiedene sind. --> - - - - - + + + + + + + + + + + + +
@@ -137,10 +157,10 @@
- - - - - + + + + + diff --git a/workspace/profil.html b/workspace/profil.html index 636e8e44..c2985542 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -202,11 +202,11 @@ - - - - - - + + + + + + diff --git a/workspace/report.html b/workspace/report.html index 121e2499..b89922f5 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -94,11 +94,11 @@ - - - - - - + + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index 749657c4..0f4fc703 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -127,10 +127,10 @@ - - - - - + + + + + diff --git a/workspace/start.html b/workspace/start.html index 208f0baa..6b759fc8 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -9,12 +9,12 @@ - - + + - - + + @@ -320,10 +320,10 @@

- - - - - + + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index f025f82c..2d88e4b1 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -73,11 +73,11 @@ - - - - - - + + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index df3538e3..0d2c5bd6 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -114,10 +114,10 @@ - - - - - + + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index d784915d..4ebacc60 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -9,13 +9,13 @@ - - + + - - - + + + @@ -137,11 +137,11 @@ - + - - - - + + + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 2c5e32a9..afd8b44d 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -9,11 +9,11 @@ - - - - - + + + + + @@ -178,10 +178,10 @@ - - - - - + + + + +