Was dein Verlauf sagt -- die Analyse
Filipe: "mach mir auch eine analyse, mach eine perfektion draus. eine
professionelle auch mit infos und so aus aller welt was tiktok angeht.
ich will dass es perfekt ist!!!!"
SIE WIRD GERECHNET, NICHT GESPEICHERT. Kein Feld, keine Tabelle, keine
Note -- sie entsteht bei jedem Abruf neu aus dem Verlauf dieser einen
Person und verlaesst das Haus damit genauso wenig wie er.
DREI DINGE, DIE SIE TUT:
1. Sie nennt das MUSTER, nicht den Einzelwert. "Da hakt es" in einer
Runde ist ein schlechter Tag. Dasselbe in zwei Runden ist etwas
anderes -- und genau das ist in der Forschung das Warnzeichen.
2. Sie ordnet ein. Zu JEDER der sechs Fragen ein belegter Befund aus
der Moderationsarbeit, damit niemand denkt, er sei der Einzige.
3. Sie sagt, was hilft -- aber nur dort, wo es etwas zu tun gibt. Ein
Rat an einer Stelle, die laeuft, ist Laerm und entwertet die
anderen fuenf.
UND EINES, DAS SIE NICHT TUT: bewerten. Keine Punktzahl, kein Score,
kein Ampelgesicht. Eine Zahl ueber das eigene Befinden laedt dazu ein,
sie zu verbessern statt ehrlich zu antworten -- und ab da misst die
Abfrage nur noch sich selbst.
RECHERCHIERT, NICHT AUSGEDACHT. Die sechs Fragen standen schon auf der
richtigen Spur; die Quellen bestaetigen sie und liefern die Einordnung:
"Zu wenig Zeit" und "Streit im Team" sind die zwei meistgenannten
Gruende, warum freiwillige Moderatoren aufhoeren -- noch vor den
Inhalten. Anschluss ans Team ist der staerkste einzelne Schutzfaktor.
Bei bezahlten Moderatoren, auch bei TikTok, sagen ueber 80 % der
Befragten, ihr Arbeitgeber muesse mehr fuer ihre psychische
Gesundheit tun.
https://news.umich.edu/online-content-moderators-likely-to-experience-burnout-u-m-study-suggests/
https://discord.com/safety/understanding-and-avoiding-moderator-burnout
https://restofworld.org/2025/tiktok-moderators-turkey/
https://www.japantimes.co.jp/news/2025/07/04/world/science-health/content-moderators-mental-trauma/
https://arxiv.org/pdf/2502.06985
Die drei wichtigsten stehen als Verweis unter der Analyse. Ein Satz
ueber "die Forschung" ohne Quelle ist eine Behauptung -- und bei diesem
Thema waere das der Moment, an dem man der ganzen Seite nicht mehr
glaubt.
Im Bildschirmfoto gesehen und behoben: Der Satz oben und die
Quellenzeile standen direkt auf der Buehne, also auf einem Foto. Die
Quellenzeile ist die kleinste Schrift der Seite. Dieselbe Antwort wie
heute Mittag bei der Entwicklungskarte -- keine hellere Schrift,
sondern etwas Deckendes darunter.
server/pruef-befinden.mjs 75 Pruefungen (vorher 48), 0 Fehler
Darunter: aus "neu" wird nach der dritten Runde "dauerhaft", jeder
der sechs Befunde ist ein ANDERER (kein Satz, der zu allen passt),
DogFather bekommt seine eigene leere Analyse, und im Protokoll steht
weiterhin nichts davon -- weder die Analyse noch ein Anlass.
pruef-css-klassen, pruef-entwicklung 43 -- 0 Fehler
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -366,6 +366,145 @@ melde("=== 6. Im Browser ===");
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
/* =======================================================================
|
||||
7. WAS DEIN VERLAUF SAGT
|
||||
|
||||
Filipe: „mach mir auch eine analyse, mach eine perfektion draus. eine
|
||||
professionelle auch mit infos und so aus aller welt was tiktok
|
||||
angeht."
|
||||
|
||||
Eine Auswertung über das eigene Befinden ist das Empfindlichste, was
|
||||
dieses Haus rechnet. Also dieselben drei Fragen wie beim Verlauf:
|
||||
Sagt sie das Richtige? Sagt sie es nur IHR? Und sagt sie gar nichts,
|
||||
wenn sie noch nichts sagen kann?
|
||||
======================================================================= */
|
||||
melde("");
|
||||
melde("=== 7. Die Analyse ===");
|
||||
{
|
||||
const holen = async (keks, host) =>
|
||||
json(await ruf("/workspace/api/befinden", host, "GET", { cookie: keks }));
|
||||
|
||||
/* Stand nach Abschnitt 3: zwei Runden. In der zweiten hakt der erste
|
||||
Punkt, vorher lief er -- das ist „neu", noch kein Muster. */
|
||||
const d = await holen(kFrida, CREW);
|
||||
const erste = d.punkte[0].schluessel;
|
||||
ok(d.analyse?.moeglich === true, `mit ${d.analyse?.runden} Runden gibt es eine Analyse`);
|
||||
ok(d.analyse.zeilen.length === d.punkte.length,
|
||||
`sie geht alle ${d.analyse.zeilen.length} Fragen durch, nicht nur die schlechten`);
|
||||
const z1 = d.analyse.zeilen.find((z) => z.schluessel === erste);
|
||||
ok(z1.art === "neu", `der frisch hakende Punkt gilt als neu, nicht als Muster (${z1.art})`);
|
||||
ok(/noch kein Muster/i.test(d.analyse.satz),
|
||||
`und der Satz oben sagt genau das: „${d.analyse.satz.slice(0, 60)}…“`);
|
||||
|
||||
/* DIE EINORDNUNG IST DER TEIL, DER „AUS ALLER WELT" HEISST. Sie steht
|
||||
bei JEDER Zeile -- auch bei denen, die laufen. */
|
||||
ok(d.analyse.zeilen.every((z) => z.welt && z.welt.length > 40),
|
||||
"zu jeder der sechs Fragen steht ein belegter Befund");
|
||||
ok(new Set(d.analyse.zeilen.map((z) => z.welt)).size === d.punkte.length,
|
||||
"und jeder ist ein anderer — kein Satz, der zu allen passen würde");
|
||||
/* „Was hilft" NUR dort, wo es etwas zu tun gibt. */
|
||||
ok(d.analyse.zeilen.filter((z) => z.hilft).length === 1,
|
||||
`ein Rat steht nur an der Stelle, an der es hakt (${d.analyse.zeilen.filter((z) => z.hilft).length})`);
|
||||
|
||||
/* ---- Und jetzt dasselbe ein zweites Mal: daraus wird ein Muster ---- */
|
||||
for (const p of d.punkte) {
|
||||
await ruf(`/workspace/api/entwicklung/mich/${p.schluessel}`, CREW, "PUT",
|
||||
{ cookie: kFrida }, p.schluessel === erste
|
||||
? { stufe: "hakt", anlass: "Immer noch dasselbe." } : { stufe: "laeuft" });
|
||||
}
|
||||
const dritte = await ruf("/workspace/api/befinden/runde", CREW, "POST", { cookie: kFrida }, {});
|
||||
ok(dritte.code === 201, `eine dritte Runde (${dritte.code})`);
|
||||
|
||||
const n = await holen(kFrida, CREW);
|
||||
const z2 = n.analyse.zeilen.find((z) => z.schluessel === erste);
|
||||
ok(z2.art === "dauerhaft", `jetzt ist es ein Muster (${z2.art})`);
|
||||
ok(z2.runden === modul.MUSTER_AB, `über ${z2.runden} Runden`);
|
||||
ok(/kein schlechter Tag/i.test(n.analyse.satz),
|
||||
`und der Satz sagt, worauf es ankommt: „${n.analyse.satz.slice(0, 64)}…“`);
|
||||
/* DIE REIHENFOLGE MACHT DIE AUSSAGE -- das Muster gehört nach oben.
|
||||
Sortiert wird im Browser; hier wird geprüft, dass die Angabe dafür
|
||||
überhaupt mitkommt. */
|
||||
ok(n.analyse.zahlen.dauerhaft === 1 && n.analyse.zahlen.neu === 0,
|
||||
`die Zahlen daneben stimmen (${JSON.stringify(n.analyse.zahlen)})`);
|
||||
|
||||
/* ---- Sie gehört ihr allein ---- */
|
||||
const seine = await holen(kDogi, CREW);
|
||||
ok(seine.analyse?.moeglich === false,
|
||||
"DogFather bekommt seine eigene — und die ist leer");
|
||||
ok(!JSON.stringify(seine).includes("Immer noch dasselbe"),
|
||||
"nichts von ihr steht darin");
|
||||
|
||||
/* ---- Und ohne zweite Runde gibt es sie gar nicht ---- */
|
||||
ok(seine.analyse.ab === modul.MUSTER_AB,
|
||||
`sie sagt, ab wann es sie gibt (ab ${seine.analyse.ab} Runden)`);
|
||||
ok(Array.isArray(seine.analyse.zeilen) && seine.analyse.zeilen.length === 0,
|
||||
"und liefert bis dahin keine einzige Zeile");
|
||||
|
||||
/* ---- Im Protokoll steht weiterhin nichts davon ---- */
|
||||
const db = oeffne();
|
||||
const spuren = db.prepare("SELECT aktion, detail FROM protokoll").all();
|
||||
db.close();
|
||||
ok(!spuren.some((x) => /analyse/i.test(x.aktion || "")),
|
||||
"eine Analyse ist kein Vorgang — sie steht in keinem Protokoll");
|
||||
ok(!spuren.some((x) => /Immer noch dasselbe/.test(x.detail || "")),
|
||||
"und ihr Anlass erst recht nicht");
|
||||
}
|
||||
|
||||
/* =======================================================================
|
||||
8. DIE ANALYSE AUF DEM BILDSCHIRM
|
||||
======================================================================= */
|
||||
melde("");
|
||||
melde("=== 8. Die Analyse im Browser ===");
|
||||
{
|
||||
const { chromium } = await import(
|
||||
"file:///C:/Users/qciga/Documents/Obelix/Analyse/node_modules/playwright/index.mjs");
|
||||
const browser = await chromium.launch();
|
||||
const kontext = await browser.newContext({ viewport: { width: 1280, height: 1000 } });
|
||||
await kontext.addCookies(kFrida.split("; ").filter(Boolean).map((teil) => {
|
||||
const i = teil.indexOf("=");
|
||||
return { name: teil.slice(0, i), value: teil.slice(i + 1), domain: "127.0.0.1", path: "/" };
|
||||
}));
|
||||
const seite = await kontext.newPage();
|
||||
const konsole = [];
|
||||
seite.on("console", (m) => { if (m.type() === "error" && !/favicon|ERR_/i.test(m.text())) konsole.push(m.text()); });
|
||||
seite.on("pageerror", (e) => konsole.push("Absturz: " + e.message));
|
||||
|
||||
await seite.goto(`http://127.0.0.1:${PORT}/workspace/befinden.html`, { waitUntil: "networkidle" });
|
||||
await seite.waitForTimeout(1000);
|
||||
|
||||
const a = await seite.evaluate(() => ({
|
||||
da: document.getElementById("analyse-block")?.hidden === false,
|
||||
satz: document.getElementById("analyse-satz")?.textContent.trim() || "",
|
||||
zeilen: document.querySelectorAll(".b-analyse__zeile").length,
|
||||
ersteMarke: document.querySelector(".b-analyse__zeile")?.dataset.ton || "",
|
||||
welt: document.querySelectorAll(".b-analyse__welt").length,
|
||||
hilft: document.querySelectorAll(".b-analyse__hilft").length,
|
||||
quellen: [...document.querySelectorAll(".b-analyse__quelle-hin")].map((x) => x.href),
|
||||
blank: [...document.querySelectorAll(".b-analyse__quelle-hin")]
|
||||
.every((x) => x.rel.includes("noopener")),
|
||||
}));
|
||||
ok(a.da, "die Analyse steht auf der Seite");
|
||||
ok(a.zeilen === 6, `mit allen sechs Fragen (${a.zeilen})`);
|
||||
/* DAS MUSTER STEHT OBEN. Alphabetisch oder in Katalogreihenfolge
|
||||
müsste man es suchen -- und wer sucht, liest es beim zweiten Mal
|
||||
nicht mehr. */
|
||||
ok(a.ersteMarke === "hakt",
|
||||
`und das, was seit mehreren Runden hakt, steht zuoberst (${a.ersteMarke})`);
|
||||
ok(a.welt === 6, `zu jeder Zeile die Einordnung (${a.welt})`);
|
||||
ok(a.hilft === 1, `ein Rat, genau dort, wo es hakt (${a.hilft})`);
|
||||
ok(a.quellen.length === 3, `${a.quellen.length} Quellen stehen darunter`);
|
||||
ok(a.quellen.some((x) => /tiktok/i.test(x)),
|
||||
"darunter eine zu TikTok — danach hatte Filipe ausdrücklich gefragt");
|
||||
ok(a.blank, "die Verweise öffnen ohne Zugriff aufs eigene Fenster (noopener)");
|
||||
if (process.env.SCHIRM) {
|
||||
await seite.locator("#analyse-block").screenshot(
|
||||
{ path: "C:/Users/qciga/Documents/Obelix/DogiHompage/blick.png" });
|
||||
}
|
||||
ok(konsole.length === 0,
|
||||
konsole.length ? "Fehler im Browser: " + konsole[0].slice(0, 90) : "keine Fehler im Browser");
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
melde("");
|
||||
melde(`${geprueft} Pruefungen, ${fehler} Fehler`);
|
||||
|
||||
Reference in New Issue
Block a user