Assessor_2.0/docs/POSTGRESQL.md

6.4 KiB

PostgreSQL-Persistenz

Architekturstand

Phase 11 ergänzt PostgresAssessorRepository als produktiven Adapter hinter dem bestehenden AssessorRepository. React, API, Importengine und Vergleichslogik kennen weder SQL noch den PostgreSQL-Treiber.

Relationale Spalten und Fremdschlüssel sichern Identitäten und Beziehungen. Das vollständige versionierte Fachobjekt bleibt zusätzlich als JSONB erhalten. Damit können neue Scannerfelder verlustfrei aufgenommen werden, ohne die Integritätsregeln für Projekt, Assessment, Scan-Lauf, Datei und Finding zu umgehen.

Lokale Datenbank starten

  1. .env.postgres.example nach .env.postgres kopieren.
  2. Ein langes, nur lokal verwendetes Passwort eintragen.
  3. npm run db:up ausführen.

pm run start:local oder pm run serve:local starten. Das Startskript lädt .env.postgres automatisch und bildet daraus die lokale Loopback-Verbindung.

ASSESSOR_DATABASE_URL=postgresql://assessor:<passwort>@127.0.0.1:5432/assessor
ASSESSOR_DATABASE_SSL=disable
ASSESSOR_DATABASE_POOL_SIZE=10
  1. npm run serve:local starten.

Ohne ASSESSOR_DATABASE_URL startet ASSESSOR bewusst im flüchtigen In-Memory-Entwicklungsmodus. Ist eine URL gesetzt und PostgreSQL nicht erreichbar, bricht der Serverstart ab; er fällt nicht still auf Arbeitsspeicher zurück. Dadurch kann ein Konfigurationsfehler keine scheinbar erfolgreichen, aber nicht dauerhaften Importe erzeugen.

ASSESSOR_DATABASE_SSL=disable ist ausschließlich für die Loopback-Verbindung auf dem Entwicklungsrechner vorgesehen. Für entfernte Datenbankziele ist TLS standardmäßig erforderlich. Die spätere Firmenkonfiguration benötigt eine vertrauenswürdige interne Zertifikatskette.

Migrationen

Migrationen liegen versioniert unter server/postgres/migrations. Beim Start mit PostgreSQL:

  1. nimmt der Prozess einen PostgreSQL-Advisory-Lock,
  2. prüft Version und SHA-256-Prüfsumme jeder bekannten Migration,
  3. führt jede neue Migration in einer eigenen Transaktion aus,
  4. dokumentiert sie in assessor_schema_migrations,
  5. verweigert den Start, wenn eine bereits angewandte Migration verändert wurde.

Angewandte Migrationen dürfen niemals nachträglich editiert werden. Änderungen erhalten stets eine neue, aufsteigend nummerierte SQL-Datei.

Schema und Suche

Das Schema besitzt unter anderem:

  • Primär- und Fremdschlüssel mit kontrollierten Löschregeln
  • eindeutige Scan-Reihenfolgen pro Assessment
  • optimistische Review-Revisionen
  • eine globale Repository-Revision für konkurrierende Importtransaktionen
  • B-Tree-Indizes auf Fremdschlüsseln und Filterspalten
  • gespeicherte tsvector-Dokumente und GIN-Indizes für Findings
  • einen GIN-JSONB-Index für spätere strukturierte Zusatzfeldabfragen

Importdaten werden zunächst im Prozess gestagt. Der Commit öffnet genau eine Datenbanktransaktion auf genau einer Poolverbindung, sperrt die Repository-Revision, schreibt alle Entitäten, validiert das vollständige kanonische Assessment-Modell und führt danach den Commit aus. Fehler erzeugen ein Rollback ohne Teilimport.

Import-Fingerprints

Migration 002_import_fingerprints.sql ergänzt assessor_import_fingerprints. Der SHA-256-Wert ist Primärschlüssel; gespeichert werden außerdem Dateiname, Größe, letzter Dateiänderungszeitpunkt, erster und letzter Importzeitpunkt sowie ein Wiederholungszähler.

Der Abschluss eines bestätigten Batchimports verwendet commitCanonicalImport. Der PostgreSQL-Adapter schreibt neues Projekt, Assessment, Scan-Lauf, kanonische Importdaten und Fingerprints auf derselben Poolverbindung innerhalb derselben Transaktion. Die Repository-Revision wird dabei genau einmal erhöht. Ein Validierungs-, Auswahl- oder Datenbankfehler erzeugt ein vollständiges Rollback.

Abgeleitete Result DB

assessor_result_db_rows und assessor_result_db_state (Migration 024) sind abgeleitete Daten: Das Backend baut sie unter einer Advisory-Sperre aus den kanonischen Tabellen neu auf, sobald sich die Repository-Revision oder eine Policy-/Waechterversion aendert. Sie werden nie von Hand bearbeitet und zaehlen die Repository-Revision nicht hoch.

Backup

Vor Migrationen, Updates und größeren Löschvorgängen ist ein logisches Backup zu erstellen. Bei installiertem PostgreSQL-Client:

pg_dump --format=custom --no-owner --file=assessor-YYYYMMDD.backup "$ASSESSOR_DATABASE_URL"

Das Backup muss außerhalb des Datenbankcontainers, zugriffsgeschützt und gemäß der später festzulegenden Aufbewahrungsfrist abgelegt werden. Regelmäßig muss ein Restore in eine getrennte Testdatenbank durchgeführt werden; ein Backup ohne geprüften Restore gilt nicht als belastbar.

Restore

Ein Restore ersetzt Daten und darf nur nach exakter Prüfung der Zieldatenbank erfolgen. Empfohlen wird zunächst eine neue leere Datenbank:

createdb assessor_restore_test
pg_restore --no-owner --exit-on-error --dbname=assessor_restore_test assessor-YYYYMMDD.backup

Danach werden Migrationstabelle, Projektanzahl, Assessments, Scan-Läufe, Findings, Reviews und Stichprobenexporte geprüft. Erst nach erfolgreicher Validierung darf ein betriebliches Umschalten geplant werden.

Löschung

Projektlöschung verlangt weiterhin die exakte Projekt-ID und cascade: true. PostgreSQL entfernt abhängige Assessments, Scan-Läufe, Dateien, Tabellen, Vorkommen, Evidenz, Diagnosen, Reviews, Regeln und Vergleiche innerhalb einer Transaktion. Nicht mehr verwendete Finding-Definitionen werden anschließend bereinigt. Datenbank-Backups bleiben davon unberührt und benötigen ein eigenes Aufbewahrungs- und Löschkonzept in Phase 14.

Verifikation

Neben Schema- und Migrationsläufertests existiert ein echter Integrationstest gegen PostgreSQL 16. Er prüft idempotente Migrationen, atomare Mehrlaufimporte, Volltextsuche, optimistische Reviewkonflikte, Vergleiche, Export, Parallelkonflikte, kanonische Batchimporte, dauerhafte Fingerprint-Zähler und kaskadierende Projektlöschung. Der Test verwendet ASSESSOR_TEST_DATABASE_URL und darf niemals auf eine produktive Datenbank zeigen.

Technische Referenzen