Das Ideen-Board -- und fuenf Kacheln, die ins Leere fuehrten

KAPITEL 5.6: "Sammelstelle fuer Content-, Live- und Community-Ideen mit
Priorisierung." Fast nichts davon musste neu gebaut werden: `eintraege`
hat Titel, Text, Status und `dringlichkeit` (hoch/mittel/niedrig) -- und
das IST die Priorisierung. Eine eigene Tabelle daneben waere eine VIERTE
Sichtbarkeitsregel gewesen; genau deren Vervielfaeltigung hat heute
schon ein Leck verursacht.

Der Bereich gehoert niemandem einzeln (`ohneCreatorBezug`) -- eine Idee
gehoert der Runde. KEIN `fuerAlle`: Das waere der naheliegende Griff
gewesen und der falsche, denn es heisst woertlich JEDER. Wer die
Sammlung sieht, entscheidet dieselbe Regel wie ueberall.

DER RISKANTE TEIL WAR DIE DATENBANK. Die erlaubten Bereiche stehen als
CHECK-Regel, und SQLite kann die nicht aendern -- die Tabelle muss neu
gebaut werden. Die alte Umstellung fuer 'agentur' schreibt dafuer den
ganzen Bauplan von Hand ab; im Kommentar dort steht, dass dabei schon
einmal drei Spalten vergessen wurden. Statt einer vierten Abschrift ist
die Fassung von heute Morgen jetzt tabellenunabhaengig
(checkListeErweitern): Spaltenliste aus der Tabelle, Sicherung vorher,
Zaehlung innerhalb der Transaktion.

UND DABEI WAERE EIN STILLER TOTALAUSFALL PASSIERT. Das Muster fuer den
Tabellenkopf stand in einem Template-Literal -- dort verschluckt
JavaScript den Backslash, aus `\s` wird `s`, das Muster hiess
"CREATE TABLEs+..." und traf nie etwas. Die Umstellung haette
SCHWEIGEND nichts getan: kein Fehler, kein Hinweis, nur ein Bereich, den
es nie gegeben haette. Im Quelltext war das nicht zu sehen; gefunden hat
es eine Messung. Jetzt steht dort gar kein Muster mehr -- alles vor der
ersten Klammer IST der Tabellenkopf, und das kann man nicht falsch
maskieren.

Die Pruefung baut deshalb eine ECHTE ALTE Tabelle und laesst die
Umstellung darauf laufen. Eine frische Datenbank bringt den Bereich
schon mit -- die Umstellung liefe gar nicht erst an, und alles waere
gruen, ohne das Riskante angesehen zu haben.

=== DER GROESSERE FUND ===

FUENF VON ZEHN MODI-KACHELN FUEHRTEN INS LEERE. Der Server hat eine
Liste, welche Rolle welche Seite oeffnen darf; bereich.html und
profil.html schlossen 'modi' aus. Vier Bereichs-Kacheln und das eigene
Profil leiteten wortlos auf die Startseite zurueck.

Der Rollen-Rundgang meldete sie trotzdem als "ok", und zu Recht: Eine
Umleitung ist kein Fehler. Die Seite laedt, keine rote Konsole, keine
4xx-Antwort. Sie ist nur eine ANDERE. Das ist eine eigene Fehlerklasse
-- nicht "kaputt", sondern "fuehrt woandershin" -- und sie faellt nur
dem auf, der die Anwendung benutzt und merkt, dass ein Knopf nichts tut.

Beinahe waere meine eigene Pruefung darauf hereingefallen: Sie fand auf
der zurueckgeleiteten Startseite das Wort "Ideen-Board" -- den Text der
KACHEL -- und hielt sie fuer das Board. Jetzt steht die Adresse in der
Bedingung.

DIE SPERRE DAGEGEN GILT AB SOFORT FUER ALLE: pruef-rollen klickt fuer
JEDE Rolle jede Kachel durch, die sie angeboten bekommt, und verlangt,
dass sie dort ankommt. Geprueft wird die Zusage der Startseite, nicht
eine Liste daneben -- eine Liste koennte selbst veralten. 113 -> 243
Pruefungen; der Zuwachs ist genau das.

