Die Sicht wirkt jetzt auch auf die SEITE, nicht nur auf die Listen

Gemeldet: "ich hab oben die Ansicht von Tili ausgewaehlt und seh immer
noch die Seite genau wie meine." Das stimmte.

Der Umschalter war HALB gebaut. Die Daten dahinter folgten der Auswahl
(Aufgaben, Kalender, Dateien, Bereiche, Hinweise, Suche) -- die Seite
drumherum nicht: /workspace/api/ich lieferte immer den Angemeldeten, und
daraus baut die Startseite ihre Kacheln, die Rollenzeile und die
Begruessung. DogFather sah einen fremden Arbeitsplatz in seiner eigenen
Verkleidung.

ZWEI FEHLER STECKTEN DARIN.

1. /api/ich verschwieg die gewaehlte Sicht. Es liefert sie jetzt als
   eigenes Feld `sicht` -- NEBEN den eigenen Angaben, nicht an ihrer
   Stelle. Die Oberflaeche braucht beides: WER BIN ICH (Kopfleiste,
   "das bin ich" in Listen, alles was schreibt) und WESSEN ARBEITSPLATZ
   SEHE ICH (was gezeigt wird). Die beiden zu vermischen waere der
   sichere Weg dazu, dass irgendwann etwas unter fremdem Namen
   gespeichert wird.

2. EIN FEHLER DER REIHENFOLGE, und der war der eigentliche Grund.
   In kopf.js wurde `aktiv` (welche Sicht laeuft) erst in
   sichtAufbauen() gesetzt -- das laeuft ueber werZeigen(), also
   NACHDEM die Seite ihre erste Abfrage abgeschickt hat. Ausgerechnet
   /api/ich, aus dem Kacheln, Rolle und Begruessung entstehen, ging
   damit IMMER ohne die gewaehlte Sicht hinaus. Beide Zeilen waren fuer
   sich richtig; im Quelltext sieht man so etwas nicht.

WAS JETZT PASSIERT: In der Sicht auf einen Creator verschwinden die
Leitungs-Kacheln (18 -> 14, kein "Personen & Zugaenge", keine
"Automationen"), die Gruppe heisst "Wissen" statt "Team & System" --
genau wie bei ihm -- und unter dem Gruss steht "Arbeitsplatz von Tili ·
Creator". Plakette und Name oben bleiben die eigenen: Man ist weiterhin
man selbst, man sieht nur einen anderen Arbeitsplatz.

WARUM DIE PRUEFUNG DAS UEBERSEHEN HAT, und das ist die Lehre: Sie hat
geprueft, dass WENIGER AUFGABEN erscheinen -- und das stimmte ja. Sie
prueft genau die Haelfte, die fertig war. Jetzt prueft sie auch, dass
die Leitungs-Kacheln verschwinden, die Gruppentitel mitgehen und
dransteht, wessen Arbeitsplatz man ansieht.

Beim Schreiben dieser Pruefung dieselbe Falle noch einmal: Sie mass
"seine eigenen Kacheln", waehrend aus einem Abschnitt davor noch die
Scout-Sicht lief (die ueberlebt den Seitenwechsel, das ist gewollt), und
meldete einen Fehler, den es nicht gab. Eine Pruefung, die ihren eigenen
Ausgangszustand nicht herstellt, misst den Nachhall der vorigen.

