CUT-02: VAL-04 (Audit-Kontinuitaet) in Ablaufplan einbinden

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Sonnet 5 committed 2026-10-14 22:45:01 +00:00
1 parent f282831820
commit 9bc0d9b67f
4 files changed
+57 -6

No files matched your search

+8 -4
View File
@@ -17,10 +17,11 @@ import (
)
type Config struct {
RepoRoot string
WorkRoot string
Seed int64
BcryptCost int
RepoRoot string
WorkRoot string
Seed int64
BcryptCost int
Generalprobe bool
}
type Dryrun struct {
@@ -178,8 +179,11 @@ func (d *Dryrun) Plan() []Step {
{ID: "MAI-04", Title: "Reconciliation-Reports-Archivierung", DependsOn: []string{"SCHEMA-02"}, Run: d.stage("archive", "mai04")},
{ID: "TAR-02", Title: "Vier-Augen-Loeschworkflow-Migration", DependsOn: []string{"TAR-01", "COR-02"}, Run: d.stage("archive", "tar02")},
{ID: "WFL-01", Title: "Workflow-Historie-Migration", DependsOn: []string{"COR-02", "SCHEMA-02"}, Run: d.stage("workflow", "wfl01")},
{ID: "VAL-04", Title: "Audit-Log-Kontinuitaetspruefung", DependsOn: []string{"COR-05"}, Run: d.val04},
{ID: "VAL-03", Title: "Retention-Fristen-Stichprobenvergleich", DependsOn: []string{"TAR-01"}, Run: d.stage("archive", "val03")},
{ID: "VAL-01", Title: "Zeilenzahl-Abgleich je Kerntabelle", DependsOn: []string{"COR-02", "DOK-01", "MAI-02"}, Run: d.val01},
{ID: "VAL-02", Title: "Hash-Vergleich migrierter Binaerdateien", DependsOn: []string{"DOK-01", "MAI-02"}, Run: d.val02},
{ID: "TXT-01", Title: "Volltextvergleich migrierter Dokumenttitel und Nachrichten", DependsOn: []string{"DOK-01", "MAI-02", "VAL-02"}, Run: d.txt01},
{ID: "VAL-05", Title: "Login-Test mit migrierten Zugangsdaten", DependsOn: []string{"COR-02"}, Run: d.val05},
{ID: "CHK-01", Title: "Modulgrenzen-uebergreifende Kettenpruefung", DependsOn: []string{"DOK-03", "DOK-05", "TAR-02", "MAI-03", "MAI-04", "WFL-01"}, Run: d.chk01},
}
+1 -1
View File
@@ -37,7 +37,7 @@ func WriteJSON(path string, rep Report) error {
func RenderText(rep Report) string {
var b strings.Builder
fmt.Fprintf(&b, "CUT-01 Trockenlauf-Protokoll\n")
fmt.Fprintf(&b, "NEXARCH Migrations-Trockenlauf-Protokoll\n")
fmt.Fprintf(&b, "Lauf: %s (%s)\n", rep.RunTag, rep.Label)
fmt.Fprintf(&b, "Beginn: %s Ende: %s Dauer: %s\n",
rep.StartedAt.Format("2006-01-02 15:04:05 MST"), rep.FinishedAt.Format("2006-01-02 15:04:05 MST"),
+8 -1
View File
@@ -26,7 +26,11 @@ func (d *Dryrun) prepWorkdir(ctx context.Context) (Outcome, error) {
}
func (d *Dryrun) prepLegacyCopy(ctx context.Context) (Outcome, error) {
ds, err := GenerateDataset(d.cfg.Seed, d.now, d.cfg.BcryptCost)
gen := GenerateDataset
if d.cfg.Generalprobe {
gen = GenerateGeneralprobeDataset
}
ds, err := gen(d.cfg.Seed, d.now, d.cfg.BcryptCost)
if err != nil {
return Outcome{}, err
}
@@ -67,6 +71,9 @@ func (d *Dryrun) prepLegacyCopy(ctx context.Context) (Outcome, error) {
return out, err
}
out.Notes = append(out.Notes, fmt.Sprintf("generator-seed %d, quelle ausschliesslich internal/cutoverorchestrator/dataset.go", d.cfg.Seed))
if d.cfg.Generalprobe {
out.Notes = append(out.Notes, "Generalprobe-Testkopie (GenerateGeneralprobeDataset): rein synthetisch, keine Verbindung zu archivmail/archivdms moeglich")
}
return out, nil
}
+40
View File
@@ -0,0 +1,40 @@
package cutoverorchestrator
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"gitea.perlbach24.de/scripte/nexarch/internal/migrationauditcontinuity"
)
// val04 verwendet VAL-04 (internal/migrationauditcontinuity) direkt: Quelle
// und Ziel liegen beide in der Registry-DB (legacy_audit_log_staging bzw.
// audit_events aus COR-05), eine Modulstufe ist dafuer nicht noetig.
func (d *Dryrun) val04(ctx context.Context) (Outcome, error) {
var slugs []string
for _, t := range d.tenants {
slugs = append(slugs, t.Slug)
}
source := migrationauditcontinuity.PostgresSourceStatsProvider{RegistryPool: d.registry}
target := migrationauditcontinuity.PostgresTargetStatsProvider{AuditPool: d.registry}
reports, err := migrationauditcontinuity.Run(ctx, slugs, source, target)
if err != nil {
return Outcome{}, err
}
if err := os.WriteFile(filepath.Join(d.RunDir, "val04-audit-kontinuitaet.md"), []byte(migrationauditcontinuity.RenderBericht(reports)), 0o644); err != nil {
return Outcome{}, err
}
out := Outcome{Counts: map[string]int{"tenants": len(reports)}}
if offen := migrationauditcontinuity.OffeneBefunde(reports); len(offen) > 0 {
var lines []string
for _, r := range offen {
lines = append(lines, r.String())
}
out.Counts["offene_befunde"] = len(offen)
return out, fmt.Errorf("audit-log-kontinuitaet: %d offene befunde: %s", len(offen), strings.Join(lines, "; "))
}
return out, nil
}