Eine Bewerbung, die niemand sieht, ist keine
Beim Weiterarbeiten am Vorlagenbrett nachgemessen und gefunden:
`benachrichtige` kam in workspace-zuteilung.js KEIN EINZIGES MAL vor,
in workspace-vorlagen.js auch nicht.
Beide Bewerbungswege waren gebaut, beide funktionierten -- und beide
waren stumm:
* Bewirbt sich Frida, erfaehrt DogFather es nur, wenn er von sich
aus das Brett aufmacht.
* Antwortet er, erfaehrt Frida es nur, wenn SIE von sich aus
nachsieht.
Das ist keine Kleinigkeit, das ist die Funktion. Wer sich bewirbt,
wartet -- und Warten ohne Rueckmeldung fuehlt sich nach zwei Tagen an
wie "interessiert keinen". Genau das soll eine Bewerbung verhindern.
WER ES ERFAEHRT -- ABGELEITET, NICHT AUFGEZAEHLT
------------------------------------------------
Die naheliegende Zeile waere `rolle IN ('admin','hand')` gewesen; so
steht sie in workspace-hilfe.js. Das ist eine Abschrift, und
Abschriften altern: Kaeme morgen eine Rolle dazu, die entscheiden
darf, bekaeme sie keine einzige Meldung -- und niemand merkte es, weil
ja alles funktioniert.
Gefragt wird deshalb die Regel selbst (entscheidetUeberAufgaben),
Person fuer Person. Und zusaetzlich darfSchreibenMit: Wer den Bewerber
gar nicht sehen darf, bekommt auch keine Meldung ueber ihn. Das ist
keine Vorsicht um ihrer selbst willen -- ohne diese Zeile erfuehre die
Agentur ueber eine Push-Nachricht, dass es Team Dogi ueberhaupt gibt.
Gemessen: Die Bewerbung eines Modis erreicht genau zwei Leute
(admin, hand) von sechs Aktiven. Nicht die linke Hand (sie entscheidet
hier nicht mit), niemand aus dem anderen Haus, und nicht der Bewerber
selbst.
ZWEI SCHALTER, ZWEI ENTSCHEIDUNGEN
----------------------------------
"bewerbung_neu" trifft den, der antwortet -- an einem lebhaften Tag
mehrfach, das kann man stumm stellen wollen. "bewerbung_antwort"
trifft den, der wartet; sie kommt einmal, und niemand will sie stumm
stellen. Eine gemeinsame Art hiesse: beides zusammen abschalten oder
beides zusammen ertragen. Dieselbe Ueberlegung wie beim Chat
(Nachricht / Erwaehnung).
Beide von sich aus an. Keine Ausnahme von der Ruhezeit: Eine Bewerbung
wartet, ein Anruf nicht.
DIE NOTIZ STEHT IN DER MELDUNG
------------------------------
Filipe hat sie ausdruecklich verlangt ("mit einem text als notiz").
Sie erst zu verlangen und dann an genau der Stelle zu verschweigen, an
der man sie liest, waere die halbe Funktion. Und das Ergebnis steht im
TITEL -- "angenommen" oder "diesmal nicht" -- damit man es lesen kann,
ohne zu oeffnen. Auch die gute Nachricht.
Der Wortlaut steht in zwei reinen Funktionen (bewerbungText,
antwortText), exportiert, damit eine Pruefung sie lesen kann, ohne
einen Push-Dienst nachzubauen. Genau an so einer Stelle steckte am
18.09. der Fehler "Nachricht von [object Object]", der von aussen
nicht messbar war.
EINE STELLE FUER BEIDE WEGE
---------------------------
workspace-bewerbung-melden.js. Zwei Fassungen waeren zwei
Gelegenheiten, dass eine davon die Ruhezeit, die Abschaltbarkeit oder
die Haeusertrennung vergisst -- und dieselbe Person laese zweimal
etwas Verschiedenes ueber denselben Vorgang.
Die Meldung wird NICHT abgewartet (`void`): Ob sie durchgeht, haengt
am Push-Dienst, an der Ruhezeit und an den Einstellungen des
Empfaengers. Nichts davon darf entscheiden, ob die Bewerbung
gespeichert ist -- die ist es laengst.
NOCH EINE ROTE PRUEFUNG, DIE NIEMAND GESEHEN HAT
-------------------------------------------------
pruef-push-ziel meldete: "aber nicht auf eine Seite, die es fuer ihn
nicht gibt (/workspace/calls.html)". Das sah aus wie ein Befund und
war eine erfuellte Bestellung -- Filipe hatte am 22.09. genau das
Gegenteil bestellt ("jeder der einen kalender hat soll auch sowas
haben"). Nachgemessen: Modi, rechte und linke Hand haben je eine
Calls-Kachel.
Die Pruefung steht jetzt andersherum: Die Calls-Seite MUSS stehen
bleiben. Dieselbe Zeile schuetzt damit das, was sie vorher verboten
hat -- und wird rot, wenn die Kachel je wieder verschwindet. Das
Umlenken selbst bleibt geprueft (Scouting, zweimal).
Das ist die DRITTE stille rote Pruefung an einem Tag (nach
pruef-modi-wortleck und pruef-zuteilung). Die Frage an Filipe, ob ein
naechtlicher Lauf sie selbst anstossen soll, steht in der Vault-Notiz
und wird nicht von mir allein entschieden.
GEPRUEFT
--------
pruef-modi-katalog: 116 Pruefungen, 0 Fehler (vorher 95).
Neu: die beiden Schalter, wer es erfaehrt (samt Gegenprobe, dass es
nicht einfach alle sind: 2 von 6), und der Wortlaut an acht Proben.
Dabei war meine eigene erste Messung falsch -- sie erwartete eine
Kuerzung bei 50 Zeichen, die nur gilt, wenn eine Notiz danebensteht.
Steht als Begruendung in der Pruefung.
pruef-push-ziel: 11 von 11 (vorher 1 Fehler).
pruef-zuteilung, pruef-push, pruef-push-weg: gruen.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -860,6 +860,129 @@ console.log("");
|
||||
} finally { await browser.close(); }
|
||||
}
|
||||
|
||||
/* =======================================================================
|
||||
6c. EINE BEWERBUNG, DIE NIEMAND SIEHT, IST KEINE (23.09.2026)
|
||||
=======================================================================
|
||||
|
||||
Beide Bewerbungswege waren gebaut und beide funktionierten -- und
|
||||
beide waren STUMM. Nachgemessen vor dem Bauen: `benachrichtige` kam
|
||||
weder in workspace-zuteilung.js noch in workspace-vorlagen.js ein
|
||||
einziges Mal vor.
|
||||
|
||||
Wer sich bewirbt, wartet. Warten ohne Rueckmeldung fuehlt sich nach
|
||||
zwei Tagen an wie "interessiert keinen" -- und genau das soll eine
|
||||
Bewerbung verhindern.
|
||||
|
||||
GEPRUEFT WIRD, WAS SICH OHNE PUSH-DIENST PRUEFEN LAESST, und das ist
|
||||
fast alles: WER etwas erfaehrt (abgeleitet, nicht aufgezaehlt), WAS
|
||||
darin steht (reine Funktionen), und DASS es zwei getrennte Schalter
|
||||
gibt.
|
||||
======================================================================= */
|
||||
console.log("\n=== 6c. Erfaehrt es auch jemand? ===\n");
|
||||
{
|
||||
const melder = await import("./workspace-bewerbung-melden.js");
|
||||
const { ARTEN } = await import("./workspace-push.js");
|
||||
|
||||
/* ---- DIE SCHALTER --------------------------------------------- */
|
||||
const neu2 = ARTEN.find((a) => a.schluessel === "bewerbung_neu");
|
||||
const antwort = ARTEN.find((a) => a.schluessel === "bewerbung_antwort");
|
||||
ok(!!neu2 && !!antwort,
|
||||
"beide Arten stehen in den Benachrichtigungs-Einstellungen");
|
||||
ok(neu2?.vorgabe === true && antwort?.vorgabe === true,
|
||||
"und sind von sich aus an");
|
||||
/* ZWEI SCHALTER, ZWEI ENTSCHEIDUNGEN. Wer an einem lebhaften Tag
|
||||
viele Bitten bekommt, will die stumm stellen koennen -- die
|
||||
Antwort auf die EIGENE Bewerbung will niemand stumm stellen. Eine
|
||||
gemeinsame Art hiesse: beides zusammen abschalten oder beides
|
||||
zusammen ertragen. */
|
||||
ok(neu2?.schluessel !== antwort?.schluessel,
|
||||
"getrennt voneinander — die eine trifft den, der antwortet, die andere den, der wartet");
|
||||
|
||||
/* ---- WER ES ERFAEHRT ------------------------------------------- */
|
||||
const wer = melder.entscheiderFuer({ id: idModi, name: "Marina" });
|
||||
const rollen = wer.map((x) => x.rolle).sort();
|
||||
ok(wer.length > 0, `die Bewerbung eines Modis erreicht ${wer.length} Leute`);
|
||||
ok(rollen.includes("admin") && rollen.includes("hand"),
|
||||
`DogFather und die rechte Hand sind dabei (${rollen.join(", ")})`);
|
||||
/* DIE LINKE HAND NICHT -- sie darf verteilen, aber nicht ueber
|
||||
Bewerbungen entscheiden. Eine Meldung ueber etwas, das man nicht
|
||||
beantworten kann, ist Laerm. */
|
||||
ok(!rollen.includes("linke"),
|
||||
"die linke Hand nicht — sie entscheidet hier nicht mit");
|
||||
/* UND DIE AGENTUR ERST RECHT NICHT. Ohne die Haeuser-Bedingung
|
||||
erfuehre ein Manager ueber eine Push-Nachricht, dass es Team Dogi
|
||||
ueberhaupt gibt. */
|
||||
ok(!rollen.includes("manager") && !rollen.includes("creator"),
|
||||
`niemand aus dem anderen Haus (${rollen.join(", ") || "niemand"})`);
|
||||
/* Und der Bewerber nicht sich selbst. */
|
||||
ok(!wer.some((x) => x.id === idModi), "und der Bewerber nicht sich selbst");
|
||||
|
||||
/* GEGENPROBE: Die Liste darf nicht einfach "alle Aktiven" sein --
|
||||
sonst waere jede Zeile oben zufaellig richtig. */
|
||||
const alleAktiven = (await import("node:sqlite")).DatabaseSync;
|
||||
const d3 = new alleAktiven(process.env.WORKSPACE_DB, { readOnly: true });
|
||||
const anzahl = d3.prepare("SELECT COUNT(*) AS n FROM personen WHERE aktiv = 1").get().n;
|
||||
d3.close();
|
||||
ok(wer.length < anzahl,
|
||||
`Gegenprobe: es sind nicht einfach alle (${wer.length} von ${anzahl} Aktiven)`);
|
||||
|
||||
/* ---- WAS DRINSTEHT --------------------------------------------- */
|
||||
const b1 = melder.bewerbungText({
|
||||
name: "Marina", titel: "Die Regeln des Rudels einmal ganz lesen",
|
||||
wort: "ich habe Freitag Zeit" });
|
||||
ok(b1.titel === "Marina bewirbt sich", `der Titel nennt den Menschen (${b1.titel})`);
|
||||
ok(b1.text.includes("Regeln des Rudels"), "und die Zeile darunter die Aufgabe");
|
||||
/* DAS WORT IST OFT DIE GANZE AUSKUNFT. Wer es schon auf dem
|
||||
Sperrbildschirm liest, kann entscheiden, ohne zu oeffnen. */
|
||||
ok(b1.text.includes("ich habe Freitag Zeit"),
|
||||
`samt dem Wort des Bewerbers (${b1.text})`);
|
||||
|
||||
const b2 = melder.bewerbungText({ name: "Marina", titel: "Kurz", wort: "" });
|
||||
ok(!b2.text.includes("„"), `ohne Wort bleibt es sauber (${b2.text})`);
|
||||
ok(b2.text === "Kurz", "und nur die Aufgabe steht da");
|
||||
|
||||
/* NAMENLOS DARF NICHT "undefined bewirbt sich" ergeben. */
|
||||
const b3 = melder.bewerbungText({ name: "", titel: "X", wort: "" });
|
||||
ok(b3.titel === "Jemand bewirbt sich", `ohne Namen steht ein Wort da (${b3.titel})`);
|
||||
|
||||
const a1 = melder.antwortText({ titel: "Die Regeln", ja: true, notiz: "mach das gern" });
|
||||
const a2 = melder.antwortText({ titel: "Die Regeln", ja: false, notiz: "diesmal jemand anders" });
|
||||
/* DAS ERGEBNIS STEHT IM TITEL -- man soll es lesen koennen, ohne zu
|
||||
oeffnen. Auch die gute Nachricht. */
|
||||
ok(/angenommen/.test(a1.titel), `die Zusage sagt es im Titel (${a1.titel})`);
|
||||
ok(/nicht/.test(a2.titel) && a2.titel !== a1.titel,
|
||||
`die Absage auch, und anders (${a2.titel})`);
|
||||
/* DIE NOTIZ IST DER GRUND, WARUM FILIPE SIE VERLANGT HAT ("mit
|
||||
einem text als notiz"). Sie hier wegzulassen hiesse, sie an genau
|
||||
der Stelle zu verstecken, an der man sie liest. */
|
||||
ok(a1.text.includes("mach das gern") && a2.text.includes("diesmal jemand anders"),
|
||||
"und die Notiz steht in beiden");
|
||||
|
||||
/* LANGES WIRD GEKUERZT, ABER NICHT MITTEN IM WORT.
|
||||
|
||||
DIE ERSTE FASSUNG DIESER ZEILE WAR FALSCH und hat mich das
|
||||
Richtige gelehrt: Sie nahm einen 68 Zeichen langen Titel und
|
||||
erwartete eine Kuerzung bei 50 -- die gilt aber nur, wenn eine
|
||||
Notiz danebensteht und Platz wegnimmt. Ohne Notiz darf der Titel
|
||||
die ganzen 90 haben. Die Pruefung war rot, das Programm richtig.
|
||||
Gemessen wird jetzt mit etwas, das JEDE Grenze reisst. */
|
||||
const langerSatz = "Eine ganze Sendung neben einem Neuen sitzen und im Zweifel "
|
||||
+ "eingreifen und danach noch drei Zeilen aufschreiben, damit am naechsten "
|
||||
+ "Tag jemand weiss, was eigentlich los war";
|
||||
const lang = melder.antwortText({ titel: langerSatz, ja: true, notiz: "" });
|
||||
ok(lang.text.length < langerSatz.length && /…$/.test(lang.text),
|
||||
`zu Langes endet mit Auslassung (${lang.text})`);
|
||||
/* KEIN SCHNITT MITTEN IM WORT -- ein "eingrei…" liest sich wie ein
|
||||
Fehler, nicht wie eine Kuerzung. */
|
||||
ok(/\s…$/.test(lang.text) || /[a-zA-Zäöüß]{3,}\s?…$/.test(lang.text),
|
||||
`und nicht mitten im Wort (${lang.text.slice(-24)})`);
|
||||
/* GEGENPROBE: Kurzes bleibt unangetastet -- sonst bewiese die Zeile
|
||||
darueber nur, dass immer gekuerzt wird. */
|
||||
const kurzerSatz = melder.antwortText({ titel: "Kurzer Titel", ja: true, notiz: "" });
|
||||
ok(kurzerSatz.text === "Kurzer Titel",
|
||||
`Gegenprobe: Kurzes bleibt unangetastet (${kurzerSatz.text})`);
|
||||
}
|
||||
|
||||
/* ---------- 7. Gegenprobe -------------------------------------------- */
|
||||
console.log("\n=== 7. Gegenprobe: kann das hier ueberhaupt scheitern? ===\n");
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user