Die drei offenen Punkte aus Abschnitt 9 des Plans, plus Filipes zweite
Ansage: "auf dieser seite soll nichts stehen von agentur, diese seite
hier ist nur fuer mich meine modis und meine community."
1. PROBE -> ZUGANG (ein Knopf statt eines Satzes)
Auf der Stufe "Probe" stand bisher "Zugang in Personen & Zugaenge
anlegen, Rolle Modi" - und wer das vergass, hatte eine Karte auf "Im
Team" und keinen Menschen darin. Jetzt haengt das Anlegen am Schritt
selbst.
Ueber DENSELBEN Weg wie in "Personen & Zugaenge", nicht ueber einen
zweiten: POST /workspace/api/verwaltung/personen, mit ihrer
Rechtepruefung, ihrem Protokolleintrag und ihrem genau einmal
angezeigten Code. Der Talente-Server legt selbst keinen einzigen Zugang
an, und die Pruefung zaehlt nach, dass es bei einem Weg bleibt.
Der Code steht im gleichen Kasten wie dort - die Gestaltung ist aus
personen.css nach start.css umgezogen, weil talente.html sie sonst nicht
laedt. Ein Geheimnis sieht im ganzen Haus gleich aus. Er steht
ausserhalb der Liste, sonst waere er in dem Moment weg, in dem er
entsteht: wenn die Karte auf "Im Team" springt.
Die rechte Hand bekommt an dieser Stelle KEINEN Knopf, sondern einen
Satz. Ein Knopf, der ihr jedes Mal "darfst du nicht" antwortet, waere
schlechter als gar keiner - er verspricht etwas.
2. DIE EIGENE KARTE (Abschnitt "Deine Karte")
Wer beschrieben wird, darf es lesen - aber erst, wenn ALLE gesetzt
haben (sonst waere die erste Einschaetzung eine Vorgabe fuer die
zweite), und ohne Namen und ohne Anlasstext. Gemessen in beide
Richtungen: vorher nicht sichtbar, nachher sichtbar.
3. DER VORLAGENTEXT
Gebaut aus den angeklickten Merkmalen, in einem Feld zum Aendern, nicht
zum Abschicken. Ohne Merkmale steht auch keines drin.
4. "GILT FUER" SAGT DER SERVER
In bereich.js stand woertlich "Agentur" - richtig auf der
Agenturadresse, falsch auf jeder anderen. Jetzt liefert der Server
`gehoert` ("Der Treff" / "Team Dogi" / "Agentur"); gemessen mit einem
einzigen Menschen auf zwei Adressen.
PRUEFUNGEN: treff 58 -> 66, nachwuchs 69 -> 109, neue-seiten 70 -> 93.
Die Katalogseiten werden jetzt auch mit den Augen der rechten Hand
angesehen - ohne das waere "Deine Karte" nie auf einem Bildschirm
gewesen. Und pruef-neue-seiten wartet nicht mehr 900 ms, sondern bis
sich der Text nicht mehr aendert: Die Karte stand da und wurde
trotzdem als fehlend gemeldet, weil zu frueh gelesen wurde.
Co-Authored-By: Claude Opus 5 <[email protected]>
322 lines
16 KiB
JavaScript
322 lines
16 KiB
JavaScript
/* =====================================================================
|
||
Der Katalog „Talente" (11.09.2026)
|
||
|
||
Zuschauer, die ins Team passen könnten. Die andere Hälfte von
|
||
Filipes Auftrag: *„fertige Sachen, so dass DogFather und rechte Hand
|
||
es so einfach wie möglich haben."*
|
||
|
||
Herleitung im Vault (02 Projekte/Entwicklung & Nachwuchs – Plan.md,
|
||
Abschnitt 1.3 und 4). Hier steht bei jedem Eintrag, warum er drin
|
||
ist — und bei zweien, warum sie es NICHT sind.
|
||
|
||
---------------------------------------------------------------------
|
||
TALENTE IST EIN TRICHTER, KEINE LISTE
|
||
|
||
Eine Liste wächst und wird nie wieder angesehen. Ein Trichter hat
|
||
Stufen, und jede Stufe hat GENAU EINEN nächsten Schritt — nicht drei
|
||
Möglichkeiten, zwischen denen man sich entscheiden müsste. Wer eine
|
||
Karte öffnet, soll in zwei Sekunden wissen, was jetzt dran ist.
|
||
|
||
UND DIE STANDZEIT GEHOERT ZUR ANZEIGE. „Seit 41 Tagen beobachtet,
|
||
nie angesprochen" ist eine Auskunft über UNS, nicht über den
|
||
Kandidaten. Ohne sie verwandelt sich der Trichter in eine Liste
|
||
zurück.
|
||
|
||
---------------------------------------------------------------------
|
||
ZWEI DINGE STEHEN AUSDRUECKLICH NICHT IM KATALOG
|
||
|
||
„SCHREIBT VIEL IM CHAT." Angenehm im Chat zu sein und ein guter
|
||
Moderator zu sein sind nachweislich verschiedene Dinge. Die beiden
|
||
zu verwechseln ist der häufigste Fehler bei der Modsuche — und weil
|
||
die Zahl so leicht zu bekommen wäre, steht hier, dass sie fehlt.
|
||
|
||
HEIMLICHE TESTS. Kein Zweitkonto, das jemanden auf die Probe stellt.
|
||
Das kostet mehr Vertrauen, als es an Erkenntnis bringt — und zwar
|
||
auch bei denen, die davon nur hören.
|
||
|
||
---------------------------------------------------------------------
|
||
UND EIN RIEGEL, DER NICHT VERHANDELBAR IST
|
||
|
||
In diesem Katalog stehen Namen von Menschen, die nichts davon
|
||
wissen. Er gehört DogFather und der rechten Hand, sonst niemandem —
|
||
kein Modi, keine Agentur, und ganz sicher nicht der Community.
|
||
Durchgesetzt wird das in workspace-entwicklung.js und in der
|
||
Rechtetafel, nicht hier; hier steht nur, warum.
|
||
===================================================================== */
|
||
|
||
/** Die fünf Stufen des Trichters.
|
||
*
|
||
* `schritt` ist der EINE nächste Handgriff. `frist` die Zahl der Tage,
|
||
* nach denen eine Karte auf dieser Stufe als liegengeblieben gilt --
|
||
* sie wird nicht gemahnt, sie wird ANGEZEIGT. Eine Erinnerung, die
|
||
* man wegklicken kann, wird weggeklickt; eine Zahl, die dasteht,
|
||
* nicht. */
|
||
export const TALENT_STUFEN = [
|
||
{
|
||
schluessel: "aufgefallen", name: "Aufgefallen", rang: 1, frist: 14,
|
||
bedeutet: "Ein Name ist gefallen. Mehr nicht.",
|
||
schritt: "Beobachten einschalten – ab jetzt Merkmale sammeln.",
|
||
knopf: "Beobachten",
|
||
},
|
||
{
|
||
schluessel: "beobachtet", name: "Beobachtet", rang: 2, frist: 30,
|
||
bedeutet: "Merkmale werden über Wochen gesammelt.",
|
||
schritt: "Ansprechen – der Vorlagentext liegt bereit.",
|
||
knopf: "Ansprechen",
|
||
},
|
||
{
|
||
schluessel: "angesprochen", name: "Angesprochen", rang: 3, frist: 7,
|
||
bedeutet: "Gefragt, ob überhaupt Interesse besteht.",
|
||
schritt: "Antwort eintragen: ja, nein oder später.",
|
||
knopf: "Auf Probe nehmen",
|
||
},
|
||
{
|
||
schluessel: "probe", name: "Probe", rang: 4, frist: 30,
|
||
bedeutet: "Echte Schicht, kleiner Rahmen, fester Buddy – 30 Tage, beidseitig ausgesprochen.",
|
||
schritt: "Nach 30 Tagen: übernehmen – der Zugang entsteht dabei – oder sauber beenden.",
|
||
knopf: "Ins Team",
|
||
},
|
||
{
|
||
schluessel: "imteam", name: "Im Team", rang: 5, frist: null,
|
||
bedeutet: "Zugang steht. Ab hier zählt die Entwicklungskarte, nicht mehr diese.",
|
||
schritt: "Nichts mehr zu tun – der Zugang steht, ab hier zählt die Entwicklungskarte.",
|
||
knopf: null,
|
||
},
|
||
];
|
||
|
||
/** Die Merkmale, in fünf Gruppen. Angeklickt, nicht getippt.
|
||
*
|
||
* DIE REIHENFOLGE DER GRUPPEN IST NICHT ZUFAELLIG: „Ruhe" steht
|
||
* vorn, weil es das am besten belegte Einzelmerkmal ueberhaupt ist --
|
||
* und weil die erste Gruppe die ist, die man immer ausfuellt. */
|
||
export const TALENT_GRUPPEN = [
|
||
{
|
||
schluessel: "ruhe", name: "Ruhe",
|
||
text: "Das am stärksten belegte Einzelmerkmal. Wer unter Druck ruhig bleibt, "
|
||
+ "kann alles andere lernen – umgekehrt nicht.",
|
||
},
|
||
{
|
||
schluessel: "hilft", name: "Hilft von selbst",
|
||
text: "Nicht ob jemand helfen WILL, sondern ob er es schon tut, ohne gefragt zu sein.",
|
||
},
|
||
{
|
||
schluessel: "haus", name: "Kennt das Haus",
|
||
text: "Regeln, Leute, Witze. Das kann man nicht einarbeiten – das hat man oder nicht.",
|
||
},
|
||
{
|
||
schluessel: "da", name: "Ist da",
|
||
text: "Regelmäßigkeit schlägt Menge. Und eine Zeit, zu der ihr niemanden habt, "
|
||
+ "schlägt beides.",
|
||
},
|
||
{
|
||
schluessel: "empfohlen", name: "Aus dem Team",
|
||
text: "Wer aus dem Team kommt, ist schon einmal durch ein Augenpaar gegangen.",
|
||
},
|
||
];
|
||
|
||
export const TALENT_MERKMALE = {
|
||
ruhe: [
|
||
{ schluessel: "t-ruhe-streit", du: "auch dann ruhig bleibst, wenn es im Chat hitzig wird",
|
||
titel: "Bleibt ruhig, wenn im Chat gestritten wird",
|
||
text: "Der Normalfall, an dem sich alles zeigt." },
|
||
{ schluessel: "t-ruhe-provokation", du: "auf Provokation nicht anspringst",
|
||
titel: "Geht auf Provokation nicht ein",
|
||
text: "Nicht ignorieren – nicht mitgehen. Zwei verschiedene Dinge." },
|
||
{ schluessel: "t-ruhe-widerspricht", du: "widersprichst, ohne auszuteilen",
|
||
titel: "Widerspricht, ohne auszuteilen",
|
||
text: "Wer nie widerspricht, ist nicht ruhig, sondern still. Das ist etwas anderes." },
|
||
{ schluessel: "t-ruhe-gegen-sich", du: "dich sogar dann im Griff hast, wenn es gegen dich selbst geht",
|
||
titel: "Hat sich auch dann im Griff, wenn es gegen ihn selbst geht",
|
||
text: "Der härteste der vier – und der aussagekräftigste." },
|
||
],
|
||
hilft: [
|
||
{ schluessel: "t-hilft-vor-team", du: "Fragen von anderen beantwortest, bevor jemand von uns da ist",
|
||
titel: "Beantwortet Fragen anderer, bevor jemand vom Team da ist",
|
||
text: "Tut die Arbeit schon, ohne den Titel zu haben." },
|
||
{ schluessel: "t-hilft-erklaert-neuen", du: "Neuen erklärst, wie es hier läuft",
|
||
titel: "Erklärt Neuen, wie es hier läuft",
|
||
text: "Setzt voraus, dass er es selbst verstanden hat." },
|
||
{ schluessel: "t-hilft-meldet-statt-moderiert", du: "Sachen meldest, statt selbst durchzugreifen",
|
||
titel: "Meldet etwas, statt selbst zu moderieren",
|
||
text: "Genau die richtige Grenze zu kennen, ist das eigentliche Signal – "
|
||
+ "wer ohne Rolle durchgreift, wird es mit Rolle erst recht." },
|
||
{ schluessel: "t-hilft-unbeobachtet", du: "auch dann hilfst, wenn gerade niemand hinsieht",
|
||
titel: "Hilft auch dann, wenn es niemand sieht",
|
||
text: "Schwer zu beobachten, deshalb selten angeklickt – und wenn, dann zählt es." },
|
||
],
|
||
haus: [
|
||
{ schluessel: "t-haus-regeln", du: "die Regeln hier kennst, ohne nachzulesen",
|
||
titel: "Kennt die Regeln, ohne sie nachzulesen",
|
||
text: "Und wendet sie im Gespräch an, nicht als Zitat." },
|
||
{ schluessel: "t-haus-leute", du: "die Leute kennst und weißt, wer wer ist",
|
||
titel: "Kennt die Leute – weiß, wer wer ist",
|
||
text: "Ein halbes Jahr Einarbeitung, die schon passiert ist." },
|
||
{ schluessel: "t-haus-witze", du: "die Witze verstehst, die nur hier funktionieren",
|
||
titel: "Versteht die Witze, die nur hier funktionieren",
|
||
text: "Klingt nebensächlich und ist der Unterschied zwischen Gast und Zuhause." },
|
||
{ schluessel: "t-haus-frueh-dabei", du: "schon dabei warst, als es hier noch kleiner war",
|
||
titel: "War schon da, als es kleiner war",
|
||
text: "Nicht mehr wert – aber belastbarer, weil länger beobachtet." },
|
||
],
|
||
da: [
|
||
{ schluessel: "t-da-regelmaessig", du: "über Wochen regelmäßig da bist, nicht nur bei den großen Streams",
|
||
titel: "Über Wochen regelmäßig, nicht nur bei den großen Streams",
|
||
text: "Regelmäßigkeit ist planbar, Begeisterung nicht." },
|
||
{ schluessel: "t-da-auch-wenig-los", du: "auch dann kommst, wenn wenig los ist",
|
||
titel: "Auch dann, wenn wenig los ist",
|
||
text: "Die kleinen Streams sind der ehrlichere Test." },
|
||
{ schluessel: "t-da-luecke", du: "oft genau dann da bist, wenn wir sonst niemanden haben",
|
||
titel: "Zu Zeiten, zu denen wir niemanden haben",
|
||
text: "Operativ der entscheidendste Punkt der ganzen Liste: Ein guter Kandidat "
|
||
+ "zur falschen Zeit löst kein einziges Problem." },
|
||
{ schluessel: "t-da-kommt-wieder", du: "nach einer Pause von selbst wieder auftauchst",
|
||
titel: "Kommt nach einer Pause von selbst wieder",
|
||
text: "Pausen sind normal. Wiederkommen ist das Signal." },
|
||
],
|
||
empfohlen: [
|
||
{ schluessel: "t-emp-vom-team", du: "jemandem aus dem Team aufgefallen bist",
|
||
titel: "Von jemandem aus dem Team vorgeschlagen",
|
||
text: "Ein Augenpaar, das den Alltag kennt." },
|
||
{ schluessel: "t-emp-mehrfach", du: "gleich mehreren aus dem Team unabhängig voneinander aufgefallen bist",
|
||
titel: "Mehr als eine Person hat unabhängig denselben Namen genannt",
|
||
text: "Der stärkste Einzelbefund im ganzen Katalog. Zwei unabhängige Nennungen "
|
||
+ "schlagen jede einzelne Beobachtung." },
|
||
{ schluessel: "t-emp-schicht-tauschen", du: "jemand aus dem Team gern eine Schicht mit dir tauschen würde",
|
||
titel: "Jemand aus dem Team würde eine Schicht mit ihm tauschen",
|
||
text: "Die ehrlichste Frage, die man dem Team stellen kann." },
|
||
{ schluessel: "t-emp-schon-ausgeholfen", du: "schon mal ausgeholfen hast, ohne dass du musstest",
|
||
titel: "Hat schon mal ausgeholfen, ohne Rolle",
|
||
text: "Der beste verfügbare Beweis – er hat es getan." },
|
||
{ schluessel: "t-emp-von-zuschauer", du: "auch anderen Zuschauern aufgefallen bist",
|
||
titel: "Wurde von einem Zuschauer vorgeschlagen",
|
||
text: "Schwächer als eine Nennung aus dem Team, aber es zählt." },
|
||
],
|
||
};
|
||
|
||
/** Die Warnzeichen. Getrennt und in einem warmen Ton — nicht rot.
|
||
*
|
||
* WARUM SIE UEBERHAUPT GETRENNT STEHEN: Bei Moderatoren sagt das
|
||
* Fehlverhalten mehr voraus als das Koennen. Ein Warnzeichen neben
|
||
* zwanzig Haken ginge unter; getrennt steht es da.
|
||
*
|
||
* UND WARUM NICHT ROT: Keines davon ist ein Ausschluss. Rot heisst
|
||
* "nein" -- gemeint ist "hier laenger hinsehen". Ein Ton, der mehr
|
||
* sagt als die Sache, macht aus einem Hinweis ein Urteil. */
|
||
export const TALENT_WARNZEICHEN = [
|
||
{ schluessel: "t-warn-will-die-rolle", titel: "Will die Rolle sehr deutlich",
|
||
text: "Der klassischste Warnhinweis überhaupt. Kein Ausschluss – "
|
||
+ "aber ein Grund, länger hinzusehen." },
|
||
{ schluessel: "t-warn-war-ausfaellig", titel: "War im Chat schon einmal ausfällig",
|
||
text: "Muss nicht das letzte Wort sein. Aber es gehört auf die Karte, "
|
||
+ "nicht in die Erinnerung von einem." },
|
||
{ schluessel: "t-warn-nur-ein-thema", titel: "Nur bei einem Thema da",
|
||
text: "Begeisterung für eine Sache, nicht für den Ort. Hält, solange das Thema hält." },
|
||
{ schluessel: "t-warn-verschwindet", titel: "Verschwindet für Wochen und kommt wieder",
|
||
text: "Schwer zu verplanen – unabhängig davon, wie gut jemand ist." },
|
||
{ schluessel: "t-warn-redet-ueber", titel: "Redet über andere, nicht mit ihnen",
|
||
text: "Sagt Streit im Team voraus – den zweithäufigsten Ausstiegsgrund." },
|
||
{ schluessel: "t-warn-nur-bei-dir", titel: "Nur da, wenn du sendest",
|
||
text: "An eine Person gebunden, nicht an die Community. Das hält nicht." },
|
||
];
|
||
|
||
/* ---------------------------------------------------------------------
|
||
Abgeleitet, nicht abgeschrieben -- dieselbe Regel wie im anderen
|
||
Katalog: keine Zahl, die jemand pflegen muesste.
|
||
------------------------------------------------------------------- */
|
||
|
||
export const TALENT_ALLE = TALENT_GRUPPEN.flatMap((g) =>
|
||
(TALENT_MERKMALE[g.schluessel] || []).map((m) => ({ ...m, gruppe: g.schluessel })));
|
||
|
||
export const TALENT_NACH_SCHLUESSEL = new Map([
|
||
...TALENT_ALLE.map((m) => [m.schluessel, { ...m, warnung: false }]),
|
||
...TALENT_WARNZEICHEN.map((w) => [w.schluessel, { ...w, warnung: true }]),
|
||
]);
|
||
|
||
/** Die Stufe zu einem Schluessel -- und `null`, wenn es sie nicht gibt.
|
||
* Kein Rueckfall auf die erste Stufe: Eine erfundene Stufe soll
|
||
* auffallen, nicht stillschweigend zu "Aufgefallen" werden. */
|
||
export const talentStufe = (s) =>
|
||
TALENT_STUFEN.find((x) => x.schluessel === s) || null;
|
||
|
||
/* =====================================================================
|
||
DER VORLAGENTEXT ZUM ANSPRECHEN (11.09.2026)
|
||
=====================================================================
|
||
|
||
Auf Stufe 2 steht als naechster Schritt "Ansprechen". Bis heute stand
|
||
daneben "der Vorlagentext liegt bereit" -- und es gab keinen. Ein
|
||
Versprechen an eine Schublade.
|
||
|
||
ER WIRD GEBAUT, NICHT ABGESCHRIEBEN. Aus den Merkmalen, die wirklich
|
||
angeklickt wurden. Ein allgemeiner Text ("wir fanden dich toll")
|
||
klingt wie ein Serienbrief, weil er einer ist; drei konkrete
|
||
Beobachtungen klingen nach jemandem, der hingesehen hat -- und das
|
||
ist der Unterschied, ob jemand zusagt.
|
||
|
||
HOECHSTENS DREI. Wer fuenf Beobachtungen auflistet, klingt nach
|
||
Personalakte. Die drei kommen in der Reihenfolge des Katalogs, und
|
||
die faengt bei "Ruhe" an -- dem am besten belegten Merkmal.
|
||
|
||
DREI SAETZE, DIE IMMER DRINSTEHEN, und jeder hat einen Grund:
|
||
* "kein Druck, sag ruhig nein" -- wer sich gedraengt fuehlt, sagt
|
||
ja und hoert nach drei Wochen auf.
|
||
* "30 Tage, danach schauen wir beide" -- die Probezeit wird
|
||
BEIDSEITIG ausgesprochen. Wer weiss, dass er ohne Gesichtsverlust
|
||
wieder gehen kann, sagt eher ehrlich, wie es ihm damit geht.
|
||
* "du musst nichts koennen" -- die haeufigste Absage kommt nicht
|
||
aus Desinteresse, sondern aus der Annahme, man muesse etwas
|
||
mitbringen.
|
||
|
||
ER WIRD NICHT VERSCHICKT. Er steht da zum Kopieren. Eine Nachricht,
|
||
die ein Programm verschickt, liest sich wie eine Nachricht, die ein
|
||
Programm verschickt hat. */
|
||
export function ansprechtext(name, gesetzteMerkmale) {
|
||
/* NUR DAS ERSTE WORT. Im Brett steht selten ein Name allein --
|
||
"Kessi aus dem Chat" ist eine Notiz, keine Anrede. "Hey Kessi aus
|
||
dem Chat," liest sich wie ein Serienbrief, und genau das soll der
|
||
Text nicht sein.
|
||
|
||
Es ist eine VORLAGE zum Kopieren, keine Nachricht, die abgeschickt
|
||
wird -- wer den Namen anders schreiben will, tut das im Text. */
|
||
const sauber = String(name || "").trim().split(/[\s,(–-]+/)[0].trim() || "du";
|
||
const beobachtet = (gesetzteMerkmale || [])
|
||
.map((sch) => TALENT_ALLE.find((m) => m.schluessel === sch)?.du)
|
||
.filter(Boolean)
|
||
.slice(0, 3);
|
||
|
||
const mitte = beobachtet.length
|
||
? "Mir ist aufgefallen, dass du " + (beobachtet.length === 1
|
||
? beobachtet[0]
|
||
: beobachtet.slice(0, -1).join(", ") + " und " + beobachtet[beobachtet.length - 1]) + "."
|
||
: "Du bist mir hier schon öfter positiv aufgefallen.";
|
||
|
||
/* ECHTE UMLAUTE UND ECHTE STRICHE.
|
||
|
||
In Kommentaren schreibt dieses Haus ASCII; in TEXT, den jemand
|
||
liest, nicht. Der erste Entwurf stand voller "Haettest" und
|
||
"koennen" -- und dieser Text hier ist der einzige im ganzen
|
||
Bereich, den ein Fremder zu sehen bekommt. "Haettest du Lust" sieht
|
||
aus wie ein Fehler, weil es einer ist. Derselbe Befund stand schon
|
||
am 10.09. in workspace-personen.js. */
|
||
return [
|
||
`Hey ${sauber},`,
|
||
"",
|
||
mitte,
|
||
"",
|
||
"Deshalb die Frage: Hättest du Lust, bei uns im Mod-Team mitzumachen?",
|
||
"",
|
||
"Du musst dafür nichts können – alles, was es zu wissen gibt, zeigen wir dir. "
|
||
+ "Wir würden mit 30 Tagen anfangen, und danach schauen wir beide, ob es passt. "
|
||
+ "Wenn nicht, ist das völlig in Ordnung und ändert nichts.",
|
||
"",
|
||
"Und ganz wichtig: kein Druck. Sag ruhig nein oder „gerade nicht“ – "
|
||
+ "das nehme ich dir null übel.",
|
||
].join("\n");
|
||
}
|
||
|
||
/** Die naechste Stufe -- oder null am Ende des Trichters. */
|
||
export function talentNaechste(s) {
|
||
const i = TALENT_STUFEN.findIndex((x) => x.schluessel === s);
|
||
if (i < 0 || i + 1 >= TALENT_STUFEN.length) return null;
|
||
return TALENT_STUFEN[i + 1];
|
||
}
|