Die Agentur-Umstellung schreibt den Bauplan nicht mehr ab

Sie baute `eintraege` mit einer von Hand abgeschriebenen Spaltenliste
neu. 24 Spalten gingen hinein, 21 kamen heraus: einsatz, nur_leitung
und gesendet_am wurden vom Spalten-Nachtrag angelegt und unmittelbar
danach weggeworfen -- mit Inhalt, ohne Fehlermeldung, bei
unveraenderter Zeilenzahl.

DAS WAR DAS ZWEITE MAL. Am 07.09.2026 fehlten an derselben Stelle die
drei Event-Spalten; sie wurden nachgetragen, und daneben kam ein
Kommentar, der woertlich vor genau dieser Verlustart warnt. Seither
kamen drei neue Spalten dazu, und die Liste wurde still falsch. An
einer anderen Stelle im selben Modul steht sogar schon der Satz: "Eine
vierte Abschrift waere die vierte Gelegenheit dazu."

Jetzt uebernimmt checkListeErweitern -- dieselbe Funktion, die alle
spaeteren Bereiche umstellt. Sie holt den Bauplan aus sqlite_master
und die Spalten aus PRAGMA table_info: eine Liste, die nicht gepflegt
wird, kann nicht veralten. Sichern, Zeilen innerhalb der Transaktion
zaehlen, Indizes mitnehmen, Verweise pruefen -- alles, was der Block
auch tat. 90 Zeilen weniger.

NACHGEMESSEN, in dieser Reihenfolge:
- pruef-agentur: 31 Fehler + Absturz -> 62 Pruefungen, alle gruen.
- Die Umstellung meldet jetzt 24 Spalten statt 21.
- Der echte Fall ist durchgespielt: Auf einer Datenbank, die 'agentur'
  schon kennt, laeuft sie GAR NICHT mehr an. Neue Pruefung dazu, die
  die Sicherungsdateien zaehlt (genau eine, trotz mehrerer Neustarts)
  -- gemessen an der Spur, die ein Umbau hinterlaesst, nicht an der
  Absicht.
- Die Datenbank auf dem Server hat alle drei Spalten und kennt
  'agentur' bereits. Sie war nie in Gefahr; gefaehrlich war das
  Zurueckspielen einer Sicherung von vor dem 06.09.2026.

ZWEI ALTE PRUEFFEHLER LAGEN DAHINTER, beide bisher von einem Absturz
verdeckt:
- "der Wochenbericht kennt 6 Bereiche" -- eine feste Zahl, inzwischen
  sind es elf. Verglichen wird jetzt gegen die CHECK-Regel der
  Datenbank; damit stimmt sie auch beim zwoelften Bereich.
