Ampel und Rueckmeldungen - bewerten darf nur die Betreuung

Der Wunsch: "der Creator sieht, ob es gut ist oder schlecht. Und wenn
nicht gut, dann muss es verbessert werden -- und nur der Ansprechpartner
kann das aendern. Die Creator koennen nur Nachrichten hinterlassen zum
Kommunizieren."

ZWEI GETRENNTE DINGE, und sie getrennt zu halten ist der ganze Punkt:

  DIE AMPEL ist eine Beurteilung. Sie gehoert dem Betreuer, und nur er
  setzt sie. Koennte ein Creator sich selbst auf gruen stellen, waere
  sie wertlos -- dann stuende ueberall gruen. Der Server lehnt es mit
  403 ab und sagt dabei, wer es kann.

  DIE NACHRICHT ist ein Gespraech. Sie gehoert beiden. Ein Creator, der
  auf eine Bewertung nicht antworten kann, bekommt ein Urteil statt
  einer Betreuung.

DREI STUFEN, NICHT FUENF. Eine Zahl von 1 bis 5 klingt genauer und ist
es nicht: Niemand kann den Unterschied zwischen 3 und 4 erklaeren, und
am Ende steht ueberall die 3. Die Frage lautet "reicht das schon?", und
darauf gibt es drei ehrliche Antworten -- passt so, noch verbessern,
noch nicht angesehen.

"NOCH VERBESSERN" VERLANGT EINE BEGRUENDUNG. Eine Bewertung, mit der der
Creator nichts anfangen kann, ist nicht streng, sondern nur
entmutigend. Der Server lehnt sie ohne Grund ab; die Oberflaeche fragt
deshalb gleich danach, statt hinterher eine Fehlermeldung zu zeigen.
"Passt so" braucht keinen -- da gibt es nichts zu erklaeren.

Die Stufe steht IMMER an der Karte, auch fuer den Creator, auch wenn sie
"noch nicht angesehen" lautet. Er soll sehen, wo er steht, ohne fragen
zu muessen. Der Grund steht daneben in voller Breite, nicht in einer
Ecke.

FREMDE NACHRICHTEN BLEIBEN STEHEN -- auch fuer DogFather. Ein Gespraech
nachtraeglich umzuschreiben waere schlimmer, als eine unbedachte
Aeusserung stehen zu lassen. Wer etwas richtigstellen will, schreibt
eine neue.

VORLAGEN AUCH FUER COMMUNITY UND TECHNIK (Screens 11 und 12): 14
Moderations-, Aktions- und Konfliktpunkte, 12 Technikpunkte. Ton steht
vorn, weil schlechter Ton der Grund Nummer eins ist, warum Leute einen
Stream verlassen. Die drei Bereiche laufen jetzt ueber EINE Zuordnung
statt drei fast gleicher Bloecke -- sonst weicht der dritte irgendwann
ab. Die beiden alten Zweige wurden entfernt: Toter Code, den man stehen
laesst, wird beim naechsten Mal fuer lebenden gehalten.

