6.7 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
.env.postgres.examplenach.env.postgreskopieren.- Lange, nur lokal verwendete PostgreSQL- und Qdrant-Schluessel eintragen.
npm run db:upausfü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
npm run serve:localstarten.
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.
npm run db:up startet im kanonischen Compose-Projekt auch Qdrant fuer die
optionale regulatorische Suche. Das aendert die PostgreSQL-Zustaendigkeit nicht:
Qdrant ist ein aus dem versionierten Korpus wiederaufbaubarer Index. Konfiguration
und Ingestion stehen in docs/REGULATORY_RAG.md.
Migrationen
Migrationen liegen versioniert unter server/postgres/migrations. Beim Start
mit PostgreSQL:
- nimmt der Prozess einen PostgreSQL-Advisory-Lock,
- prüft Version und SHA-256-Prüfsumme jeder bekannten Migration,
- führt jede neue Migration in einer eigenen Transaktion aus,
- dokumentiert sie in
assessor_schema_migrations, - 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
- PostgreSQL: https://www.postgresql.org/docs/current/ddl-constraints.html
- PostgreSQL-GIN: https://www.postgresql.org/docs/current/gin.html
- PostgreSQL-Volltextsuche: https://www.postgresql.org/docs/current/textsearch.html
- node-postgres-Transaktionen: https://node-postgres.com/features/transactions
- node-postgres-Parameter: https://node-postgres.com/features/queries