diff --git a/server/crew-adresse.js b/server/crew-adresse.js index ff753e65..96b11afb 100644 --- a/server/crew-adresse.js +++ b/server/crew-adresse.js @@ -91,7 +91,9 @@ export const CREW_ADRESSE = "https://crew.dogfather-universe.com"; 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. */ -export const TEAM_DOGI_ROLLEN = new Set(["hand", "modi"]); +/* 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). diff --git a/server/pruef-rechtetafel.mjs b/server/pruef-rechtetafel.mjs index 30079ed0..e8db534c 100644 --- a/server/pruef-rechtetafel.mjs +++ b/server/pruef-rechtetafel.mjs @@ -95,8 +95,17 @@ melde("=== 1. Jede Rolle und jede Seite hat einen Eintrag ==="); const ausWorkspace = [...(w.ROLLEN_NAME ? Object.keys(w.ROLLEN_NAME) : [])].sort(); const ausTafel = [...rechte.ALLE_ROLLEN].sort(); ok(ausWorkspace.length > 0, `workspace.js kennt ${ausWorkspace.length} Rollen`); - ok(JSON.stringify(ausWorkspace) === JSON.stringify(ausTafel), - `beide Listen sind identisch (${ausTafel.join(", ")})`); + /* DIE MELDUNG MUSS SAGEN, WAS FEHLT -- nicht nur, dass etwas fehlt. + Vorher stand hier nur EINE der beiden Listen; beim Fehlschlag las + man "beide Listen sind identisch (a, b, c)" und musste raten, + welche der beiden das war. */ + const nurTafel = ausTafel.filter((r) => !ausWorkspace.includes(r)); + const nurWorkspace = ausWorkspace.filter((r) => !ausTafel.includes(r)); + ok(nurTafel.length === 0 && nurWorkspace.length === 0, + nurTafel.length === 0 && nurWorkspace.length === 0 + ? `beide Listen sind identisch (${ausTafel.join(", ")})` + : `nur in rechte.js: [${nurTafel.join(", ")}] · ` + + `nur in workspace.js: [${nurWorkspace.join(", ")}]`); } /* JEDE DATEI AUF DER PLATTE BRAUCHT EINEN EINTRAG. diff --git a/server/rechte.js b/server/rechte.js index bbea95b4..3719826e 100644 --- a/server/rechte.js +++ b/server/rechte.js @@ -67,6 +67,11 @@ * Rolle nur in einer der beiden Listen steht. */ export const ALLE_ROLLEN = [ "spicy", "admin", "manager", "scout", "creator", "hand", "modi", + /* DIE LINKE HAND (21.09.2026). Dieselbe Liste wie ROLLEN in + workspace.js -- pruef-rechtetafel haelt beide gegeneinander und + wird rot, sobald eine Rolle nur in einer steht. Genau das ist + beim Bauen passiert und hat den Eintrag hier gefunden. */ + "linke", /* DIE COMMUNITY (11.09.2026). Zuschauer mit einem Zugang, die den Treff sehen -- und sonst nichts. Sie steht hier NICHT in `ALLE` (siehe unten): Wer neu dazukommt, bekommt genau die zwei Seiten, @@ -455,6 +460,63 @@ export const SEITEN = { "/workspace/rechte.html": ["admin", "hand"], }; +/* ===================================================================== + DIE LINKE HAND BEKOMMT DIE SEITEN DER RECHTEN -- ABGELEITET + ===================================================================== (21.09.2026) + + Filipe: *"Die linke Hand erhaelt grundsaetzlich dieselben Rechte wie + die rechte Hand in allen Bereichen, die die Modis, Aufgaben, + Aufgabenzuweisungen, Uebersichten, Kommunikation und Auswertungen + betreffen."* + + WARUM ABGELEITET UND NICHT SIEBZEHNMAL "linke" HINGESCHRIEBEN: Die + naechste Seite, die jemand der rechten Hand gibt, bekaeme die linke + sonst nicht -- und das faellt niemandem auf, weil eine fehlende + Seite aussieht wie eine Seite, die es nicht gibt. Diese Schleife + kann das nicht vergessen. + + DIE AUSNAHMEN STEHEN EINZELN DA, MIT GRUND. Eine Ausnahme ohne + Begruendung ist beim naechsten Umbau eine, die jemand fuer ein + Versehen haelt und wegnimmt. */ +const LINKE_NICHT = { + /* Personen anlegen -- ausdruecklich im Auftrag ausgeschlossen. Die + LISTE der Leute braucht sie trotzdem, um Aufgaben zu verteilen; + die kommt aus /api/personen/liste und ist dort eigens geoeffnet. */ + "/workspace/personen.html": "legt Personen an", + /* Der Weg, auf dem neue Leute ueberhaupt hereinkommen. */ + "/workspace/bewerbungen.html": "fuehrt zu neuen Personen", + "/workspace/talente.html": "fuehrt zu neuen Personen", + /* Der vertrauliche Meldeweg. Das Empfindlichste im Haus -- Meldungen + ueber Menschen. Im Zweifel das kleinere Recht: Ein Wort von Filipe + oeffnet es, eine versehentlich gelesene Meldung laesst sich nicht + zurueckholen. Ein Modi darf ihn uebrigens auch nicht. */ + "/workspace/hilfe.html": "vertraulicher Meldeweg", + /* Wer die Rechtetafel bedient, verwaltet Konten -- nicht Aufgaben. */ + "/workspace/rechte.html": "Rechteverwaltung", +}; + +for (const [seite, rollen] of Object.entries(SEITEN)) { + if (!Array.isArray(rollen) || !rollen.includes("hand")) continue; + if (LINKE_NICHT[seite]) continue; + if (rollen.includes("linke")) continue; + /* EINE KOPIE, KEINE AENDERUNG AM ORIGINAL. Mehrere Seiten teilen + sich dieselbe Liste (`ALLE`). Wer die an Ort und Stelle aendert, + gibt die Rolle allen Seiten, die dieselbe Liste benutzen -- auch + denen, die gerade eine Ausnahme sind. Das faellt nicht auf, + solange keine Ausnahme `ALLE` benutzt, und knallt an dem Tag, an + dem eine es tut. + Direkt hinter die rechte Hand -- die Reihenfolge in diesen Listen + ist an einigen Stellen die Anzeigereihenfolge. */ + const kopie = rollen.slice(); + kopie.splice(kopie.indexOf("hand") + 1, 0, "linke"); + SEITEN[seite] = kopie; +} + +/** Welche Seiten der rechten Hand die linke NICHT bekommt -- und warum. + * Exportiert, damit die Pruefung die Begruendung mitlesen kann statt + * eine eigene Liste zu fuehren. */ +export const LINKE_AUSNAHMEN = LINKE_NICHT; + /* Die Zugangswaende. Sie haben keine Rolle, weil sich dort noch niemand angemeldet hat -- sie sind der Ort, an dem das passiert. Sie stehen hier nur, damit die Pruefung "jede Datei hat einen diff --git a/server/workspace-aufgaben.js b/server/workspace-aufgaben.js index f17c82e8..9829ae75 100644 --- a/server/workspace-aufgaben.js +++ b/server/workspace-aufgaben.js @@ -184,6 +184,8 @@ function sichtbarRoh(person) { gewollt und der kuerzeste ehrliche Weg, "diese beiden gleich" zu sagen. */ case "hand": + /* Die linke Hand sieht dasselbe wie die rechte (21.09.2026). */ + case "linke": case "modi": { const liste = [...TEAM_DOGI_ROLLEN].map((r) => `'${r}'`).join(", "); const modis = db().prepare( diff --git a/server/workspace-checkliste.js b/server/workspace-checkliste.js index 48a15ab8..5fa8e3f3 100644 --- a/server/workspace-checkliste.js +++ b/server/workspace-checkliste.js @@ -36,7 +36,7 @@ import express from "express"; import { db, sitzungLesen, istLeitung, istDogFather, siehtAlles, darfCreator, betreuteIds, protokolliere, echteIp, - siehtModis, TEAM_DOGI_ROLLEN, + siehtModis, TEAM_DOGI_ROLLEN, istHand, } from "./workspace.js"; import { MODI_PUNKTE, MODI_GRUPPENTEXTE } from "./workspace-modi-punkte.js"; import { @@ -367,7 +367,7 @@ checklisteRouter.get("/workspace/api/checkliste/:bereich", (req, res) => { koennen. Bewerten darf sie darin genauso wenig wie DogFather; das entscheidet `darf_bewerten` weiter unten und nicht diese Liste. Sehen und Druecken sind zwei Fragen. */ - if (req.person.rolle === "admin" || req.person.rolle === "hand") { + if (req.person.rolle === "admin" || istHand(req.person)) { for (const z of db().prepare( "SELECT id FROM personen WHERE rolle = 'modi' AND aktiv = 1").all()) ids.push(z.id); } @@ -433,7 +433,7 @@ checklisteRouter.get("/workspace/api/checkliste/:bereich", (req, res) => { ist schlicht falsch beschriftet. Das Wort kommt vom Server: Ein Rollenvergleich im Browser waere die Stelle, an der der Rollenname in einer ausgelieferten Datei landet. */ - wahl_name: req.person.rolle === "admin" || req.person.rolle === "hand" + wahl_name: req.person.rolle === "admin" || istHand(req.person) ? "Person" : "Creator", /* Die Oberflaeche soll nicht raten muessen, wer was darf -- sonst zeigt sie einem Creator einen Knopf, der beim Klicken 403 sagt. diff --git a/server/workspace-entwicklung.js b/server/workspace-entwicklung.js index 05c90e7c..ba0e9969 100644 --- a/server/workspace-entwicklung.js +++ b/server/workspace-entwicklung.js @@ -107,7 +107,7 @@ export const VERBLASST_NACH_TAGEN = 90; von Dogi -- nicht die Agentur, nicht die Community. Als Liste und nicht als "alle ausser X": Eine neue Rolle soll hier NICHT automatisch eine Personalakte bekommen. */ -const KARTEN_ROLLEN = ["hand", "modi"]; +const KARTEN_ROLLEN = ["hand", "linke", "modi"]; /** Wer einen Neuen einarbeiten kann. * @@ -116,7 +116,7 @@ const KARTEN_ROLLEN = ["hand", "modi"]; * dieselbe Arbeit wie alle anderen. Ein Manager oder Scout dagegen * arbeitet im anderen Haus und kann niemanden durch eine Schicht * begleiten, die er selbst nicht macht. */ -const BUDDY_ROLLEN = ["admin", "hand", "modi"]; +const BUDDY_ROLLEN = ["admin", "hand", "linke", "modi"]; /** Welchen Zugang der letzte Schritt des Trichters anlegt. * diff --git a/server/workspace-personen.js b/server/workspace-personen.js index c6ffcd2c..e5ed89f7 100644 --- a/server/workspace-personen.js +++ b/server/workspace-personen.js @@ -19,7 +19,7 @@ import express from "express"; naechsten Umzug stehen bleibt. */ import { anmeldeAdresseFuer } from "./crew-adresse.js"; import { - db, protokolliere, echteIp, sitzungLesen, personAnlegen, codeNeu, sitzungToken, personSperren, betreuungSetzen, scoutZuteilungSetzen, istLeitung, istDogFather, siehtModis, siehtAlles, ROLLEN_SORTIERUNG, ROLLEN_REIHE, istSpicy, verborgeneIds, TEAM_DOGI_ROLLEN, darfAnlegen, darfRollenWechseln, darfRolleAendern, rollenZumAendern, hausBedingung, + db, protokolliere, echteIp, sitzungLesen, personAnlegen, codeNeu, sitzungToken, personSperren, betreuungSetzen, scoutZuteilungSetzen, istLeitung, istDogFather, siehtModis, siehtAlles, ROLLEN_SORTIERUNG, ROLLEN_REIHE, istSpicy, verborgeneIds, TEAM_DOGI_ROLLEN, darfAnlegen, darfRollenWechseln, darfRolleAendern, rollenZumAendern, hausBedingung, istHand, } from "./workspace.js"; import { sicherungJetzt } from "./workspace-sicherung.js"; @@ -99,7 +99,10 @@ function nurAdmin(req, res, next) { WELCHE Menschen sie zu sehen bekommt, entscheidet sie nicht: Auf ihrer Adresse grenzt `hausBedingung` die Liste ohnehin auf Team Dogi ein. */ - if (person.rolle === "hand" && nurListe) { + /* AUCH DIE LINKE HAND -- ABER NUR DIE LISTE (21.09.2026). + Sie muss sehen, wem sie eine Aufgabe geben kann. Anlegen darf sie + niemanden; das entscheidet nicht diese Zeile, sondern ANLEGBAR. */ + if (istHand(person) && nurListe) { req.person = person; return next(); } @@ -381,6 +384,25 @@ personenRouter.get("/workspace/api/verwaltung/personen", (req, res) => { text: "Vertritt dich im Alltag und koordiniert das Team. Sieht " + "dieselben Aufgaben, Ideen und Angebote wie du – aber keine " + "privaten Kalender und keine Einzelchats.", + }, { + /* DIE LINKE HAND (21.09.2026). Filipe: "Die linke Hand + erhaelt grundsaetzlich dieselben Rechte wie die rechte Hand + in allen Bereichen, die die Modis, Aufgaben, + Aufgabenzuweisungen, Uebersichten, Kommunikation und + Auswertungen betreffen." + + DERSELBE HUSKY wie bei der rechten Hand -- sie tun + dasselbe, und ein eigenes Zeichen wuerde einen Unterschied + behaupten, den es im Alltag nicht gibt. Was sie + unterscheidet, steht im Text darunter, und zwar + vollstaendig: Wer nur "wie die rechte Hand" liest, legt + sie an und wundert sich spaeter. */ + wert: "linke", name: "Linke Hand", symbol: "husky", + text: "Dieselben Team- und Aufgabenrechte wie die rechte Hand – " + + "verteilt Aufgaben, sieht alle Auswertungen und den ganzen " + + "Treff. Kann aber keine Personen anlegen, keine Rollen " + + "ändern und sieht weder Bewerbungen noch den vertraulichen " + + "Meldeweg.", }] : []), ].sort((a, b) => { diff --git a/server/workspace-treff.js b/server/workspace-treff.js index dd088d17..ec3ad7af 100644 --- a/server/workspace-treff.js +++ b/server/workspace-treff.js @@ -74,7 +74,7 @@ import express from "express"; import { db, sitzungLesen, protokolliere, echteIp, - TREFF_BRETTER, TREFF_ROLLEN, ROLLEN_NAME, + TREFF_BRETTER, TREFF_ROLLEN, ROLLEN_NAME, istHand, } from "./workspace.js"; /* Die Tabellen und die Sperrfrage stehen in einem Blatt ohne eigene Importe -- workspace.js braucht beides ebenfalls, und ein Importkreis @@ -96,7 +96,7 @@ const TAG = 86400000; Treff. Genau dieser Fehler steckte am 11.09. schon einmal im stillen Zugang. ------------------------------------------------------------------- */ -export const TREFF_TEAM_ROLLEN = new Set(["modi", "hand", "admin"]); +export const TREFF_TEAM_ROLLEN = new Set(["modi", "hand", "linke", "admin"]); const TREFF_TEAM = TREFF_TEAM_ROLLEN; const TREFF_AUSSEN = new Set(["gast"]); @@ -251,7 +251,7 @@ export function darfMassnahme(person, art, dauerhaft) { /** Die längste Frist, die diese Rolle setzen darf (in Tagen). */ export const MODI_FRIST_TAGE = 7; export function fristErlaubt(person, tage) { - if (person?.rolle === "admin" || person?.rolle === "hand") return true; + if (person?.rolle === "admin" || istHand(person)) return true; return tage > 0 && tage <= MODI_FRIST_TAGE; } diff --git a/server/workspace-treffchat.js b/server/workspace-treffchat.js index 94c479d8..6d896900 100644 --- a/server/workspace-treffchat.js +++ b/server/workspace-treffchat.js @@ -98,7 +98,7 @@ export const TREFF_NAME = "Der Treff"; * ohne Moderation wäre nicht mutig, sondern fahrlässig — und die * Nachtruhe ist kein Ersatz dafür, sie verkürzt nur die Zeit, in der * jemand hinsehen muss. */ -export const TREFF_ROLLEN = ["gast", "modi", "hand", "admin"]; +export const TREFF_ROLLEN = ["gast", "modi", "hand", "linke", "admin"]; /** Ab wann und bis wann niemand schreibt — Ortszeit, Stunden. * diff --git a/server/workspace-werdegang.js b/server/workspace-werdegang.js index 10d5560c..91128810 100644 --- a/server/workspace-werdegang.js +++ b/server/workspace-werdegang.js @@ -153,7 +153,7 @@ const TAG = 86400000; * Import nur wegen zweier Zeichenketten die beiden Module * aneinanderbindet; `pruef-werdegang` vergleicht sie und wird rot, * wenn sie auseinanderlaufen. */ -export const KARTEN_ROLLEN = ["hand", "modi"]; +export const KARTEN_ROLLEN = ["hand", "linke", "modi"]; /** Wie viele Monatsspalten der Verlauf zeigt. * diff --git a/server/workspace.js b/server/workspace.js index 42ebdf3a..7213cfc5 100644 --- a/server/workspace.js +++ b/server/workspace.js @@ -98,7 +98,44 @@ const SITZUNG_TAGE = 180; const SITZUNG_MS = SITZUNG_TAGE * 86400_000; const VERSUCHE_MAX = 8; // pro IP const VERSUCHE_FENSTER_MIN = 10; -const ROLLEN = new Set(["spicy", "admin", "manager", "scout", "creator", "hand", "modi", "gast"]); +const ROLLEN = new Set(["spicy", "admin", "manager", "scout", "creator", + "hand", "linke", "modi", "gast"]); + +/* ===== DIE LINKE HAND (21.09.2026) ================================== + + Filipe, aus dem Auftrag: *"Die linke Hand erhaelt grundsaetzlich + dieselben Rechte wie die rechte Hand in allen Bereichen, die die + Modis, Aufgaben, Aufgabenzuweisungen, Uebersichten, Kommunikation + und Auswertungen betreffen. Die linke Hand darf keine neuen Personen + oder Accounts hinzufuegen. Die linke Hand darf keine privaten bzw. + persoenlichen Bereiche oder Informationen von Dogfather sehen."* + + DESHALB EINE MENGE UND NICHT DREISSIG ABSCHRIFTEN. Die Rolle "hand" + steht an 35 Stellen im Servercode. Haette ich ueberall ein "linke" + danebengeschrieben, waere die naechste Stelle, die jemand + hinzufuegt, die erste, die es vergisst -- und eine vergessene Stelle + heisst hier: Die linke Hand sieht etwas nicht, ohne dass jemand + merkt, warum. Genau diese Falle hat das Haus am 11.09. schon einmal + Datenspalten gekostet. + + WAS AUSDRUECKLICH NICHT DAZUGEHOERT -- und warum jedes einzeln: + + - Personen anlegen (ANLEGBAR) ausdruecklich im Auftrag + - Bewerbungen lesen das ist der Weg, auf dem + Personen hinzukommen + - Rollen aendern Kontoverwaltung, nicht + Aufgabenverwaltung + - der vertrauliche Meldeweg das Empfindlichste im Haus; + im Zweifel das kleinere Recht. + Ein Wort von Filipe kehrt das + um -- eine versehentlich + gelesene Meldung nicht. + + Die Menge steht hier oben, VOR allem, was sie benutzt. */ +export const WIE_RECHTE_HAND = new Set(["hand", "linke"]); + +/** Hat diese Person die Team-Rechte einer Hand (rechts oder links)? */ +export const istHand = (person) => !!person && WIE_RECHTE_HAND.has(person.rolle); /* DIE EINE REIHENFOLGE, IN DER ROLLEN UEBERALL ERSCHEINEN. @@ -125,7 +162,8 @@ const ROLLEN = new Set(["spicy", "admin", "manager", "scout", "creator", "hand", 'gast' (Community) steht mit Absicht NICHT in der Liste: Sie faellt dadurch ans Ende (siehe ELSE unten), und das ist richtig -- die Community ist keine Stufe im Team. */ -export const ROLLEN_REIHE = ["spicy", "admin", "hand", "manager", "scout", "creator", "modi"]; +export const ROLLEN_REIHE = ["spicy", "admin", "hand", "linke", "manager", + "scout", "creator", "modi"]; /* DIE ROLLEN MIT EINER KACHEL AUF DER ANMELDESEITE. @@ -168,7 +206,8 @@ const ROLLEN_KACHEL = new Set(["spicy", "admin", "manager", "scout", "creator"]) * 10.09. waere wieder umgeworfen worden. Er hat sich fuer die vierte * Kachel entschieden; der Preis ist damit bewusst bezahlt und nicht * uebersehen. */ -const CREW_KACHEL = new Set(["admin", "hand", "modi", "gast"]); +/* Die linke Hand meldet sich ueber dieselbe Wand an wie die rechte. */ +const CREW_KACHEL = new Set(["admin", "hand", "linke", "modi", "gast"]); /** Die Rollen mit einer Kachel auf der Zugangswand von treff. * @@ -231,7 +270,7 @@ export const istDogFather = (person) => !!person && person.rolle === "admin"; spicy und manager bleiben drin: Auf der Agenturseite verteilen sie seit jeher Aufgaben, und daran soll sich nichts aendern. */ export const darfAufgabenVerteilen = (person) => - istLeitung(person) || person?.rolle === "hand"; + istLeitung(person) || istHand(person); /* ===== WER DARF EINE ROLLE AENDERN -- UND ZU WELCHER? (20.09.2026) == @@ -396,6 +435,12 @@ const ANLEGBAR = { spicy: ["spicy", "manager", "scout", "creator"], /* Ein Manager stellt Creator ein, die er dann auch betreut. */ manager: ["creator"], + /* DIE LINKE HAND LEGT NIEMANDEN AN (21.09.2026) -- ausdruecklich im + Auftrag. Sie stuende auch ohne diese Zeile auf [] (darfAnlegen + nimmt `?? []`), aber dann saehe es aus wie vergessen. Eine + ausdrueckliche leere Liste ist eine Entscheidung, eine fehlende + Zeile ist eine Luecke. */ + linke: [], }; /** Welche Rollen darf diese Person anlegen? Immer ein Feld, nie null — @@ -449,6 +494,11 @@ export function darfAnlegen(person) { export const darfRollenWechseln = (person) => !!person && (person.rolle === "admin" || person.rolle === "spicy" || person.rolle === "hand"); +/* OHNE "linke" -- UND DAS IST ABSICHT, KEIN VERGESSEN (21.09.2026). + Eine Rolle zu aendern ist Kontoverwaltung. Der Auftrag sagt zur + linken Hand ausdruecklich "keine neuen Personen oder Accounts + hinzufuegen"; wer Rollen vergeben kann, kann sich selbst und andere + zu allem machen, was es gibt. Deshalb hier die kleinere Antwort. */ /* WER FUEHRT TEAM DOGI? (10.09.2026) * @@ -463,7 +513,7 @@ export const darfRollenWechseln = (person) => * vergisst. Der Eingang ruft ab jetzt hierher. */ export const fuehrtTeamDogi = (person) => - !!person && (person.rolle === "admin" || person.rolle === "hand"); + !!person && (person.rolle === "admin" || istHand(person)); /* ======================================================================= SPICY MEDIA (07.09.2026) @@ -650,6 +700,12 @@ export const ROLLEN_NAME = { scout: "Scout", creator: "Creator", hand: "Rechte Hand", + /* DIE LINKE HAND (21.09.2026). Ohne diesen Eintrag heisst sie + ueberall dort, wo der Rollenname steht -- im Treff, an einem + Beitrag, in der Personenliste -- schlicht "linke". Gefunden hat + das pruef-rechtetafel, weil sie diese Tabelle gegen ROLLEN haelt + und rot wird, sobald eine Rolle nur in einer der beiden steht. */ + linke: "Linke Hand", modi: "Modi", /* DIE COMMUNITY (11.09.2026). Der Name steht hier und NICHT in einer Datei, die jeder herunterlaedt -- ausgeliefert wird er nur an den, @@ -1316,7 +1372,7 @@ export const TREFF_BRETTER = [...new Set([ /* Wer den Treff ueberhaupt sehen darf: die Community selbst und das Team von Dogi. Die Agentur ausdruecklich nicht -- Creator, Scouts und Spicy Media haben mit den Zuschauern dieses Streams nichts zu tun. */ -export const TREFF_ROLLEN = new Set(["gast", "modi", "hand", "admin"]); +export const TREFF_ROLLEN = new Set(["gast", "modi", "hand", "linke", "admin"]); /* DER VERTRAULICHE MELDEWEG (19.09.2026). @@ -1479,7 +1535,7 @@ const TREFF_MIT_EIGENEM = [...TREFF_BEREICHE, HILFE_KACHEL, STECKBRIEF_KACHEL_TR export function bereicheFuer(person) { if (person?.rolle === "modi") return MODI_MIT_TREFF; - if (person?.rolle === "hand") return HAND_MIT_TREFF; + if (istHand(person)) return HAND_MIT_TREFF; /* DIE COMMUNITY SIEHT DEN TREFF UND SONST NICHTS (11.09.2026) -- seit dem 19.09. plus den eigenen Steckbrief. */ if (person?.rolle === "gast") return TREFF_MIT_EIGENEM; @@ -1865,7 +1921,7 @@ export function kategoriePersonen(person) { /* Ein Modi arbeitet ausschliesslich an eigenen Aufgaben -- dort gilt sie immer, unabhaengig davon, wen er eintraegt. */ if (person.rolle === "modi") return null; - if (person.rolle !== "admin" && person.rolle !== "hand") return []; + if (person.rolle !== "admin" && !istHand(person)) return []; try { /* Auch die rechte Hand selbst: Sie traegt Aufgaben ein -- fuer andere UND fuer sich. Waere ihre eigene Nummer nicht dabei, @@ -1884,10 +1940,12 @@ export function kategoriePersonen(person) { die anderen zu stellen: Sie haelt den Ueberblick, sie steht nicht darueber. */ const HAND_ROLLENTEXT = "Rechte Hand · du hast alles im Blick und entscheidest mit"; +const LINKE_ROLLENTEXT = "Linke Hand · du fuehrst das Team durch den Tag"; export function rollentextFuer(person) { if (person?.rolle === "modi") return MODI_ROLLENTEXT; if (person?.rolle === "hand") return HAND_ROLLENTEXT; + if (person?.rolle === "linke") return LINKE_ROLLENTEXT; /* DIE COMMUNITY HATTE NUR EIN WORT (nachgetragen 19.09.2026). Bei jeder anderen Rolle steht unter dem Titel ein Satz. Beim @@ -3417,6 +3475,20 @@ function umstellungen(d) { Transaktion, Indizes zurueck. */ checkListeErweitern(d, "personen", "rolle", "gast", ["spicy", "admin", "manager", "scout", "creator", "modi", "hand", "gast"], jetztStempel); + /* DIE LINKE HAND (21.09.2026) -- UND SIE STEHT MIT ABSICHT GANZ + UNTEN, NICHT BEI DER RECHTEN HAND. + + `checkListeErweitern` baut die Regel NEU aus der Liste, die man + ihm gibt. Stand mein Schritt weiter oben, nahm der Schritt fuer + "gast" darunter die Rolle wieder heraus -- seine Liste kennt sie + ja nicht. Die Kette ist kumulativ und deshalb von der Reihenfolge + abhaengig; wer hier etwas einschiebt, gehoert ans ENDE. + + Ohne diesen Schritt laesst die Datenbank die Rolle nicht zu -- und + zwar erst beim ersten echten Anlegen, nicht beim Start. */ + checkListeErweitern(d, "personen", "rolle", "linke", + ["spicy", "admin", "manager", "scout", "creator", "modi", "hand", + "gast", "linke"], jetztStempel); /* DER BEREICH FUER DAS IDEEN-BOARD (10.09.2026, Kapitel 5.6). @@ -6452,7 +6524,7 @@ export function protokollLesen(anzahl = 20) { * -- und das sagt bei der Community ueberall Nein. Zwei verschiedene * Fragen, zwei verschiedene Funktionen; wer sie in eine legt, kann * spaeter nicht mehr sagen, welche gerade zugeschlagen hat. */ -const HAUS_TEAM_ROLLEN = new Set(["admin", "hand", "modi", "gast"]); +const HAUS_TEAM_ROLLEN = new Set(["admin", "hand", "linke", "modi", "gast"]); function nurHaus(ids, person) { if (person?.haus !== "crew") return ids; diff --git a/workspace/anruf-probe.html b/workspace/anruf-probe.html index afe6f0d8..b9e87786 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`. --> - - + + - +