Entwicklung: die Auswertung je Person -- und elf Seiten ohne Farbe

Filipe: "dan perfektionierst du eine neue wo diagramme texte und so zu
jedem modi gemacht wird und diese kategorie kannst du entwicklung nenen."

1. DAS EIGENTLICHE PROBLEM WAR, DASS ES KEINE VERGANGENHEIT GAB.

`entwicklung_stand` hat den Schluessel (person, punkt, beurteiler) und
wird bei jeder Aenderung UEBERSCHRIEBEN -- dort richtig, eine Beobachtung
ueber einen Menschen soll aktuell sein. Nur: Damit existierte nichts,
woraus sich ein Verlauf zeichnen liesse. Nachgemessen: 43 Zeilen Stand,
NULL Zeilen Geschichte. Ein Diagramm ueber einen einzigen Zeitpunkt ist
kein Diagramm, sondern ein Balken.

Neu: `entwicklung_lauf` haengt jede Aenderung an, statt zu ueberschreiben.
Sie steht in workspace-entwicklung.js, bei der Tabelle, zu der sie
gehoert -- die Auswertung liest nur. Andersherum gaebe es einen Ring
zwischen zwei Modulen, und Ringe halten in JavaScript genau so lange,
bis jemand eine Konstante auf oberster Ebene benutzt.

KEIN ANLASS, NIE. Neben jedem "da hakt es" steht ein Satz, woran man es
gemerkt hat -- fuer ein Gespraech aufgeschrieben. Eine Chronik dieser
Saetze waere das Belastendste, was dieses Haus speichern kann. Die Spur
hat gar keine Spalte dafuer, und die Pruefung liest die TABELLE, nicht
die Ausgabe: Eine Spalte, die es gibt, wird eines Tages gefuellt.

Die Startaufnahme uebernimmt den heutigen Stand mit seinen ECHTEN Daten,
damit die Seite am ersten Tag nicht leer ist -- und zaehlt ausdruecklich
NICHT als Bewegung. Der Tag, an dem die Spur entstand, war kein Tag, an
dem 43 Dinge gleichzeitig passiert sind.

2. WAS GEZEIGT WIRD: BEWEGUNG, KEINE NOTE.

Keine Punktzahl, kein Prozentwert, kein Durchschnitt, keine Rangliste,
kein Vergleich zwischen zwei Menschen. Das ist die Recherche, nicht
Vorsicht: Ueberrechtfertigung (Deci), sozialer Vergleich senkt die
Leistung derer, die schlechter dastehen, Schwaechenfokus ebenso.

Stattdessen das progress principle (Amabile/Kramer, ~12 000
Tagebucheintraege): Sichtbarer Fortschritt ist der staerkste einzelne
Treiber. Deshalb Diagramm 1 "Was sich bewegt hat" -- zwei Richtungen um
eine Nulllinie, ein Massstab fuer beide. Diagramm 2 der Streifen (Punkt
x Monat), fortgeschrieben, aber nach 90 Tagen sichtbar verblasst.
Und die Texte in dieser Reihenfolge: was sich bewegt hat, was traegt,
erst danach was liegt.

Selbst gezeichnet, kein Diagrammpaket: 60 kB ueber die Leitung von
jemandem, der mit dem Handy im Stream steht -- und es braechte eigene
Farben neben die Hausfarben. Jede Zelle traegt ihr Zeichen als Text,
jeder Balken seine Zahl, darunter eine Legende: Die Farbe ist nie die
Auskunft.

Zwei Gesichter: Die Leitung sieht die Karten, ein Modi ausschliesslich
die Bewegung in der eigenen -- ohne Namen, ohne Anlass, ohne Streifen.

3. NEBENBEFUND, GROESSER ALS ERWARTET: ELF SEITEN OHNE FARBE.