Die Ampeln einer ganzen Liste kommen in EINER Abfrage. Zwanzig
Eintraege einzeln zu fragen waeren zwanzig Anfragen, und die Seite
ruckelte sichtbar beim Aufbau. Die Sichtbarkeitspruefung laeuft dabei
je Eintrag, nicht einmal pauschal -- ein fremder Eintrag taucht auch in
der Sammelabfrage nicht auf.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-01 16:49:56 +02:00
co-authored by Claude Opus 5
parent 5960f6e3c4
commit 372a0eb95a
26 changed files with 1153 additions and 139 deletions
+82 -6
View File
@@ -43,6 +43,10 @@ export const vorlagenRouter = express.Router();
const jetzt = () => new Date().toISOString();
/* Welche Bereiche haben Punktelisten? Eine Zuordnung statt drei
Sonderfaellen im Code. */
const BEREICH_PUNKTE = {};
/* =====================================================================
CONTENT-IDEEN
@@ -172,6 +176,66 @@ export const LIVE_PUNKTE = {
Gespräch nach Fragebogen ist ein Verhör, kein Gespräch.
===================================================================== */
/* =====================================================================
COMMUNITY-PUNKTE
Moderation ist die Arbeit, die niemand sieht, solange sie
funktioniert. Die Punkte hier sind so gewaehlt, dass sie VOR dem
Ernstfall abgehakt werden koennen -- danach ist es zu spaet.
===================================================================== */
export const COMMUNITY_PUNKTE = {
moderation: [
{ titel: "Regeln stehen sichtbar", text: "Kurz, verstaendlich, an einer Stelle, die man findet. Drei Saetze reichen.", hilfe: false },
{ titel: "Jemand kann eingreifen", text: "Waehrend des Streams ist eine zweite Person mit Rechten da -- oder es ist klar, dass keine da ist.", hilfe: true },
{ titel: "Wortfilter eingerichtet", text: "Die offensichtlichen Sachen automatisch weg, damit man sich um den Rest kuemmern kann.", hilfe: true },
{ titel: "Was passiert bei einem Verstoss?", text: "Verwarnen, stummschalten, sperren -- vorher entscheiden, nicht im Moment.", hilfe: false },
{ titel: "Umgang mit Minderjaehrigen", text: "Wie erkennt man sie, und was gilt dann? Das ist keine Ermessensfrage.", hilfe: true },
],
aktion: [
{ titel: "Neue begruessen", text: "Wer zum ersten Mal da ist, wird angesprochen. Kostet zwei Sekunden und entscheidet, ob jemand bleibt.", hilfe: false },
{ titel: "Stammleute erkennen", text: "Namen merken oder notieren. Wiedererkannt zu werden ist der halbe Grund wiederzukommen.", hilfe: false },
{ titel: "Etwas geben, das nur hier gibt", text: "Ein Insider, ein Ritual, ein Spitzname. Community entsteht aus Gemeinsamem.", hilfe: false },
{ titel: "Ausserhalb des Streams antworten", text: "Kommentare und Nachrichten -- die Community lebt auch zwischen den Sendungen.", hilfe: false },
],
konflikt: [
{ titel: "Ruhig bleiben und nicht oeffentlich streiten", text: "Im Chat gewinnt niemand. Kurz ansagen, dann privat klaeren.", hilfe: true },
{ titel: "Was ist genau passiert?", text: "Zeitpunkt, Beteiligte, Wortlaut. Ohne das ist jede Entscheidung angreifbar.", hilfe: false },
{ titel: "Beweise sichern", text: "Bildschirmfoto oder Ausschnitt, solange es noch da ist. Chats verschwinden.", hilfe: true },
{ titel: "Betreuung einbeziehen", text: "Bei allem, was groesser ist als ein blöder Kommentar. Dafuer ist sie da.", hilfe: true },
{ titel: "Danach: was hat gefehlt?", text: "Regel unklar, niemand zum Eingreifen da, zu spaet gemerkt -- daraus wird der naechste Punkt oben.", hilfe: false },
],
};
/* =====================================================================
TECHNIK-PUNKTE
Technik faellt immer im ungeeignetsten Moment aus. Die Punkte sind
deshalb danach sortiert, was am haeufigsten schiefgeht -- und Ton
steht vorn, weil schlechter Ton der Grund Nummer eins ist, warum
Leute einen Stream verlassen.
===================================================================== */
export const TECHNIK_PUNKTE = {
setup: [
{ titel: "Mikrofon richtig eingestellt", text: "Nicht uebersteuert, nicht zu leise, kein Rauschen. Einmal aufnehmen und anhoeren.", hilfe: true },
{ titel: "Kamera scharf und gut belichtet", text: "Gesicht heller als der Hintergrund. Automatik oft abschalten -- sie pumpt.", hilfe: true },
{ titel: "Szenen im Streaming-Programm angelegt", text: "Start, Vollbild, Pause, Ende. Wer waehrend der Sendung baut, sendet Chaos.", hilfe: true },
{ titel: "Bitrate zur Leitung passend", text: "Lieber stabil und etwas weicher als scharf mit Aussetzern.", hilfe: true },
{ titel: "Alles einmal komplett getestet", text: "Eine Probesendung von fuenf Minuten, aufgezeichnet und angesehen.", hilfe: true },
],
problem: [
{ titel: "Ton weg oder verzerrt", text: "Wann genau, welches Geraet, was lief gleichzeitig? Ohne das findet es niemand.", hilfe: true },
{ titel: "Bild ruckelt oder friert ein", text: "Auslastung, Leitung, Aufloesung -- eins nach dem anderen ausschliessen.", hilfe: true },
{ titel: "Stream bricht ab", text: "Zeitpunkt notieren und im Protokoll des Programms nachsehen.", hilfe: true },
{ titel: "Ton und Bild laufen auseinander", text: "Meist ein Puffer. Wann faellt es auf, sofort oder erst spaeter?", hilfe: true },
],
loesung: [
{ titel: "Was hat es behoben?", text: "Genau die eine Aenderung aufschreiben, nicht alles was probiert wurde.", hilfe: false },
{ titel: "Kommt es wieder?", text: "Beim naechsten Mal nachsehen. Einmal weg ist nicht geloest.", hilfe: false },
{ titel: "Einstellung gesichert", text: "Damit sie nach einem Update nicht wieder weg ist.", hilfe: false },
],
};
export const CALL_LEITFAEDEN = [
{ titel: "Erstgespräch",
text: "Wer bist du, was machst du, was willst du erreichen? · Was läuft schon gut? · "
@@ -191,6 +255,12 @@ export const CALL_LEITFAEDEN = [
+ "Termin für das nächste Review festhalten" },
];
/* Erst hier gefuellt -- die Listen stehen weiter oben und muessen
definiert sein, bevor sie eingetragen werden. */
BEREICH_PUNKTE.live = LIVE_PUNKTE;
BEREICH_PUNKTE.community = COMMUNITY_PUNKTE;
BEREICH_PUNKTE.technik = TECHNIK_PUNKTE;
/* ---------- Schnittstelle ------------------------------------------------ */
function angemeldet(req, res, next) {
@@ -205,6 +275,8 @@ vorlagenRouter.get("/workspace/api/vorlagen", (req, res) => {
res.json({
content: CONTENT_IDEEN,
live: LIVE_PUNKTE,
community: COMMUNITY_PUNKTE,
technik: TECHNIK_PUNKTE,
calls: CALL_LEITFAEDEN,
});
});
@@ -266,19 +338,23 @@ vorlagenRouter.post("/workspace/api/vorlagen/uebernehmen", gleicheHerkunft,
einfuegen("content", "idee", v.titel, v.text, { hook: v.hook, format: v.format });
}
} else if (art === "live") {
} else if (BEREICH_PUNKTE[art]) {
/* live, community, technik -- alle drei funktionieren gleich.
Drei fast gleiche Bloecke waeren der sichere Weg dazu, dass
der dritte irgendwann anders reagiert als die ersten beiden. */
const unterart = String(req.body.unterart || "");
const liste = LIVE_PUNKTE[unterart];
const liste = BEREICH_PUNKTE[art][unterart];
if (!liste) return res.status(400).json({ fehler: "Unbekannter Abschnitt." });
const v = liste[nr];
if (!v) return res.status(400).json({ fehler: "Unbekannte Vorlage." });
einfuegen("live", unterart, v.titel, v.text);
einfuegen(art, unterart, v.titel, v.text);
} else if (art === "live_alle") {
} else if (BEREICH_PUNKTE[art.replace(/_alle$/, "")] && art.endsWith("_alle")) {
const bereich = art.replace(/_alle$/, "");
const unterart = String(req.body.unterart || "");
const liste = LIVE_PUNKTE[unterart];
const liste = BEREICH_PUNKTE[bereich][unterart];
if (!liste) return res.status(400).json({ fehler: "Unbekannter Abschnitt." });
for (const v of liste) einfuegen("live", unterart, v.titel, v.text);
for (const v of liste) einfuegen(bereich, unterart, v.titel, v.text);
} else {
return res.status(400).json({ fehler: "Unbekannte Art." });