diff --git a/pruef-ampel.png b/pruef-ampel.png index 39d07bb5..889a89ea 100644 Binary files a/pruef-ampel.png and b/pruef-ampel.png differ diff --git a/pruef-checkliste.png b/pruef-checkliste.png index 860e2a2c..81b55520 100644 Binary files a/pruef-checkliste.png and b/pruef-checkliste.png differ diff --git a/server/pruef-vorlagen.mjs b/server/pruef-vorlagen.mjs index e1248b72..d4e9bcbf 100644 --- a/server/pruef-vorlagen.mjs +++ b/server/pruef-vorlagen.mjs @@ -95,10 +95,6 @@ let vorlagen; ok(anteilWert >= 0.45, `der groesste Teil sind Inhalte mit Wert (${Math.round(anteilWert * 100)} %: ${JSON.stringify(zaehl)})`); - /* Punkte, bei denen man Hilfe braucht, muessen als solche erkennbar - sein -- sonst weiss niemand, wo er fragen darf. */ - const mitHilfe = Object.values(vorlagen.live).flat().filter((v) => v.hilfe); - ok(mitHilfe.length >= 5, `Punkte mit Hilfe-Angebot (${mitHilfe.length})`); } /* ---------- Uebernehmen --------------------------------------------------- */ @@ -166,47 +162,9 @@ function anlegenFremd() { return id; } -/* ---------- Hilfe anfordern ----------------------------------------------- */ -console.log("\n=== Hilfe anfordern"); -{ - const a = await hole("/workspace/api/vorlagen/hilfe", kTili, { - method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ thema: "Ton geprüft", notiz: "Mein Mikro rauscht." }) }); - ok(a.ok, `ein Creator kann Hilfe anfordern (${a.status})`); - - /* Es muss eine AUFGABE geworden sein, nicht eine Nachricht. */ - const d3 = new DatabaseSync(process.env.WORKSPACE_DB, { readOnly: true }); - const auf = d3.prepare( - "SELECT * FROM aufgaben WHERE titel LIKE 'Hilfe gewünscht%' ORDER BY id DESC LIMIT 1").get(); - d3.close(); - ok(!!auf, "daraus wird eine Aufgabe"); - ok(auf?.verantwortlich_id === idScout, - `sie geht an seinen Betreuer Patrick (${auf?.verantwortlich_id} = ${idScout})`); - ok(auf?.creator_id === idTili, "und haengt an ihm"); - ok(auf?.prioritaet === "hoch", `mit hoher Prioritaet (${auf?.prioritaet})`); - /* Ohne Frist bleibt sie liegen -- das ist der Unterschied zwischen - einer Aufgabe und einem Zettel. */ - ok(!!auf?.frist, `und einer Frist (${auf?.frist})`); - ok(String(auf?.beschreibung || "").includes("Mein Mikro rauscht"), - "die Notiz steht mit drin"); - - /* Der Betreuer sieht sie auf seiner Startseite. */ - const kScout = await keks("scout", "CODE-SCOU-0001"); - /* Sie steht in SEINER Aufgabenliste. Als Hinweis auf der Startseite - erscheint sie erst, wenn die Frist naeher rueckt -- eine Aufgabe mit - drei Tagen Zeit ist weder ueberfaellig noch heute faellig, und das - ist richtig so. Ein erster Anlauf hat genau das geprueft und war - rot, obwohl das Verhalten stimmte. */ - const seine = await (await hole("/workspace/api/aufgaben", kScout)).json(); - const dabei = (seine.aufgaben || []).some((x) => String(x.titel).startsWith("Hilfe gewünscht")); - ok(dabei, `und steht in seiner Aufgabenliste (${(seine.aufgaben || []).length} Aufgaben)`); - - /* Ohne Thema geht nichts -- eine leere Bitte hilft niemandem. */ - const leer = await hole("/workspace/api/vorlagen/hilfe", kTili, { - method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ thema: "" }) }); - ok(leer.status === 400, `ohne Thema wird abgelehnt (${leer.status})`); -} +/* Der Abschnitt "Hilfe anfordern" stand hier. Der Weg ist am + 01.09.2026 entfallen -- geblieben ist die Rückmeldung an jedem Punkt, + geprüft in pruef-checkliste.mjs. */ /* ---------- Die Oberflaeche ---------------------------------------------- diff --git a/server/workspace-vorlagen.js b/server/workspace-vorlagen.js index 82845ede..ee2629cc 100644 --- a/server/workspace-vorlagen.js +++ b/server/workspace-vorlagen.js @@ -133,38 +133,35 @@ export const CONTENT_IDEEN = [ formuliert, dass man sie in einem Moment anklicken kann, in dem man eigentlich keine Zeit hat. - `hilfe: true` heißt: Der Creator kann das anklicken und sagen, dass - er dabei Unterstützung braucht -- daraus wird eine Aufgabe für seinen - Betreuer. ===================================================================== */ export const LIVE_PUNKTE = { vorbereitung: [ - { schluessel: "ton-geprueft", titel: "Ton geprüft", text: "Eine Minute aufnehmen und anhören. Ton ist der Grund Nummer eins, warum Leute wieder gehen.", hilfe: true }, - { schluessel: "licht-sitzt", titel: "Licht sitzt", text: "Gesicht heller als der Hintergrund. Kein Fenster im Rücken.", hilfe: true }, - { schluessel: "verbindung-getestet", titel: "Verbindung getestet", text: "Upload-Geschwindigkeit geprüft, Kabel statt WLAN wenn möglich.", hilfe: true }, - { schluessel: "titel-und-thema-stehen", titel: "Titel und Thema stehen", text: "Wer den Titel liest, weiß, was ihn erwartet – und ob es für ihn ist.", hilfe: false }, - { schluessel: "ablauf-grob-im-kopf", titel: "Ablauf grob im Kopf", text: "Drei Blöcke reichen. Ein Stream ohne roten Faden fühlt sich für Zuschauer wie Warten an.", hilfe: false }, - { schluessel: "angekuendigt", titel: "Angekündigt", text: "Mindestens einmal vorher gesagt, dass es losgeht – Story, Post oder Nachricht.", hilfe: false }, - { schluessel: "moderation-geklaert", titel: "Moderation geklärt", text: "Weiß jemand Bescheid, der eingreifen kann, wenn es im Chat kippt?", hilfe: true }, - { schluessel: "technik-ersatz-bereit", titel: "Technik-Ersatz bereit", text: "Was passiert, wenn der Stream abbricht? Handy als Notlösung bereitlegen.", hilfe: true }, + { schluessel: "ton-geprueft", titel: "Ton geprüft", text: "Eine Minute aufnehmen und anhören. Ton ist der Grund Nummer eins, warum Leute wieder gehen." }, + { schluessel: "licht-sitzt", titel: "Licht sitzt", text: "Gesicht heller als der Hintergrund. Kein Fenster im Rücken." }, + { schluessel: "verbindung-getestet", titel: "Verbindung getestet", text: "Upload-Geschwindigkeit geprüft, Kabel statt WLAN wenn möglich." }, + { schluessel: "titel-und-thema-stehen", titel: "Titel und Thema stehen", text: "Wer den Titel liest, weiß, was ihn erwartet – und ob es für ihn ist." }, + { schluessel: "ablauf-grob-im-kopf", titel: "Ablauf grob im Kopf", text: "Drei Blöcke reichen. Ein Stream ohne roten Faden fühlt sich für Zuschauer wie Warten an." }, + { schluessel: "angekuendigt", titel: "Angekündigt", text: "Mindestens einmal vorher gesagt, dass es losgeht – Story, Post oder Nachricht." }, + { schluessel: "moderation-geklaert", titel: "Moderation geklärt", text: "Weiß jemand Bescheid, der eingreifen kann, wenn es im Chat kippt?" }, + { schluessel: "technik-ersatz-bereit", titel: "Technik-Ersatz bereit", text: "Was passiert, wenn der Stream abbricht? Handy als Notlösung bereitlegen." }, ], mitschrift: [ - { schluessel: "guter-moment-aufheben", titel: "Guter Moment – aufheben", text: "Etwas ist gut gelaufen. Kurz notieren, woran es lag – daraus wird später ein Clip.", hilfe: false }, - { schluessel: "hier-sind-leute-gegangen", titel: "Hier sind Leute gegangen", text: "Zeitpunkt merken. Später nachsehen, was in dem Moment passiert ist.", hilfe: false }, - { schluessel: "frage-aus-dem-chat-die-wiederkommt", titel: "Frage aus dem Chat, die wiederkommt", text: "Wird oft gefragt? Dann gehört sie in ein eigenes Video.", hilfe: false }, - { schluessel: "technik-hat-gehakt", titel: "Technik hat gehakt", text: "Ton weg, Bild eingefroren, Verzögerung – aufschreiben, solange man es noch weiß.", hilfe: true }, - { schluessel: "unangenehme-situation-im-chat", titel: "Unangenehme Situation im Chat", text: "Was war es, wie ist es ausgegangen? Auch wenn es gut lief.", hilfe: true }, - { schluessel: "neue-zuschauer-aufgetaucht", titel: "Neue Zuschauer aufgetaucht", text: "Woher kamen sie? Wurde jemand begrüßt oder ging es unter?", hilfe: false }, - { schluessel: "ich-wusste-nicht-weiter", titel: "Ich wusste nicht weiter", text: "Stelle merken, an der es gestockt hat. Dafür gibt es Hilfe.", hilfe: true }, + { schluessel: "guter-moment-aufheben", titel: "Guter Moment – aufheben", text: "Etwas ist gut gelaufen. Kurz notieren, woran es lag – daraus wird später ein Clip." }, + { schluessel: "hier-sind-leute-gegangen", titel: "Hier sind Leute gegangen", text: "Zeitpunkt merken. Später nachsehen, was in dem Moment passiert ist." }, + { schluessel: "frage-aus-dem-chat-die-wiederkommt", titel: "Frage aus dem Chat, die wiederkommt", text: "Wird oft gefragt? Dann gehört sie in ein eigenes Video." }, + { schluessel: "technik-hat-gehakt", titel: "Technik hat gehakt", text: "Ton weg, Bild eingefroren, Verzögerung – aufschreiben, solange man es noch weiß." }, + { schluessel: "unangenehme-situation-im-chat", titel: "Unangenehme Situation im Chat", text: "Was war es, wie ist es ausgegangen? Auch wenn es gut lief." }, + { schluessel: "neue-zuschauer-aufgetaucht", titel: "Neue Zuschauer aufgetaucht", text: "Woher kamen sie? Wurde jemand begrüßt oder ging es unter?" }, + { schluessel: "ich-wusste-nicht-weiter", titel: "Ich wusste nicht weiter", text: "Stelle merken, an der es gestockt hat. Dafür gibt es Hilfe." }, ], auswertung: [ - { schluessel: "was-hat-diesmal-getragen", titel: "Was hat diesmal getragen?", text: "Ein Ding. Nicht drei. Das eine, das man wiederholen will.", hilfe: false }, - { schluessel: "was-war-zaeh", titel: "Was war zäh?", text: "Ehrlich sein. Die zähen Stellen sind die, an denen man wächst.", hilfe: false }, - { schluessel: "zahlen-im-vergleich", titel: "Zahlen im Vergleich", text: "Zuschauer, Verweildauer, Kommentare – gegen das letzte Mal, nicht gegen andere.", hilfe: true }, - { schluessel: "clips-gesichert", titel: "Clips gesichert", text: "Die guten Momente rausgeschnitten und abgelegt, solange man sie noch findet.", hilfe: false }, - { schluessel: "eine-sache-fuer-naechstes-mal", titel: "Eine Sache für nächstes Mal", text: "Genau eine. Wer sich fünf Dinge vornimmt, macht keins davon.", hilfe: false }, - { schluessel: "braucht-besprechung", titel: "Braucht Besprechung", text: "Etwas, das man nicht allein lösen kann – geht an die Betreuung.", hilfe: true }, + { schluessel: "was-hat-diesmal-getragen", titel: "Was hat diesmal getragen?", text: "Ein Ding. Nicht drei. Das eine, das man wiederholen will." }, + { schluessel: "was-war-zaeh", titel: "Was war zäh?", text: "Ehrlich sein. Die zähen Stellen sind die, an denen man wächst." }, + { schluessel: "zahlen-im-vergleich", titel: "Zahlen im Vergleich", text: "Zuschauer, Verweildauer, Kommentare – gegen das letzte Mal, nicht gegen andere." }, + { schluessel: "clips-gesichert", titel: "Clips gesichert", text: "Die guten Momente rausgeschnitten und abgelegt, solange man sie noch findet." }, + { schluessel: "eine-sache-fuer-naechstes-mal", titel: "Eine Sache für nächstes Mal", text: "Genau eine. Wer sich fünf Dinge vornimmt, macht keins davon." }, + { schluessel: "braucht-besprechung", titel: "Braucht Besprechung", text: "Etwas, das man nicht allein lösen kann – geht an die Betreuung." }, ], }; @@ -186,24 +183,24 @@ export const LIVE_PUNKTE = { export const COMMUNITY_PUNKTE = { moderation: [ - { schluessel: "regeln-stehen-sichtbar", titel: "Regeln stehen sichtbar", text: "Kurz, verstaendlich, an einer Stelle, die man findet. Drei Saetze reichen.", hilfe: false }, - { schluessel: "jemand-kann-eingreifen", 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 }, - { schluessel: "wortfilter-eingerichtet", titel: "Wortfilter eingerichtet", text: "Die offensichtlichen Sachen automatisch weg, damit man sich um den Rest kuemmern kann.", hilfe: true }, - { schluessel: "was-passiert-bei-einem-verstoss", titel: "Was passiert bei einem Verstoss?", text: "Verwarnen, stummschalten, sperren -- vorher entscheiden, nicht im Moment.", hilfe: false }, - { schluessel: "umgang-mit-minderjaehrigen", titel: "Umgang mit Minderjaehrigen", text: "Wie erkennt man sie, und was gilt dann? Das ist keine Ermessensfrage.", hilfe: true }, + { schluessel: "regeln-stehen-sichtbar", titel: "Regeln stehen sichtbar", text: "Kurz, verstaendlich, an einer Stelle, die man findet. Drei Saetze reichen." }, + { schluessel: "jemand-kann-eingreifen", titel: "Jemand kann eingreifen", text: "Waehrend des Streams ist eine zweite Person mit Rechten da -- oder es ist klar, dass keine da ist." }, + { schluessel: "wortfilter-eingerichtet", titel: "Wortfilter eingerichtet", text: "Die offensichtlichen Sachen automatisch weg, damit man sich um den Rest kuemmern kann." }, + { schluessel: "was-passiert-bei-einem-verstoss", titel: "Was passiert bei einem Verstoss?", text: "Verwarnen, stummschalten, sperren -- vorher entscheiden, nicht im Moment." }, + { schluessel: "umgang-mit-minderjaehrigen", titel: "Umgang mit Minderjaehrigen", text: "Wie erkennt man sie, und was gilt dann? Das ist keine Ermessensfrage." }, ], aktion: [ - { schluessel: "neue-begruessen", titel: "Neue begruessen", text: "Wer zum ersten Mal da ist, wird angesprochen. Kostet zwei Sekunden und entscheidet, ob jemand bleibt.", hilfe: false }, - { schluessel: "stammleute-erkennen", titel: "Stammleute erkennen", text: "Namen merken oder notieren. Wiedererkannt zu werden ist der halbe Grund wiederzukommen.", hilfe: false }, - { schluessel: "etwas-geben-das-nur-hier-gibt", titel: "Etwas geben, das nur hier gibt", text: "Ein Insider, ein Ritual, ein Spitzname. Community entsteht aus Gemeinsamem.", hilfe: false }, - { schluessel: "ausserhalb-des-streams-antworten", titel: "Ausserhalb des Streams antworten", text: "Kommentare und Nachrichten -- die Community lebt auch zwischen den Sendungen.", hilfe: false }, + { schluessel: "neue-begruessen", titel: "Neue begruessen", text: "Wer zum ersten Mal da ist, wird angesprochen. Kostet zwei Sekunden und entscheidet, ob jemand bleibt." }, + { schluessel: "stammleute-erkennen", titel: "Stammleute erkennen", text: "Namen merken oder notieren. Wiedererkannt zu werden ist der halbe Grund wiederzukommen." }, + { schluessel: "etwas-geben-das-nur-hier-gibt", titel: "Etwas geben, das nur hier gibt", text: "Ein Insider, ein Ritual, ein Spitzname. Community entsteht aus Gemeinsamem." }, + { schluessel: "ausserhalb-des-streams-antworten", titel: "Ausserhalb des Streams antworten", text: "Kommentare und Nachrichten -- die Community lebt auch zwischen den Sendungen." }, ], konflikt: [ - { schluessel: "ruhig-bleiben-und-nicht-oeffentlich-stre", titel: "Ruhig bleiben und nicht oeffentlich streiten", text: "Im Chat gewinnt niemand. Kurz ansagen, dann privat klaeren.", hilfe: true }, - { schluessel: "was-ist-genau-passiert", titel: "Was ist genau passiert?", text: "Zeitpunkt, Beteiligte, Wortlaut. Ohne das ist jede Entscheidung angreifbar.", hilfe: false }, - { schluessel: "beweise-sichern", titel: "Beweise sichern", text: "Bildschirmfoto oder Ausschnitt, solange es noch da ist. Chats verschwinden.", hilfe: true }, - { schluessel: "betreuung-einbeziehen", titel: "Betreuung einbeziehen", text: "Bei allem, was groesser ist als ein blöder Kommentar. Dafuer ist sie da.", hilfe: true }, - { schluessel: "danach-was-hat-gefehlt", titel: "Danach: was hat gefehlt?", text: "Regel unklar, niemand zum Eingreifen da, zu spaet gemerkt -- daraus wird der naechste Punkt oben.", hilfe: false }, + { schluessel: "ruhig-bleiben-und-nicht-oeffentlich-stre", titel: "Ruhig bleiben und nicht oeffentlich streiten", text: "Im Chat gewinnt niemand. Kurz ansagen, dann privat klaeren." }, + { schluessel: "was-ist-genau-passiert", titel: "Was ist genau passiert?", text: "Zeitpunkt, Beteiligte, Wortlaut. Ohne das ist jede Entscheidung angreifbar." }, + { schluessel: "beweise-sichern", titel: "Beweise sichern", text: "Bildschirmfoto oder Ausschnitt, solange es noch da ist. Chats verschwinden." }, + { schluessel: "betreuung-einbeziehen", titel: "Betreuung einbeziehen", text: "Bei allem, was groesser ist als ein blöder Kommentar. Dafuer ist sie da." }, + { schluessel: "danach-was-hat-gefehlt", titel: "Danach: was hat gefehlt?", text: "Regel unklar, niemand zum Eingreifen da, zu spaet gemerkt -- daraus wird der naechste Punkt oben." }, ], }; @@ -218,22 +215,22 @@ export const COMMUNITY_PUNKTE = { export const TECHNIK_PUNKTE = { setup: [ - { schluessel: "mikrofon-richtig-eingestellt", titel: "Mikrofon richtig eingestellt", text: "Nicht uebersteuert, nicht zu leise, kein Rauschen. Einmal aufnehmen und anhoeren.", hilfe: true }, - { schluessel: "kamera-scharf-und-gut-belichtet", titel: "Kamera scharf und gut belichtet", text: "Gesicht heller als der Hintergrund. Automatik oft abschalten -- sie pumpt.", hilfe: true }, - { schluessel: "szenen-im-streaming-programm-angelegt", titel: "Szenen im Streaming-Programm angelegt", text: "Start, Vollbild, Pause, Ende. Wer waehrend der Sendung baut, sendet Chaos.", hilfe: true }, - { schluessel: "bitrate-zur-leitung-passend", titel: "Bitrate zur Leitung passend", text: "Lieber stabil und etwas weicher als scharf mit Aussetzern.", hilfe: true }, - { schluessel: "alles-einmal-komplett-getestet", titel: "Alles einmal komplett getestet", text: "Eine Probesendung von fuenf Minuten, aufgezeichnet und angesehen.", hilfe: true }, + { schluessel: "mikrofon-richtig-eingestellt", titel: "Mikrofon richtig eingestellt", text: "Nicht uebersteuert, nicht zu leise, kein Rauschen. Einmal aufnehmen und anhoeren." }, + { schluessel: "kamera-scharf-und-gut-belichtet", titel: "Kamera scharf und gut belichtet", text: "Gesicht heller als der Hintergrund. Automatik oft abschalten -- sie pumpt." }, + { schluessel: "szenen-im-streaming-programm-angelegt", titel: "Szenen im Streaming-Programm angelegt", text: "Start, Vollbild, Pause, Ende. Wer waehrend der Sendung baut, sendet Chaos." }, + { schluessel: "bitrate-zur-leitung-passend", titel: "Bitrate zur Leitung passend", text: "Lieber stabil und etwas weicher als scharf mit Aussetzern." }, + { schluessel: "alles-einmal-komplett-getestet", titel: "Alles einmal komplett getestet", text: "Eine Probesendung von fuenf Minuten, aufgezeichnet und angesehen." }, ], problem: [ - { schluessel: "ton-weg-oder-verzerrt", titel: "Ton weg oder verzerrt", text: "Wann genau, welches Geraet, was lief gleichzeitig? Ohne das findet es niemand.", hilfe: true }, - { schluessel: "bild-ruckelt-oder-friert-ein", titel: "Bild ruckelt oder friert ein", text: "Auslastung, Leitung, Aufloesung -- eins nach dem anderen ausschliessen.", hilfe: true }, - { schluessel: "stream-bricht-ab", titel: "Stream bricht ab", text: "Zeitpunkt notieren und im Protokoll des Programms nachsehen.", hilfe: true }, - { schluessel: "ton-und-bild-laufen-auseinander", titel: "Ton und Bild laufen auseinander", text: "Meist ein Puffer. Wann faellt es auf, sofort oder erst spaeter?", hilfe: true }, + { schluessel: "ton-weg-oder-verzerrt", titel: "Ton weg oder verzerrt", text: "Wann genau, welches Geraet, was lief gleichzeitig? Ohne das findet es niemand." }, + { schluessel: "bild-ruckelt-oder-friert-ein", titel: "Bild ruckelt oder friert ein", text: "Auslastung, Leitung, Aufloesung -- eins nach dem anderen ausschliessen." }, + { schluessel: "stream-bricht-ab", titel: "Stream bricht ab", text: "Zeitpunkt notieren und im Protokoll des Programms nachsehen." }, + { schluessel: "ton-und-bild-laufen-auseinander", titel: "Ton und Bild laufen auseinander", text: "Meist ein Puffer. Wann faellt es auf, sofort oder erst spaeter?" }, ], loesung: [ - { schluessel: "was-hat-es-behoben", titel: "Was hat es behoben?", text: "Genau die eine Aenderung aufschreiben, nicht alles was probiert wurde.", hilfe: false }, - { schluessel: "kommt-es-wieder", titel: "Kommt es wieder?", text: "Beim naechsten Mal nachsehen. Einmal weg ist nicht geloest.", hilfe: false }, - { schluessel: "einstellung-gesichert", titel: "Einstellung gesichert", text: "Damit sie nach einem Update nicht wieder weg ist.", hilfe: false }, + { schluessel: "was-hat-es-behoben", titel: "Was hat es behoben?", text: "Genau die eine Aenderung aufschreiben, nicht alles was probiert wurde." }, + { schluessel: "kommt-es-wieder", titel: "Kommt es wieder?", text: "Beim naechsten Mal nachsehen. Einmal weg ist nicht geloest." }, + { schluessel: "einstellung-gesichert", titel: "Einstellung gesichert", text: "Damit sie nach einem Update nicht wieder weg ist." }, ], }; export const CALL_LEITFAEDEN = [ @@ -369,61 +366,11 @@ vorlagenRouter.post("/workspace/api/vorlagen/uebernehmen", gleicheHerkunft, } }); -/* ---------- "Ich brauche Hilfe" ------------------------------------------ +/* Die frühere Route /vorlagen/hilfe ist am 01.09.2026 entfallen. + Sie machte aus einer Bitte eine Aufgabe. Das war gut gemeint, aber + es gab damit zwei Wege, dasselbe zu sagen -- und Antworten landeten + mal als Aufgabe, mal als Nachricht. Geblieben ist die Rückmeldung an + jedem Punkt (workspace-checkliste.js). - Ein Creator klickt an einem LIVE-Punkt auf "Hilfe". Daraus wird eine - Aufgabe für seinen Betreuer -- nicht eine Nachricht, die untergeht, - sondern ein Eintrag im Aufgabenbrett mit Frist. - - Warum eine Aufgabe und keine Benachrichtigung: Eine Benachrichtigung - ist gelesen und dann weg. Eine Aufgabe bleibt stehen, bis sie jemand - erledigt -- und taucht auf der Startseite des Betreuers auf, wenn sie - überfällig wird. */ - -vorlagenRouter.post("/workspace/api/vorlagen/hilfe", gleicheHerkunft, - express.json({ limit: "8kb" }), (req, res) => { - try { - const thema = String(req.body.thema || "").trim().slice(0, 160); - if (thema.length < 3) return res.status(400).json({ fehler: "Worum geht es?" }); - const notiz = String(req.body.notiz || "").trim().slice(0, 2000); - - const creatorId = req.person.rolle === "creator" ? req.person.id - : Number(req.body.creator_id) || null; - if (!creatorId) return res.status(400).json({ fehler: "Kein Creator angegeben." }); - if (req.person.rolle !== "creator" && !darfCreator(req.person, creatorId)) { - return res.status(404).json({ fehler: "nicht_gefunden" }); - } - - /* An wen? An den Betreuer. Gibt es keinen, an die Leitung -- eine - Bitte um Hilfe darf nicht ins Leere laufen, nur weil die - Zuordnung fehlt. */ - const betreuer = db().prepare( - "SELECT betreuer_id FROM betreuung WHERE creator_id = ? LIMIT 1").get(creatorId); - const ziel = betreuer?.betreuer_id - || db().prepare( - "SELECT id FROM personen WHERE rolle = 'admin' AND aktiv = 1 ORDER BY id LIMIT 1") - .get()?.id - || null; - - const name = db().prepare("SELECT name FROM personen WHERE id = ?").get(creatorId)?.name - || "Creator"; - - /* Frist: in drei Tagen. Eine Bitte um Hilfe ohne Frist ist eine - Bitte, die liegen bleibt. */ - const frist = new Date(Date.now() + 3 * 86400_000).toISOString().slice(0, 10); - - db().prepare(`INSERT INTO aufgaben - (titel, beschreibung, status, prioritaet, creator_id, verantwortlich_id, - frist, erstellt, erstellt_von) - VALUES (?,?,'offen','hoch',?,?,?,?,?)`) - .run(`Hilfe gewünscht: ${thema}`, - `${name} hat um Unterstützung gebeten.\n\n${notiz || "(keine weitere Angabe)"}`, - creatorId, ziel, frist, jetzt(), req.person.id); - - protokolliere("hilfe_angefragt", req.person, echteIp(req), thema); - res.json({ ok: true, an: ziel }); - } catch (fehler) { - console.error("[workspace] Hilfe anfragen:", fehler?.message); - res.status(503).json({ fehler: "nicht_verfuegbar" }); - } - }); + Entfernt statt auskommentiert: Eine Route, die niemand mehr aufruft, + wird beim nächsten Mal für lebenden Code gehalten und mitgepflegt. */ diff --git a/workspace/assets/css/content.css b/workspace/assets/css/content.css index bcbbfd7b..3a5db452 100644 --- a/workspace/assets/css/content.css +++ b/workspace/assets/css/content.css @@ -396,7 +396,6 @@ body.start { border-color: color-mix(in srgb, var(--ton, var(--akzent)) 32%, transparent); color: var(--ton, var(--akzent)); } -.vorlage__marke--hilfe { border-color: rgba(216, 161, 58, .34); color: #d8a13a; } .vorlage__fuss .schritt { margin-left: auto; } .vorlagen__alle { @@ -405,16 +404,6 @@ body.start { padding-top: 4px; } -/* Der Hilfe-Knopf ist bewusst auffaelliger als die uebrigen: Wer ihn - braucht, soll ihn finden, ohne zu suchen. */ -.schritt--hilfe { - border-color: rgba(216, 161, 58, .4); - color: #e0b45c; -} -.schritt--hilfe[data-fertig="ja"] { - border-color: rgba(80, 167, 130, .45); - color: #6fbd95; -} @media (max-width: 560px) { .vorlagen__kopf { flex-direction: column; align-items: stretch; } diff --git a/workspace/assets/js/checkliste.js b/workspace/assets/js/checkliste.js index 95b67afa..e7c9f2e9 100644 --- a/workspace/assets/js/checkliste.js +++ b/workspace/assets/js/checkliste.js @@ -219,11 +219,6 @@ reden.addEventListener('click', () => gespraech(k, bereich, p, daten, reden)); fuss.append(reden); - /* Bei Punkten, wo Hilfe angeboten wird, kann der Creator sie hier - anfordern -- daraus wird eine Aufgabe bei seinem Betreuer. */ - if (p.hilfe && !daten.darf_bewerten && window.hilfeKnopf) { - fuss.append(window.hilfeKnopf(p.titel, daten.creator_id)); - } k.append(fuss); return k; diff --git a/workspace/assets/js/vorlagen.js b/workspace/assets/js/vorlagen.js index 5d50a08d..2335b704 100644 --- a/workspace/assets/js/vorlagen.js +++ b/workspace/assets/js/vorlagen.js @@ -108,8 +108,6 @@ const fuss = el('div', 'vorlage__fuss'); if (v.format) fuss.append(el('span', 'vorlage__marke', v.format)); if (v.saeule) fuss.append(el('span', 'vorlage__marke vorlage__marke--saeule', v.saeule)); - /* Punkte, bei denen man Hilfe anfordern kann, sagen das auch. */ - if (v.hilfe) fuss.append(el('span', 'vorlage__marke vorlage__marke--hilfe', 'Hilfe möglich')); const nehmen = el('button', 'schritt', 'Übernehmen'); nehmen.type = 'button'; @@ -182,33 +180,10 @@ behaelter.hidden = false; }; - /* ---------- "Ich brauche Hilfe" --------------------------------------- - - Ein Knopf, der aus einer Bitte eine AUFGABE macht -- keine - Nachricht. Eine Nachricht ist gelesen und dann weg; eine Aufgabe - bleibt stehen, bis sie jemand erledigt, und taucht beim Betreuer auf - der Startseite auf, wenn sie überfällig wird. */ - - window.hilfeKnopf = function (thema, creatorId) { - const b = el('button', 'schritt schritt--hilfe', 'Hilfe anfordern'); - b.type = 'button'; - b.addEventListener('click', async () => { - const notiz = prompt(`Hilfe zu „${thema}“.\n\n` - + 'Was genau brauchst du? (Ein Satz reicht – kann auch leer bleiben.)'); - if (notiz === null) return; /* abgebrochen */ - b.disabled = true; - b.textContent = 'wird gemeldet …'; - try { - const a = await hole('/workspace/api/vorlagen/hilfe', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ thema, notiz, creator_id: creatorId }), - }); - if (!a.ok) { b.textContent = 'ging nicht'; b.disabled = false; return; } - b.textContent = 'Hilfe angefordert'; - b.dataset.fertig = 'ja'; - } catch { b.disabled = false; b.textContent = 'Hilfe anfordern'; } - }); - return b; - }; + /* Der frühere Knopf "Hilfe anfordern" ist am 01.09.2026 entfallen. + Es gab damit zwei Wege, dasselbe zu sagen -- einen Knopf, der eine + Aufgabe erzeugte, und ein Textfeld für eine Nachricht. Zwei Wege + für eine Sache heißt, dass niemand weiß, welcher der richtige ist, + und dass Antworten mal hier und mal dort landen. Geblieben ist die + Rückmeldung an jedem Punkt. */ })(); diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index fbd0f9af..f8499f4d 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -7,9 +7,9 @@ - - - + + + @@ -139,9 +139,9 @@ - - - - + + + + diff --git a/workspace/automation.html b/workspace/automation.html index 23092e49..691daf49 100644 --- a/workspace/automation.html +++ b/workspace/automation.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -132,9 +132,9 @@ - - - - + + + + diff --git a/workspace/bereich.html b/workspace/bereich.html index a4a2d6bd..f0a03bf6 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -115,13 +115,13 @@ - - - - - - - - + + + + + + + + diff --git a/workspace/calls.html b/workspace/calls.html index 6d6ea4f9..5466a31e 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -54,10 +54,10 @@ - - - - - + + + + + diff --git a/workspace/content.html b/workspace/content.html index 98c8dfef..403cc38a 100644 --- a/workspace/content.html +++ b/workspace/content.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -162,11 +162,11 @@ - - - - - - + + + + + + diff --git a/workspace/dateien.html b/workspace/dateien.html index c2e945b9..9ca44902 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -93,9 +93,9 @@ - - - - + + + + diff --git a/workspace/index.html b/workspace/index.html index 05636c4e..ee62e19a 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -25,7 +25,7 @@ type="image/webp" media="(max-width: 899px)" /> - + @@ -143,6 +143,6 @@

- + diff --git a/workspace/kalender.html b/workspace/kalender.html index 3a593261..5dc5e3e7 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -147,9 +147,9 @@ - - - - + + + + diff --git a/workspace/personen.html b/workspace/personen.html index 3e67efe2..6703e1db 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -121,9 +121,9 @@ - - - - + + + + diff --git a/workspace/profil.html b/workspace/profil.html index be11e1dd..0264393e 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -175,10 +175,10 @@ - - - - - + + + + + diff --git a/workspace/report.html b/workspace/report.html index a2d982e0..765c856b 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -91,10 +91,10 @@ - - - - - + + + + + diff --git a/workspace/scouting.html b/workspace/scouting.html index 4c4e72ac..60f5254a 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -124,9 +124,9 @@ - - - - + + + + diff --git a/workspace/start.html b/workspace/start.html index 76875001..c6183bb9 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -7,8 +7,8 @@ - - + + @@ -99,9 +99,9 @@

- - - - + + + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index 31d7882b..bcb1b9dc 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -70,10 +70,10 @@ - - - - - + + + + + diff --git a/workspace/steckbrief.html b/workspace/steckbrief.html index b2d5f44a..1f78b588 100644 --- a/workspace/steckbrief.html +++ b/workspace/steckbrief.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -85,9 +85,9 @@ - - - - + + + + diff --git a/workspace/uebersicht.html b/workspace/uebersicht.html index ec855fe9..0df12dbd 100644 --- a/workspace/uebersicht.html +++ b/workspace/uebersicht.html @@ -7,9 +7,9 @@ - - - + + + @@ -57,9 +57,9 @@ - + - - + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 140314c8..9d2bb437 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -175,9 +175,9 @@ - - - - + + + +