Der Umbau von heute frueh heisst "Jede Seite traegt die Farbe ihrer
Kachel". Nachgemessen traf das auf 18 von 34 Seiten zu. Elf Seiten mit
echter Kachel gingen leer aus -- ausgerechnet die von Team Dogi:
befinden, bewerben, bewerbungen, entwicklung, hilfe, rechte, talente,
teamlage, teilen, treff-moderation, treff-regeln, unsere-seiten.

Der Grund: `zuSeite()` sucht nur in `Bereiche.GRUPPEN`, und dort stehen
ausschliesslich die Kacheln der Agentur. Die von Team Dogi liefert der
Server (`ich.bereiche`, `ich.bereiche_zusatz`). Auffallen konnte das
nicht -- eine Seite ohne Farbe sieht aus wie eine, die eben keine hat.

kopf.js faerbt jetzt zweimal: sofort aus GRUPPEN (Agenturseiten ohne
Flackern wie bisher), und noch einmal aus den Serverkacheln, sobald
`werZeigen` sie bringt. Nur, wenn beim ersten Mal nichts gefunden wurde.

pruef-buehne misst den Kontrast an echten Bildpunkten und kannte diese
zwoelf Seiten nicht. Jetzt stehen sie in der Liste; ihre Frist waechst
mit der Laenge, statt als feste Zahl irgendwann zu reissen. Gemessen
fuer werdegang.html: 4,83:1 am Computer, 6,22:1 am Handy.

4. TON 38 SAH FREI AUS UND WAR ES NICHT.

Erster Anlauf war Ton 38, weil 37 die hoechste Nummer in workspace.js
ist. Gezaehlt in start.css sind es 39, alle vergeben. Genau davor warnt
das Farbwerkzeug im eigenen Kopf ("Ton 22, weil er frei AUSSAH").

Dabei aufgefallen: Die zwei Kacheln von heute Nacht wurden ohne das
Werkzeug gesetzt. Ton 39 lag 0,0362 von Ton 15 entfernt -- der engste
Abstand im ganzen Haus, zwei praktisch gleiche Cyan-Toene. Filipe dazu
mehrfach: "keine die sich irgendwie aehnlich sind".

Neues Werkzeug `tools/kachel-farbe-einzeln.mjs`: zieht EINE Farbe nach,
ohne die anderen anzufassen. Das grosse Werkzeug haette alle 40 neu
gefaerbt -- jede Kachel im Haus, ungefragt. Es bricht ab, wenn es nicht
alle Toene lesen kann: Der erste Anlauf las 31 von 40, weil einstellige
Nummern mit ZWEI Leerzeichen dastehen, und rechnete froehlich weiter.

Ergebnis: kleinster Abstand 0,0362 -> 0,0840, durch Aendern von zwei
Kacheln, die es erst seit gestern Nacht gibt.

5. anruf-probe.html lud `basis.css` und `kopf.css` -- beide gibt es
nicht. Ausgerechnet dort faellt es nicht auf, weil die Seite ihre eigene
Stilangabe im Kopf hat. pruef-struktur war deshalb rot (5 Befunde) und
ist jetzt gruen.

