Deterministischer Abgleich zwischen DMS file_revisions und Objekt-Storage-Verzeichnis, existenz-only (keine Inhaltspruefung, saubere Abgrenzung zu BAK-08). Report sortiert nach storage_key fuer stabile Weiterverarbeitung durch BAK-08. Systemd-Timer taeglich, real auf 192.168.1.131 verdrahtet und ausgeloest.
109 lines
5.4 KiB
Markdown
109 lines
5.4 KiB
Markdown
# BAK-05 – Prüfprotokoll: Reconciliation / Konsistenzprüfung Storage vs. DB
|
||
|
||
Voraussetzung BAK-01, BAK-02 (Welle 1) – erledigt, siehe eigene Protokolle.
|
||
|
||
## Grundsatzentscheidung: reine Funktion + zwei Quell-Adapter
|
||
|
||
`internal/reconcile.Reconcile` ist eine reine Funktion ohne DB-/Storage-
|
||
Zugriff (leicht ohne echte Infrastruktur testbar), die Ein- und
|
||
Auslesen echter Systeme ist strikt in `sources.go` getrennt
|
||
(`ListDBStorageKeys` gegen echtes Postgres, `ListStorageObjects` gegen
|
||
echtes Dateisystem). Beide Seiten liefern nur SCHLÜSSEL – niemals Inhalt
|
||
– dadurch bleibt BAK-05 sauber getrennt von BAK-08 (Inhalts-/Prüfsummen-
|
||
verifikation, eigene Fehlerklasse, eigenes Ticket).
|
||
|
||
Report-Format bewusst deterministisch: beide Ergebnislisten
|
||
(`missing_in_storage`, `orphaned_in_storage`) nach `storage_key`
|
||
aufsteigend sortiert, damit BAK-08 später dieselbe Objektliste als
|
||
stabile Stichprobenquelle weiterverarbeiten kann, ohne selbst neu zu
|
||
sortieren/filtern (Nutzervorgabe).
|
||
|
||
Meldeweg über OPS-05 (wie später BAK-08) wurde als offene Design-Frage
|
||
aufgeworfen, aber nicht zur Vorbedingung gemacht – hier bewusst noch
|
||
nicht umgesetzt (kein OPS-05-Abhängigkeitseintrag im Board für BAK-05);
|
||
Report wird aktuell nur als JSON auf stdout ausgegeben und per
|
||
Exit-Code (1 bei Abweichungen) für systemd/Monitoring sichtbar gemacht.
|
||
Anbindung an OPS-05 kann bei Bedarf nachgezogen werden, ohne
|
||
`Reconcile` selbst zu ändern.
|
||
|
||
## Umsetzung
|
||
|
||
- `internal/reconcile.Reconcile(dbEntries, storageKeys) Report` – reine
|
||
Vergleichsfunktion, liefert `MissingInStorage`/`OrphanedInStorage`,
|
||
`Report.IsClean()` als eindeutiges Sauber-Merkmal.
|
||
- `internal/reconcile.ListDBStorageKeys` – liest `file_revisions`
|
||
(DMS FDN-02) per direktem SQL aus derselben physischen Tenant-DB
|
||
(Modell C, Core TEN-01) – kein Import von DMS-Go-Paketen möglich
|
||
(eigenes Go-Modul), daher reiner SQL-Zugriff gegen das dokumentierte
|
||
Schema.
|
||
- `internal/reconcile.ListStorageObjects` – durchläuft den lokalen
|
||
FDN-03-`LocalDriver`-Basisordner (`filepath.WalkDir`), liefert `nil,
|
||
nil` bei fehlendem Verzeichnis statt Fehler (noch keine Objekte ist
|
||
kein Fehlerzustand).
|
||
- `cmd/reconcile-cli` – liest `NEXARCH_RECONCILE_TENANT_DSN` und
|
||
`NEXARCH_RECONCILE_STORAGE_DIR`, gibt Report als JSON auf stdout aus,
|
||
Exit-Code 1 bei Abweichungen.
|
||
|
||
## Prüfungen
|
||
|
||
| # | Prüfung | Ergebnis |
|
||
|---|---|---|
|
||
| 1 | Datenbankeintrag ohne Storage-Objekt wird erkannt | **bestanden** — `TestReconcile_DetectsMissingInStorage` |
|
||
| 2 | Storage-Objekt ohne Datenbankeintrag wird erkannt | **bestanden** — `TestReconcile_DetectsOrphanedInStorage` |
|
||
| 3 | Lauf ohne Abweichungen liefert leeren, eindeutig sauberen Bericht | **bestanden** — `TestReconcile_CleanRunProducesEmptyReport` (zusätzlich `IsClean()`-Konsistenzprüfung) |
|
||
|
||
Zusätzlich (Nutzervorgaben, nicht explizit im Ticket als Pflichtprüfung
|
||
benannt, aber zentral für die Abgrenzung/Weiterverwendbarkeit):
|
||
|
||
- `TestReconcile_ExistingButCorruptedObjectProducesNoFinding` – Nachweis,
|
||
dass Reconcile AUSSCHLIESSLICH Existenz prüft, niemals Inhalt (Trennung
|
||
von BAK-08).
|
||
- `TestReconcile_DeterministicOrdering` – zwei Läufe mit identischer
|
||
Eingabe liefern identische Reihenfolge, aufsteigend nach `storage_key`.
|
||
- `TestListDBStorageKeys_ReadsRealFileRevisions` – liest echt gegen die
|
||
gemeinsame Tenant-Testdatenbank `dms_tenant_test` (reales DMS-FDN-02-
|
||
Schema, kein Mock).
|
||
- `TestListStorageObjects_WalksRealDirectory` /
|
||
`_MissingDirectoryReturnsEmpty` – echtes Dateisystem, kein Mock.
|
||
|
||
## Echte Verdrahtung auf 192.168.1.131
|
||
|
||
- `reconcile-cli` gebaut nach `/opt/nexarch-archive/bin/`
|
||
- `/etc/nexarch/archive-reconcile.env` (0600): `NEXARCH_RECONCILE_TENANT_DSN`
|
||
zeigt auf die gemeinsame Tenant-Testdatenbank `dms_tenant_test`
|
||
(DMS selbst läuft auf 192.168.1.131 noch nicht als eigener systemd-
|
||
Dienst mit persistenter Konfiguration – dies ist die real verfügbare
|
||
Tenant-DB mit echtem FDN-02-Schema, dokumentierter bekannter Stand,
|
||
kein stiller Mock); `NEXARCH_RECONCILE_STORAGE_DIR` zeigt auf
|
||
`/var/nexarch-archiv/dms-objects` (persistentes ZFS-Dataset, NICHT
|
||
`/var/nexarch-test/`).
|
||
- Timer `nexarch-archive-reconcile.timer` installiert und aktiviert
|
||
(täglich 05:00 UTC), `systemctl list-timers` bestätigt scharf.
|
||
- `systemctl start nexarch-archive-reconcile.service` real ausgelöst:
|
||
`status=0/SUCCESS`, Journal zeigt echten JSON-Report
|
||
(`missing_in_storage: null, orphaned_in_storage: null` – Tenant-DB
|
||
aktuell leer, daher sauberer Bericht, keine synthetische Ausgabe).
|
||
|
||
## Build/Test-Ergebnis (192.168.1.131, `make check`)
|
||
|
||
```
|
||
go build ./... -> clean
|
||
go vet ./... -> clean
|
||
golangci-lint run ./... -> 0 issues
|
||
go test ./... -p 1 -count=1 -> 3/3 Pakete mit Tests ok (internal/backup, internal/objectbackup, internal/reconcile), 0 Fehlschläge
|
||
```
|
||
|
||
`internal/reconcile`-Tests separat mit gesetzter `TEST_TENANT_DSN` gegen
|
||
`dms_tenant_test` verifiziert: 8/8 Tests bestanden (5 reine
|
||
`Reconcile`-Tests + 3 `sources.go`-Integrationstests).
|
||
|
||
## Gesamtergebnis
|
||
|
||
**Bestanden.** Alle drei Akzeptanzkriterien und alle Pflicht- sowie
|
||
Nutzervorgaben-Prüfungen real erfüllt (echte Postgres-Instanz, echtes
|
||
Dateisystem, echter systemd-Lauf). Zwei Testfehler während der
|
||
Entwicklung (Schema-Abweichung `revision_number` NOT NULL in der realen
|
||
`dms_tenant_test`-Tabelle; inkonsistente Fixture-Daten in
|
||
`TestReconcile_DeterministicOrdering`) gefunden und korrigiert – beide
|
||
waren Testautorenfehler, keine Fehler in `Reconcile` selbst.
|