Aufgaben an Menschen: zuteilen, annehmen, ablehnen, bewerten

Auftrag vom 21.09.2026, Abschnitte 2 bis 5 -- der Serverteil.

DREI ARTEN ZU VERTEILEN, und der Unterschied zwischen den letzten
beiden ist der ganze Punkt:

  einzeln   eine Person, sie macht es
  mehrere   mehrere Personen, JEDE macht ihren Teil
  pool      mehrere sehen es, EINE nimmt es -- danach ist es fuer die
            anderen weg, damit niemand doppelt arbeitet

EINE EIGENE TABELLE, KEINE SPALTEN AN DER AUFGABE. Abschnitt 4
verlangt ausdruecklich: *"Die Aufgabe muss in der Auswertung auf die
einzelnen zugewiesenen Personen aufgeteilt werden"* -- und gleichzeitig
soll "die urspruengliche gemeinsame Aufgabe ihre uebergeordnete
Struktur" behalten. Eine Aufgabe hat EINEN Titel und EINE Frist, aber
je Mensch einen eigenen Stand, einen eigenen Grund beim Ablehnen, ein
eigenes Erledigt-Datum und eine eigene Rueckmeldung. Das in Spalten zu
pressen hiesse, dieselbe Aufgabe mehrfach anzulegen.

`aufgaben.status` bleibt daneben unberuehrt. Zwei Ebenen, weil es zwei
Fragen sind: "Wie steht die Aufgabe?" und "Wie steht sie bei IHM?" Ein
einziges Feld koennte bei drei Leuten nicht gleichzeitig "angenommen"
und "abgelehnt" sein.

DER WICHTIGSTE EINZELNE HANDGRIFF -- und er steht nicht im Auftrag:
Wer eine Aufgabe BEKOMMEN hat, sieht sie jetzt immer. Bei "mehrere"
und "pool" bleibt `verantwortlich_id` leer, und die alten Sichtregeln
fragen genau danach. Ohne die Erweiterung stuende eine Aufgabe im
Resuemee der Leitung und waere fuer den, der sie machen soll,
unsichtbar -- der unangenehmste denkbare Fehler in einem
Aufgabensystem, und man sieht ihn nirgends. Die Erweiterung ist ein
ODER, kein UND: Sie erweitert die Sicht, die Haustrennung darueber
bleibt ein UND und wirkt weiter.

WAS SONST NOCH ENTSCHIEDEN WURDE, mit Grund im Code:

  - Ablehnen braucht eine Begruendung (mind. 3 Zeichen). Ein leeres
    Nein ist fuer den, der verteilt hat, keine Information -- er muss
    dann nachfragen, und genau das sollte die Nachricht ersparen.
  - "Verbesserungsmoeglichkeiten" braucht einen Text. Ein leeres
    "kann besser" sagt nichts ausser, dass jemand unzufrieden war.
  - Bewertet wird erst, wenn jemand FERTIG ist. Eine Rueckmeldung auf
    etwas, das noch laeuft, ist keine Bewertung, sondern eine
    Einmischung.
  - Beim Pool wird VOR dem Schreiben gefragt, ob schon jemand zugesagt
    hat -- sonst nehmen zwei im selben Moment dieselbe Aufgabe und
    beide sehen "hat geklappt".
  - Wer schon geantwortet hat, behaelt seinen Stand, wenn die Aufgabe
    noch einmal gespeichert wird. Sonst muesste er ohne Grund erneut
    zusagen.
  - Wer nicht mehr dabei ist, faellt raus -- aber nur, solange er noch
    nicht geantwortet hat. Jemandem eine angenommene Aufgabe
    wegzunehmen, ohne dass er es erfaehrt, waere die unangenehmste Art,
    Arbeit zu verlieren.
  - "pool" mit einer Person wird "einzeln". Ein Pool aus einem
    Menschen ist keiner.

`verantwortlich_id` bleibt und wird mitgefuehrt (einzeln = die Person,
pool = der Uebernehmer, mehrere = leer): Brett, Startseite und
Uebersicht gruppieren danach. Drei gewachsene Ansichten gleichzeitig
umzubauen waere der groessere Eingriff -- und im haeufigsten Fall
sagen beide dasselbe.

