Entwicklung: aus einer Beobachtung wird ein Schritt
Filipe: "ich will die noch viel besser, perfektionniert, viel geiler und krasser. es soll so einfach wie moeglich sein fuer jeden." Die Karte konnte bisher genau eines: festhalten, dass etwas hakt -- mit Anlass, das war schon richtig. Danach passierte nichts. Beim naechsten Oeffnen stand dieselbe Beobachtung da, nur aelter. Die Quellen zur laufenden Entwicklungsbegleitung sagen zweierlei: weg von der Bewertung, hin zum Gespraech -- und ein Entwicklungsplan wirkt dann, wenn er an einer ECHTEN Aufgabe haengt. Nicht "daran arbeiten wir", sondern etwas mit Verantwortlichem und Frist. Also: An einem Punkt, der hakt, steht ein Knopf. Er legt eine Aufgabe auf dem Brett an -- Titel = der Punkt, der Anlass wandert in die Beschreibung (ohne ihn waere es ein Vorwurf), verantwortlich ist der Mensch selbst, Frist in 14 Tagen. Die Karte zeigt danach, dass ein Schritt laeuft, und verweist auf ihn. UND DANN SCHLIESST SICH DER KREIS: Ist der Schritt erledigt, sagt die Karte das und bittet, noch einmal hinzusehen. Das ist der Rhythmus, den die Quellen meinen -- keine Bewertung einmal im Jahr, sondern eine Runde, die zu Ende geht. Danach geht derselbe Punkt wieder. Die Riegel: nur aus dem EIGENEN "da hakt es" (aus dem eines anderen hiesse, in seinem Namen zu handeln), nur ein offener Schritt je Punkt, nur Leitung, und ein Punkt aus Block 5 sieht von aussen aus wie ein erfundener. Im Protokoll steht, DASS -- nie der Anlass. NEBENBEFUND, beim Uebernehmen der Schreibweise gefunden: aufgaben.html #a<nummer> stand an DREI Stellen im Haus (bereich.js, report.js, jetzt die Entwicklungskarte) und wurde von keiner gelesen -- das Brett kannte nur ?zeigen=, und eine Karte mit ihrer Nummer als Anker gab es nicht. Wer draufdrueckte, landete auf dem Brett und suchte von Hand. Jetzt tragen die Karten ihre Nummer, und das Brett hebt genau die eine hervor. Alle drei Verweise funktionieren damit. Und was die Pruefung an sich selbst gefunden hat: Ich habe die rechte Hand ueber die Adresse von DogFather gerufen. Sie bekam 401 -- und WEIL sie nichts setzen konnte, ging ein zweiter Test aus dem falschen Grund durch. Ein gruener Haken ueber einer Leere. server/pruef-schritt.mjs 46 Pruefungen, 0 Fehler (Port 4421) pruef-uebergang 61, pruef-nachwuchs 123, pruef-entwicklung 43, pruef-uebernahme 39, pruef-aufgabenbrett, pruef-css-klassen -- 0 Fehler Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -326,6 +326,7 @@ entwicklungRouter.get("/workspace/api/entwicklung/person/:id", nurLeitung, (req,
|
||||
WHERE s.person_id = ? AND s.von_id <> ?`).all(id, req.person.id);
|
||||
|
||||
const grenze = Date.now() - VERBLASST_NACH_TAGEN * TAG;
|
||||
const schritte = schritteVon(p.id);
|
||||
const bloecke = katalogFuer(req.person, false).map((b) => ({
|
||||
...b,
|
||||
punkte: b.punkte.map((pt) => {
|
||||
@@ -344,6 +345,10 @@ entwicklungRouter.get("/workspace/api/entwicklung/person/:id", nurLeitung, (req,
|
||||
nicht" dasselbe Bild, und das erste ist eine Auskunft,
|
||||
das zweite eine Taeuschung. */
|
||||
andere_offen: m ? 0 : fremde.filter((f) => f.schluessel === pt.schluessel).length,
|
||||
/* DER SCHRITT ZU DIESEM PUNKT. Er steht an der Karte und
|
||||
nicht auf einer eigenen Liste: Wer die Beobachtung sieht,
|
||||
soll im selben Blick sehen, ob daraus etwas geworden ist. */
|
||||
schritt: schritte.get(pt.schluessel) || null,
|
||||
};
|
||||
}),
|
||||
}));
|
||||
@@ -381,6 +386,124 @@ entwicklungRouter.get("/workspace/api/entwicklung/person/:id", nurLeitung, (req,
|
||||
}
|
||||
});
|
||||
|
||||
/* =====================================================================
|
||||
AUS EINER BEOBACHTUNG WIRD EIN SCHRITT (15.09.2026)
|
||||
|
||||
Filipe: „ich will die noch viel besser, perfektionniert […] so
|
||||
einfach wie möglich für jeden."
|
||||
|
||||
---------------------------------------------------------------------
|
||||
WAS GEFEHLT HAT
|
||||
|
||||
Die Karte konnte bisher genau eines: festhalten, dass etwas hakt --
|
||||
mit Anlass, das war schon richtig. Danach passierte nichts. Beim
|
||||
nächsten Öffnen stand dieselbe Beobachtung da, nur älter.
|
||||
|
||||
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
|
||||
steht, einen Verantwortlichen hat und irgendwann erledigt ist.
|
||||
|
||||
Genau dieses Muster gibt es im Haus schon: Aus einer Idee auf einem
|
||||
Brett wird eine Aufgabe. Hier ist es dasselbe, nur mit einem anderen
|
||||
Ausgangspunkt -- und deshalb sieht es auch gleich aus.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
UND DANN SCHLIESST SICH DER KREIS
|
||||
|
||||
Ist der Schritt erledigt, sagt die Karte das und fragt dieselbe Frage
|
||||
noch einmal. Das ist der Rhythmus, den die Quellen meinen: nicht
|
||||
einmal im Jahr eine Bewertung, sondern eine Runde, die zu Ende geht.
|
||||
|
||||
Quellen:
|
||||
https://www.quantumworkplace.com/future-of-work/continuous-performance-management
|
||||
https://www.aihr.com/blog/continuous-performance-management/
|
||||
https://www.deel.com/blog/implement-continuous-performance-management-system/
|
||||
===================================================================== */
|
||||
|
||||
/** Wie lange ein Schritt Zeit bekommt. Vorschlag, kein Gesetz --
|
||||
* auf dem Aufgabenbrett lässt sich die Frist ändern wie bei jeder
|
||||
* anderen Aufgabe auch. Zwei Wochen sind nah genug, dass man sich
|
||||
* erinnert, und weit genug, dass sich etwas ändern kann. */
|
||||
export const SCHRITT_TAGE = 14;
|
||||
|
||||
/** Die Schritte zu den Punkten einer Person — einer je Punkt.
|
||||
*
|
||||
* ES IST IMMER DER JÜNGSTE. Wer denselben Punkt ein zweites Mal
|
||||
* angeht, soll den neuen Schritt sehen und nicht den von vor einem
|
||||
* halben Jahr. */
|
||||
function schritteVon(personId) {
|
||||
const zeilen = db().prepare(
|
||||
`SELECT id, titel, status, frist, erledigt_am, aus_punkt, erstellt
|
||||
FROM aufgaben
|
||||
WHERE verantwortlich_id = ? AND aus_punkt IS NOT NULL
|
||||
ORDER BY id DESC`).all(personId);
|
||||
const nach = new Map();
|
||||
for (const z of zeilen) if (!nach.has(z.aus_punkt)) nach.set(z.aus_punkt, z);
|
||||
return nach;
|
||||
}
|
||||
|
||||
entwicklungRouter.post("/workspace/api/entwicklung/person/:id/:schluessel/schritt",
|
||||
gleicheHerkunft, nurLeitung, express.json({ limit: "8kb" }), (req, res) => {
|
||||
try {
|
||||
const id = nummer(req.params.id);
|
||||
const schluessel = String(req.params.schluessel || "");
|
||||
const p = id && db().prepare("SELECT id, name, rolle FROM personen WHERE id = ?").get(id);
|
||||
if (!p || !KARTEN_ROLLEN.includes(p.rolle)) {
|
||||
return res.status(404).json({ fehler: "nicht_gefunden" });
|
||||
}
|
||||
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
|
||||
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(
|
||||
`SELECT stufe, anlass FROM entwicklung_stand
|
||||
WHERE person_id = ? AND schluessel = ? AND von_id = ?`)
|
||||
.get(id, schluessel, req.person.id);
|
||||
if (!stand || stand.stufe !== "hakt") {
|
||||
return res.status(400).json({ fehler: "kein_hakt" });
|
||||
}
|
||||
|
||||
/* EIN OFFENER SCHRITT REICHT. Zwei Aufgaben zum selben Punkt
|
||||
wären zwei Erinnerungen an dieselbe Sache -- und die zweite
|
||||
macht die erste wertlos. */
|
||||
const offen = db().prepare(
|
||||
`SELECT id FROM aufgaben
|
||||
WHERE verantwortlich_id = ? AND aus_punkt = ?
|
||||
AND status NOT IN ('erledigt','abgebrochen')`).get(id, schluessel);
|
||||
if (offen) return res.status(400).json({ fehler: "schon_da", aufgabe_id: offen.id });
|
||||
|
||||
const frist = new Date(Date.now() + SCHRITT_TAGE * 86400000).toISOString().slice(0, 10);
|
||||
const jetztIso = jetzt();
|
||||
db().prepare(`INSERT INTO aufgaben
|
||||
(titel, beschreibung, status, prioritaet, verantwortlich_id,
|
||||
frist, erstellt, erstellt_von, aus_punkt)
|
||||
VALUES (?,?,'offen','mittel',?,?,?,?,?)`)
|
||||
.run(
|
||||
punkt.titel,
|
||||
/* DER ANLASS WANDERT MIT. Ohne ihn stünde auf dem Brett ein
|
||||
Satz ohne Anlass, und die Aufgabe wäre ein Vorwurf. */
|
||||
`${punkt.text}\n\nWoran es aufgefallen ist: ${stand.anlass || "–"}`,
|
||||
id, frist, jetztIso, req.person.id, schluessel);
|
||||
const neu = db().prepare("SELECT last_insert_rowid() AS id").get().id;
|
||||
|
||||
protokolliere("entwicklung_schritt", {
|
||||
personId: req.person.id, ip: echteIp(req),
|
||||
/* KEIN ANLASS IM PROTOKOLL. Dass ein Schritt entstanden ist,
|
||||
gehört hinein; woran jemand etwas gemerkt hat, nicht. */
|
||||
detail: `${punkt.titel} für ${p.name}`.slice(0, 120),
|
||||
});
|
||||
res.status(201).json({ id: neu, titel: punkt.titel, frist });
|
||||
} catch (f) {
|
||||
console.error("[entwicklung] Schritt:", f?.message);
|
||||
res.status(503).json({ fehler: "nicht_verfuegbar" });
|
||||
}
|
||||
});
|
||||
|
||||
const STUFEN_SATZ = new Set(ENTWICKLUNG_STUFEN.map((s) => s.schluessel));
|
||||
|
||||
entwicklungRouter.put("/workspace/api/entwicklung/person/:id/:schluessel",
|
||||
|
||||
Reference in New Issue
Block a user