Der vertrauliche Meldeweg vergisst jetzt -- und sagt, bis wann

Zwei Entscheidungen, die offenstanden. Beide getroffen, nachdem
gemessen war, was wirklich da ist.

1. WIE LANGE BLEIBEN ABGESCHLOSSENE FAELLE?  90 Tage.

Die Entscheidung war bereits getroffen: `AUFBEWAHRUNG_TAGE = 90` steht
seit dem 19.09. in hilfe-tabellen.js, mit Begruendung ("ein Fall kommt
manchmal wieder auf"). Nur hat sie NIEMAND durchgesetzt --
`hilfeAufraeumen()` gab es, und der einzige Aufrufer war ihre eigene
Pruefung. Der Kommentar darueber behauptete "Wird beim Start
aufgerufen (siehe index.js)"; das war nie wahr.

Jetzt steht die Regel in workspace-aufbewahrung.js, dem Loeschkonzept,
das sich selbst durchsetzt -- beim Start und danach taeglich. Die
zweite Fassung in workspace-hilfe.js ist WEG, nicht doppelt: Zwei
DELETEs auf dieselben Daten waeren morgen verschieden, und der
Unterschied fiele erst auf, wenn er zaehlt.

GEMESSEN VOR DEM EINSCHALTEN:
  In der echten Datenbank steht heute KEIN einziger Fall. Der erste
    Lauf loescht nichts, und der erste Fall kann fruehestens in drei
    Monaten 90 Tage alt werden. Jetzt einschalten ist frei -- spaeter
    waere es der riskante Moment gewesen.
  PRAGMA foreign_keys steht im Dienst auf 1, und hilfe_nachrichten
    traegt ON DELETE CASCADE. An einem echten Fall mit Nachricht
    nachgemessen: vorher 1/1, nachher 0/0. Ohne diese Messung waere
    der Fall verschwunden und der eigentliche Text liegengeblieben.

2. SOLL EIN GESCHLOSSENER FALL WIEDER ZU OEFFNEN SEIN?  Nein.

Im Kopf von workspace-hilfe.js steht: "EIN GESCHLOSSENER FALL IST
GESCHLOSSEN. Auch fuer die Leitung -- sonst ist 'zugemacht' eine
Meinung und keine Tatsache." Das ist eine gute Regel, und sie bleibt.

Nachgemessen, dass sie auch traegt: Ein Melder kann seinen
geschlossenen Fall weiter LESEN, und ein geschlossener Fall zaehlt
nicht gegen das Limit von drei offenen. Wer eine Wiederholung melden
will, kann das also jederzeit -- die Bauweise ist stimmig.

NUR WUSSTE DAS NIEMAND. Dort stand ein Satz: "Dieser Fall ist
abgeschlossen (Datum)." Jetzt stehen drei -- und sie beantworten die
drei Fragen, die man in dem Moment hat:
  Kann ich noch schreiben?   Nein, und er laesst sich nicht oeffnen.
  Bleibt das hier stehen?    Bis zum TT.MM.JJJJ, dann geloescht.
  Und wenn es wieder passiert? Neu melden, der alte zaehlt nicht mit.

Das Datum kommt vom Server (`lesbar_bis`), die Frist ebenso -- sie
steht nur an EINER Stelle. Und sie steht jetzt auch im Dialog BEIM
Schliessen: Wer eine Uhr startet, soll das vorher wissen, nicht
danach.

OHNE UHRZEIT, und das ist kein Schoenheitsgrund: Ein Fall, der am
20.09. um 14:04 (Sommerzeit) geschlossen wird, verfaellt 90 Tage
spaeter um 13:04 -- die Uhr wird dazwischen zurueckgestellt. Richtig
gerechnet, sieht aus wie ein Fehler. Wer eine Stunde sucht, die es
nicht gibt, hat Zeit verloren.

UND DIE URSACHE, DAMIT ES NICHT WIEDER PASSIERT:
hilfe_faelle kam am 19.09. dazu, das Loeschkonzept ist vom 15.09., und
nichts hat die beiden je verglichen. Neue Pruefung in
pruef-aufbewahrung: Jede Tabelle mit einer Spalte, die "hier ist etwas
zu Ende" sagt, MUSS im Konzept stehen.
  Kein "jede Tabelle muss drinstehen": 46 Tabellen, 41 mit
  Personenbezug -- das gaebe 38 Meldungen, von denen fast alle falsch
  waeren (sie sind ueber personen_geloescht gedeckt). Eine Pruefung,
  die 38-mal meldet, wo einmal richtig waere, wird abgeschaltet.
  Gesucht wird das schmale Merkmal: GENAU ZWEI Tabellen im Haus tragen
  so eine Spalte. Beide jetzt im Konzept -- hilfe_faelle mit Frist,
  aufgaben ausdruecklich OHNE (erledigte Aufgaben sind
  Arbeitsdokumentation, keine Meldung ueber einen Menschen).

pruef-hilfe 84/0 (war 59) -- darunter zehn neue am Bildschirm:
"drei Saetze statt einem", "sie stehen untereinander, nicht
nebeneinander" (ein <p> in einem <p> waere ungueltig, der Container
ist jetzt ein <div>), "und WANN, mit Datum".
pruef-aufbewahrung 45/0 (war 41), mit Gegenprobe.
This commit is contained in:
2026-09-20 14:10:38 +02:00
parent 9e9ed67c4a
commit 285038f400
43 changed files with 1039 additions and 564 deletions
+46 -41
View File
@@ -19,7 +19,7 @@
import express from "express";
import { db, protokolliere } from "./workspace.js";
import { FALL_STAND } from "./hilfe-tabellen.js";
import { FALL_STAND, AUFBEWAHRUNG_TAGE } from "./hilfe-tabellen.js";
import { benachrichtige } from "./workspace-push.js";
export const hilfeRouter = express.Router();
@@ -109,6 +109,10 @@ hilfeRouter.get("/workspace/api/hilfe", (req, res) => {
darf, ohne es durch einen Fehlschlag herauszufinden. */
offen_eigene: leitung ? null : zeilen.filter((z) => z.stand !== FALL_STAND.zu).length,
offen_max: OFFEN_MAX,
/* Damit der Abschluss-Dialog die Frist nennen kann, ohne sie
ein zweites Mal im Browser stehen zu haben. Eine Zahl, die an
zwei Stellen steht, ist morgen an einer davon falsch. */
aufbewahrung_tage: AUFBEWAHRUNG_TAGE,
});
} catch (fehler) {
console.error("[hilfe] Liste:", fehler?.message);
@@ -146,6 +150,25 @@ hilfeRouter.get("/workspace/api/hilfe/:id(\\d+)", (req, res) => {
id: fall.id, betreff: fall.betreff, stand: fall.stand,
erstellt: fall.erstellt, geaendert: fall.geaendert,
geschlossen_am: fall.geschlossen_am,
/* BIS WANN ER NOCH DA IST (20.09.2026).
----------------------------------------------------------
Ein abgeschlossener Fall wird nach 90 Tagen geloescht --
das steht im Loeschkonzept und laeuft taeglich. Bis heute
stand auf der Seite nur „Dieser Fall ist abgeschlossen".
Niemand konnte wissen, dass er verschwindet, und erst recht
nicht, wann.
Das ist keine Kleinigkeit: Wer eine Meldung gemacht hat,
hat ein Recht darauf zu erfahren, wie lange das gespeichert
bleibt (Art. 13 Abs. 2 lit. a DSGVO). Und praktisch braucht
er es auch -- wer nachlesen will, was vereinbart wurde,
soll nicht erst merken, dass es weg ist.
GERECHNET WIRD HIER, nicht im Browser: Sonst stuende
dieselbe Frist an zwei Stellen, und eine davon altert. */
lesbar_bis: fall.geschlossen_am
? new Date(Date.parse(fall.geschlossen_am) + AUFBEWAHRUNG_TAGE * 86400000).toISOString()
: null,
...(leitung ? { melder: melder?.name || "(gelöscht)" } : {}),
},
nachrichten: nachrichten.map((n) => ({
@@ -318,44 +341,26 @@ async function schlussBenachrichtigen(fall) {
});
}
/* ---------- Aufräumen --------------------------------------------------- */
/* ---------- Aufräumen: steht jetzt im Löschkonzept --------------------
Hier stand `hilfeAufraeumen(tage)` -- mit einem Kommentar darüber,
sie werde „beim Start aufgerufen (siehe index.js)". Das war nie
wahr: Gesucht im ganzen Verzeichnis war der einzige Aufrufer ihre
eigene Prüfung. Die Prüfung war grün und bewies nichts über den
Betrieb.
Am 20.09.2026 ist die Regel dorthin gewandert, wo sie sich selbst
durchsetzt: `workspace-aufbewahrung.js`, Eintrag
`hilfe_geschlossen`. Diese Datei ist beides -- die Übersicht, was
wie lange aufgehoben wird, UND das Programm, das es tut. Sie läuft
beim Start und danach täglich.
ZWEI STELLEN WÄREN SCHLIMMER ALS KEINE. Eine zweite Fassung
desselben DELETE hier wäre morgen anders als die dort, und der
Unterschied fiele erst auf, wenn er zählt -- beim Löschen der
empfindlichsten Texte des Hauses. Deshalb ist sie weg, nicht
doppelt.
Die Frist selbst (`AUFBEWAHRUNG_TAGE = 90`) steht unverändert in
`hilfe-tabellen.js`, samt Begründung. */
/** Löscht geschlossene Fälle, die älter sind als die Aufbewahrung.
*
* ACHTUNG, NACHGEMESSEN AM 19.09.2026: Diese Funktion wird im Betrieb
* NICHT aufgerufen. Hier stand vorher "Wird beim Start aufgerufen
* (siehe index.js)" -- das war nie wahr. Gesucht im ganzen Verzeichnis:
* der einzige Aufrufer ist `pruef-hilfe.mjs`, also ihre eigene Prüfung.
*
* Die Prüfung ist deshalb grün und beweist nichts über den Betrieb:
* Sie zeigt, dass die Funktion richtig löscht -- nicht, dass jemand
* sie aufruft. Genau das Muster, vor dem die Hausregeln warnen.
*
* FOLGE: Geschlossene Fälle bleiben derzeit unbegrenzt stehen. Das ist
* die sichere Richtung (nichts geht verloren), aber nicht die
* gewollte -- ein vertraulicher Fall über einen Menschen soll nicht
* ewig gespeichert bleiben.
*
* Das EINZUSCHALTEN löscht echte Daten und ist deshalb keine
* Reparatur, die nebenbei passiert, sondern Filipes Entscheidung:
* Wie lange sollen abgeschlossene Fälle stehen bleiben? Die Prüfung
* rechnet mit 90 Tagen, das ist aber nur ihre Annahme.
*
* Läuft still: Wenn es nichts zu tun gibt, sagt es auch nichts --
* eine Meldung, die jeden Start begleitet, wird nach einer Woche
* nicht mehr gelesen. */
export function hilfeAufraeumen(tage) {
try {
const grenze = new Date(Date.now() - tage * 86400000).toISOString();
const weg = db().prepare(
"DELETE FROM hilfe_faelle WHERE stand = ? AND geschlossen_am IS NOT NULL"
+ " AND geschlossen_am < ?").run(FALL_STAND.zu, grenze);
if (weg.changes > 0) {
console.log(`[hilfe] ${weg.changes} abgeschlossene Fälle nach ${tage} Tagen gelöscht.`);
}
return weg.changes;
} catch (fehler) {
console.error("[hilfe] aufraeumen:", fehler?.message);
return 0;
}
}