KEIN CHECK an der nachgetragenen Spalte `verteilart`, mit Absicht: Ein
CHECK auf einer nachgetragenen Spalte hiesse, die Tabelle neu zu bauen
-- der Weg, der in diesem Haus am 11.09. und heute schon Spalten
gekostet hat. Geprueft wird beim Schreiben.

pruef-zuteilung.mjs, 48 Aussagen -- ein Arbeitstag durchgespielt.

Ein Fehlschlag beim ersten Lauf, und er war lehrreich: "Cem hat keinen
eigenen Stand" schlug fehl, weil Cem die Aufgabe gar nicht SIEHT
(`null?.x` ist `undefined`, nicht `null`). Die Zusicherung konnte
"sieht sie nicht" und "sieht sie ohne Stand" nicht unterscheiden --
also pruefte sie beides nicht richtig. Dass er sie nicht sieht, ist
genau Abschnitt 1: *"Eine Modi darf nicht automatisch die
vollstaendige Aufgabenuebersicht aller anderen Modis sehen."* Beide
Faelle stehen jetzt einzeln da, mit einer Gegenprobe, dass seine Liste
ueberhaupt laedt.

Nachbarn gruen: pruef-verteilen 16/0, pruef-aufgabenbrett 49/0,
pruef-umstellung 18/0.
This commit is contained in:
2026-09-21 17:52:52 +02:00
parent 21793b6c36
commit ef0fddc724
5 changed files with 1072 additions and 2 deletions
+103
View File
@@ -2693,6 +2693,38 @@ function umstellungen(d) {
Wechsel verloren, ob die Arbeit schon lief.
"Im Review abgebrochen" ist eine ganz andere
Aussage als "nie angefangen". */
/* WIE EINE AUFGABE VERTEILT WURDE (21.09.2026).
Filipe, Abschnitt 3: *"Dogfather und die rechte Hand muessen
eine Aufgabe einer einzelnen Person zuweisen koennen. Sie
muessen eine Aufgabe auch mehreren bestimmten Personen
gleichzeitig zuweisen koennen. Zusaetzlich soll es eine Option
geben, bei der eine Aufgabe fuer mehrere Modis sichtbar ist und
die erste Modi, die gerade Zeit hat, die Aufgabe uebernehmen
kann."*
DREI WERTE, UND DER UNTERSCHIED ZWISCHEN DEN LETZTEN BEIDEN IST
DER GANZE PUNKT:
einzeln eine Person, sie macht es
mehrere mehrere Personen, JEDE macht ihren Teil
pool mehrere sehen es, EINE nimmt es -- danach ist es
fuer die anderen erledigt
Ohne diese Spalte waeren "mehrere" und "pool" in der Datenbank
nicht zu unterscheiden: Beide sind n Zeilen in
aufgaben_zuteilung. Die Oberflaeche muesste dann raten, ob eine
uebernommene Aufgabe fuer die anderen noch offen ist -- und
genau daraus entsteht die doppelte Bearbeitung, die der Auftrag
ausdruecklich verhindern will.
KEIN CHECK an dieser Spalte, mit Absicht: Sie wird nachgetragen,
und ein CHECK auf einer nachgetragenen Spalte hiesse die Tabelle
neu zu bauen -- der Weg, der in diesem Haus am 11.09. und am
21.09. schon Spalten gekostet hat. Geprueft wird beim
Schreiben, in der Route. */
["aufgaben", "verteilart", "TEXT"],
["aufgaben", "abbruch_grund", "TEXT"],
["aufgaben", "abgebrochen_am", "TEXT"],
["aufgaben", "abbruch_von", "INTEGER REFERENCES personen(id) ON DELETE SET NULL"],
@@ -3742,6 +3774,77 @@ export function db() {
);
CREATE INDEX IF NOT EXISTS idx_aufgaben_notizen ON aufgaben_notizen (aufgabe_id);
/* =================================================================
WER HAT DIE AUFGABE -- UND WIE STEHT ES BEI IHM? (21.09.2026)
Filipe, Abschnitt 4: *"Wenn eine Aufgabe mehreren Modis
zugewiesen wird, darf sie im Resuemee von Dogfather und der
rechten Hand nicht lediglich als eine einzige grosse
Sammelaufgabe erscheinen. Die Aufgabe muss in der Auswertung
auf die einzelnen zugewiesenen Personen aufgeteilt werden."*
GENAU DESHALB EINE EIGENE TABELLE und nicht mehrere Spalten an
der Aufgabe. Eine Aufgabe hat EINEN Titel und EINE Frist --
aber je Mensch einen eigenen Stand, einen eigenen Grund, wenn
er ablehnt, ein eigenes Erledigt-Datum und eine eigene
Bewertung. Das in Spalten zu pressen hiesse, dieselbe Aufgabe
mehrfach anzulegen; dann waere die uebergeordnete Struktur
weg, die der Auftrag ausdruecklich erhalten will.
"zustand" ist der Stand DIESES Menschen, nicht der Aufgabe:
offen er hat sie bekommen, aber noch nicht geantwortet
angenommen er hat ja gesagt
arbeit er ist dran
erledigt er ist fertig
abgelehnt er hat nein gesagt -- "grund" sagt, warum
"aufgaben.status" bleibt daneben unberuehrt. Zwei Ebenen, weil
es zwei Fragen sind: "Wie steht die Aufgabe?" und "Wie steht
SIE bei ihm?" Ein einziges Feld koennte bei drei Leuten nicht
gleichzeitig "angenommen" und "abgelehnt" sein.
WARUM HIER EIN CHECK STEHT, oben aber keiner: Diese Tabelle
entsteht neu. Ein CHECK auf einer neuen Tabelle kostet nichts;
einer auf einer nachgetragenen Spalte kostet einen Neubau.
KEINE BACKTICKS IN DIESEM KOMMENTAR: Er steht INNERHALB eines
Template-Literals (d.exec). Ein Backtick beendet es mitten im
Satz, und die Datei ist ab da syntaktisch kaputt -- an einer
Stelle, die nichts mit dem Fehler zu tun hat.
UNIQUE (aufgabe_id, person_id): Niemand bekommt dieselbe
Aufgabe zweimal. Ohne das entstuenden bei einem doppelten
Klick zwei Zeilen, und das Resuemee zaehlte eine Aufgabe
doppelt -- ein Fehler, den man erst an einer krummen Zahl
bemerkt und dann nicht mehr erklaeren kann.
ON DELETE CASCADE: Wird die Aufgabe geloescht, gehen die
Zuteilungen mit. Fremdschluessel sind in diesem Haus
eingeschaltet (am 20.09. gemessen, nicht angenommen). */
CREATE TABLE IF NOT EXISTS aufgaben_zuteilung (
id INTEGER PRIMARY KEY AUTOINCREMENT,
aufgabe_id INTEGER NOT NULL REFERENCES aufgaben(id) ON DELETE CASCADE,
person_id INTEGER NOT NULL REFERENCES personen(id) ON DELETE CASCADE,
zustand TEXT NOT NULL DEFAULT 'offen'
CHECK (zustand IN ('offen','angenommen','arbeit','erledigt','abgelehnt')),
grund TEXT,
zugeteilt_am TEXT NOT NULL,
zugeteilt_von INTEGER REFERENCES personen(id) ON DELETE SET NULL,
geantwortet_am TEXT,
erledigt_am TEXT,
/* DIE RUECKMELDUNG (Abschnitt 5). Sie haengt am MENSCHEN und
nicht an der Aufgabe: Bei drei Leuten koennen drei
verschiedene Rueckmeldungen richtig sein. */
bewertung TEXT CHECK (bewertung IN ('gut','nicht_gut','verbessern')),
bewertung_text TEXT,
bewertet_von INTEGER REFERENCES personen(id) ON DELETE SET NULL,
bewertet_am TEXT,
UNIQUE (aufgabe_id, person_id)
);
CREATE INDEX IF NOT EXISTS idx_zuteilung_aufgabe ON aufgaben_zuteilung (aufgabe_id);
CREATE INDEX IF NOT EXISTS idx_zuteilung_person ON aufgaben_zuteilung (person_id, zustand);
/* =================================================================
CHAT (06.09.2026)