- Die Meldung wurde am Satzbau erkannt statt an der Aussage.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-11 14:43:14 +02:00
co-authored by Claude Opus 5
parent c98aa06554
commit b34586be91
2 changed files with 93 additions and 92 deletions
+61 -4
View File
@@ -26,7 +26,7 @@
schlimmere Ausgang.
===================================================================== */
import { mkdtempSync, rmSync, appendFileSync, writeFileSync } from "node:fs";
import { mkdtempSync, rmSync, appendFileSync, writeFileSync, readdirSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, dirname } from "node:path";
import { fileURLToPath } from "node:url";
@@ -259,7 +259,13 @@ let ausgabe = "";
ausgabe = aus();
}
ok(/Bereich 'agentur' freigeschaltet/.test(ausgabe),
/* NICHT AUF DEN WORTLAUT FESTNAGELN (11.09.2026). Hier stand
/Bereich 'agentur' freigeschaltet/ -- der Satz des alten, von Hand
abgeschriebenen Blocks. Seit die Umstellung ueber
checkListeErweitern laeuft, heisst es "'agentur' in
eintraege.bereich freigeschaltet". Gemeint ist beides Mal dasselbe;
geprueft wird deshalb die AUSSAGE, nicht der Satzbau. */
ok(/agentur.*freigeschaltet/.test(ausgabe),
"die Anwendung meldet die Umstellung"
+ (/agentur/.test(ausgabe) ? "" : ` — Ausgabe: ${ausgabe.slice(-300)}`));
@@ -585,8 +591,37 @@ melde("\n=== Ueberall, wo Bereiche vorkommen ===");
vorgekommen, ohne Fehler und ohne Luecke. */
const { daten } = await ruf("GET", "/workspace/api/report", keksDogi);
const b = daten?.bereiche || {};
ok(Object.keys(b).length === 6,
`der Wochenbericht kennt ${Object.keys(b).length} Bereiche: ${Object.keys(b).join(", ")}`);
/* ABGELEITET STATT GEZAEHLT (11.09.2026). Hier stand `=== 6`. Das
war richtig, als es sechs Bereiche gab; inzwischen sind es elf,
und die Zeile war seither still falsch -- versteckt hinter einem
Absturz weiter oben, der den Lauf vorher beendete. Dieselbe feste
Zahl, dieselbe Falle wie in der Umstellung, die diese Datei
aufgedeckt hat.
Verglichen wird jetzt gegen die Bereiche, die die DATENBANK
ueberhaupt zulaesst -- die CHECK-Regel ist die einzige Liste, an
der niemand vorbeikommt. Damit stimmt die Pruefung auch beim
zwoelften Bereich noch, ohne dass jemand sie anfasst. */
const erlaubt = (() => {
const dd = new DatabaseSync(DB, { readOnly: true });
const plan = dd.prepare(
"SELECT sql FROM sqlite_master WHERE type='table' AND name='eintraege'").get()?.sql || "";
dd.close();
/* Ohne regulaeren Ausdruck: Der Bauplan enthaelt die Regel
woertlich als "bereich IN (...)". Ein Muster mit Klammern und
Leerzeichenklassen waere hier nur eine weitere Stelle, an der
man sich vertun kann. */
const auf = plan.indexOf("bereich IN (");
if (auf < 0) return [];
const zu = plan.indexOf(")", auf);
if (zu < 0) return [];
return plan.slice(auf + "bereich IN (".length, zu)
.split(",").map((t) => t.trim().split("'").join(""));
})();
const fehlend = erlaubt.filter((n) => !(n in b));
ok(erlaubt.length > 0 && fehlend.length === 0,
`der Wochenbericht kennt alle ${erlaubt.length} Bereiche der Datenbank`
+ (fehlend.length ? ` -- es fehlen: ${fehlend.join(", ")}` : ""));
ok(b.agentur && b.agentur.neu >= ARTEN.length,
`und zaehlt ${b.agentur?.neu} neue Agentur-Eintraege`);
}
@@ -741,6 +776,28 @@ melde("\n=== Die Kachel ===");
await browser.close();
}
/* =======================================================================
6. UND SIE LAEUFT GENAU EINMAL (11.09.2026)
=======================================================================
Der Fall, der auf dem echten Server gilt: Dort kennt die CHECK-Regel
'agentur' laengst. Ein Neustart darf die Tabelle dann NICHT noch
einmal umbauen -- jeder Umbau ist ein Kopieren von Hand auf echten
Daten, und was man nicht tun muss, tut man auf einer Live-Datenbank
nicht.
GEMESSEN AN DEN SICHERUNGEN, nicht an der Absicht: Vor jedem Umbau
legt die Anwendung eine Datei ".vor-agentur-<stempel>" an. Diese
Datei ist der Beweis, dass umgebaut wurde. Waeren es zwei, haette
ein Neustart erneut angefasst -- und genau das soll hier auffallen.
Der Server ist zwischendurch mehrfach neu gestartet worden, der Fall
ist also wirklich durchgespielt und nicht nur behauptet. */
{
const spuren = readdirSync(ordner).filter((n) => n.includes(".vor-agentur-"));
ok(spuren.length === 1,
`die Agentur-Umstellung lief genau EINMAL, trotz mehrerer Neustarts `
+ `(${spuren.length} Sicherung(en))`);
}
await serverStoppen();
try { rmSync(ordner, { recursive: true, force: true }); } catch { /* egal */ }