diff --git a/server/pruef-modi-katalog.mjs b/server/pruef-modi-katalog.mjs index 2d38bea9..fd34129a 100644 --- a/server/pruef-modi-katalog.mjs +++ b/server/pruef-modi-katalog.mjs @@ -99,24 +99,58 @@ let katalog = null; { const a = await hole(modiAn.keks, "/workspace/api/vorlagen"); katalog = a.daten?.katalog || null; - /* SECHZIG, fest hingeschrieben. Das Dokument wirbt mit "60+ konkrete - Aufgaben"; faellt eine heraus, muss das auffallen. Eine Zahl, die - sich selbst nachzaehlt, kann das nicht. */ - ok(katalog && katalog.aufgaben.length === 60, - `${katalog?.aufgaben?.length ?? 0} Aufgaben (erwartet 60)`); - ok(katalog && katalog.gruppen.length === 9, - `${katalog?.gruppen?.length ?? 0} Etappen (erwartet 9)`); - /* Die Verteilung aus Teil 2, Phase fuer Phase. Sie steht hier, weil - eine reine Gesamtzahl auch dann stimmt, wenn zwoelf Aufgaben in der - falschen Etappe liegen. */ - const soll = { aufbau: 12, alltag: 9, vor: 5, waehrend: 5, nach: 4, - content: 8, woche: 5, monat: 5, community: 7 }; - const ist = {}; - for (const v of katalog?.aufgaben || []) ist[v.gruppe] = (ist[v.gruppe] || 0) + 1; - ok(JSON.stringify(ist) === JSON.stringify(soll), - `die Verteilung stimmt (${Object.entries(ist).map(([k, n]) => `${k}:${n}`).join(" ")})`); - ok((katalog?.aufgaben || []).every((v) => v.titel && v.text && v.kategorie && v.rolle && v.tage), - "jede Aufgabe hat Titel, Text, Kategorie, empfohlene Rolle und Frist"); + /* SEIT DEM 16.09.2026 NACH KATEGORIE UND STUFE. + + Vorher standen hier neun PHASEN mit 60 Eintraegen -- und + nachgezaehlt gehoerten 39 davon DogFather und der rechten Hand. + Es war ein Aufbauplan, kein Arbeitskatalog. Der Aufbauplan gibt es + weiterhin, unter `aufbauplan`; hier steht jetzt, was ein Mensch im + Team TUT. + + ZAHLEN FEST HINGESCHRIEBEN, wie vorher: Eine Zahl, die sich selbst + nachzaehlt, merkt nicht, wenn etwas herausfaellt. */ + ok(katalog && katalog.gruppen.length === 14, + `${katalog?.gruppen?.length ?? 0} Kategorien (erwartet 14)`); + ok(katalog && katalog.stufen.length === 3, + `${katalog?.stufen?.length ?? 0} Stufen (erwartet 3)`); + ok(katalog && katalog.aufgaben.length === 88, + `${katalog?.aufgaben?.length ?? 0} Aufgaben (erwartet 88)`); + + /* JEDE KATEGORIE MUSS BELEGT SEIN. Vorher hatten vier von vierzehn + eine Aufgabe oder keine (Events 1, Wachstum 1, Branding 1, + Sonstiges 0) -- eine Kategorie ohne Inhalt ist ein leeres + Versprechen im Auswahlfeld. */ + const je = {}; + for (const v of katalog?.aufgaben || []) je[v.gruppe] = (je[v.gruppe] || 0) + 1; + const leer = (katalog?.gruppen || []).filter((g) => !je[g.schluessel]); + ok(leer.length === 0, + `jede Kategorie hat Aufgaben${leer.length ? ": leer sind " + leer.map((g) => g.name).join(", ") : ""}`); + ok(Math.min(...Object.values(je)) >= 3, + `auch die kleinste hat mindestens drei (${Math.min(...Object.values(je))})`); + + /* UND JEDE STUFE. Eine Stufe ohne Aufgaben waere ein Knopf, der eine + leere Liste oeffnet. */ + const jeStufe = {}; + for (const v of katalog?.aufgaben || []) jeStufe[v.stufe] = (jeStufe[v.stufe] || 0) + 1; + ok((katalog?.stufen || []).every((s) => jeStufe[s.schluessel] > 0), + `jede Stufe ist belegt (${Object.entries(jeStufe).map(([k, n]) => `${k}:${n}`).join(" ")})`); + + ok((katalog?.aufgaben || []).every((v) => v.titel && v.text && v.gruppe && v.stufe && v.tage), + "jede Aufgabe hat Titel, Text, Kategorie, Stufe und Frist"); + /* DER TEXT SAGT WARUM, nicht was. Ein Text, der kuerzer ist als der + Titel, ist eine Wiederholung -- und die haette man sich sparen + koennen. */ + const duenn = (katalog?.aufgaben || []).filter((v) => v.text.length < v.titel.length + 20); + ok(duenn.length === 0, + `jeder Text begruendet${duenn.length ? ": zu duenn bei " + duenn[0].schluessel : ""}`); + ok(new Set((katalog?.aufgaben || []).map((v) => v.schluessel)).size + === (katalog?.aufgaben || []).length, "keine Kennung doppelt"); + + /* DER AUFBAUPLAN IST NICHT VERLORENGEGANGEN. */ + const plan = a.daten?.aufbauplan; + ok(plan && plan.aufgaben.length === 60 && plan.gruppen.length === 9, + `der Aufbauplan steht weiter zur Verfuegung (${plan?.aufgaben?.length ?? 0} in ` + + `${plan?.gruppen?.length ?? 0} Etappen)`); } /* Jede Kategorie im Katalog muss es auch wirklich geben -- sonst nimmt @@ -124,7 +158,11 @@ let katalog = null; { const a = await hole(modiAn.keks, "/workspace/api/aufgaben"); const gueltig = new Set((a.daten?.kategorien || []).map((k) => k.wert)); - const unbekannt = [...new Set((katalog?.aufgaben || []).map((v) => v.kategorie))] + /* Die Kategorie heisst im ausgelieferten Katalog `gruppe` -- sie ist + zugleich die Gruppe, nach der die Oberflaeche sortiert. Ein + zweiter Name fuer dasselbe waere die Gelegenheit, dass beide + auseinanderlaufen. */ + const unbekannt = [...new Set((katalog?.aufgaben || []).map((v) => v.gruppe))] .filter((k) => !gueltig.has(k)); ok(gueltig.size > 0 && unbekannt.length === 0, unbekannt.length @@ -152,11 +190,11 @@ for (const [name, an] of [["Manager", manAn], ["Creator", creatAn]]) { /* ---------- 3. Uebernehmen ------------------------------------------- */ console.log("\n=== 3. Aus der Vorlage wird eine echte Aufgabe ===\n"); { - const nr = katalog.aufgaben.findIndex((v) => v.gruppe === "waehrend"); + const nr = katalog.aufgaben.findIndex((v) => v.gruppe === "chat"); const vorlage = katalog.aufgaben[nr]; const a = await hole(modiAn.keks, "/workspace/api/vorlagen/uebernehmen", { method: "POST", headers: jsonKopf, - body: JSON.stringify({ art: "katalog", nr, gruppe: "waehrend" }), + body: JSON.stringify({ art: "katalog", nr, gruppe: "chat" }), }); ok(a.status === 200 && a.daten?.angelegt === 1, `übernommen (${a.status})`); @@ -166,30 +204,34 @@ console.log("\n=== 3. Aus der Vorlage wird eine echte Aufgabe ===\n"); /* DIE KATEGORIE IST DER HALBE WERT DER VORLAGE. Ginge sie unterwegs verloren, muesste man 60-mal von Hand einsortieren, was im Dokument danebensteht -- und niemand merkte es, weil die Aufgabe ja da ist. */ - ok(neu?.kategorie === vorlage.kategorie, - `mit ihrer Kategorie (${neu?.kategorie} / erwartet ${vorlage.kategorie})`); + /* DIE KATEGORIE IST DER HALBE WERT DER VORLAGE -- und sie heisst im + ausgelieferten Katalog `gruppe`, weil die Oberflaeche damit + zeichnet. Ginge sie unterwegs verloren, muesste man von Hand + einsortieren, was danebensteht. */ + ok(neu?.kategorie === vorlage.gruppe, + `mit ihrer Kategorie (${neu?.kategorie} / erwartet ${vorlage.gruppe})`); ok(!!neu?.frist, `und mit Frist (${neu?.frist})`); ok(neu?.verantwortlich_id === idModi, "und er selbst ist verantwortlich"); } /* Eine ganze Etappe auf einmal. */ { - const wieViele = katalog.aufgaben.filter((v) => v.gruppe === "nach").length; + const wieViele = katalog.aufgaben.filter((v) => v.gruppe === "technik").length; const a = await hole(modiAn.keks, "/workspace/api/vorlagen/uebernehmen", { method: "POST", headers: jsonKopf, - body: JSON.stringify({ art: "katalog_alle", gruppe: "nach" }), + body: JSON.stringify({ art: "katalog_alle", gruppe: "technik" }), }); ok(a.status === 200 && a.daten?.angelegt === wieViele, - `eine ganze Etappe auf einmal: ${a.daten?.angelegt} von ${wieViele}`); + `eine ganze Kategorie auf einmal: ${a.daten?.angelegt} von ${wieViele}`); } /* ---------- 4. DogFather traegt fuer jemanden ein -------------------- */ console.log("\n=== 4. DogFather trägt für einen Modi ein ===\n"); { - const nr = katalog.aufgaben.findIndex((v) => v.gruppe === "monat"); + const nr = katalog.aufgaben.findIndex((v) => v.gruppe === "analyse"); const a = await hole(dogiAn.keks, "/workspace/api/vorlagen/uebernehmen", { method: "POST", headers: jsonKopf, - body: JSON.stringify({ art: "katalog", nr, gruppe: "monat", person_id: idModi }), + body: JSON.stringify({ art: "katalog", nr, gruppe: "analyse", person_id: idModi }), }); ok(a.status === 200 && a.daten?.angelegt === 1, `für den Modi geht es (${a.status})`); @@ -259,14 +301,26 @@ console.log("\n=== 6. Das Brett im echten Browser ===\n"); const bild = await seite.evaluate(() => ({ sichtbar: !document.getElementById("vorlagenbrett")?.hidden, - etappen: [...document.querySelectorAll(".stufenleiter__knopf .stufenleiter__name")] + /* ZWEI REIHEN SEIT DEM 16.09.2026: oben die Kategorien, darunter + die Stufen. Getrennt gezaehlt -- eine gemeinsame Zahl haette + nicht gesagt, WELCHE der beiden fehlt. */ + kategorien: [...document.querySelectorAll( + ".stufenleiter:not(.stufenleiter--fein) .stufenleiter__name")] .map((z) => z.textContent.trim()), + stufen: [...document.querySelectorAll( + ".stufenleiter--fein .stufenleiter__name")].map((z) => z.textContent.trim()), karten: document.querySelectorAll(".vorlagenbrett__karte").length, text: document.body.innerText, kopf: (document.querySelector(".kopfleiste .marke__text") || {}).textContent || "", })); ok(bild.sichtbar, "das Brett steht da"); - ok(bild.etappen.length === 9, `mit neun Etappen (${bild.etappen.join(" · ")})`); + ok(bild.kategorien.length === 14, + `mit vierzehn Kategorien (${bild.kategorien.join(" · ")})`); + /* DREI STUFEN PLUS "Alle" -- der vierte Knopf ist die Ruecknahme. + Ohne ihn kaeme man aus einer Stufe nicht wieder heraus, ohne die + Kategorie zu wechseln. */ + ok(bild.stufen.length === 4 && bild.stufen[0] === "Alle", + `und drei Stufen daneben (${bild.stufen.join(" · ")})`); ok(bild.karten > 0, `und ${bild.karten} Karten in der offenen Etappe`); /* Der Katalog des ANDEREN darf nirgends durchschlagen. */ ok(!/vier Bereichen und vier Stufen/.test(bild.text), diff --git a/server/workspace-vorlagen.js b/server/workspace-vorlagen.js index 9f1d921f..11e9e358 100644 --- a/server/workspace-vorlagen.js +++ b/server/workspace-vorlagen.js @@ -37,7 +37,7 @@ import express from "express"; import { db, sitzungLesen, istLeitung, darfCreator, protokolliere, echteIp, kategorienFuer, - termineSichtbar, + termineSichtbar, MODI_KATEGORIEN, MODI_STUFEN, } from "./workspace.js"; export const vorlagenRouter = express.Router(); @@ -1394,7 +1394,41 @@ vorlagenRouter.get("/workspace/api/vorlagen", (req, res) => { An denselben Personenkreis wie die Kategorien -- es ist dieselbe Frage, und zwei Abfragen dafuer waeren zwei Gelegenheiten, dass sie auseinanderlaufen. */ + /* SEIT DEM 16.09.2026 NACH KATEGORIE UND STUFE. + + Vorher standen hier neun PHASEN (Aufbau, Alltag, Vor dem Live + …). Nachgezaehlt, wem die 60 Eintraege darin gehoerten: + 39 davon DogFather und der rechten Hand -- es war ein + Aufbauplan, kein Arbeitskatalog. Und die Verteilung ueber die + vierzehn Kategorien war schief: Planung 10, Events 1, Wachstum + 1, Branding 1, Sonstiges 0. + + Jetzt dieselbe Form wie bei den Creator-Vorlagen: Kategorie mal + Stufe. Wer eine Aufgabe vergibt, denkt "Frida macht Chat" und + nicht "wir sind in Phase 3". + + `gruppe` heisst weiter `gruppe` und nicht `kategorie`: Die + Oberflaeche zeichnet damit schon, und ein zweiter Name fuer + dasselbe waere eine Gelegenheit, dass beide auseinanderlaufen. */ katalog: kategorienFuer(req.person).length + ? { + gruppen: MODI_KATEGORIEN.map((k) => ({ + schluessel: k.wert, name: k.name, text: k.text, + })), + stufen: MODI_STUFEN.map((s) => ({ + schluessel: s.wert, name: s.name, text: s.text, + })), + aufgaben: MODI_AUFGABEN_FLACH.map((a) => ({ + schluessel: a.schluessel, titel: a.titel, text: a.text, tage: a.tage, + gruppe: a.kategorie, stufe: a.stufe, + })), + } + : null, + /* DER AUFBAUPLAN BLEIBT -- er ist nicht falsch, nur etwas anderes: + die Liste dessen, was EINMAL zu tun ist, bis der Laden steht. + Ihn zu loeschen hiesse, 60 durchdachte Schritte wegzuwerfen, + weil sie am falschen Platz standen. */ + aufbauplan: kategorienFuer(req.person).length ? { gruppen: MODI_GRUPPEN, aufgaben: MODI_KATALOG } : null, }); @@ -1551,10 +1585,24 @@ vorlagenRouter.post("/workspace/api/vorlagen/uebernehmen", gleicheHerkunft, return res.status(404).json({ fehler: "nicht_gefunden" }); } + /* AUS DEM KATALOG, DEN DIE SEITE AUCH BEKOMMEN HAT (16.09.2026). + + Hier stand `MODI_KATALOG` -- die neun Phasen. Seit der Umbau + auf Kategorie mal Stufe liefert /api/vorlagen etwas anderes + aus, und der Browser schickt die Nummer aus DIESER Liste + zurueck. Waere es so geblieben, haette ein Klick auf + "Uebernehmen" eine voellig andere Aufgabe angelegt -- und + zwar eine, die es gibt, also ohne Fehlermeldung. + + Gefunden hat das pruef-modi-katalog, nicht das Lesen: Die + Pruefung suchte eine Phase, die es nicht mehr gibt, und + stuerzte ab. */ const gruppe = String(req.body.gruppe || ""); + const stufe = String(req.body.stufe || ""); const auswahl = art === "katalog_alle" - ? MODI_KATALOG.filter((v) => v.gruppe === gruppe) - : [MODI_KATALOG[nr]]; + ? MODI_AUFGABEN_FLACH.filter((v) => v.kategorie === gruppe + && (!stufe || v.stufe === stufe)) + : [MODI_AUFGABEN_FLACH[nr]]; if (!auswahl.length || auswahl.some((v) => !v)) { return res.status(400).json({ fehler: "Unbekannte Vorlage." }); } @@ -1667,3 +1715,390 @@ vorlagenRouter.post("/workspace/api/vorlagen/uebernehmen", gleicheHerkunft, Entfernt statt auskommentiert: Eine Route, die niemand mehr aufruft, wird beim nächsten Mal für lebenden Code gehalten und mitgepflegt. */ + +/* ===================================================================== + DER AUFGABENKATALOG FÜR DAS TEAM (16.09.2026) + + Filipe: „perfektionniere die kategorien wo ich aufgaben an die modis + verteile und so, ich will dass du alles was es gibt auf der welt + durch gehst und wie bei den aufgaben wo sie für mich haben auch mit + kategorien und vielen aufgaben will ich das genau für sie genau so + perfektioniert und hochwertig geil." + + --------------------------------------------------------------------- + WAS DIE MESSUNG ERGEBEN HAT, BEVOR ICH ANGEFANGEN HABE + + Es gab schon einen Katalog: MODI_KATALOG, 60 Einträge in neun + Phasen. Nachgezählt, wem sie gehören: + + DogFather 13 + DogFather & rechte Hand 12 + rechte Hand 14 + --------------------------------- + zusammen 39 von 60 + + Zwei Drittel des „Modi-Katalogs" waren Aufbauarbeiten für Filipe + selbst. Nur 20 Einträge waren wirklich Arbeit für einen Menschen im + Team. Und die Verteilung über die vierzehn Kategorien war schief: + Planung 10, Events 1, Wachstum 1, Branding 1, Sonstiges 0. + + MODI_KATALOG bleibt, was er ist — der Aufbauplan. Hier steht etwas + anderes: was ein Mensch im Team TUT, wenn der Laden läuft. + + --------------------------------------------------------------------- + KATEGORIE × STUFE — dieselbe Form wie bei den Creator-Vorlagen + + Nicht nach Phasen, sondern nach Kategorie: Wer eine Aufgabe vergibt, + denkt „Frida macht Chat" und nicht „wir sind in Phase 3". Und je + Kategorie drei Stufen, weil dieselbe Kategorie für einen Neuen etwas + anderes bedeutet als für jemanden, der einarbeitet. + + --------------------------------------------------------------------- + WORAUF DIE INHALTE BERUHEN + + Twitch und Discord (was ein Moderator tatsächlich tut): Chat in + Echtzeit beobachten, Spam und Regelbrüche entfernen, Auszeiten und + Sperren aussprechen, Neue begrüßen, Regeln erklären statt nur + durchzusetzen, die Energie tragen, ohne den Sendenden zu übertönen. + Lead-Moderatoren verwalten zusätzlich das Team selbst. + https://help.twitch.tv/s/article/Managing-Roles-for-your-Channel + https://discord.com/safety/training-and-onboarding-new-moderators + https://discord.com/safety/developing-moderator-guidelines + + TikTok LIVE im Besonderen: gefilterte Kommentare durchsehen, Konten + stummschalten und sperren, GÄSTE verwalten (bis zu 20), Regeln zu + Beginn sichtbar machen, bei Matches („PK", offiziell LIVE Match) den + Gegenüber respektieren und den Chat mitnehmen, und Geschenke + bedanken, ohne darum zu betteln. + https://www.tiktok.com/discover/what-can-tiktok-live-moderators-do + https://ondigitals.com/how-to-battle-on-tiktok-live/ + + Community-Arbeit: ein bis zwei eigene Beiträge je Woche, monatlich + ein Rückblick darauf, welche Formate und Zeiten getragen haben, + Vertretung für Abwesenheiten, und Routinearbeit an vertraute Leute + abgeben statt alles selbst zu machen. + https://www.higherlogic.com/blog/community-management-checklist/ + https://blog.hubspot.com/marketing/great-community-management-tips + + Und aus der Burnout-Forschung, die schon in „Wie geht's dir?" steht: + Die zwei meistgenannten Gründe fürs Aufhören sind zu wenig Zeit und + Streit im Team — deshalb stehen in der Kategorie „Team" Aufgaben, die + genau das früh sichtbar machen. + + --------------------------------------------------------------------- + JEDE AUFGABE SAGT, WARUM + + `text` ist keine Wiederholung des Titels. Wer eine Aufgabe bekommt, + ohne den Grund zu kennen, macht sie einmal und danach nicht mehr. + `tage` ist ein Vorschlag für die Frist, kein Gesetz. + ===================================================================== */ + +export const MODI_AUFGABEN = { + chat: { + neu: [ + { schluessel: "ma-chat-regeln-lesen", titel: "Die Regeln des Treffs einmal ganz lesen", tage: 2, + text: "Nicht überfliegen. Wer sie kennt, kann sie erklären – und Erklären ist in neun von zehn Fällen wirksamer als Löschen." }, + { schluessel: "ma-chat-begruessen", titel: "Eine Sendung lang jeden Neuen begrüßen", tage: 3, + text: "Der erste Satz an einen Neuen entscheidet, ob er wiederkommt. Kostet nichts und passiert trotzdem selten." }, + { schluessel: "ma-chat-werkzeuge-ueben", titel: "Löschen, Stummschalten und Sperren einmal ausprobieren", tage: 2, + text: "In einer ruhigen Minute, nicht im Ernstfall. Wer den Knopf erst sucht, während es eskaliert, findet ihn zu spät." }, + { schluessel: "ma-chat-gefiltert-durchsehen", titel: "Die gefilterten Kommentare einmal durchgehen", tage: 3, + text: "TikTok hält Beiträge zurück, die es für problematisch hält. Dort steht beides: echter Müll und zu Unrecht Gefiltertes – das zweite kostet sonst einen Zuschauer." }, + ], + dabei: [ + { schluessel: "ma-chat-regeln-ansage", titel: "Die Regeln zu Beginn jeder Sendung sichtbar machen", tage: 7, + text: "Ein angehefteter Satz am Anfang. Regeln, die niemand gesehen hat, wirken beim Durchsetzen wie Willkür." }, + { schluessel: "ma-chat-eskalation-ueben", titel: "Hinweis, Pause, Ausschluss – einmal bewusst in dieser Reihenfolge", tage: 7, + text: "Wer sofort sperrt, hat einen Gegner statt eines Mitglieds. Die Reihenfolge ist die eigentliche Arbeit." }, + { schluessel: "ma-chat-stille-phasen", titel: "Bei Stille eine Frage in den Chat stellen", tage: 5, + text: "Ein Chat, in dem nichts steht, füllt sich nicht von allein. Eine Frage, die man mit einem Wort beantworten kann, bringt ihn zurück." }, + { schluessel: "ma-chat-uebergabe-notieren", titel: "Nach der Schicht drei Zeilen hinterlassen", tage: 5, + text: "Was auffiel, wer auffiel, was offen ist. Am nächsten Tag weiß es niemand mehr – auch du nicht." }, + ], + erfahren: [ + { schluessel: "ma-chat-faelle-sammeln", titel: "Fünf echte Fälle aufschreiben, wie sie entschieden wurden", tage: 14, + text: "Aus Entscheidungen wird erst dann eine Linie, wenn sie irgendwo steht. Sonst entscheidet jeder nach Bauchgefühl – und das unterscheidet sich." }, + { schluessel: "ma-chat-zweitmeinung", titel: "Bei jedem dauerhaften Ausschluss eine zweite Meinung einholen", tage: 10, + text: "Nicht, weil du falsch liegst. Sondern damit niemand allein dasteht, wenn jemand sich beschwert." }, + { schluessel: "ma-chat-neue-einarbeiten", titel: "Eine ganze Sendung neben einem Neuen sitzen", tage: 14, + text: "Nicht erklären, sondern danebensitzen und im Zweifel eingreifen. Ein fester Ansprechpartner in den ersten Wochen ist die am besten belegte Maßnahme gegen frühes Aufhören." }, + ], + }, + + community: { + neu: [ + { schluessel: "ma-com-stammnamen", titel: "Zehn Namen lernen, die immer da sind", tage: 5, + text: "Wiedererkannt zu werden ist der halbe Grund wiederzukommen. Zehn reichen für den Anfang." }, + { schluessel: "ma-com-erste-frage", titel: "Jemanden, der zum ersten Mal schreibt, mit Namen ansprechen", tage: 3, + text: "Einmal am Abend genügt. Es ist der Unterschied zwischen einem Publikum und einer Runde." }, + ], + dabei: [ + { schluessel: "ma-com-lange-weg", titel: "Wer lange nicht da war, bekommt eine Nachricht", tage: 7, + text: "Keine Werbung, eine Frage. Die meisten kommen nicht wieder, weil sie sich gestritten haben, sondern weil es niemandem aufgefallen ist." }, + { schluessel: "ma-com-geburtstage", titel: "Eine Liste der Geburtstage anlegen und pflegen", tage: 10, + text: "Ein Satz am richtigen Tag wirkt stärker als jede Aktion. Aber nur, wenn ihn jemand aufschreibt." }, + { schluessel: "ma-com-stimmung-melden", titel: "Nach jeder Sendung die Stimmung in einem Wort festhalten", tage: 7, + text: "Über Wochen sieht man daran mehr als an den Zahlen – und es dauert fünf Sekunden." }, + ], + erfahren: [ + { schluessel: "ma-com-kuemmerer", titel: "Für drei Stammleute die Zuständigkeit übernehmen", tage: 14, + text: "Feste Zuständigkeit statt „irgendwer“. Wer weiß, an wen er sich wendet, meldet sich, bevor er wegbleibt." }, + { schluessel: "ma-com-konflikt-frueh", titel: "Einen schwelenden Streit ansprechen, bevor er eskaliert", tage: 10, + text: "Streit in der Runde ist der zweithäufigste Grund, warum Leute gehen – und der, über den am wenigsten geredet wird." }, + ], + }, + + events: { + neu: [ + { schluessel: "ma-ev-termin-eintragen", titel: "Einen Termin vollständig in den Kalender eintragen", tage: 2, + text: "Titel, Beginn, wer dabei ist. Ein Termin, den nur einer im Kopf hat, findet ohne ihn nicht statt." }, + { schluessel: "ma-ev-erinnerung", titel: "Am Vortag an den Termin erinnern", tage: 3, + text: "Nicht am selben Tag – dann ist der Abend schon verplant." }, + ], + dabei: [ + { schluessel: "ma-ev-match-vorbereiten", titel: "Ein Match vorbereiten: Gegenüber, Zeit, Regeln", tage: 7, + text: "Fünf Minuten laufen schnell ab. Wer vorher weiß, worum es geht, verliert sie nicht mit Erklären." }, + { schluessel: "ma-ev-gaeste-verwalten", titel: "Die Gästeliste während einer Sendung betreuen", tage: 7, + text: "Wer hereingelassen wird und wer wartet. Ein Gast, der zehn Minuten in der Warteschlange hängt, kommt nicht wieder." }, + { schluessel: "ma-ev-nachbereitung", titel: "Nach einer Aktion aufschreiben, was getragen hat", tage: 5, + text: "Solange man es noch weiß. Eine Aktion, die niemand auswertet, wird beim nächsten Mal genauso gemacht – auch die Fehler." }, + ], + erfahren: [ + { schluessel: "ma-ev-reihe-planen", titel: "Eine Reihe über vier Wochen planen statt einzelner Abende", tage: 14, + text: "Eine Reihe hat einen Grund wiederzukommen. Ein einzelner guter Abend hat das nicht." }, + { schluessel: "ma-ev-ausfallplan", titel: "Für den nächsten Termin einen Ausfallplan festlegen", tage: 10, + text: "Wer springt ein, wenn du krank bist? Die Antwort muss vorher feststehen, nicht am Abend selbst." }, + ], + }, + + clipping: { + neu: [ + { schluessel: "ma-cl-erster-clip", titel: "Einen Ausschnitt schneiden und hochladen", tage: 3, + text: "Irgendeinen. Der erste ist nie gut – der zehnte schon, und zum zehnten kommt nur, wer den ersten gemacht hat." }, + { schluessel: "ma-cl-marken-setzen", titel: "Während der Sendung Stellen markieren", tage: 2, + text: "Zeitpunkt und drei Wörter. Wer hinterher zwei Stunden durchsucht, macht es genau einmal." }, + ], + dabei: [ + { schluessel: "ma-cl-erste-sekunden", titel: "Bei fünf Ausschnitten nur den Anfang überarbeiten", tage: 7, + text: "Die ersten ein bis drei Sekunden entscheiden über die Verbreitung. Alles danach ist für die, die schon geblieben sind." }, + { schluessel: "ma-cl-untertitel", titel: "Untertitel setzen und einmal ohne Ton ansehen", tage: 5, + text: "Ein großer Teil sieht ohne Ton. Ein Ausschnitt, der stumm nicht funktioniert, funktioniert für sie gar nicht." }, + { schluessel: "ma-cl-takt", titel: "Einen festen Tag pro Woche für Ausschnitte", tage: 7, + text: "Zwei feste Tage schlagen fünf zufällige – bei Sendungen wie bei Ausschnitten." }, + ], + erfahren: [ + { schluessel: "ma-cl-was-lief", titel: "Die zehn erfolgreichsten Ausschnitte nebeneinanderlegen", tage: 14, + text: "Nicht raten, welche Art funktioniert. Nachsehen – meist ist es eine, die man selbst für die schwächste hielt." }, + { schluessel: "ma-cl-vorlage-bauen", titel: "Eine Vorlage bauen, mit der andere schneiden können", tage: 14, + text: "Solange nur einer schneiden kann, hört das Schneiden auf, sobald er keine Zeit hat." }, + ], + }, + + social: { + neu: [ + { schluessel: "ma-so-ankuendigung", titel: "Eine Ankündigung vor der Sendung absetzen", tage: 2, + text: "30 bis 60 Minuten vorher. Sie bündelt die, die ohnehin kommen wollten – und ein voller Start zieht neue nach." }, + { schluessel: "ma-so-antworten", titel: "Alle Kommentare unter einem Beitrag beantworten", tage: 3, + text: "Eine unbeantwortete Frage ist schlimmer als eine abgelehnte – sie sagt: du bist hier nicht gemeint." }, + ], + dabei: [ + { schluessel: "ma-so-woche-planen", titel: "Die Beiträge einer Woche im Voraus festlegen", tage: 7, + text: "Ein bis zwei eigene Beiträge je Woche reichen – aber sie müssen kommen, auch an einem schlechten Tag." }, + { schluessel: "ma-so-beste-zeit", titel: "Zwei Uhrzeiten gegeneinander ausprobieren", tage: 10, + text: "Dieselbe Art Beitrag, zwei Zeiten, zwei Wochen. Danach weißt du es, statt es zu vermuten." }, + ], + erfahren: [ + { schluessel: "ma-so-monatsrueckblick", titel: "Einmal im Monat durchgehen, welche Formate getragen haben", tage: 14, + text: "Welche Formate, welche Zeiten, welcher Kanal überflüssig geworden ist. Der Alltag gibt diesen Blick nicht her." }, + { schluessel: "ma-so-ton-festhalten", titel: "Aufschreiben, wie wir klingen – und wie nicht", tage: 14, + text: "Drei Sätze, die passen, und drei, die nicht passen. Sobald mehr als einer schreibt, ist das der Unterschied zwischen einer Stimme und einem Durcheinander." }, + ], + }, + + technik: { + neu: [ + { schluessel: "ma-te-ton-hoeren", titel: "Den eigenen Ton einmal aufnehmen und anhören", tage: 2, + text: "Eine Minute mit dem echten Aufbau, danach mit Kopfhörern. Während der Sendung hört man sich selbst nie." }, + { schluessel: "ma-te-verbindung-messen", titel: "Vor der Sendung die Verbindung messen", tage: 2, + text: "Dauert zwanzig Sekunden. Eine hakende Sendung sucht man sonst zwei Stunden beim Ton." }, + ], + dabei: [ + { schluessel: "ma-te-last-messen", titel: "Bei laufender Sendung einmal die Auslastung ansehen", tage: 7, + text: "Prozessor, Grafik, Netz. Steht die CPU am Anschlag, bekommt der Ton keine Rechenzeit – und genau das klingt wie eine Roboterstimme." }, + { schluessel: "ma-te-ersatz", titel: "Für jedes wichtige Gerät den Ersatz kennen", tage: 10, + text: "Welches Mikrofon, welches Kabel, welches Handy springt ein. Mitten in der Sendung ist die falsche Zeit, das herauszufinden." }, + { schluessel: "ma-te-checkliste", titel: "Eine Startliste mit fünf Punkten aufschreiben", tage: 7, + text: "Fünf, nicht zwanzig. Eine Liste, die zu lang ist, wird übersprungen – und dann fehlt auch der erste Punkt." }, + ], + erfahren: [ + { schluessel: "ma-te-ausfall-durchspielen", titel: "Einen Ausfall einmal absichtlich durchspielen", tage: 14, + text: "Stecker ziehen, während niemand zusieht. Was man einmal geübt hat, macht man im Ernstfall in dreißig Sekunden statt in zehn Minuten." }, + { schluessel: "ma-te-anleitung-deutsch", titel: "Die Einstellungen in deutschen Menüpunkten aufschreiben", tage: 14, + text: "Wer eine Anleitung mit englischen Begriffen bekommt, findet sie auf seinem Bildschirm nicht wieder." }, + ], + }, + + planung: { + neu: [ + { schluessel: "ma-pl-verfuegbarkeit", titel: "Die eigenen Zeiten für die nächsten zwei Wochen eintragen", tage: 3, + text: "Auch die Tage, an denen du NICHT kannst — genau die fehlen sonst beim Planen. Wer sie nicht einträgt, wird eingeteilt und sagt hinterher ab; das kostet mehr als ein Nein vorher." }, + ], + dabei: [ + { schluessel: "ma-pl-sendeplan", titel: "Den Sendeplan für vier Wochen festlegen", tage: 10, + text: "Zwei feste Tage schlagen fünf zufällige. Wer weiß, wann es losgeht, plant sich den Abend frei." }, + { schluessel: "ma-pl-themen-vorrat", titel: "Fünf Themen auf Vorrat aufschreiben", tage: 7, + text: "Für die Abende, an denen nichts einfällt. Die kommen, und dann ist die Liste mehr wert als jede Idee von heute." }, + { schluessel: "ma-pl-schichten", titel: "Die Schichten für die nächste Woche verteilen", tage: 5, + text: "Niemand ist dauerhaft zuständig. Rotation ist in der Forschung eine der wenigen Maßnahmen, die Belastung wirklich senken." }, + ], + erfahren: [ + { schluessel: "ma-pl-engpass", titel: "Den Engpass der nächsten vier Wochen benennen", tage: 14, + text: "Eine Person, ein Gerät, ein Termin. Wer ihn vorher sagt, hat eine Wahl; wer ihn erlebt, hat keine." }, + { schluessel: "ma-pl-urlaub", titel: "Abwesenheiten einsammeln und Vertretung festlegen", tage: 14, + text: "Nicht „wir schauen dann“ – ein Name. Eine Vertretung, die erst am Tag davor gesucht wird, ist keine." }, + ], + }, + + organisation: { + neu: [ + { schluessel: "ma-or-ablage-finden", titel: "Drei Dateien in der Ablage suchen und wiederfinden", tage: 2, + text: "Wer nicht findet, legt neu an – und ab da gibt es zwei Fassungen von allem." }, + { schluessel: "ma-or-aufgabe-schliessen", titel: "Eine erledigte Aufgabe wirklich abschließen", tage: 2, + text: "Ein Brett, auf dem Erledigtes stehen bleibt, sagt nach zwei Wochen nichts mehr." }, + ], + dabei: [ + { schluessel: "ma-or-namen-regel", titel: "Eine Regel für Dateinamen aufschreiben und anwenden", tage: 7, + text: "Datum vorn, dann worum es geht. Klingt nach Kleinigkeit und ist der Unterschied zwischen Suchen und Finden." }, + { schluessel: "ma-or-alte-aufraeumen", titel: "Alles durchgehen, was länger als 30 Tage offen liegt", tage: 10, + text: "Entweder es ist wichtig – dann bekommt es eine Frist. Oder nicht – dann weg. Liegenbleiben ist die dritte Möglichkeit, und die kostet am meisten." }, + ], + erfahren: [ + { schluessel: "ma-or-zugaenge-pruefen", titel: "Alle Zugänge durchgehen: wer braucht noch welchen", tage: 14, + text: "Wer geht, nimmt seinen Zugang nicht mit. Einmal im Quartal durchsehen – es dauert zehn Minuten und schließt Türen, die niemand mehr im Blick hat." }, + { schluessel: "ma-or-uebersicht-bauen", titel: "Eine Übersicht bauen, die auch ohne dich verständlich ist", tage: 14, + text: "Der Test ist einfach: Kann jemand anders damit arbeiten, ohne zu fragen? Wenn nicht, ist es eine Notiz, keine Übersicht." }, + ], + }, + + team: { + neu: [ + { schluessel: "ma-tm-wen-fragen", titel: "Aufschreiben, wen du bei was fragst", tage: 2, + text: "Drei Namen, drei Themen. Wer im Ernstfall überlegen muss, wen er fragt, fragt niemanden." }, + { schluessel: "ma-tm-vorstellen", titel: "Sich im Team kurz vorstellen", tage: 3, + text: "Zwei Sätze, wer du bist und was du machst. Ein Team, in dem man Namen liest statt Menschen zu kennen, hilft sich nicht gegenseitig." }, + ], + dabei: [ + { schluessel: "ma-tm-uebergabe", titel: "Eine saubere Übergabe an die nächste Schicht schreiben", tage: 5, + text: "Was offen ist, was auffiel, worauf zu achten ist. Ohne sie fängt die nächste Schicht bei null an." }, + { schluessel: "ma-tm-danken", titel: "Einer Person ausdrücklich für etwas Bestimmtes danken", tage: 5, + text: "Nicht allgemein – für etwas Bestimmtes. Fehlende Anerkennung ist der am häufigsten genannte emotionale Preis dieser Arbeit und der billigste zu beheben." }, + { schluessel: "ma-tm-nein-sagen", titel: "Einmal bewusst nein sagen, wenn es zu viel ist", tage: 7, + text: "Zu wenig Zeit ist der meistgenannte Grund, warum Moderatoren aufhören. Ein Nein zur richtigen Zeit verhindert ein Aufhören zur falschen." }, + ], + erfahren: [ + { schluessel: "ma-tm-buddy", titel: "Einen Neuen durch seine erste Schicht begleiten", tage: 14, + text: "Ein fester Ansprechpartner in den ersten Wochen ist die am besten belegte Einzelmaßnahme gegen frühes Aufhören." }, + { schluessel: "ma-tm-runde", titel: "Eine kurze Runde nach einer harten Sendung", tage: 10, + text: "Wer Hässliches wegmoderiert, nimmt es mit. Ein fester kurzer Austausch wirkt nachweislich besser als ein Angebot, das man von sich aus annehmen muss." }, + { schluessel: "ma-tm-vertretung-einarbeiten", titel: "Jemanden so einarbeiten, dass er dich vertreten kann", tage: 21, + text: "Solange nur du es kannst, kannst du nicht krank werden. Das ist keine Vorsicht, das ist Rechnen." }, + ], + }, + + kommunikation: { + neu: [ + { schluessel: "ma-ko-antwortzeit", titel: "Offene Nachrichten innerhalb eines Tages beantworten", tage: 3, + text: "Auch mit „ich schaue es mir an“. Eine Antwort ohne Ergebnis ist besser als Schweigen mit Ergebnis." }, + ], + dabei: [ + { schluessel: "ma-ko-vorlagen", titel: "Drei Textbausteine für wiederkehrende Fragen schreiben", tage: 7, + text: "Dieselbe Frage kommt zwanzigmal. Ein Baustein spart nicht nur Zeit – er sorgt auch dafür, dass alle dieselbe Antwort bekommen." }, + { schluessel: "ma-ko-anfrage-weiterleiten", titel: "Eine Anfrage sauber weitergeben statt liegen zu lassen", tage: 5, + text: "Mit einem Satz, worum es geht, und einem Namen. Eine weitergeleitete Anfrage ohne Zusammenhang ist eine neue Aufgabe für den Nächsten." }, + ], + erfahren: [ + { schluessel: "ma-ko-kooperation", titel: "Eine Anfrage von außen vollständig durchziehen", tage: 21, + text: "Von der ersten Nachricht bis zur Absage oder Zusage. Wer nur den Anfang macht, hinterlässt eine halbe Sache im Postfach eines anderen." }, + { schluessel: "ma-ko-ton-schwierig", titel: "Eine unangenehme Nachricht schreiben und gegenlesen lassen", tage: 10, + text: "Absagen, Beschwerden, Korrekturen. Vier Augen kosten fünf Minuten und ersparen eine Woche Aufräumen." }, + ], + }, + + analyse: { + neu: [ + { schluessel: "ma-an-zahlen-finden", titel: "Die Zahlen einer Sendung einmal selbst heraussuchen", tage: 3, + text: "Zuschauer, Verweildauer, Wiederkehr — einmal selbst heraussuchen, nicht vorgelesen bekommen. Wer nicht weiß, wo sie stehen, glaubt jede Zahl, die ihm jemand sagt." }, + ], + dabei: [ + { schluessel: "ma-an-verweildauer", titel: "Die Verweildauer der letzten fünf Sendungen vergleichen", tage: 7, + text: "Über 15 Minuten heißt: die Stimmung trägt. Darunter liegt es fast nie am Thema, sondern am Anfang." }, + { schluessel: "ma-an-eine-zahl", titel: "Für den Monat EINE Zahl festlegen, auf die ihr schaut", tage: 7, + text: "Zehn Zahlen beobachten heißt keine beobachten. Eine, die ihr beeinflussen könnt – und sie muss nicht die größte sein." }, + ], + erfahren: [ + { schluessel: "ma-an-verlauf-lesen", titel: "Einen Verlauf über drei Monate lesen und deuten", tage: 14, + text: "Ein einzelner schlechter Wert ist ein schlechter Tag. Dasselbe über drei Monate ist ein Muster – und nur das Muster ist eine Auskunft." }, + { schluessel: "ma-an-gegenprobe", titel: "Eine Annahme nachmessen, von der alle ausgehen", tage: 14, + text: "„Freitags ist am meisten los.“ Nachsehen. Ungefähr jede zweite solche Annahme hält der Messung nicht stand." }, + ], + }, + + wachstum: { + neu: [ + { schluessel: "ma-wa-woher", titel: "Zehn Neue fragen, wie sie hergefunden haben", tage: 5, + text: "Die Antwort ist selten die, die man erwartet – und sie kostet eine Frage." }, + ], + dabei: [ + { schluessel: "ma-wa-zeit-testen", titel: "Eine neue Sendezeit vier Wochen lang ausprobieren", tage: 21, + text: "Eine Zeit, zu der ihr niemanden habt, schlägt eine, zu der alle senden. Vier Wochen, sonst misst man den Zufall." }, + { schluessel: "ma-wa-wiederkehr", titel: "Zählen, wie viele von letzter Woche wieder da sind", tage: 10, + text: "Wachstum ohne Wiederkehr ist ein Eimer mit Loch. Die Zahl ist unangenehm und die wichtigste, die es gibt." }, + ], + erfahren: [ + { schluessel: "ma-wa-kanal-pruefen", titel: "Einen zusätzlichen Kanal testen und danach ehrlich entscheiden", tage: 21, + text: "Vier Wochen, dann Schluss oder weiter. Ein Kanal, den niemand pflegt, schadet mehr als er nützt." }, + { schluessel: "ma-wa-empfehlung", titel: "Einen Weg bauen, auf dem Stammleute jemanden mitbringen", tage: 14, + text: "Wer aus der Runde kommt, ist schon einmal durch ein Augenpaar gegangen – das ist die beste Quelle, die es gibt." }, + ], + }, + + branding: { + neu: [ + { schluessel: "ma-br-farben-kennen", titel: "Die Farben und Schriften einmal nachschlagen", tage: 2, + text: "Damit du sie benutzt, statt sie zu schätzen. Zwei ähnliche Blautöne nebeneinander sehen aus wie ein Versehen." }, + ], + dabei: [ + { schluessel: "ma-br-vorlage-nutzen", titel: "Drei Beiträge mit derselben Vorlage bauen", tage: 7, + text: "Wiedererkennung entsteht durch Wiederholung, nicht durch Einfälle." }, + { schluessel: "ma-br-sprache", titel: "Aufschreiben, wie wir jemanden ansprechen", tage: 7, + text: "Du oder Sie, Spitznamen oder nicht, Emojis oder nicht. Sobald mehr als einer schreibt, merkt man den Unterschied sofort." }, + ], + erfahren: [ + { schluessel: "ma-br-durchgang", titel: "Alle Kanäle nebeneinanderlegen und Abweichungen notieren", tage: 14, + text: "Bild, Beschreibung, Farben, Ton. Nach einem halben Jahr läuft immer etwas auseinander – man sieht es nur, wenn man es nebeneinanderlegt." }, + { schluessel: "ma-br-zeichen", titel: "Ein wiedererkennbares Zeichen für eine Reihe festlegen", tage: 14, + text: "Ein Bild, das immer gleich aussieht, spart jede Erklärung. Wer es sieht, weiß, was kommt." }, + ], + }, + + sonstiges: { + neu: [ + { schluessel: "ma-sn-notieren", titel: "Aufschreiben, was dir in der ersten Woche gefehlt hat", tage: 7, + text: "Nur ein Neuer kann das sagen – nach drei Monaten fällt es niemandem mehr auf. Genau deshalb ist es die wertvollste Liste im Haus." }, + ], + dabei: [ + { schluessel: "ma-sn-idee-einbringen", titel: "Eine eigene Idee aufs Brett schreiben", tage: 7, + text: "Nicht im Gespräch sagen – aufschreiben. Was nur gesagt wurde, ist nach zwei Tagen weg." }, + ], + erfahren: [ + { schluessel: "ma-sn-ueberfluessiges", titel: "Etwas benennen, das ihr nicht mehr braucht", tage: 14, + text: "Ein Ablauf, eine Liste, ein Kanal. Weglassen ist die einzige Verbesserung, die nichts kostet – und die einzige, die niemand von selbst vorschlägt." }, + ], + }, +}; + +/* Flach, mit Kategorie und Stufe an jedem Eintrag -- fuer die Pruefung + und fuer jeden, der zaehlen will, ohne zweimal zu verschachteln. */ +export const MODI_AUFGABEN_FLACH = Object.entries(MODI_AUFGABEN) + .flatMap(([kategorie, stufen]) => Object.entries(stufen) + .flatMap(([stufe, liste]) => liste.map((a) => ({ ...a, kategorie, stufe })))); diff --git a/server/workspace.js b/server/workspace.js index 5789560a..d65c239f 100644 --- a/server/workspace.js +++ b/server/workspace.js @@ -1146,21 +1146,82 @@ const MODI_MARKE = "Team Dogi"; sondern weil eine Liste, die im Browser jedes Menschen liegt und nur bei einem einzigen benutzt wird, die Frage aufwirft, fuer wen sie da ist. Genau diese Frage soll niemand stellen. */ +/* DIE VIERZEHN KATEGORIEN -- jetzt mit einem Satz dazu (16.09.2026). + * + * Filipe: "perfektionniere die kategorien wo ich aufgaben an die modis + * verteile." + * + * Bis heute standen hier vierzehn nackte Namen. "Organisation" und + * "Planung" nebeneinander, ohne einen Satz, der sagt, was worin + * gehoert -- und dann landet dieselbe Aufgabe beim einen unter + * Planung, beim anderen unter Organisation, und die Auswertung + * darueber ist wertlos. + * + * Der Satz steht deshalb an der Kategorie und nicht in einer + * Anleitung: Er wird dort gebraucht, wo man sich entscheidet. */ export const MODI_KATEGORIEN = [ - { wert: "chat", name: "Chat-Moderation" }, - { wert: "community", name: "Community" }, - { wert: "events", name: "Events" }, - { wert: "clipping", name: "Clipping" }, - { wert: "social", name: "Social Media" }, - { wert: "technik", name: "Technik" }, - { wert: "planung", name: "Planung" }, - { wert: "organisation", name: "Organisation" }, - { wert: "team", name: "Team" }, - { wert: "kommunikation", name: "Kommunikation" }, - { wert: "analyse", name: "Analyse" }, - { wert: "wachstum", name: "Wachstum" }, - { wert: "branding", name: "Branding" }, - { wert: "sonstiges", name: "Sonstiges" }, + { wert: "chat", name: "Chat-Moderation", + text: "Was im Livechat passiert, waehrend gesendet wird. Loeschen, " + + "stummschalten, begruessen, deeskalieren." }, + { wert: "community", name: "Community", + text: "Die Menschen ausserhalb der Sendung: wer wiederkommt, wer neu " + + "ist, wer lange nicht da war." }, + { wert: "events", name: "Events", + text: "Alles mit einem Termin: Matches, Aktionen, Geburtstage, " + + "besondere Sendungen." }, + { wert: "clipping", name: "Clipping", + text: "Aus einer Sendung viele Videos machen -- schneiden, " + + "beschriften, hochladen." }, + { wert: "social", name: "Social Media", + text: "Alles ausserhalb des Livestreams: Ankuendigungen, Beitraege, " + + "Antworten unter Videos." }, + { wert: "technik", name: "Technik", + text: "Ton, Bild, Verbindung, Geraete. Meistens unsichtbar -- und " + + "sofort sichtbar, wenn es fehlt." }, + { wert: "planung", name: "Planung", + text: "Was NOCH NICHT ist: Sendeplan, Themen, wer wann kann." }, + { wert: "organisation", name: "Organisation", + text: "Was BEREITS ist, in Ordnung halten: Ablage, Listen, Zugaenge, " + + "Uebersichten." }, + { wert: "team", name: "Team", + text: "Die Zusammenarbeit selbst: Uebergaben, Einarbeitung, " + + "Absprachen, Vertretung." }, + { wert: "kommunikation", name: "Kommunikation", + text: "Was nach aussen geht und beantwortet werden muss: " + + "Nachrichten, Anfragen, Kooperationen." }, + { wert: "analyse", name: "Analyse", + text: "Nachsehen statt schaetzen: Zahlen, Verlaeufe, was sich " + + "veraendert hat." }, + { wert: "wachstum", name: "Wachstum", + text: "Gezielt mehr werden: neue Zuschauer, neue Kanaele, neue " + + "Zeiten ausprobieren." }, + { wert: "branding", name: "Branding", + text: "Wie es aussieht und klingt: Farben, Zeichen, Sprache, " + + "Wiedererkennung." }, + { wert: "sonstiges", name: "Sonstiges", + text: "Was in keine der dreizehn passt. Bleibt absichtlich klein -- " + + "wird es gross, fehlt eine Kategorie." }, +]; + +/** Die drei Stufen einer Modi-Aufgabe. + * + * DIESELBE IDEE WIE BEI DEN CREATOR-VORLAGEN, andere Worte: Dort heisst + * es Anfaenger/Fortgeschritten/Profi, und das passt fuer jemanden, der + * etwas LERNT. Hier geht es nicht um Koennen, sondern darum, wie lange + * jemand dabei ist und wie viel Vertrauen die Aufgabe braucht. + * + * Eine Aufgabe der Stufe "erfahren" an einen Neuen zu geben ist kein + * Kompliment, sondern ein Ueberfallen. */ +export const MODI_STUFEN = [ + { wert: "neu", name: "Neu dabei", + text: "Die ersten Wochen. Klar umrissen, ohne Folgen, wenn etwas " + + "schiefgeht -- und jemand ist erreichbar." }, + { wert: "dabei", name: "Eingearbeitet", + text: "Kennt den Laden. Kann allein entscheiden, ohne vorher zu " + + "fragen, und weiss, wann man doch fragt." }, + { wert: "erfahren", name: "Erfahren", + text: "Traegt Verantwortung fuer andere: arbeitet ein, vertritt, " + + "entscheidet im Zweifel." }, ]; /** * Darf diese Person mit Kategorien arbeiten? diff --git a/workspace/app.webmanifest b/workspace/app.webmanifest index dffcaf8c..e78c1a95 100644 --- a/workspace/app.webmanifest +++ b/workspace/app.webmanifest @@ -13,25 +13,25 @@ "theme_color": "#06090f", "icons": [ { - "src": "/assets/img/app-symbole/workspace-192.png?v=202609161803", + "src": "/assets/img/app-symbole/workspace-192.png?v=202609161903", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-512.png?v=202609161803", + "src": "/assets/img/app-symbole/workspace-512.png?v=202609161903", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { - "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609161803", + "src": "/assets/img/app-symbole/workspace-192-maskable.png?v=202609161903", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { - "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609161803", + "src": "/assets/img/app-symbole/workspace-512-maskable.png?v=202609161903", "sizes": "512x512", "type": "image/png", "purpose": "maskable" diff --git a/workspace/assets/css/start.css b/workspace/assets/css/start.css index f13fd2e7..0e70340f 100644 --- a/workspace/assets/css/start.css +++ b/workspace/assets/css/start.css @@ -7607,6 +7607,18 @@ body.start .k-leiste .feldschild::after { .stufenleiter__knopf[data-stufe="fort"] { --sf: #a78bfa; } .stufenleiter__knopf[data-stufe="profi"] { --sf: #e8a94e; } .stufenleiter__knopf[data-stufe="meister"] { --sf: #5fc99a; } +/* DIE DREI STUFEN DES TEAMS (16.09.2026). Dieselbe Reihe, zweite + Ebene: oben die Kategorie, darunter fuer wen die Aufgabe gedacht + ist. Die Toene steigen wie bei den Creator-Stufen -- hell fuer den + Anfang, warm fuer das, was Verantwortung traegt. */ +.stufenleiter__knopf[data-stufe="neu"] { --sf: #7ec8f2; } +.stufenleiter__knopf[data-stufe="dabei"] { --sf: #a78bfa; } +.stufenleiter__knopf[data-stufe="erfahren"] { --sf: #e8a94e; } + +/* Die zweite Reihe steht dichter unter der ersten und traegt weniger + Gewicht: Sie waehlt innerhalb dessen, was oben schon gewaehlt ist. */ +.stufenleiter--fein { margin: -6px 0 14px; } +.stufenleiter--fein .stufenleiter__knopf { padding: 5px 11px; font-size: .76rem; } .stufenleiter__knopf:hover { color: var(--text); diff --git a/workspace/assets/js/aufgaben.js b/workspace/assets/js/aufgaben.js index df31edaf..2291ab19 100644 --- a/workspace/assets/js/aufgaben.js +++ b/workspace/assets/js/aufgaben.js @@ -1050,6 +1050,9 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe schliessen laesst, fuer wen er gedacht ist. */ let katalog = null; let kGruppe = null; + /* WELCHE STUFE. `null` heisst alle -- und das ist die Vorgabe: + Wer eine Kategorie aufmacht, will erst sehen, was es gibt. */ + let kStufe = null; /* Getrennt vom Inhalt, weil "nichts bekommen" ein gueltiges Ergebnis ist. Ohne dieses Merkmal fragte die Seite bei jedem Neuzeichnen erneut nach -- und bekaeme jedes Mal wieder nichts. */ @@ -1290,11 +1293,16 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe kopf.setAttribute('aria-controls', 'vorlagenbrett-koerper'); const kText = el('span', 'vorlagenbrett__kopftext'); kText.append(el('span', 'feldschild', 'Aufgaben aus der Vorlage')); + /* DER SATZ MUSS SAGEN, WONACH SORTIERT IST. Bis zum 16.09.2026 stand + hier "Nach Etappen sortiert" -- und seit dem Umbau auf Kategorie + mal Stufe war das schlicht falsch. Ein Satz, der etwas anderes + beschreibt als das, was darunter steht, kostet mehr Zeit als er + spart. */ kText.append(el('span', 'vorlagenbrett__unter', vOffen - ? 'Nach Etappen sortiert. Übernommen wird als ganz normale Aufgabe ' - + '– mit Frist und Kategorie, veränderbar, auf dem Brett darunter.' + ? 'Nach Kategorie und Stufe sortiert. Übernommen wird als ganz normale ' + + 'Aufgabe – mit Frist und Kategorie, veränderbar, auf dem Brett darunter.' : `${katalog.aufgaben.length} fertige Aufgaben in ` - + `${katalog.gruppen.length} Etappen – zum Übernehmen.`)); + + `${katalog.gruppen.length} Kategorien – zum Übernehmen.`)); kopf.append(kText); const pfeil = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); pfeil.setAttribute('viewBox', '0 0 24 24'); @@ -1341,6 +1349,51 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe const gruppe = katalog.gruppen.find((g) => g.schluessel === kGruppe); if (gruppe?.text) koerper.append(el('p', 'vorlagenbrett__stand', gruppe.text)); + /* ---- Die Stufe (16.09.2026) --------------------------------------- + + Filipe: "wie bei den aufgaben wo sie für mich haben auch mit + kategorien und vielen aufgaben." + + Dieselbe Kategorie bedeutet für jemanden in der ersten Woche + etwas anderes als für jemanden, der einarbeitet. Eine Aufgabe + der Stufe "erfahren" an einen Neuen zu geben ist kein + Kompliment, sondern ein Überfallen. + + DIE STUFEN KOMMEN VOM SERVER, nicht aus einer Liste hier: Eine + zweite Liste im Browser wäre die, die beim nächsten Zusatz + veraltet -- und ausgeliefert wird sie an jeden. */ + const inGruppe = katalog.aufgaben.filter((v) => v.gruppe === kGruppe); + if (Array.isArray(katalog.stufen) && katalog.stufen.length) { + const sr = el('div', 'stufenleiter stufenleiter--fein'); + sr.setAttribute('role', 'group'); + sr.setAttribute('aria-label', 'Stufe wählen'); + const alle = el('button', 'stufenleiter__knopf'); + alle.type = 'button'; + alle.setAttribute('aria-pressed', String(kStufe === null)); + alle.append(el('span', 'stufenleiter__name', 'Alle')); + alle.append(el('span', 'stufenleiter__zahl', String(inGruppe.length))); + alle.addEventListener('click', () => { kStufe = null; vorlagenbrettZeigen(); }); + sr.append(alle); + for (const st of katalog.stufen) { + const n = inGruppe.filter((v) => v.stufe === st.schluessel).length; + if (!n) continue; + const k = el('button', 'stufenleiter__knopf'); + k.type = 'button'; + k.dataset.stufe = st.schluessel; + k.setAttribute('aria-pressed', String(kStufe === st.schluessel)); + k.title = st.text || ''; + k.append(el('span', 'stufenleiter__name', st.name)); + k.append(el('span', 'stufenleiter__zahl', String(n))); + k.addEventListener('click', () => { kStufe = st.schluessel; vorlagenbrettZeigen(); }); + sr.append(k); + } + koerper.append(sr); + const gewaehlt = katalog.stufen.find((x) => x.schluessel === kStufe); + if (gewaehlt?.text) { + koerper.append(el('p', 'vorlagenbrett__stand', gewaehlt.text)); + } + } + /* Was schon auf dem Brett liegt -- aus den Aufgaben, die ohnehin geladen sind. Verglichen wird die Kennung der Vorlage und nicht der Titel: Der darf geändert werden. */ @@ -1349,7 +1402,8 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe const liste = katalog.aufgaben .map((v, nr) => ({ ...v, nr })) - .filter((v) => v.gruppe === kGruppe); + .filter((v) => v.gruppe === kGruppe) + .filter((v) => !kStufe || v.stufe === kStufe); const box = el('div', 'vorlagenbrett__liste'); for (const v of liste) { const karte = el('div', 'vorlagenbrett__karte'); @@ -1382,17 +1436,23 @@ Das laesst sich nicht rueckgaengig machen. Erledigte Aufgaben sollten normalerwe const offen = liste.filter((v) => !schonDa.has(v.schluessel)).length; koerper.append(el('p', 'vorlagenbrett__stand', offen ? `${offen} von ${liste.length} noch nicht übernommen.` - : `Alle ${liste.length} dieser Etappe sind übernommen.`)); + : `Alle ${liste.length} davon sind übernommen.`)); } koerper.append(box); if (liste.length > 1) { const alle = el('button', 'abmelden', `Alle ${liste.length} übernehmen`); - alle.title = 'Legt alle Aufgaben dieser Etappe an – auch die, die schon auf dem Brett liegen.'; + alle.title = 'Legt alle Aufgaben an, die gerade in der Liste stehen – ' + + 'auch die, die schon auf dem Brett liegen.'; alle.type = 'button'; alle.style.marginTop = '12px'; + /* DIE STUFE WANDERT MIT (16.09.2026). Ohne sie legte dieser Knopf + alle Aufgaben der Kategorie an -- auch die, die gerade + ausgeblendet sind. Der Knopf sagt "Alle 4 übernehmen" und + legte elf an; das merkt man erst auf dem Brett. */ alle.addEventListener('click', () => uebernehmen(alle, - { art: 'katalog_alle', gruppe: kGruppe, person_id: katalogZiel() })); + { art: 'katalog_alle', gruppe: kGruppe, stufe: kStufe || '', + person_id: katalogZiel() })); koerper.append(alle); } } diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 01360d3d..3cc3468f 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -12,19 +12,19 @@ Ton wie die Kopfleiste darunter (#06090f), damit Leiste und Seite eine Flaeche sind statt zweier. --> - - - - - - + + + + + + - +
@@ -282,10 +282,10 @@ - - - - - + + + + +