Nichts verschwindet mehr ohne eine Nachfrage, die sagt was passiert
Filipe: "Es darf vor allem keine Stellen geben, an denen ein Benutzer
etwas falsch machen kann, nur weil die Seite es nicht verstaendlich
genug erklaert."
Gemessen: 30 Stellen in 16 Dateien benutzten confirm() oder prompt().
Das Haus hatte die richtige Bauweise laengst -- einen <dialog>, in
aufgaben.html sogar ausfuehrlich begruendet -- aber sie stand IN EINER
SEITE. Wer anderswo etwas loeschen liess, hatte sie nicht.
confirm('Wirklich loeschen?') stellt die falsche Frage: Es fragt, ob
man sicher ist, und nennt nicht, WAS passiert, was BLEIBT und ob es
ZURUECK geht. Jetzt beantwortet jeder der 41 Dialoge alle drei.
Neu: workspace/assets/js/nachfrage.js -- window.frageNach() mit
Pflichtgrund, Zahlenfeld, einzeiliger Eingabe und Abtippsicherung.
Drei Ausgaenge: <dialog> / confirm()-Notnagel fuer Safari vor 15.4 /
Abbruch (Esc, Klick daneben, "Doch nicht" -- immer false).
DREIMAL DERSELBE FALLSTRICK, dreimal nachgemessen statt vermutet:
.dialog stand in aufgaben.css und leistung.css -> auf dateien.html
waere der Dialog ein weisser Systemkasten gewesen. 14 Regeln
klammergenau nach module.css verschoben (Klammern gezaehlt, nicht
per Muster geschnitten -- heute frueh hat ein nicht-gieriges
Muster schon einmal CSS zerrissen).
Das Formular trug .neu neu--blank -- und .neu gibt seine Abstaende
nur in aufgaben.css. Gemessen: padding 0px, und die Felder
verloren ihre height:44px. Jetzt steht alles unter
.nachfrage__form in module.css; der Dialog borgt nichts mehr.
Die erste Fassung der Pruefung zaehlte nachfrage.js SELBST als
Nutzer -- damit war jede Seite trivialerweise "Nutzer" und die
Pruefung gruen ohne Inhalt. Jetzt ausdruecklich ausgenommen.
ZWEI FUNDE NEBENBEI:
hilfeAufraeumen() wird im Betrieb NIE aufgerufen. Der Kommentar
behauptete "wird beim Start aufgerufen (siehe index.js)" -- das
war nie wahr; einziger Aufrufer ist die eigene Pruefung. Folge:
geschlossene vertrauliche Faelle bleiben unbegrenzt stehen. NICHT
eingeschaltet (das loescht echte Daten und ist Filipes
Entscheidung), sondern der Kommentar richtiggestellt.
Einen Hilfe-Fall zu schliessen ist endgueltig -- es gibt keine
Route, die ihn wieder oeffnet. Vorher stand darueber nur die
Frage nach einem Schlusswort. Jetzt sagt der Dialog es.
pruef-struktur hat meine eigene Pruefung von heute Nachmittag
erwischt: Sie bildete ihr Datum aus UTC. Beim Beheben erst
heuteLokal(datum) genommen -- die Funktion nimmt gar kein Argument
und haette still "heute" statt "+3 Tage" geliefert. Jetzt tagLokal(3),
nachgerechnet: Abstand 3 Tage.
Am Bildschirm angesehen (Rechner 1280, Handy 390): passt rein, Esc
ergibt false, Fokus liegt auf dem harmlosen Knopf, Knoepfe 44px auf
Touch. Der Platzhalter im Abtippfeld zeigte den erwarteten Namen --
das sah aus wie ein schon ausgefuelltes Feld, entfernt.
Neu: server/pruef-nachfrage.mjs -- 17/0, mit sechs Gegenproben und
beiden Richtungen (wer fragt, laedt die Datei; wer nie fragt, laedt
sie nicht -- sonst truege die Anmeldewand 4,8 KB fuer nichts).
pruef-meldungen 8/0, pruef-css-klassen gruen, pruef-struktur gruen,
pruef-leistung gruen.
This commit is contained in:
@@ -97,6 +97,7 @@
|
||||
Dauer: rund drei Minuten (4 Rollen × 2 Breiten × ~20 Seiten).
|
||||
===================================================================== */
|
||||
|
||||
import { tagLokal } from "./helfer-zeit.mjs";
|
||||
import { mkdtempSync, rmSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join, dirname } from "node:path";
|
||||
@@ -182,7 +183,11 @@ for (const [titel, wer] of [
|
||||
+ " erstellt, frist) VALUES (?,?,?,?,?,?,?)",
|
||||
titel, "Beschreibung mit genug Text, dass die Karte wirklich Höhe bekommt "
|
||||
+ "und ein Umbruch entstehen kann.", "offen", wer, idDogi, jetzt,
|
||||
new Date(Date.now() + 3 * 86400000).toISOString().slice(0, 10));
|
||||
/* Ortszeit, nicht UTC: Zwischen 00:00 und 02:00 deutscher Zeit
|
||||
liegt UTC noch im Vortag -- die Frist waere dann um einen Tag
|
||||
verschoben, und die Pruefung schluege nachts falsch an.
|
||||
Gefunden hat das `pruef-struktur`, nicht ich. */
|
||||
tagLokal(3));
|
||||
}
|
||||
|
||||
for (const [bereich, titel] of [
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/* =====================================================================
|
||||
pruef-nachfrage.mjs — Nichts verschwindet ohne Nachfrage.
|
||||
|
||||
Filipe, 19.09.2026: „Es darf vor allem keine Stellen geben, an denen
|
||||
ein Benutzer etwas falsch machen kann, nur weil die Seite es nicht
|
||||
verständlich genug erklärt." Und: „Fehler möglichst verhindern,
|
||||
bevor sie entstehen."
|
||||
|
||||
---------------------------------------------------------------------
|
||||
WAS DAS PROBLEM WAR
|
||||
|
||||
Das Haus hatte die richtige Bauweise — einen <dialog> statt
|
||||
`confirm()` — und begründete sie in `aufgaben.html` sogar ausführlich.
|
||||
Nur stand sie IN EINER SEITE. Gemessen am 19.09.2026: **30 Stellen**
|
||||
in 16 Dateien griffen weiterhin zu `confirm()` oder `prompt()`.
|
||||
|
||||
Der Unterschied ist nicht Geschmack. `confirm('Wirklich löschen?')`
|
||||
stellt die falsche Frage: Es fragt, ob man sicher ist, und nennt
|
||||
nicht, WAS passiert, was BLEIBT und ob es ZURÜCK geht. Genau das
|
||||
sind die drei Dinge, die man vor einem Löschen wissen will.
|
||||
|
||||
---------------------------------------------------------------------
|
||||
VIER DINGE WERDEN GEPRÜFT
|
||||
|
||||
1. KEIN NATIVER DIALOG mehr in einer Seiten-Datei. Ausgenommen ist
|
||||
allein der Notnagel in `nachfrage.js` selbst — für Browser ohne
|
||||
<dialog>. (Ein Verbot ohne diese Ausnahme wäre falsch: Ein
|
||||
iPhone vor Safari 15.4 bekäme sonst gar nichts angezeigt.)
|
||||
|
||||
2. ANGESCHLOSSEN — jede Seite, deren Skripte `frageNach` benutzen,
|
||||
lädt auch `nachfrage.js`. Ohne die Datei wäre `frageNach` nicht
|
||||
definiert, und aus einer Rückfrage würde ein Absturz: Der Knopf
|
||||
täte stillschweigend nichts.
|
||||
|
||||
ACHTUNG, hier steckte beim Bauen schon eine Falle: Die erste
|
||||
Fassung dieser Prüfung zählte `nachfrage.js` SELBST als Nutzer
|
||||
(die Datei enthält das Wort natürlich) — damit war jede Seite
|
||||
„Nutzer", die Prüfung immer grün und sie bewies nichts. Deshalb
|
||||
ist die Datei unten ausdrücklich ausgenommen.
|
||||
|
||||
3. GESTALTET — `.dialog` wird in einer Datei gestaltet, die JEDE
|
||||
Seite lädt. Vorher stand sie in `aufgaben.css`; auf `dateien.html`
|
||||
wäre der Dialog ein weißer Systemkasten auf dunkler Seite
|
||||
gewesen. Das ist keine Schönheitsfrage: Ein Kasten, der aussieht
|
||||
wie eine Browser-Warnung, wird weggeklickt statt gelesen.
|
||||
|
||||
4. VOLLSTÄNDIG — jeder Aufruf hat einen `titel` und sagt, was
|
||||
passiert (`was`). Ein Dialog ohne diese Angabe ist ein
|
||||
`confirm()` mit mehr Zeilen Code.
|
||||
|
||||
Dazu GEGENPROBEN: Jede Prüfung muss beweisen, dass sie auch
|
||||
„nicht in Ordnung" sagen kann.
|
||||
|
||||
AUFRUF: node server/pruef-nachfrage.mjs
|
||||
Läuft in unter zwei Sekunden, ohne Server.
|
||||
===================================================================== */
|
||||
|
||||
import { readFileSync, readdirSync } from "node:fs";
|
||||
import { join, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const HIER = dirname(fileURLToPath(import.meta.url));
|
||||
const WURZEL = join(HIER, "..");
|
||||
const SEITEN_ORDNER = join(WURZEL, "workspace");
|
||||
const JS_ORDNER = join(SEITEN_ORDNER, "assets", "js");
|
||||
const CSS_ORDNER = join(SEITEN_ORDNER, "assets", "css");
|
||||
|
||||
/* Die eine Datei, die `confirm`/`prompt` benutzen DARF -- sie ist der
|
||||
Notnagel fuer Browser ohne <dialog>. */
|
||||
const DER_NOTNAGEL = "nachfrage.js";
|
||||
|
||||
let ok = 0, fehl = 0;
|
||||
const pruef = (name, bedingung, zusatz = "") => {
|
||||
if (bedingung) { ok++; console.log(` OK ${name}`); }
|
||||
else { fehl++; console.log(` FEHL ${name}${zusatz ? "\n " + zusatz : ""}`); }
|
||||
};
|
||||
|
||||
const lies = (p) => readFileSync(p, "utf8");
|
||||
const seiten = readdirSync(SEITEN_ORDNER).filter((f) => f.endsWith(".html"));
|
||||
const skripte = readdirSync(JS_ORDNER).filter((f) => f.endsWith(".js"));
|
||||
|
||||
console.log("\n=== Nachfragen: kein nativer Dialog, und keiner ohne Erklärung ===\n");
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
1. KEIN NATIVER DIALOG
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
/** Entfernt Kommentare, bevor gesucht wird. Ohne das zaehlt jeder
|
||||
* Kommentar, der `confirm()` ERWAEHNT, als Fund -- und davon gibt es
|
||||
* in diesem Haus absichtlich mehrere (die Begruendungen). */
|
||||
function ohneKommentare(js) {
|
||||
return js.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
|
||||
}
|
||||
|
||||
const nativ = [];
|
||||
for (const f of skripte) {
|
||||
if (f === DER_NOTNAGEL) continue;
|
||||
const code = ohneKommentare(lies(join(JS_ORDNER, f)));
|
||||
for (const m of code.matchAll(/(?:^|[^.\w])(confirm|prompt)\s*\(/g)) {
|
||||
const zeile = code.slice(0, m.index).split("\n").length;
|
||||
nativ.push(`${f}:${zeile} → ${m[1]}()`);
|
||||
}
|
||||
}
|
||||
pruef("keine Seite benutzt noch confirm() oder prompt()", nativ.length === 0,
|
||||
nativ.slice(0, 8).join("\n "));
|
||||
|
||||
/* Und der Notnagel ist da -- sonst haetten Browser ohne <dialog> gar
|
||||
nichts. Die ZAHL gehoert in die Bedingung, nicht nur in den Text. */
|
||||
const notnagel = lies(join(JS_ORDNER, DER_NOTNAGEL));
|
||||
pruef("der Notnagel für alte Browser ist vorhanden",
|
||||
/HTMLDialogElement/.test(notnagel) && /window\.confirm\(/.test(notnagel));
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
2. ANGESCHLOSSEN
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
/** Welche Skripte rufen frageNach auf? OHNE die Datei, die es
|
||||
* DEFINIERT -- sonst ist die Antwort immer „alle". */
|
||||
const nutzer = new Set();
|
||||
for (const f of skripte) {
|
||||
if (f === DER_NOTNAGEL) continue;
|
||||
if (/\bfrageNach\s*\(/.test(ohneKommentare(lies(join(JS_ORDNER, f))))) nutzer.add(f);
|
||||
}
|
||||
pruef("es gibt überhaupt Seiten, die nachfragen", nutzer.size > 0,
|
||||
`gefunden: ${nutzer.size}`);
|
||||
|
||||
const ohneDatei = [], totesGewicht = [], fragendeSeiten = [];
|
||||
let mitNutzung = 0;
|
||||
for (const s of seiten) {
|
||||
const html = lies(join(SEITEN_ORDNER, s));
|
||||
const geladen = [...html.matchAll(/<script src="assets\/js\/([a-z0-9-]+\.js)/g)]
|
||||
.map((m) => m[1]);
|
||||
const kannFragen = geladen.some((g) => nutzer.has(g));
|
||||
const hatDatei = html.includes("assets/js/nachfrage.js");
|
||||
if (kannFragen) { mitNutzung++; fragendeSeiten.push(s); if (!hatDatei) ohneDatei.push(s); }
|
||||
else if (hatDatei) totesGewicht.push(s);
|
||||
}
|
||||
pruef("jede Seite, die nachfragt, lädt auch nachfrage.js",
|
||||
mitNutzung > 0 && ohneDatei.length === 0,
|
||||
`${mitNutzung} Seiten nutzen es, ohne Datei: ${ohneDatei.join(", ") || "keine"}`);
|
||||
|
||||
/* UND DIE GEGENRICHTUNG. Ohne sie waere „ueberall einbinden" die
|
||||
bequeme Antwort -- und die Anmeldewand, die jeder Besucher als
|
||||
erste laedt, truege 4,8 KB fuer einen Dialog, den sie nie zeigt.
|
||||
Zwei Richtungen, eine Regel: Die Datei liegt genau dort, wo sie
|
||||
gebraucht wird. */
|
||||
pruef("und keine Seite lädt sie, ohne je nachzufragen",
|
||||
totesGewicht.length === 0,
|
||||
`unnötig geladen auf: ${totesGewicht.join(", ")}`);
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
3. GESTALTET, UND ZWAR ÜBERALL
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
/** In welchen CSS-Dateien wird `.dialog` gestaltet? */
|
||||
const dialogCss = readdirSync(CSS_ORDNER).filter((f) => f.endsWith(".css"))
|
||||
.filter((f) => /^\.dialog[\s,{:]/m.test(lies(join(CSS_ORDNER, f))));
|
||||
|
||||
/** Und welche davon laedt jede Seite, DIE NACHFRAGEN KANN? Abgeleitet,
|
||||
* nicht behauptet -- eine Liste „module.css laedt ueberall" waere genau
|
||||
* die abgeschriebene Liste, vor der die Hausregeln warnen.
|
||||
*
|
||||
* Gemessen wird gegen die fragenden Seiten, nicht gegen alle: Die zwei
|
||||
* Anmeldewaende zeigen nie einen Dialog. Von ihnen die Dialog-
|
||||
* Gestaltung zu verlangen hiesse, 12 KB auf die Seite zu legen, die
|
||||
* jeder Besucher als erste laedt -- fuer nichts. */
|
||||
const ueberall = new Set(dialogCss);
|
||||
for (const s of fragendeSeiten) {
|
||||
const html = lies(join(SEITEN_ORDNER, s));
|
||||
const css = new Set([...html.matchAll(/href="assets\/css\/([a-z0-9-]+\.css)/g)]
|
||||
.map((m) => m[1]));
|
||||
for (const d of [...ueberall]) if (!css.has(d)) ueberall.delete(d);
|
||||
}
|
||||
pruef(".dialog wird dort gestaltet, wo jede fragende Seite es lädt",
|
||||
ueberall.size > 0 && fragendeSeiten.length > 0,
|
||||
`.dialog steht in: ${dialogCss.join(", ")} — von allen `
|
||||
+ `${fragendeSeiten.length} fragenden Seiten geladen: `
|
||||
+ `${[...ueberall].join(", ") || "KEINE"}`);
|
||||
|
||||
/* Die zwei eigenen Bauteile des Nachfrage-Dialogs gehoeren in dieselbe
|
||||
Datei -- sonst waere der wichtigste Satz ("nicht rueckgaengig")
|
||||
ungestaltet. */
|
||||
const gemeinsam = [...ueberall][0];
|
||||
const gCss = gemeinsam ? lies(join(CSS_ORDNER, gemeinsam)) : "";
|
||||
pruef("auch die Warnzeile und die Fehlerzeile sind dort gestaltet",
|
||||
/\.nachfrage__endgueltig/.test(gCss) && /\.nachfrage__fehler/.test(gCss));
|
||||
|
||||
/* Und sie traegt ihre Aussage nicht nur ueber Farbe. */
|
||||
pruef("die Warnzeile hat ein Zeichen, nicht nur eine Farbe",
|
||||
/\.nachfrage__endgueltig::before\s*{[^}]*content/.test(gCss),
|
||||
"Farbe allein trägt keine Aussage — Rot-Grün-Schwäche, Kontrastmodus");
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
4. VOLLSTÄNDIG: jeder Aufruf sagt, was passiert
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
/** Schneidet den Objektliteral-Teil eines frageNach-Aufrufs heraus,
|
||||
* klammergenau. Ein Muster „bis zur naechsten }" wuerde bei jedem
|
||||
* verschachtelten Ausdruck danebengreifen. */
|
||||
function aufrufe(js) {
|
||||
const out = [];
|
||||
for (const m of js.matchAll(/frageNach\s*\(\s*{/g)) {
|
||||
let i = m.index + m[0].length - 1, tiefe = 0, j = i;
|
||||
for (; j < js.length; j++) {
|
||||
if (js[j] === "{") tiefe++;
|
||||
else if (js[j] === "}") { tiefe--; if (tiefe === 0) { j++; break; } }
|
||||
}
|
||||
out.push(js.slice(i, j));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
let gezaehlt = 0;
|
||||
const ohneTitel = [], ohneWas = [];
|
||||
for (const f of skripte) {
|
||||
if (f === DER_NOTNAGEL) continue;
|
||||
const code = ohneKommentare(lies(join(JS_ORDNER, f)));
|
||||
for (const a of aufrufe(code)) {
|
||||
gezaehlt++;
|
||||
if (!/\btitel\s*:/.test(a)) ohneTitel.push(f);
|
||||
if (!/\bwas\s*:/.test(a)) ohneWas.push(f);
|
||||
}
|
||||
}
|
||||
/* DIE ZAHL GEHOERT IN DIE BEDINGUNG: Bei null Aufrufen waere
|
||||
„alle haben einen Titel" trivialerweise wahr. */
|
||||
pruef("jeder Aufruf hat einen Titel", gezaehlt > 0 && ohneTitel.length === 0,
|
||||
`${gezaehlt} Aufrufe geprüft, ohne Titel: ${ohneTitel.join(", ") || "keiner"}`);
|
||||
pruef("jeder Aufruf sagt, WAS passiert", gezaehlt > 0 && ohneWas.length === 0,
|
||||
`ohne „was": ${ohneWas.join(", ") || "keiner"}`);
|
||||
|
||||
/* Und die gefaehrlichste Handlung im Haus -- eine Person loeschen --
|
||||
verlangt das Abtippen des Namens. Das ist keine Schikane: Der
|
||||
Loeschknopf sitzt neben dem Sperrknopf. */
|
||||
pruef("eine Person löschen verlangt den Namen abgetippt",
|
||||
/tippen:\s*v\.person\.name/.test(lies(join(JS_ORDNER, "personen.js"))));
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
DIE GEGENPROBEN — jede muss anschlagen
|
||||
------------------------------------------------------------------ */
|
||||
console.log("\n --- Gegenproben (jede MUSS anschlagen) ---");
|
||||
|
||||
pruef("Gegenprobe: ein erfundenes confirm() würde gefunden",
|
||||
/(?:^|[^.\w])(confirm|prompt)\s*\(/.test(
|
||||
ohneKommentare("function x(){ if (!confirm('weg?')) return; }")));
|
||||
|
||||
pruef("Gegenprobe: ein confirm() im KOMMENTAR wird NICHT gemeldet",
|
||||
!/(?:^|[^.\w])(confirm|prompt)\s*\(/.test(
|
||||
ohneKommentare("/* frueher stand hier confirm('weg?') */")));
|
||||
|
||||
pruef("Gegenprobe: nachfrage.js selbst zählt nicht als Nutzer",
|
||||
!nutzer.has(DER_NOTNAGEL),
|
||||
'sonst wäre jede Seite trivialerweise Nutzer und die Prüfung grün ohne Inhalt');
|
||||
|
||||
pruef("Gegenprobe: die Gestaltung-Prüfung kann auch NEIN sagen",
|
||||
(() => {
|
||||
/* Eine erfundene Seite, die nachfragt, aber die Datei nicht laedt:
|
||||
Die Schnittmenge muss dadurch leer werden. */
|
||||
const probe = new Set(dialogCss);
|
||||
for (const d of [...probe]) if (!new Set(["gibt-es-nicht.css"]).has(d)) probe.delete(d);
|
||||
return probe.size === 0;
|
||||
})());
|
||||
|
||||
pruef("Gegenprobe: ein Aufruf ohne Titel würde auffallen",
|
||||
aufrufe("frageNach({ was: 'x' })").length === 1
|
||||
&& !/\btitel\s*:/.test(aufrufe("frageNach({ was: 'x' })")[0]));
|
||||
|
||||
pruef("Gegenprobe: der Klammerzähler findet das Ende auch bei Verschachtelung",
|
||||
aufrufe("frageNach({ titel: f({a:1}), was: 'x' }) ; danach")[0]
|
||||
=== "{ titel: f({a:1}), was: 'x' }");
|
||||
|
||||
console.log(`\n ${ok} bestanden, ${fehl} fehlgeschlagen`);
|
||||
console.log(` (${gezaehlt} Rückfragen in ${nutzer.size} Dateien, `
|
||||
+ `${mitNutzung} Seiten)\n`);
|
||||
process.exit(fehl ? 1 : 0);
|
||||
@@ -322,9 +322,28 @@ async function schlussBenachrichtigen(fall) {
|
||||
|
||||
/** Löscht geschlossene Fälle, die älter sind als die Aufbewahrung.
|
||||
*
|
||||
* Wird beim Start aufgerufen (siehe index.js). 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. */
|
||||
* 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();
|
||||
|
||||
Reference in New Issue
Block a user