Er hat im ersten Anlauf zwei weitere Loecher gefunden:

  * "Mein Profil" war die falsche Seite. profil.html ist der
    Creator-Entwicklungsplan und antwortet mit 404, wenn die Person kein
    Creator ist. Die eigene Seite heisst steckbrief.html.
  * content.html stand auf `null` ("jede angemeldete Rolle") -- mit der
    neuen Rolle also auch sie. Die Seite laedt, ihre Schnittstelle gibt
    404. Das ist die Kehrseite von "geschuetzt ist die Regel, nicht die
    Ausnahme": Eine NEUE ROLLE erbt jedes `null` automatisch.

Und ein Modi kommt nur in SEINE Bereiche -- sonst waere er ueber die
Adresszeile in der Agentur-Ablage gelandet. Welche erlaubt sind, wird
aus seinen Kacheln abgeleitet statt danebengeschrieben.

=== KLEINERES, ABER SICHTBARES ===

Ueber dem Board stand "Betreuung" -- die Beschriftung fuer Akten, die
UEBER jemanden gefuehrt werden. Eine Sammelstelle ist das Gegenteil.
Aufgefallen auf dem Bildschirmfoto, wie so oft heute.

Der Farbton der Kachel ist nicht nach Gefuehl gewaehlt: Alle 22
vorhandenen waren belegt, also wurde der Abstand zu jedem ausgerechnet
und der genommen, der sich am deutlichsten unterscheidet, ohne grau zu
wirken (#5f8a9f, Abstand 127).

BEINAHE HAETTE ICH EIN LOCH REPARIERT, DAS ES NICHT GIBT: Meine Pruefung
meldete, die Suche verrate die Ideen an Spicy Media. Tatsaechlich fand
sie null Treffer -- die Pruefung hatte ihren EIGENEN Suchbegriff
wiedergefunden, weil die Antwort ihn im Feld `frage` zurueckspiegelt.
Gezaehlt wird jetzt, was gefunden wurde.

pruef-spicy erwartete den alten Wortlaut der Umstellungsmeldung. Sie
nennt jetzt Tabelle und Spalte statt "Rolle"; geprueft wird der Sinn,
nicht der Satz.

GEPRUEFT: pruef-modi-ideen (30, neu), pruef-rollen (243 statt 113),
pruef-modi-verborgen (75), pruef-modi-katalog (29), pruef-spicy (60),
pruef-css-klassen, pruef-start-ansicht.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-10 02:19:06 +02:00
co-authored by Claude Opus 5
parent 138bcce80b
commit e1608ee783
29 changed files with 882 additions and 273 deletions
+95 -1
View File
@@ -18,7 +18,7 @@ import express from "express";
import {
db, protokolliere, echteIp, sitzungLesen, betreutWo, darfCreator, betreuteIds, istLeitung, istDogFather, siehtAlles, istSpicy, ohneDogFather,
externPruefen, externSql,
ohneModi, siehtModis,
ohneModi, siehtModis, MODI_BEREICHE_ERLAUBT,
} from "./workspace.js";
export const bereicheRouter = express.Router();
@@ -120,6 +120,55 @@ export const BEREICHE = {
Zwei Schalter, weil es zwei verschiedene Fragen sind:
fuerAlle -- jeder sieht jeden Eintrag dieses Bereichs
ohneCreatorBezug -- ein Eintrag gehoert hier NIEMANDEM einzeln */
/* =====================================================================
DAS IDEEN-BOARD (10.09.2026, Kapitel 5.6 des Anforderungsdokuments)
"Sammelstelle fuer Content-, Live- und Community-Ideen mit
Priorisierung." Genau das steht hier -- und fast nichts davon
musste neu gebaut werden: `eintraege` hat Titel, Text, Status und
`dringlichkeit` (hoch/mittel/niedrig), und das IST die
Priorisierung. Eine eigene Tabelle daneben waere eine VIERTE
Sichtbarkeitsregel gewesen; genau deren Vervielfaeltigung hat heute
schon ein Leck verursacht.
`ohneCreatorBezug`: Eine Idee gehoert der Runde, nicht einer
Person. Stuende ein Name daneben, laese sich der Eintrag wie ein
Auftrag an diese Person -- und niemand faende ihn spaeter wieder,
wenn sie nicht mehr da ist.
KEIN `fuerAlle`. Das waere der naheliegende Griff gewesen (die
Agentur-Ablage darueber macht es so) und der falsche: `fuerAlle`
heisst woertlich JEDER, auch Manager, Scouts und Creator. Wer die
Sammlung sehen darf, entscheidet stattdessen dieselbe Regel wie
ueberall -- sichtbar() haengt die Modi-Bedingung an, und der Zugang
zur Seite haengt an siehtModis(). Zwei Wege, eine Antwort.
DIE ARTEN SIND DIE DREI AUS DEM DOKUMENT, dazu "Sonstiges": Eine
Idee, die in keine der drei passt, soll nicht ungeschrieben
bleiben, weil das Formular sie nicht kennt. */
ideen: {
name: "Ideen-Board",
/* DAS WORT UEBER DEM TITEL. Ueberall sonst steht dort "Betreuung",
weil die Bereichsseiten Betreuungsakten sind -- ueber jemanden
gefuehrt, von seinen Betreuern. Eine Ideensammlung ist das
Gegenteil: Sie gehoert niemandem und wird von allen gefuellt.
Es stand fest in bereich.html und wurde nie gesetzt; aufgefallen
ist es auf dem Bildschirmfoto. Das Feld ist ab jetzt Teil der
Bereichsangaben, damit der naechste Bereich es einfach mitbringen
kann statt es zu erben. */
ober: "Sammelstelle",
arten: {
content: "Content-Idee",
live: "Live-Idee",
community: "Community-Idee",
sonstiges: "Sonstiges",
},
bewertung: false,
dringlichkeit: true,
ohneCreatorBezug: true,
},
agentur: {
name: "Agentur",
arten: {
@@ -166,6 +215,51 @@ function gleicheHerkunft(req, res, next) {
bereicheRouter.use("/workspace/api/bereich", angemeldet);
/* =====================================================================
DAS IDEEN-BOARD GIBT ES NUR FUER DIE, DIE ES SEHEN DUERFEN
(10.09.2026)
404 und nicht 403: "Kein Zugriff" waere die Auskunft, dass es den
Bereich gibt -- und wer nach "warum darf ich das nicht" fragt, fragt
als naechstes "wer denn dann". Ein Bereich, den es fuer mich nicht
gibt, wirft keine Fragen auf. Wortgleich mit der Antwort auf einen
erfundenen Bereichsnamen (siehe `if (!BEREICHE[bereich])` weiter
unten).
ALS EIGENE HUERDE UND NICHT ALS ABFRAGE IN DEN VIER HANDLERN: Es gibt
Lesen, Anlegen, Aendern und Loeschen. Vier Abfragen sind vier
Gelegenheiten, eine zu vergessen -- und die vergessene faellt nicht
auf, weil an ihrer Stelle nichts steht. Der Pfad-Praefix greift auch
fuer die Wege mit einer Nummer dahinter.
ZWEI SCHLOESSER, ABSICHTLICH: Hier haengt der ZUGANG zur Seite,
sichtbar() haengt die Bedingung an die ZEILEN. Faellt eines weg,
haelt das andere. */
bereicheRouter.use("/workspace/api/bereich/ideen", (req, res, next) => {
if (siehtModis(req.person)) return next();
return res.status(404).json({ fehler: "nicht_gefunden" });
});
/* ---------------------------------------------------------------------
UND UMGEKEHRT: Ein Modi kommt nur in SEINE Bereiche.
Seit dem 10.09.2026 darf er bereich.html oeffnen -- ohne diese Huerde
auch `?b=agentur`, die Ablage der Agentur, die ihn nichts angeht. Die
Kacheln bieten sie ihm nicht an; eine Regel, die nur im Formular
gilt, ist aber keine.
Welche erlaubt sind, steht nicht hier, sondern wird aus seinen
Kacheln abgeleitet (MODI_BEREICHE_ERLAUBT). Zwei Listen waeren die
Stelle, an der es auseinanderlaeuft.
404 wie ueberall: Ein Bereich, den es fuer mich nicht gibt, wirft
keine Fragen auf. */
bereicheRouter.use("/workspace/api/bereich/:bereich", (req, res, next) => {
if (req.person?.rolle !== "modi") return next();
if (MODI_BEREICHE_ERLAUBT.has(String(req.params.bereich))) return next();
return res.status(404).json({ fehler: "nicht_gefunden" });
});
/* ---------- Die Bereiche sind fuer Creator zum LESEN da ----------------
Wunsch Filipe, 31.08.2026: "die creator sollen da nur die sehen die wir