Dateifassungen: die alte Fassung sieht man ihr an

Stufe 9 aus dem Plan: "Dateiversionen statt Ueberschreiben".

GEMESSEN, BEVOR ETWAS GEBAUT WURDE -- DER PLAN LAG DANEBEN

Ueberschrieben wurde nie: `name_datei` ist eindeutig und zufaellig,
jedes Hochladen legt eine neue Zeile an. Der wirkliche Mangel ist ein
anderer, und er ist gefaehrlicher als Ueberschreiben:

  Zwei Dateien gleichen Namens standen BEZIEHUNGSLOS nebeneinander. Die
  alte kann "freigegeben" sein, die neue "entwurf" -- und wer die Liste
  ansieht, laedt die freigegebene herunter. Also die falsche. Kein
  Fehler, keine Meldung, nur die alte Fassung in der Hand.

WAS JETZT PASSIERT

Beim Hochladen erkennt der Server die Vorgaengerin selbst: gleicher
Originalname, gleicher Creator-Bezug, und sie darf nicht schon ersetzt
sein. An der Datei steht danach "Fassung 2"; an der alten steht "nicht
mehr aktuell".

  AUTOMATISCH, NICHT GEFRAGT -- eine Abwaegung: Wer die Verknuepfung
  vergisst, hat zwei Dateien ohne Zusammenhang, und irgendwann laedt
  jemand die alte herunter. Wer sie faelschlich bekommt, SIEHT das
  sofort und loest sie mit einem Klick. Der stille Schaden ist groesser
  als der sichtbare.

  BEI ZWEIFEL WIRD NICHT GERATEN. Gibt es zwei unersetzte Dateien
  gleichen Namens, bleibt die neue eigenstaendig.

  LOESEN GEHT NUR AN DER AKTUELLEN FASSUNG. Wer eine ueberholte loest,
  macht daraus eine zweite aktuelle -- und hat das Problem zurueck.

  DIE NUMMER IST GERECHNET, NICHT GESPEICHERT. Eine Spalte "version"
  muesste beim Loeschen einer mittleren Fassung nachgezogen werden, und
  genau das vergisst man. Faellt die erste weg, zaehlt die zweite
  wieder als erste -- richtig, denn mehr weiss das System dann nicht.

  EIN RING IN DEN DATEN HAELT DIE SEITE NICHT AN. Kann ueber die Wege
  hier nicht entstehen, aber ein Fehler anderswo koennte ihn erzeugen,
  und ein Stillstand ist schlimmer als ein Fehler. Gemessen: 1 ms.

ZWEI SITZUNGEN IM SELBEN VERZEICHNIS

Der vorige Commit (d2210fd, aus einer anderen Sitzung) hat mit
`git add -A` meine damals noch unfertige Spalte `dateien.ersetzt_id`
mitgenommen -- sie steht dort unter einer Ueberschrift, die nichts
damit zu tun hat. Niemand hat etwas falsch gemacht; die Sitzungen
konnten voneinander nicht wissen. Aufgefallen ist es, weil der
Versionsstempel ploetzlich 347 statt 372 Verweise meldete und ich dem
Rueckgang nachgegangen bin.

PRUEFUNGEN: pruef-fassungen neu mit 37, davon 6 im Browser.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-15 12:58:26 +02:00
co-authored by Claude Opus 5
parent d2210fdd77
commit 478a2895b5
33 changed files with 787 additions and 347 deletions
+34
View File
@@ -259,6 +259,40 @@ function fassungenSetzen(liste) {
}
}
/* =====================================================================
DIE VERKNUEPFUNG WIEDER LOESEN (15.09.2026)
Der Server verknuepft von selbst, wenn Name und Creator gleich sind.
Meistens stimmt das; manchmal nicht -- zwei verschiedene Dateien
koennen denselben Namen tragen.
EINE AUTOMATIK OHNE AUSWEG IST EINE BEHAUPTUNG. Deshalb dieser Weg:
ein Klick, und die Datei steht wieder fuer sich. NUR die Verknuepfung
geht, nie eine Datei -- der Weg kann also nichts anrichten, was sich
nicht in einem zweiten Klick zuruecknehmen liesse.
===================================================================== */
dateienRouter.delete("/workspace/api/dateien/:id(\\d+)/fassung", (req, res) => {
try {
const id = Number(req.params.id);
const { wo, werte } = sichtbar(req.sicht || req.person);
const d = db().prepare(
`SELECT d.id, d.name_original, d.ersetzt_id ${VERBUND} WHERE ${wo} AND d.id = ?`)
.get(...werte, id);
if (!d) return res.status(404).json({ fehler: "nicht_gefunden" });
if (!d.ersetzt_id) return res.status(409).json({ fehler: "keine_fassung" });
db().prepare("UPDATE dateien SET ersetzt_id = NULL WHERE id = ?").run(id);
protokolliere("datei_fassung_geloest", {
personId: req.person.id, rolle: req.person.rolle, ip: echteIp(req),
detail: `#${id} ${d.name_original} war Fassung von #${d.ersetzt_id}`.slice(0, 120),
});
res.json({ ok: true });
} catch (fehler) {
console.error("[dateien] Fassung loesen:", fehler?.message);
res.status(503).json({ fehler: "nicht_verfuegbar" });
}
});
/* ---------- Liste ------------------------------------------------------- */
dateienRouter.get("/workspace/api/dateien", (req, res) => {