Der Absturz auf dem Server bestand nach dem ersten Fix fort:
node::RemoveEnvironmentCleanupHook … Assertion failed: (env) != nullptr
Statement::~Statement() … better_sqlite3.node
Abgebrochen
DER ERSTE VERSUCH GING AN DER URSACHE VORBEI
Ich hatte db.close() entfernt -- naheliegend, weil der Aufrufverlauf
auf einen Statement-Destruktor zeigte. Es half nicht. Die Ursache liegt
eine Ebene tiefer: process.exit() beendet Node SOFORT, waehrend
better-sqlite3 noch offene Statements haelt. Deren Aufraeumhaken laeuft
dann ins Leere.
process.exitCode setzt nur den Rueckgabewert; Node beendet sich danach
von selbst, sobald nichts mehr aussteht -- und raeumt dabei in der
richtigen Reihenfolge auf.
WARUM DAS MEHR ALS EIN SCHOENHEITSFEHLER WAR
Der Absturz kam NACH allen Pruefungen und VOR der Zusammenfassung. Der
Test meldete einen Fehler, obwohl inhaltlich alles bestanden war. In
einer mit && verketteten Befehlsfolge blieb deshalb der anschliessende
Dienst-Neustart aus, und die neuen Endpunkte antworteten weiter mit
404. Gesucht habe ich bei den Endpunkten, beim Deploy, an der
Zugangswand -- die Ursache lag beim Beenden eines Testprozesses.
BEMERKENSWERT
Fuenf Tests im Projekt benutzten process.exitCode bereits. Das Muster
war also etabliert; meine neuen Dateien wichen davon ab, ohne dass es
jemandem auffiel. Sechs Tests sind jetzt angeglichen, alle geprueft:
Rueckgabewert 0, Zusammenfassung vollstaendig.
test-push-kette 30, test-altabbruch 16, test-webdesign-anfragen 37,
test-webdesign-portal 49, test-webdesign-paypal 28,
test-personendaten 15
Co-Authored-By: Claude Opus 5 <[email protected]>
Auf dem Server brach test-personendaten.mjs ab:
node::RemoveEnvironmentCleanupHook … Assertion failed: (env) != nullptr
Statement::~Statement() … better_sqlite3.node
Abgebrochen
better-sqlite3 raeumt seine Statements ueber einen Aufraeumhaken ab.
Wird die Verbindung unmittelbar vor dem Prozessende geschlossen, laeuft
dieser Haken ins Leere.
DIE FOLGE WAR SCHLIMMER ALS DER ABSTURZ
Der Absturz kam NACH allen Pruefungen, aber VOR der Zusammenfassung.
Der Test lieferte also einen Fehlercode, obwohl inhaltlich alles
bestanden war. In der mit && verketteten Befehlsfolge blieb deshalb der
anschliessende Dienst-Neustart aus -- und die neuen Endpunkte
antworteten weiter mit 404.
Man sucht dann den Fehler bei den Endpunkten, beim Deploy, an der
Zugangswand. Die Ursache lag beim Aufraeumen einer Testdatenbank.
Node schliesst die Verbindung beim Beenden ohnehin. Zusaetzlich faengt
das Loeschen der Testdateien jetzt Fehler ab: Ohne db.close() haelt der
Prozess sie noch offen, unter Windows scheitert das Loeschen dann mit
EBUSY -- und "force" hilft dagegen nicht, es unterdrueckt nur "Datei
nicht gefunden". Ein Test, der an seinem eigenen Aufraeumen scheitert,
meldet einen Fehler, den es fachlich nicht gibt.
Beide betroffenen Tests geprueft: Rueckgabewert 0, Zusammenfassung
vollstaendig.
Co-Authored-By: Claude Opus 5 <[email protected]>
Schreibt jemand "Welche Daten haben Sie ueber mich?" oder "Bitte
loeschen Sie meine Daten", laeuft eine Frist von einem Monat (Art. 12
Abs. 3 DSGVO). Bisher haette man dafuer von Hand durch ein Dutzend
Tabellen suchen muessen -- und uebersieht man eine, ist die Auskunft
unvollstaendig, ohne dass man es ihr ansieht.
⚠️ LOESCHEN IST NICHT EINFACH LOESCHEN
Der naheliegende Weg waere ein "Alles loeschen". Das waere bequem und
doppelt falsch: Rechnungen und Buchungsbelege unterliegen einer
gesetzlichen Aufbewahrungspflicht -- § 147 Abs. 3 AO nennt acht Jahre
fuer Buchungsbelege, zehn fuer Handelsbuecher, gerechnet ab dem Ende
des Kalenderjahres (Abs. 4). Wer sie auf Zuruf loescht, verstoesst
gegen Steuerrecht, um Datenschutzrecht zu erfuellen.
Die DSGVO nimmt diesen Fall selbst aus (Art. 17 Abs. 3 lit. b). Fuer
das, was bleiben muss, sieht sie die Einschraenkung der Verarbeitung
vor (Art. 18) -- genau so wird es ausgewiesen, samt Datum, ab dem
geloescht werden darf.
Dasselbe bei Widerrufserklaerungen: Sie sind der Nachweis, DASS und
WANN widerrufen wurde. Wer sie loescht, vernichtet seinen eigenen Beleg
in genau der Sache, in der es spaeter Streit geben koennte.
EIN FEHLER, DEN DER TEST VOR DEM ERSTEN LAUF GEFUNDEN HAT
Die Tabelle wd_widerrufe fuehrt die Adresse nicht als "email", sondern
als "kontakt". Die erste Fassung suchte nach "email" -- sie haette dort
NIE einen Treffer geliefert, und die Auskunft haette trotzdem sauber
ausgesehen. Aufgefallen nur, weil die Testdaten gegen das echte Schema
angelegt wurden statt gegen die Annahme.
Deshalb steht in der Quellenliste jetzt die Spalte, nicht eine
Vermutung.
WEITERE ENTSCHEIDUNGEN
- Die Suche geht ueber die Adresse UND ueber die Kundenkennung. Vieles
haengt nicht an der Adresse; ohne diesen Schritt bliebe die halbe
Auskunft leer.
- Gross- und Kleinschreibung spielt keine Rolle -- sonst bekaeme
jemand eine leere Auskunft, weil er seine Adresse anders schreibt.
- Die Loeschung verlangt die Adresse ein zweites Mal. Der Unterschied
zwischen .org und .com ist ein Buchstabe, die Folge unwiederbringlich.
- Sie laeuft in einer Transaktion: Bricht sie ab, bliebe sonst ein
halbgeloeschter Bestand, und niemand wuesste, welcher Teil weg ist.
- Der Vorgang wird protokolliert, aber OHNE die geloeschten Inhalte --
sie dabei erneut zu speichern waere das Gegenteil des Zwecks.
15 Pruefungen gruen, mit Gegenprobe (fremde Adresse liefert nichts).
Die Oberflaeche in der Verwaltung folgt. Deploy braucht Filipe:
server-internal liegt unter /home/dogiintern mit Rechten 700.
Co-Authored-By: Claude Opus 5 <[email protected]>