Abgebrochene Aufgaben mahnen nicht mehr -- an zwoelf Stellen, nicht an einer
Filipe, screen12: "die abgebrochenen sollen oben nicht mehr mit zaehlen
die sollen ihre eigenen kategorie kriegen".
DIE URSACHE war eine Bedingung, die harmlos aussieht: `a.status <>
'erledigt'`. Eine abgebrochene Aufgabe ist nicht "erledigt" -- also fiel
sie durch, und zwar in JEDE Zahl, die "noch zu tun" bedeutet. Eine
Aufgabe, die niemand mehr anfassen wird, mahnte weiter als ueberfaellig.
Das ist die Kehrseite einer bewussten Entscheidung: "abgebrochen" steht
absichtlich NICHT in STATUS, damit der normale Weg es nicht setzen kann.
Genau deshalb rutscht es aber durch jede Pruefung, die nur gegen
'erledigt' vergleicht.
FILIPE HAT EINE STELLE GESEHEN. Gesucht werden musste nach dem MUSTER:
Es waren zwoelf, in sieben Dateien.
workspace-aufgaben.js 2 ueberfaellig und heute (die Zahlen "oben")
workspace-hinweise.js 2 die Hinweiszeilen der Startseite
workspace-kalender.js 1 Aufgaben mit Frist im Kalender
workspace-personen.js 1 "offene_aufgaben" je Person
workspace-profil.js 1 dieselbe Zahl im Profil
workspace-push.js 2 ERINNERUNGEN, die verschickt werden
workspace-reports.js 3 Berichte
Am schwersten wiegt workspace-push.js: Dort gingen Push-Nachrichten
hinaus -- fuer Aufgaben, die laengst abgebrochen waren.
`NOT IN ('erledigt', 'abgebrochen')` statt einer zweiten Ungleichung: Wer
spaeter einen dritten Endzustand einfuehrt, ergaenzt eine Liste, statt
eine Kette von `<>` zu verlaengern, bei der das Vergessen niemandem
auffaellt.
DIE EIGENE KATEGORIE, die Filipe verlangt hat, gibt es jetzt in der
Schnittstelle (`abgebrochen`) und auf der Startseite -- hinten bei
"Erledigt", weil beides dasselbe bedeutet: vom Tisch.
GEGENPROBE an einer abgebrochenen Aufgabe mit Frist von gestern:
alte Bedingung "<> erledigt" -> ueberfaellig = 3
neue Bedingung "NOT IN (erledigt, abg)" -> ueberfaellig = 2
Unterschied 1 = genau die abgebrochene. Die Schnittstelle liefert 2
und abgebrochen = 1.
pruef-start-ansicht hat den Umbau bemerkt und "die Aufgabenzahlen stehen
(7)" gemeldet -- sie zaehlt die Kategorien und erwartete sechs. Die Zahl
steht in der Bedingung, nicht nur im Meldetext; deshalb faellt eine
Kategorie, die still verschwindet, sofort auf. Auf 7 nachgezogen:
EXIT=0, 140 Pruefungen. pruef-aufgabenbrett EXIT=0, 44.
Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -336,7 +336,13 @@ for (const [breite, wie] of [[1440, "Computer"], [390, "Handy"]]) {
|
||||
ok(r.dranZeilen.filter((z) => z.stufe !== "warnung")
|
||||
.every((z) => z.zahlFarbe !== "rgb(255, 154, 162)"),
|
||||
"und nur die");
|
||||
ok(r.zahlen === 6, `die Aufgabenzahlen stehen (${r.zahlen})`);
|
||||
/* SIEBEN seit dem 08.09.2026: "Abgebrochen" ist als eigene Kategorie
|
||||
dazugekommen (screen12). Vorher zaehlten abgebrochene Aufgaben
|
||||
unsichtbar bei "Ueberfaellig" und "Heute faellig" mit.
|
||||
Die Zahl steht bewusst hier in der Bedingung und nicht nur im
|
||||
Meldetext -- eine Kategorie, die still verschwindet, faellt sonst
|
||||
niemandem auf. */
|
||||
ok(r.zahlen === 7, `die Aufgabenzahlen stehen (${r.zahlen})`);
|
||||
ok(!r.zahlenLeer, "und nicht der Leer-Satz");
|
||||
ok(r.ueber <= 0, `nichts steht über (${r.ueber}px, ${r.ueberstehend.join(", ")})`);
|
||||
ok(konsole.length === 0, `keine Fehler in der Konsole${konsole.length ? " -> " + konsole.join(" | ") : ""}`);
|
||||
|
||||
@@ -157,15 +157,47 @@ aufgabenRouter.get("/workspace/api/uebersicht", (req, res) => {
|
||||
.get(...werte, ...extra).n;
|
||||
|
||||
const heute = jetzt().slice(0, 10);
|
||||
|
||||
/* ABGEBROCHENE SIND NICHT "NOCH ZU TUN" (08.09.2026).
|
||||
|
||||
Filipe, screen12: "die abgebrochenen sollen oben nicht mehr mit
|
||||
zählen die sollen ihre eigenen kategorie kriegen".
|
||||
|
||||
Hier stand nur "ungleich erledigt", und das war der Fehler: Eine
|
||||
abgebrochene Aufgabe ist zwar nicht "erledigt", aber eben auch
|
||||
nicht offen. Sie fiel damit in BEIDE Zahlen oben -- eine Aufgabe,
|
||||
die niemand mehr anfassen wird, mahnte weiter als überfällig.
|
||||
|
||||
DERSELBE FEHLER STAND AN ZWÖLF STELLEN in sieben Dateien, nicht
|
||||
nur hier. Am schwersten wog `workspace-push.js`: Dort werden
|
||||
Erinnerungen VERSCHICKT -- für Aufgaben, die längst abgebrochen
|
||||
waren. Filipe hat eine Stelle gesehen; gesucht werden musste nach
|
||||
dem Muster, nicht nach dem Symptom.
|
||||
|
||||
Das ist die Kehrseite einer bewussten Entscheidung weiter unten in
|
||||
dieser Datei: "abgebrochen" steht absichtlich NICHT in STATUS,
|
||||
damit der normale Weg es nicht setzen kann. Genau deshalb rutscht
|
||||
es aber durch jede Bedingung, die nur gegen 'erledigt' prüft --
|
||||
und davon gab es hier zwei.
|
||||
|
||||
`NOT IN` statt einer zweiten Ungleichung: Wer später einen dritten
|
||||
Endzustand einführt, ergänzt eine Liste, statt eine Kette von
|
||||
`<>` zu verlängern, bei der das Vergessen niemandem auffällt. */
|
||||
const ERLEDIGT_ODER_WEG = " AND a.status NOT IN ('erledigt', 'abgebrochen')";
|
||||
|
||||
res.json({
|
||||
offen: zaehle(" AND a.status = 'offen'"),
|
||||
arbeit: zaehle(" AND a.status = 'arbeit'"),
|
||||
review: zaehle(" AND a.status = 'review'"),
|
||||
erledigt: zaehle(" AND a.status = 'erledigt'"),
|
||||
/* Überfällig = Frist vorbei und noch nicht erledigt. Genau die Zahl,
|
||||
/* Die eigene Kategorie, die Filipe verlangt hat. Sie steht bei den
|
||||
abgeschlossenen, nicht bei den offenen -- die Aufgabe ist vom
|
||||
Tisch, nur eben anders als durch Erledigen. */
|
||||
abgebrochen: zaehle(" AND a.status = 'abgebrochen'"),
|
||||
/* Überfällig = Frist vorbei und noch offen. Genau die Zahl,
|
||||
die das Konzept auf dem Dashboard sehen will. */
|
||||
ueberfaellig: zaehle(" AND a.status <> 'erledigt' AND a.frist IS NOT NULL AND a.frist < ?", [heute]),
|
||||
heute: zaehle(" AND a.status <> 'erledigt' AND a.frist = ?", [heute]),
|
||||
ueberfaellig: zaehle(ERLEDIGT_ODER_WEG + " AND a.frist IS NOT NULL AND a.frist < ?", [heute]),
|
||||
heute: zaehle(ERLEDIGT_ODER_WEG + " AND a.frist = ?", [heute]),
|
||||
});
|
||||
} catch (fehler) {
|
||||
console.error("[workspace] Übersicht:", fehler?.message);
|
||||
@@ -315,7 +347,7 @@ aufgabenRouter.get("/workspace/api/uebersicht/creator", (req, res) => {
|
||||
(SELECT COUNT(*) FROM aufgaben a
|
||||
WHERE a.creator_id = p.id AND a.status = 'review') AS review,
|
||||
(SELECT COUNT(*) FROM aufgaben a
|
||||
WHERE a.creator_id = p.id AND a.status <> 'erledigt'
|
||||
WHERE a.creator_id = p.id AND a.status NOT IN ('erledigt', 'abgebrochen')
|
||||
AND a.frist IS NOT NULL AND a.frist < ?) AS ueberfaellig,
|
||||
(SELECT COUNT(*) FROM aufgaben a
|
||||
WHERE a.creator_id = p.id AND a.erledigt_am IS NOT NULL
|
||||
|
||||
@@ -91,13 +91,13 @@ hinweisRouter.get("/workspace/api/hinweise", (req, res) => {
|
||||
dazu("aufgaben_ueberfaellig", "warnung",
|
||||
"überfällig", "aufgaben.html",
|
||||
zaehle(`SELECT COUNT(*) n FROM aufgaben a
|
||||
WHERE ${a.wo} AND a.status <> 'erledigt'
|
||||
WHERE ${a.wo} AND a.status NOT IN ('erledigt', 'abgebrochen')
|
||||
AND a.frist IS NOT NULL AND a.frist < ?`, [...a.werte, heute]));
|
||||
|
||||
dazu("aufgaben_heute", "offen",
|
||||
"heute fällig", "aufgaben.html",
|
||||
zaehle(`SELECT COUNT(*) n FROM aufgaben a
|
||||
WHERE ${a.wo} AND a.status <> 'erledigt' AND a.frist = ?`,
|
||||
WHERE ${a.wo} AND a.status NOT IN ('erledigt', 'abgebrochen') AND a.frist = ?`,
|
||||
[...a.werte, heute]));
|
||||
|
||||
/* Aufgaben, die im Review haengen. Sie warten auf jemanden --
|
||||
|
||||
@@ -315,7 +315,7 @@ kalenderRouter.get("/workspace/api/termine", (req, res) => {
|
||||
const fristen = db().prepare(`
|
||||
SELECT a.id, a.titel, a.frist, a.status, a.prioritaet, pv.name AS verantwortlich_name
|
||||
FROM aufgaben a LEFT JOIN personen pv ON pv.id = a.verantwortlich_id
|
||||
WHERE ${aufgabenWo.wo} AND a.frist IS NOT NULL AND a.status <> 'erledigt'
|
||||
WHERE ${aufgabenWo.wo} AND a.frist IS NOT NULL AND a.status NOT IN ('erledigt', 'abgebrochen')
|
||||
AND a.frist >= ? AND a.frist <= ?
|
||||
ORDER BY a.frist`).all(...aufgabenWo.werte, von, bis);
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ personenRouter.get("/workspace/api/verwaltung/personen", (req, res) => {
|
||||
(SELECT COUNT(*) FROM sitzungen s WHERE s.person_id = p.id) AS sitzungen,
|
||||
(SELECT COUNT(*) FROM aufgaben a
|
||||
WHERE (a.creator_id = p.id OR a.verantwortlich_id = p.id)
|
||||
AND a.status <> 'erledigt') AS offene_aufgaben,
|
||||
AND a.status NOT IN ('erledigt', 'abgebrochen')) AS offene_aufgaben,
|
||||
b.betreuer_id,
|
||||
(SELECT name FROM personen x WHERE x.id = b.betreuer_id) AS betreuer_name,
|
||||
(SELECT COUNT(*) FROM betreuung y WHERE y.betreuer_id = p.id) AS betreut_anzahl,
|
||||
|
||||
@@ -139,7 +139,7 @@ profilRouter.get("/workspace/api/profil", (req, res) => {
|
||||
creator: db().prepare(`
|
||||
SELECT p.id, p.name, p.aktiv, p.letzter_login,
|
||||
(SELECT COUNT(*) FROM aufgaben a
|
||||
WHERE a.creator_id = p.id AND a.status <> 'erledigt') AS offene_aufgaben,
|
||||
WHERE a.creator_id = p.id AND a.status NOT IN ('erledigt', 'abgebrochen')) AS offene_aufgaben,
|
||||
(SELECT naechster_review FROM profile f WHERE f.person_id = p.id) AS naechster_review,
|
||||
(SELECT geaendert FROM profile f WHERE f.person_id = p.id) AS profil_geaendert
|
||||
FROM personen p WHERE p.rolle = 'creator'${nur}
|
||||
|
||||
@@ -241,7 +241,7 @@ export async function laufen() {
|
||||
/* --- Aufgaben, die morgen faellig sind ---------------------------- */
|
||||
for (const a of d.prepare(`
|
||||
SELECT a.id, a.titel, a.verantwortlich_id FROM aufgaben a
|
||||
WHERE a.status <> 'erledigt' AND a.frist = ? AND a.verantwortlich_id IS NOT NULL`).all(morgen)) {
|
||||
WHERE a.status NOT IN ('erledigt', 'abgebrochen') AND a.frist = ? AND a.verantwortlich_id IS NOT NULL`).all(morgen)) {
|
||||
await senden(a.verantwortlich_id, "aufgabe_faellig", {
|
||||
titel: "Morgen fällig",
|
||||
text: a.titel,
|
||||
@@ -253,7 +253,7 @@ export async function laufen() {
|
||||
/* --- Aufgaben, die ueberfaellig sind ------------------------------ */
|
||||
for (const a of d.prepare(`
|
||||
SELECT a.id, a.titel, a.frist, a.verantwortlich_id FROM aufgaben a
|
||||
WHERE a.status <> 'erledigt' AND a.frist IS NOT NULL AND a.frist < ?
|
||||
WHERE a.status NOT IN ('erledigt', 'abgebrochen') AND a.frist IS NOT NULL AND a.frist < ?
|
||||
AND a.verantwortlich_id IS NOT NULL`).all(heute)) {
|
||||
await senden(a.verantwortlich_id, "aufgabe_ueberfaellig", {
|
||||
titel: "Überfällig",
|
||||
|
||||
@@ -123,15 +123,15 @@ reportRouter.get("/workspace/api/report", (req, res) => {
|
||||
erledigt_davor: erledigt(davorIso, abIso),
|
||||
angelegt: angelegt(abIso, jetztIso),
|
||||
angelegt_davor: angelegt(davorIso, abIso),
|
||||
offen: zahl(`SELECT COUNT(*) AS n FROM aufgaben a WHERE a.status <> 'erledigt'${nurA}`, wertA),
|
||||
offen: zahl(`SELECT COUNT(*) AS n FROM aufgaben a WHERE a.status NOT IN ('erledigt', 'abgebrochen')${nurA}`, wertA),
|
||||
ueberfaellig: zahl(
|
||||
`SELECT COUNT(*) AS n FROM aufgaben a
|
||||
WHERE a.status <> 'erledigt' AND a.frist IS NOT NULL AND a.frist < ?${nurA}`,
|
||||
WHERE a.status NOT IN ('erledigt', 'abgebrochen') AND a.frist IS NOT NULL AND a.frist < ?${nurA}`,
|
||||
[heute, ...wertA]),
|
||||
/* "Was blockiert?" aus dem Konzept: was liegt am laengsten offen? */
|
||||
aeltester: db().prepare(
|
||||
`SELECT a.titel, a.frist, a.erstellt FROM aufgaben a
|
||||
WHERE a.status <> 'erledigt'${nurA} ORDER BY a.erstellt LIMIT 3`).all(...wertA),
|
||||
WHERE a.status NOT IN ('erledigt', 'abgebrochen')${nurA} ORDER BY a.erstellt LIMIT 3`).all(...wertA),
|
||||
};
|
||||
|
||||
/* --- Bereiche -------------------------------------------------------- */
|
||||
|
||||
@@ -1104,6 +1104,12 @@
|
||||
{ schluessel: 'arbeit', name: 'In Arbeit' },
|
||||
{ schluessel: 'review', name: 'Review' },
|
||||
{ schluessel: 'erledigt', name: 'Erledigt' },
|
||||
/* ABGEBROCHEN als eigene Zahl (08.09.2026, screen12). Sie steht
|
||||
hinten bei "Erledigt", weil beides dasselbe bedeutet: vom Tisch.
|
||||
Vorher tauchte sie nirgends auf und schlug sich stattdessen
|
||||
unsichtbar auf "Überfällig" und "Heute fällig" nieder -- eine
|
||||
Aufgabe, die niemand mehr anfasst, mahnte weiter. */
|
||||
{ schluessel: 'abgebrochen', name: 'Abgebrochen' },
|
||||
];
|
||||
|
||||
async function zahlenLaden() {
|
||||
|
||||
Reference in New Issue
Block a user