Die rechte Hand verteilt Aufgaben und wechselt Rollen

Filipe: "jeder soll sich selber aufgabe vergeben koennen aber nur die
rechte hand und dogfather aufgaben an andere verteilen." Und: "ich will
dass ich da auch die rollen der leute wechseln kann ohne dass ich denen
einen neuen account machen muss ... perfektionier das fuer die rolle
dogfather und rechte hand."

---- AUFGABEN VERTEILEN ---------------------------------------------

Die Regel gab es schon -- sie fragte `istLeitung`, und darin steht die
rechte Hand NICHT. Sie konnte also keine Aufgabe weitergeben.

`hand` DORT EINZUTRAGEN WAERE FAHRLAESSIG GEWESEN: `istLeitung` wird an
57 Stellen in 19 Dateien gefragt -- unter anderem im vertraulichen
Meldeweg, in der Personenverwaltung und in den Auswertungen ueber
Menschen. Das haette in einem Zug ueber Einsicht in fremde Meldungen
entschieden, und das hat niemand gewollt.

Stattdessen `darfAufgabenVerteilen` -- eine eigene Regel mit eigenem
Namen. Man sieht an der Aufrufstelle, worum es geht, und wer sie
spaeter aendert, aendert genau diese eine Sache.

Wer nicht verteilen darf, bekommt KEINE Absage: Die Aufgabe landet bei
ihm selbst. Das ist genau, was Filipe wollte ("jeder soll sich selber
aufgabe vergeben koennen") und freundlicher als ein Fehler.

---- ROLLEN WECHSELN ------------------------------------------------

Auch das gab es schon, samt dem wichtigen Satz in der Rueckfrage: "Der
Zugangscode bleibt derselbe." Es konnte nur DogFather (und Spicy
Media).

DREI GRENZEN, JEDE MIT GRUND:
  * Niemand wird zu "admin" -- unveraendert seit dem 11.09.2026.
  * Die rechte Hand ernennt keine zweite rechte Hand. Wer jemanden auf
    die eigene Ebene hebt, vergibt Vertrauen, das ihm nicht gehoert.
    Und wer eine Rolle UEBER sich aendern koennte, koennte sich selbst
    befoerdern, indem er zuerst den anderen herabstuft.
  * Niemand aendert die eigene Rolle -- sonst waere jede Grenze nur ein
    Umweg.

SPICY MEDIA BEHAELT, WAS SIE HATTE. Beim ersten Anlauf waere sie durch
die neue Regel ausgesperrt gewesen -- ein Rueckschritt, den ich selbst
verursacht haette. Sie steht jetzt ausdruecklich in der Tabelle.

---- UND DIE OBERFLAECHE RECHNET NICHT MEHR SELBST ------------------

Die Rollenwahl nahm die Knoepfe des ANLEGE-Formulars. Fuer die rechte
Hand ist das leer -- sie legt niemanden an. Die Wahl waere leer
geblieben, das Recht unbenutzbar.

Der Server schickt jetzt zwei Listen mit: wozu ich machen darf
(`rollen_zum_aendern`) und wessen Rolle ich anfassen darf
(`rollen_anfassbar`). Beide aus denselben Funktionen wie die Schranke.
Damit kann die Seite weder zu streng sein (ein Recht, das niemand
findet) noch zu grosszuegig (ein Knopf, der eine Absage bringt) -- der
Fehler vom 10.09.2026, als zwei Listen drei Zeilen auseinander
einander widersprachen.

Dabei fast hineingelaufen: `ROLLEN_REIHE` ist die SORTIERUNG, und
darin fehlt "gast" mit Absicht. Wer sie fuer eine Aufzaehlung nimmt,
verliert die Community still -- genau diese Verwechslung hat am
17.09.2026 schon einmal verhindert, dass sich jemand zu "Community"
machen liess.

---- AUSSERDEM ------------------------------------------------------

Screen 2: "Unsere Seiten" und "Regeln & Hilfe" haben die Plaetze
getauscht -- nur diese zwei.