31 von 31 Dateien, 1236 von 1236 Einzelpunkten.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-02 16:21:39 +02:00
co-authored by Claude Opus 5
parent 60c3edb10d
commit 1d54058760
39 changed files with 285 additions and 141 deletions
+74
View File
@@ -346,6 +346,80 @@ ok(parseFloat(nachher.rahmen) >= 1,
`ein Rahmen um die Seite erinnert daran (${nachher.rahmen}) – `
+ "der gefaehrlichste Fall ist, dass man es vergisst");
/* ================================================================
DIE SEITE SELBST MUSS SICH AENDERN, nicht nur die Listen.
Der Fehler, den diese Pruefung uebersehen hat (gemeldet 02.09.2026):
"ich hab oben die Ansicht von Tili ausgewaehlt und seh immer noch die
Seite genau wie meine."
Sie hat bisher nur geprueft, dass WENIGER AUFGABEN erscheinen -- und
das stimmte ja. Kacheln, Rollenzeile und Begruessung kamen aber
weiterhin von DogFather, weil /api/ich immer den Angemeldeten
lieferte. Der Umschalter war halb gebaut, und die Pruefung hat genau
die Haelfte geprueft, die fertig war.
Deshalb jetzt: Sieht man den Arbeitsplatz eines CREATORS, duerfen die
Kacheln der Leitung nicht mehr dastehen -- und es muss dranstehen,
WESSEN Arbeitsplatz das ist. */
console.log("\n=== Die Seite zeigt den fremden Arbeitsplatz, nicht den eigenen");
await bDogi.seite.goto(BASIS + "/workspace/start.html", { waitUntil: "networkidle" });
await bDogi.seite.waitForTimeout(1400);
/* ZUERST AUF DIE EIGENE SICHT ZURUECK. Der Abschnitt davor hat auf einen
Scout umgeschaltet, und die Auswahl ueberlebt den Seitenwechsel -- das
ist ja gerade gewollt. Ohne dieses Zuruecksetzen mass der erste Anlauf
"seine eigenen Kacheln" waehrend noch die fremde Sicht lief und
meldete einen Fehler, den es nicht gab.
Eine Pruefung, die ihren eigenen Ausgangszustand nicht herstellt,
misst den Nachhall der vorigen. */
await bDogi.seite.selectOption("#sicht-feld", "");
await bDogi.seite.waitForTimeout(1600);
const eigene = await bDogi.seite.evaluate(() => ({
kacheln: [...document.querySelectorAll(".kachel__name")].map((e) => e.textContent),
rolle: document.getElementById("rollentext")?.textContent,
}));
ok(eigene.kacheln.includes("Personen & Zugänge"),
`als er selbst sieht er die Leitungs-Kacheln (${eigene.kacheln.length} Kacheln)`);
await bDogi.seite.selectOption("#sicht-feld", String(idTili));
await bDogi.seite.waitForTimeout(1800);
const fremd = await bDogi.seite.evaluate(() => ({
kacheln: [...document.querySelectorAll(".kachel__name")].map((e) => e.textContent),
rolle: document.getElementById("rollentext")?.textContent,
gruppen: [...document.querySelectorAll(".gruppe__name")].map((e) => e.textContent),
}));
ok(!fremd.kacheln.includes("Personen & Zugänge"),
`in der Sicht eines Creators fehlen die Leitungs-Kacheln `
+ `(${eigene.kacheln.length} -> ${fremd.kacheln.length})`);
ok(!fremd.kacheln.includes("Automationen"), " auch die Automationen");
ok(fremd.kacheln.length < eigene.kacheln.length,
" die Seite zeigt wirklich weniger, nicht dasselbe");
ok(/Tili/.test(fremd.rolle || ""),
`und es steht dran, wessen Arbeitsplatz das ist ("${fremd.rolle}")`);
ok(/Creator/.test(fremd.rolle || ""),
" samt seiner Rolle");
/* Die Gruppe heisst fuer einen Creator "Wissen" statt "Team & System" --
ein weiterer Beleg, dass die SEITE der Sicht folgt und nicht nur die
Daten dahinter. */
ok(fremd.gruppen.includes("Wissen"),
`die Gruppentitel folgen ebenfalls (${fremd.gruppen.join(", ")})`);
await bDogi.seite.click(".sicht__weg");
await bDogi.seite.waitForTimeout(1600);
const zurueckSeite = await bDogi.seite.evaluate(() => ({
kacheln: [...document.querySelectorAll(".kachel__name")].map((e) => e.textContent),
rolle: document.getElementById("rollentext")?.textContent,
}));
ok(zurueckSeite.kacheln.includes("Personen & Zugänge")
&& !/Tili/.test(zurueckSeite.rolle || ""),
`zurueck bei sich sieht er wieder alles ("${zurueckSeite.rolle}")`);
await bDogi.seite.goto(BASIS + "/workspace/kalender.html", { waitUntil: "networkidle" });
await bDogi.seite.waitForTimeout(1200);
await bDogi.seite.selectOption("#sicht-feld", String(idPat));
await bDogi.seite.waitForTimeout(1800);
/* Und er BLEIBT beim Seitenwechsel -- sonst muesste man ihn auf jeder
Seite neu setzen, und genau das war der Wunsch ("ueberall"). */
await bDogi.seite.goto(BASIS + "/workspace/kalender.html", { waitUntil: "networkidle" });
+31
View File
@@ -876,9 +876,40 @@ workspaceRouter.get("/workspace/api/ich", (req, res) => {
if (z?.bild) bild = `/workspace/api/steckbrief/bild/${z.bild}`;
} catch { /* ohne Bild ist die Anmeldung trotzdem gültig */ }
/* WESSEN ARBEITSPLATZ WIRD GERADE ANGESEHEN (02.09.2026).
Ohne diese Angabe war der Umschalter nur halb gebaut: Die LISTEN
folgten der gewaehlten Sicht, die Seite drumherum nicht. DogFather
waehlte einen Creator -- und sah weiterhin seine eigene Begruessung,
seine Rolle und seine Kacheln. Gemeldet mit den Worten "ich seh
immer noch die Seite genau wie meine", und das stimmte.
`sicht` steht NEBEN den eigenen Angaben, nicht an ihrer Stelle. Die
Oberflaeche braucht beides: WER BIN ICH (fuer die Kopfleiste, fuer
"das bin ich" in Listen, fuer alles, was schreibt) und WESSEN
ARBEITSPLATZ SEHE ICH (fuer das, was gezeigt wird). Die beiden zu
vermischen waere der sichere Weg dazu, dass irgendwann etwas unter
fremdem Namen gespeichert wird.
Null, solange die eigene Sicht laeuft -- dann gibt es nichts zu
unterscheiden.
sichtPerson() wird hier direkt gerufen und nicht ueber req.sicht:
Die Middleware haengt erst NACH diesem Router (siehe index.js). */
const angesehen = sichtPerson(req);
const sicht = angesehen && angesehen.id !== person.id
? {
id: angesehen.id,
name: angesehen.name,
rolle: angesehen.rolle,
rolle_name: ROLLEN_NAME[angesehen.rolle] ?? angesehen.rolle,
}
: null;
res.json({
id: person.id, name: person.name, rolle: person.rolle,
rolle_name: ROLLEN_NAME[person.rolle] ?? person.rolle,
sicht,
bild,
});
});