GEMESSEN: pruef-werdegang 95/0 (neu), pruef-entwicklung 43/0,
pruef-befinden 75/0, pruef-rechtetafel 19/0, pruef-zwischenspeicher 21/0,
pruef-start-ansicht 0 Fehler, pruef-struktur 0 Fehler (vorher 5),
pruef-buehne fuer werdegang.html 0 Fehler.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-19 10:22:02 +02:00
co-authored by Claude Opus 5
parent 0b73fbb501
commit 19e9f471d3
50 changed files with 3307 additions and 464 deletions
+161 -22
View File
@@ -13,7 +13,7 @@
---------------------------------------------------------------------
EINE EIGENE TABELLE — UND WARUM DER PLAN DARIN FALSCH LAG
Der Plan im Vault sagt: „zwei Spalten, keine neue Tabelle" — der
Der Plan im Vault sagt: „zwei Spalten, keine neue Tabelle“ — der
Stand solle in `punkt_stand` liegen, derselben Tabelle wie die
Checkliste. Nachgemessen geht das NICHT:
@@ -32,7 +32,7 @@
---------------------------------------------------------------------
DREI RIEGEL, DIE VON ANFANG AN STEHEN
1. BLOCK 5 GEHOERT DER PERSON. „Wie geht es dir damit?" beantwortet
1. BLOCK 5 GEHOERT DER PERSON. „Wie geht es dir damit?“ beantwortet
nur sie selbst — lesend UND schreibend. Auch DogFather nicht. Was
nach aussen dringt, ist eine Ampel ohne Namen.
@@ -50,10 +50,10 @@
UND EINE ABWEICHUNG VOM PLAN, DIE FILIPES SATZ GESCHULDET IST
Der Plan verlangt einen Anlass (die drei SBI-Felder) bei JEDEM Klick
ausser „kann ich nicht sagen". Bei 28 Punkten je Person waeren das 28
Textfelder — und „so einfach wie moeglich" war die andere Haelfte des
ausser „kann ich nicht sagen“. Bei 28 Punkten je Person waeren das 28
Textfelder — und „so einfach wie moeglich“ war die andere Haelfte des
Auftrags. Pflicht ist der Anlass deshalb dort, wo er etwas
entscheidet: bei **„Da hakt es"**. Bei „Laeuft" und „Waechst gerade"
entscheidet: bei **„Da hakt es“**. Bei „Laeuft“ und „Waechst gerade“
steht dasselbe Feld da, freiwillig — wer etwas Konkretes gesehen hat,
schreibt es hin, und beim Gespraech steht es da.
===================================================================== */
@@ -171,6 +171,55 @@ export function tabellen() {
CREATE INDEX IF NOT EXISTS idx_entwicklung_person
ON entwicklung_stand (person_id, am);
/* =================================================================
DIE SPUR (19.09.2026) — jede Aenderung, angehaengt statt ueberschrieben.
Die Tabelle darueber hat den Schluessel (person, punkt, beurteiler)
und wird bei jeder Aenderung UEBERSCHRIEBEN. Das ist dort richtig:
Eine Beobachtung ueber einen Menschen soll aktuell sein, nicht
historisch.
Nur: Damit existierte nichts, woraus man einen Verlauf zeichnen
koennte. Am 19.09. nachgemessen: 43 Zeilen Stand, NULL Zeilen
Geschichte. Ein Diagramm ueber einen einzigen Zeitpunkt ist kein
Diagramm, sondern ein Balken.
SIE STEHT HIER UND NICHT IN workspace-werdegang.js, obwohl sie
dort ausgewertet wird: Eine Tabelle gehoert zu dem Modul, das sie
SCHREIBT. Andersherum gaebe es einen Ring zwischen zwei Modulen,
und Ringe halten in JavaScript genau so lange, bis jemand eine
Konstante auf oberster Ebene benutzt.
KEIN ANLASS, NIE. Neben jedem "da hakt es" steht in der Tabelle
oben ein Satz, woran man es gemerkt hat. Der ist fuer ein
Gespraech aufgeschrieben. Eine CHRONIK dieser Saetze waere das
Belastendste, was dieses Haus speichern kann -- jede laengst
geklaerte Beobachtung bliebe auf Dauer lesbar. Dasselbe Prinzip
wie beim Befinden-Verlauf.
VORHER steht dabei, obwohl es aus der vorigen Zeile abzuleiten
waere: Fuer die Startaufnahme (siehe unten) gibt es kein
"vorher", und NULL sagt das, waehrend eine abgeleitete Kette es
verschweigen wuerde.
NACHGETRAGEN unterscheidet beobachtete Uebergaenge von der
Startaufnahme. Ohne dieses Feld saehe der Tag, an dem die Spur
entstand, wie ein Tag aus, an dem 43 Dinge gleichzeitig passiert
sind.
============================================================= */
CREATE TABLE IF NOT EXISTS entwicklung_lauf (
id INTEGER PRIMARY KEY AUTOINCREMENT,
person_id INTEGER NOT NULL REFERENCES personen(id) ON DELETE CASCADE,
schluessel TEXT NOT NULL,
von_id INTEGER NOT NULL REFERENCES personen(id) ON DELETE CASCADE,
stufe TEXT NOT NULL CHECK (stufe IN ('laeuft','waechst','hakt','unklar')),
vorher TEXT,
nachgetragen INTEGER NOT NULL DEFAULT 0,
am TEXT NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_lauf_person
ON entwicklung_lauf (person_id, am);
/* Ein angeklicktes Merkmal an einem Kandidaten.
KEIN von_id IM SCHLUESSEL, anders als oben -- und das ist
@@ -293,7 +342,7 @@ export function tabellen() {
liegen -- und die Standzeit an der Karte sagt zwar, DASS etwas
liegt, aber nicht, wer es aufheben sollte.
`zustaendig_seit` kommt mit: „seit gestern uebernommen" und „seit
`zustaendig_seit` kommt mit: „seit gestern uebernommen“ und „seit
drei Wochen uebernommen" sind zwei verschiedene Auskuenfte, und
die zweite ist die, die man sehen will. */
["zustaendig_id", "INTEGER"],
@@ -307,9 +356,83 @@ export function tabellen() {
}
} catch (f) { console.error(`[talente] Spalte '${spalte}':`, f?.message); }
}
startaufnahme();
bereit = true;
}
/** Die Spur einmalig aus dem heutigen Stand fuellen (19.09.2026).
*
* WARUM UEBERHAUPT: Ohne sie waere die Auswertungsseite am ersten Tag
* leer, und zwar fuer Monate -- bis jemand genug Einschaetzungen
* geaendert hat. Eine Seite, die nach dem Bauen leer bleibt, sieht aus
* wie ein Fehler und wird kein zweites Mal geoeffnet.
*
* WARUM DAS EHRLICH IST: Jede Zeile in `entwicklung_stand` traegt ihr
* echtes `am` -- den Tag, an dem jemand wirklich geklickt hat. Es wird
* nichts erfunden, nur uebernommen, was ohnehin dasteht. Was sich
* NICHT rekonstruieren laesst -- ob vorher schon etwas anderes
* dastand --, bleibt NULL und traegt `nachgetragen = 1`. Die
* Auswertung zaehlt diese Zeilen ausdruecklich NICHT als Bewegung:
* Der Tag der Startaufnahme ist der Nullpunkt, nicht ein Tag, an dem
* etwas passiert ist.
*
* GENAU EINMAL: nur wenn die Spur leer ist. Ein zweiter Lauf traege
* jeden Stand ein zweites Mal ein, und ab da zaehlte jede Bewegung
* doppelt.
*
* UND SIE DARF NIE DEN SERVER AUFHALTEN. Schlaegt sie fehl, ist die
* Auswertung duenn -- das ist aergerlich. Wuerde dadurch `tabellen()`
* scheitern, waere die ganze Entwicklungsseite mit 503 tot, und das
* waere ungleich schlimmer. */
function startaufnahme() {
try {
const da = db().prepare("SELECT COUNT(*) AS n FROM entwicklung_lauf").get();
if (da.n > 0) return;
const staende = db().prepare(
`SELECT person_id, schluessel, von_id, stufe, am
FROM entwicklung_stand ORDER BY am`).all();
if (!staende.length) return;
const rein = db().prepare(
`INSERT INTO entwicklung_lauf
(person_id, schluessel, von_id, stufe, vorher, nachgetragen, am)
VALUES (?,?,?,?,NULL,1,?)`);
let n = 0;
for (const s of staende) {
/* DIE SELBSTAUSKUNFT FAELLT HERAUS. Block 5 ("Wie geht es dir
damit?") hat mit dem Befinden-Verlauf eine eigene Tabelle, die
niemand sonst liest. Hier waere sie eine Aussage, die ein
Mensch ueber sich selbst gemacht hat -- und die ploetzlich in
einer Auswertung fuer die Leitung stuende. */
if (!ENTWICKLUNG_FREMD.some((x) => x.schluessel === s.schluessel)) continue;
rein.run(s.person_id, s.schluessel, s.von_id, s.stufe, s.am);
n++;
}
if (n) console.log(`[entwicklung] Startaufnahme: ${n} Staende in die Spur uebernommen.`);
} catch (f) {
console.error("[entwicklung] Startaufnahme:", f?.message);
}
}
/** Eine Aenderung in der Spur festhalten.
*
* SIE DARF NIE DEN KLICK VERHINDERN. Geht hier etwas schief, ist die
* Auswertung lueckenhaft. Wuerde dadurch die Einschaetzung nicht
* gespeichert, waere die Arbeit weg. Deshalb faengt sie ihren Fehler
* selbst und meldet ihn nur ins Protokoll der Konsole. */
function spurLegen({ personId, schluessel, vonId, stufe, vorher }) {
try {
db().prepare(
`INSERT INTO entwicklung_lauf
(person_id, schluessel, von_id, stufe, vorher, nachgetragen, am)
VALUES (?,?,?,?,?,0,?)`)
.run(personId, schluessel, vonId, stufe, vorher ?? null, jetzt());
} catch (f) {
console.error("[entwicklung] Spur:", f?.message);
}
}
/* =====================================================================
DIE HUERDEN
===================================================================== */
@@ -498,7 +621,7 @@ entwicklungRouter.get("/workspace/api/entwicklung/person/:id", nurLeitung, (req,
aufgefallen ist.
Das ist keine Nebensaechlichkeit. Beim ersten Beurteilen ist
genau das die Frage: „Woher kommt der eigentlich?" -- und wer sie
genau das die Frage: „Woher kommt der eigentlich?“ -- und wer sie
nicht beantwortet bekommt, faengt bei null an, obwohl vier Wochen
Beobachtung vorliegen.
@@ -556,7 +679,7 @@ entwicklungRouter.get("/workspace/api/entwicklung/person/:id", nurLeitung, (req,
Die Quellen zur laufenden Entwicklungsbegleitung sagen übereinstimmend
zweierlei: weg von der Bewertung, hin zum Gespräch -- und ein
Entwicklungsplan wirkt dann, wenn er an einer ECHTEN Aufgabe hängt.
Nicht „daran arbeiten wir", sondern etwas, das auf dem Aufgabenbrett
Nicht „daran arbeiten wir“, sondern etwas, das auf dem Aufgabenbrett
steht, einen Verantwortlichen hat und irgendwann erledigt ist.
Genau dieses Muster gibt es im Haus schon: Aus einer Idee auf einem
@@ -610,8 +733,8 @@ entwicklungRouter.post("/workspace/api/entwicklung/person/:id/:schluessel/schrit
const punkt = ENTWICKLUNG_FREMD.find((x) => x.schluessel === schluessel);
if (!punkt) return res.status(404).json({ fehler: "nicht_gefunden" });
/* NUR AUS EINEM „DA HAKT ES" WIRD EIN SCHRITT -- und nur aus dem
EIGENEN. Aus „läuft" einen Schritt zu machen hieße, jemandem
/* NUR AUS EINEM „DA HAKT ES“ WIRD EIN SCHRITT -- und nur aus dem
EIGENEN. Aus „läuft“ einen Schritt zu machen hieße, jemandem
Arbeit zu geben für etwas, das gut läuft; aus der Beobachtung
eines anderen hieße, in seinem Namen zu handeln. */
const stand = db().prepare(
@@ -682,7 +805,7 @@ entwicklungRouter.put("/workspace/api/entwicklung/person/:id/:schluessel",
if (!STUFEN_SATZ.has(stufe)) return res.status(400).json({ fehler: "unbekannte_stufe" });
/* DER ANLASS IST PFLICHT, WO ER ETWAS ENTSCHEIDET.
„Da hakt es" ohne Beispiel ist eine Meinung; mit Beispiel ist
„Da hakt es“ ohne Beispiel ist eine Meinung; mit Beispiel ist
es ein Gespraech. Bei den anderen beiden steht dasselbe Feld
freiwillig da. */
if (stufe === "hakt" && anlass.length < 10) {
@@ -692,6 +815,15 @@ entwicklungRouter.put("/workspace/api/entwicklung/person/:id/:schluessel",
});
}
/* WAS VORHER DASTAND -- VOR dem Schreiben gelesen.
Danach ist es weg: Die Tabelle ueberschreibt. Genau deshalb
gibt es die Spur, und genau deshalb steht diese Zeile hier
oben und nicht unten. */
const vorher = db().prepare(
`SELECT stufe FROM entwicklung_stand
WHERE person_id = ? AND schluessel = ? AND von_id = ?`)
.get(id, schluessel, req.person.id)?.stufe || null;
db().prepare(`INSERT INTO entwicklung_stand
(person_id, schluessel, von_id, stufe, anlass, am)
VALUES (?,?,?,?,?,?)
@@ -699,6 +831,13 @@ entwicklungRouter.put("/workspace/api/entwicklung/person/:id/:schluessel",
stufe = excluded.stufe, anlass = excluded.anlass, am = excluded.am`)
.run(id, schluessel, req.person.id, stufe, anlass || null, jetzt());
/* ERST SPEICHERN, DANN MITSCHREIBEN. Die Reihenfolge ist die
Aussage: Wenn die Spur scheitert, fehlt eine Zeile in einer
Auswertung. Wenn das Speichern scheitert, ist die Arbeit weg. */
spurLegen({
personId: id, schluessel, vonId: req.person.id, stufe, vorher,
});
res.json({ ok: true });
} catch (f) {
console.error("[entwicklung] Setzen:", f?.message);
@@ -851,7 +990,7 @@ entwicklungRouter.get("/workspace/api/entwicklung/meine-karte", (req, res) => {
/* WAS HIER HERAUSKOMMT UND WAS NICHT.
Heraus kommt: wie viele im Team gerade mindestens einen Punkt aus
Block 5 auf „da hakt es" stehen haben -- und ab zwei Personen auch
Block 5 auf „da hakt es“ stehen haben -- und ab zwei Personen auch
das nicht mehr genau, sondern als Spanne.
Nicht heraus kommt: wer, welcher Punkt, seit wann.
@@ -861,7 +1000,7 @@ entwicklungRouter.get("/workspace/api/entwicklung/meine-karte", (req, res) => {
daraus niemanden erkennen kann.
AB WELCHER ZAHL SIE UEBERHAUPT ETWAS SAGT: Bei einem Team von zwei
Personen waere „einer hat gerade viel" dasselbe wie ein Name.
Personen waere „einer hat gerade viel“ dasselbe wie ein Name.
Deshalb schweigt sie unter MINDESTENS_TEAM Personen -- mit Grund,
nicht stillschweigend. */
const MINDESTENS_TEAM = 3;
@@ -908,7 +1047,7 @@ entwicklungRouter.get("/workspace/api/entwicklung/ampel", nurLeitung, (req, res)
res.json({
sagbar: true, team, geantwortet,
/* Keine genaue Zahl: „einer" waere bei kleinen Teams wieder ein
/* Keine genaue Zahl: „einer“ waere bei kleinen Teams wieder ein
Name. Es gibt drei Antworten, und mehr braucht es nicht. */
lage: betroffen === 0 ? "ruhig" : betroffen === 1 ? "jemand" : "mehrere",
text: betroffen === 0
@@ -1180,7 +1319,7 @@ entwicklungRouter.get("/workspace/api/talente/lage", (req, res) => {
heraussuchen, Kategorie und Stufe waehlen und uebernehmen.
Vier Schritte, die niemand macht, waehrend er gerade jemanden
aufnimmt. Genau dieses Muster hat heute schon einmal zu einer
Karte auf „Im Team" ohne Menschen darin gefuehrt.
Karte auf „Im Team“ ohne Menschen darin gefuehrt.
ES BLEIBT EIN ANGEBOT, KEINE AUTOMATIK. Filipes Entscheidung
bei der Live-Checkliste gilt hier genauso: „vierzehn Aufgaben,
@@ -1189,8 +1328,8 @@ entwicklungRouter.get("/workspace/api/talente/lage", (req, res) => {
hier nur, WAS es gaebe -- angelegt wird auf Klick, eine
Kategorie auf einmal.
KEIN ROLLENNAME, nirgends. Die Kategorien heissen „chat",
„team", „technik" -- aus keiner davon laesst sich schliessen,
KEIN ROLLENNAME, nirgends. Die Kategorien heissen „chat“,
„team“, „technik“ -- aus keiner davon laesst sich schliessen,
fuer wen sie gedacht sind. Wer den Katalog nicht bekommen
darf, bekommt `null` und die Seite baut nichts; ein leeres
Feld sagt nichts, ein Feld mit sprechendem Namen saehe jeder
@@ -1205,7 +1344,7 @@ entwicklungRouter.get("/workspace/api/talente/lage", (req, res) => {
/* WAS SIE SCHON HABEN -- je Person, in EINER Abfrage.
Ohne diese Angabe legt man beim zweiten Hinsehen dasselbe noch
einmal an; der Knopf sagt dann „6 Aufgaben" und meint die
einmal an; der Knopf sagt dann „6 Aufgaben“ und meint die
siebte bis zwoelfte. Der Server verhindert Doppelte nicht --
er soll es auch nicht, denn dieselbe Aufgabe ein zweites Mal
kann gewollt sein. Sichtbar muss es trotzdem sein. */
@@ -1444,7 +1583,7 @@ entwicklungRouter.put("/workspace/api/talente/:id/kuemmern", gleicheHerkunft,
} else {
/* Noch keine Stufenzeile -- die entsteht erst beim ersten
Schritt. Wer sich vorher kuemmern will, soll das koennen:
„Ich sehe ihn mir an" ist der haeufigste erste Schritt
„Ich sehe ihn mir an“ ist der haeufigste erste Schritt
ueberhaupt, und er faellt sonst durch. */
db().prepare(`INSERT INTO talent_stufe
(eintrag_id, stufe, seit, von_id, zustaendig_id, zustaendig_seit)
@@ -1506,7 +1645,7 @@ entwicklungRouter.put("/workspace/api/talente/:id/wieder", gleicheHerkunft,
/** Buddy und Datum prüfen. Gibt `{ fehlt: [...] }` oder `{ buddyId, schicht }`.
*
* EINE STELLE, ZWEI AUFRUFER: der Stufenwechsel auf „Probe" und das
* EINE STELLE, ZWEI AUFRUFER: der Stufenwechsel auf „Probe“ und das
* spaetere Aendern. Zwei Abschriften derselben Regeln waeren zwei
* Regeln, und die zweite ist immer die, die etwas durchlaesst. */
function uebergangPruefen(koerper, { pflicht }) {
@@ -1576,13 +1715,13 @@ entwicklungRouter.put("/workspace/api/talente/:id/stufe", gleicheHerkunft, (req,
/* AUF DIE PROBE KOMMT NIEMAND OHNE BUDDY UND DATUM.
In der Stufenbeschreibung stand „fester Buddy" seit dem ersten
In der Stufenbeschreibung stand „fester Buddy“ seit dem ersten
Tag -- ein Feld dafuer gab es nicht. Ein Versprechen ohne Feld
ist eines, an das sich nach zwei Wochen niemand erinnert, und
genau an dieser Stelle verlieren Teams die Leute, die sie gerade
gewonnen haben.
EINE ABSAGE MIT GRUND, nicht ein „ging nicht": Die Oberflaeche
EINE ABSAGE MIT GRUND, nicht ein „ging nicht“: Die Oberflaeche
fragt beides vorher ab, aber die Regel gehoert hierher. Was nur
im Browser steht, gilt nur fuer den, der den Browser benutzt. */
const p = stufe === "probe"