GEPRUEFT: pruef-verteilen 11/0 (neu, inkl. der Abgrenzung "darf
verteilen, ist aber NICHT Leitung"), pruef-rollen-anlegen 11/0,
pruef-personen-formular 36/0, pruef-personen-liste 33/0,
pruef-personen-loeschen 40/0, pruef-rechtetafel 19/0, pruef-treff 72/0.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-20 18:56:03 +02:00
co-authored by Claude Opus 5
parent e378514bb4
commit 01151574ae
43 changed files with 902 additions and 537 deletions
+157 -24
View File
@@ -212,6 +212,93 @@ const LEITUNG = new Set(["spicy", "admin", "manager"]);
export const istLeitung = (person) => !!person && LEITUNG.has(person.rolle);
export const istDogFather = (person) => !!person && person.rolle === "admin";
/* ===== WER DARF AUFGABEN AN ANDERE VERTEILEN? (20.09.2026) ==========
Filipe: "jeder soll sich selber aufgabe vergeben koennen aber nur die
rechte hand und dogfather aufgaben an andere verteilen."
WARUM EINE EIGENE REGEL UND NICHT `hand` IN DIE LEITUNG:
`istLeitung` wird an 57 Stellen in 19 Dateien gefragt -- unter
anderem im vertraulichen Meldeweg, in der Personenverwaltung und in
den Auswertungen ueber Menschen. Die rechte Hand dort ueberall
mitzunehmen waere eine Entscheidung ueber Einsicht in fremde
Meldungen, und die hat niemand getroffen.
Verteilen ist eine Frage fuer sich. Sie bekommt deshalb ihren
eigenen Namen: Man sieht an der Aufrufstelle, worum es geht, und
wer sie spaeter aendert, aendert genau diese eine Sache.
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";
/* ===== WER DARF EINE ROLLE AENDERN -- UND ZU WELCHER? (20.09.2026) ==
Filipe: "ich will dass ich da auch die rollen der leute wechseln kann
ohne dass ich denen einen neuen account machen muss mit einem neuen
code. einfach rolle wechseln und gut ist. perfektionier das fuer die
rolle dogfather und rechte hand. nur die sollen das machen koennen."
Das Wechseln selbst gab es schon -- der Zugangscode bleibt dabei
derselbe, das stand auch in der Rueckfrage. Es konnte nur DogFather.
DREI GRENZEN, UND JEDE HAT EINEN GRUND:
(1) NIEMAND WIRD ZU "admin". Das gilt seit dem 11.09.2026 fuer alle,
auch fuer DogFather selbst -- siehe ANLEGBAR. Hier aendert sich
daran nichts.
(2) DIE RECHTE HAND FASST KEINE ROLLE AN, DIE UEBER ODER NEBEN IHR
STEHT. Sie kann also einen Modi zur Community machen und
umgekehrt -- aber keinen DogFather antasten und keine zweite
rechte Hand ernennen. Wer jemanden auf die eigene Ebene hebt,
vergibt Vertrauen, das ihm nicht gehoert; das bleibt bei
DogFather. Und wer eine Rolle UEBER sich aendern koennte,
koennte sich selbst befoerdern, indem er zuerst den anderen
herabstuft.
(3) NIEMAND AENDERT DIE EIGENE ROLLE. Sonst waere jede Grenze oben
nur ein Umweg: erst sich selbst hochstufen, dann alles duerfen.
Was sie danach vergeben darf, steht in `rollenZumAendern` -- an
EINER Stelle, damit die Oberflaeche keine zweite Liste fuehrt. Genau
daran ist es am 10.09.2026 schon einmal gescheitert. */
const ROLLEN_ZUM_AENDERN = {
/* DogFather: alles, was er auch anlegen darf. */
admin: null, // null = dieselbe Liste wie ANLEGBAR
/* SPICY MEDIA STAND HIER SCHON, BEVOR ES DIESE TABELLE GAB -- sie
durfte Rollen wechseln, seit es den Weg gibt. Sie muss deshalb
drinstehen, sonst nimmt die neue Regel ihr etwas weg, das niemand
ihr wegnehmen wollte. `null` heisst: dasselbe wie beim Anlegen,
also Agenturrollen. */
spicy: null,
hand: ["modi", "gast"],
};
/** Welche Rollen darf diese Person an ANDERE vergeben? */
export function rollenZumAendern(person) {
if (!person) return [];
const eigen = ROLLEN_ZUM_AENDERN[person.rolle];
if (eigen === undefined) return [];
return eigen === null ? darfAnlegen(person) : [...eigen];
}
/** Darf diese Person die Rolle DIESES Menschen anfassen? */
export function darfRolleAendern(person, ziel) {
if (!person || !ziel) return false;
if (person.id === ziel.id) return false; // (3)
if (!rollenZumAendern(person).length) return false;
if (person.rolle === "admin") return ziel.rolle !== "admin";
/* Spicy Media wie bisher: das ganze Haus ausser DogFather. */
if (person.rolle === "spicy") return ziel.rolle !== "admin";
if (person.rolle === "hand") {
/* (2): nur unter sich -- nicht admin, nicht eine andere hand. */
return ziel.rolle !== "admin" && ziel.rolle !== "hand";
}
return false;
}
/* =======================================================================
WER DARF WEN ANLEGEN — die einzige Liste dazu (10.09.2026)
@@ -335,8 +422,20 @@ export function darfAnlegen(person) {
* wechseln" und "darf DIESE Rolle vergeben" sind zwei Fragen, und
* ihre Antworten laufen auseinander, sobald eine Rolle dazukommt.
*/
/* WER DARF DEN WEG "Rolle aendern" UEBERHAUPT BETRETEN?
*
* DIE RECHTE HAND KAM AM 20.09.2026 DAZU. Filipe: "perfektionier das
* fuer die rolle dogfather und rechte hand. nur die sollen das machen
* koennen."
*
* DIESE ZEILE OEFFNET NUR DIE TUER. Wen sie anfassen darf und wozu,
* entscheidet darfRolleAendern() / rollenZumAendern() weiter oben --
* dort steht auch, warum die rechte Hand keine zweite rechte Hand
* ernennen kann. Zwei getrennte Fragen, zwei getrennte Regeln: Wer
* hier etwas aendert, oeffnet keine Grenze versehentlich mit. */
export const darfRollenWechseln = (person) =>
!!person && (person.rolle === "admin" || person.rolle === "spicy");
!!person && (person.rolle === "admin" || person.rolle === "spicy"
|| person.rolle === "hand");
/* WER FUEHRT TEAM DOGI? (10.09.2026)
*
@@ -1061,27 +1160,8 @@ const TREFF_BEREICHE = [
zeichen: "content", ton: 30, ziel: "bereich.html?b=wunsch", szene: "portal" },
{ ...TREFF_GRUPPE, name: "Highlights", unter: "Eure Clips und Bilder",
zeichen: "live", ton: 29, ziel: "bereich.html?b=highlight", szene: "arena" },
{ ...TREFF_GRUPPE, name: "Regeln & Hilfe", unter: "Wie es hier l\u00e4uft",
/* ZEIGT JETZT AUF DIE SEITE, DIE DIE ANTWORT HAT (19.09.2026).
Sie fuehrte auf `bereich.html?b=regeln` -- ein Brett, auf das die
Leitung Regeln eintragen KANN und das am ersten Tag leer ist
("Hier stehen die Regeln des Treffs -- sobald sie eingetragen
sind.").
Die Regeln, die es WIRKLICH gibt, stehen auf `treff-regeln.html`:
Begruessung, die fuenf Regeln, die drei Stufen, das Mindestalter,
was bei Aerger zu tun ist. Diese Seite war von genau EINER Stelle
aus erreichbar -- einem kleinen Textlink unter der Unterzeile
einer Brettseite. Keine der elf Kacheln fuehrte hin.
Damit war die einzige "So laeuft das hier"-Seite des Hauses fuer
einen neuen Zuschauer praktisch unsichtbar, waehrend die Kachel,
die ihren Namen trug, auf eine leere Liste zeigte.
Das Brett gibt es weiter; treff-regeln.html verlinkt darauf. Ein
Ort fuer die Frage, nicht zwei. */
zeichen: "schutz", ton: 28, ziel: "treff-regeln.html", szene: "studio" },
{ ...TREFF_GRUPPE, name: "Unsere Seiten", unter: "Website, Shop & dein Rabatt",
zeichen: "hinaus", ton: 38, ziel: "unsere-seiten.html", szene: "portal" },
{ ...TREFF_GRUPPE, name: "Mitmachen", unter: "Wie du dazugeh\u00f6ren kannst",
zeichen: "personen", ton: 32, ziel: "bereich.html?b=mitmachen", szene: "garage" },
/* UNSERE SEITEN (19.09.2026) -- die einzige Kachel, die HINAUSFUEHRT.
@@ -1104,8 +1184,27 @@ const TREFF_BEREICHE = [
Kachel sind es fuer die Community 7 + 1 Kacheln = 9 Plaetze, also
genau drei volle Reihen. Vorher waren es acht Plaetze und damit
eine Luecke am Ende. Sie passt also nicht nur inhaltlich. */
{ ...TREFF_GRUPPE, name: "Unsere Seiten", unter: "Website, Shop & dein Rabatt",
zeichen: "hinaus", ton: 38, ziel: "unsere-seiten.html", szene: "portal" },
{ ...TREFF_GRUPPE, name: "Regeln & Hilfe", unter: "Wie es hier l\u00e4uft",
/* ZEIGT JETZT AUF DIE SEITE, DIE DIE ANTWORT HAT (19.09.2026).
Sie fuehrte auf `bereich.html?b=regeln` -- ein Brett, auf das die
Leitung Regeln eintragen KANN und das am ersten Tag leer ist
("Hier stehen die Regeln des Treffs -- sobald sie eingetragen
sind.").
Die Regeln, die es WIRKLICH gibt, stehen auf `treff-regeln.html`:
Begruessung, die fuenf Regeln, die drei Stufen, das Mindestalter,
was bei Aerger zu tun ist. Diese Seite war von genau EINER Stelle
aus erreichbar -- einem kleinen Textlink unter der Unterzeile
einer Brettseite. Keine der elf Kacheln fuehrte hin.
Damit war die einzige "So laeuft das hier"-Seite des Hauses fuer
einen neuen Zuschauer praktisch unsichtbar, waehrend die Kachel,
die ihren Namen trug, auf eine leere Liste zeigte.
Das Brett gibt es weiter; treff-regeln.html verlinkt darauf. Ein
Ort fuer die Frage, nicht zwei. */
zeichen: "schutz", ton: 28, ziel: "treff-regeln.html", szene: "studio" },
];
/* MELDUNGEN & MASSNAHMEN -- FUER DAS TEAM, NICHT FUER DIE COMMUNITY
@@ -5249,6 +5348,29 @@ workspaceRouter.get("/workspace/api/ich", (req, res) => {
`ich.rolle === 'admin'`, und dieselbe Zeile schaltete auch das
Loeschen frei; die beiden gehoeren nicht zusammen. */
darf_rollen_wechseln: darfRollenWechseln(person),
/* ZWEI LISTEN STATT EINER RECHNUNG IM BROWSER (20.09.2026).
Die Rollenwahl nahm bisher die Knoepfe des Anlege-Formulars --
also `darf_anlegen`. Fuer die rechte Hand ist das leer (sie legt
niemanden an), und damit waere die Wahl leer geblieben, obwohl
sie Rollen aendern darf. Ein Recht, das man hat und nicht
ausueben kann, ist keines.
`rollen_zum_aendern` = wozu darf ich machen
`rollen_anfassbar` = wessen Rolle darf ich ueberhaupt anfassen
Beide aus denselben Funktionen, die auch die Route fragt. Die
Oberflaeche fuehrt damit keine eigene Liste mehr -- genau daran
ist es am 10.09.2026 schon einmal gescheitert, als zwei Listen
drei Zeilen auseinander einander widersprachen. */
rollen_zum_aendern: rollenZumAendern(person),
/* [...ROLLEN] UND NICHT ROLLEN_REIHE: Die Reihe ist die
SORTIERUNG, und in ihr fehlt "gast" mit Absicht. Wer sie hier
nimmt, verliert die Community stillschweigend -- genau diese
Verwechslung hat am 17.09.2026 schon einmal dafuer gesorgt, dass
sich niemand zu "Community" machen liess. */
rollen_anfassbar: [...ROLLEN].filter((r) =>
darfRolleAendern(person, { id: -1, rolle: r })),
/* OB DER CHAT-KNOPF IN DER KOPFLEISTE ERSCHEINT (18.09.2026).
Er wurde auf JEDER Seite gebaut. Fuer ein Mitglied der Community
@@ -5280,6 +5402,17 @@ workspaceRouter.get("/workspace/api/ich", (req, res) => {
Rechnungen waeren die Stelle, an der die Seite ein Telefon
anbietet, das der Server ablehnt. */
darf_anrufen: darfTelefonieren(person),
/* DARF ICH AUFGABEN AN ANDERE GEBEN? (20.09.2026)
AUSDRUECKLICH GESAGT, NICHT ERRATEN. Das Aufgabenbrett fragte
bisher `LEITUNG.has(ich.rolle)` -- eine zweite Fassung derselben
Regel im Browser. Seit die rechte Hand verteilen darf, waere sie
die falsche gewesen: Der Server haette es erlaubt, die Seite
haette die Felder nicht gezeigt. Eine Berechtigung, die man
hat und nicht sieht, ist keine.
Aus DERSELBEN Funktion, die auch die Route benutzt. */
darf_verteilen: darfAufgabenVerteilen(person),
/* DIE KACHELN, WENN SIE NICHT IM BROWSER STEHEN DUERFEN.
Fuer die fuenf bekannten Rollen steht hier `null`, und die