CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
Core-Schnittstellen-Vertragstests / contract-tests (pull_request) Canceled after 0s
Core-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
RBAC-Rollenhierarchie-Pflichtgate / rbac-policy-invariant (pull_request) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (pull_request) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (pull_request) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (pull_request) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (pull_request) Canceled after 0s
CI / Web (dms-browser) (pull_request) Canceled after 0s
CI / Web (pdf-viewer) (pull_request) Canceled after 0s
CI / Web (shl) (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (pull_request) Canceled after 0s
Supply-Chain-Scan (npm) / npm-audit (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (pull_request) Canceled after 0s
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
64 lines
2.6 KiB
Go
64 lines
2.6 KiB
Go
package migrationverify
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
)
|
|
|
|
// TenantPoolResolver liefert den Pool der physischen Tenant-Datenbank
|
|
// (Modell C, siehe internal/tenant) zu einem Tenant-Slug.
|
|
type TenantPoolResolver func(ctx context.Context, tenantSlug string) (*pgxpool.Pool, error)
|
|
|
|
// PostgresTenantCountProvider zaehlt users und documents direkt in der
|
|
// Tenant-Datenbank, in die COR-02 (internal/migrationuser) bzw. DOK-01
|
|
// (dms/internal/migrationdocument) schreiben. Die Nachrichten-Zieltabelle
|
|
// existiert nicht in Postgres (siehe mail/internal/messagemigration,
|
|
// Metadaten liegen ausschliesslich im Manticore-Suchindex) — das
|
|
// Messages-Feld bleibt hier 0 und muss ueber einen eigenen CountProvider
|
|
// eingespeist werden (siehe CombineUsers-Muster).
|
|
type PostgresTenantCountProvider struct {
|
|
Resolver TenantPoolResolver
|
|
}
|
|
|
|
func (p PostgresTenantCountProvider) Counts(ctx context.Context, tenantSlug string) (TenantCounts, error) {
|
|
pool, err := p.Resolver(ctx, tenantSlug)
|
|
if err != nil {
|
|
return TenantCounts{}, fmt.Errorf("migrationverify: tenant-pool fuer %q: %w", tenantSlug, err)
|
|
}
|
|
|
|
var users, documents int64
|
|
if err := pool.QueryRow(ctx, `SELECT COUNT(*) FROM users`).Scan(&users); err != nil {
|
|
return TenantCounts{}, fmt.Errorf("migrationverify: users zaehlen (%q): %w", tenantSlug, err)
|
|
}
|
|
if err := pool.QueryRow(ctx, `SELECT COUNT(*) FROM documents`).Scan(&documents); err != nil {
|
|
return TenantCounts{}, fmt.Errorf("migrationverify: documents zaehlen (%q): %w", tenantSlug, err)
|
|
}
|
|
return TenantCounts{TenantSlug: tenantSlug, Users: users, Documents: documents}, nil
|
|
}
|
|
|
|
// RegistryApprovedUserCountProvider zaehlt freigegebene
|
|
// user_migration_map-Eintraege je Tenant (siehe
|
|
// internal/migrationuser.MapStore.Approved) als Quellzahl der
|
|
// Benutzer-Kerntabelle.
|
|
type RegistryApprovedUserCountProvider struct {
|
|
RegistryPool *pgxpool.Pool
|
|
TenantIDBySlug map[string]string
|
|
}
|
|
|
|
func (p RegistryApprovedUserCountProvider) Counts(ctx context.Context, tenantSlug string) (TenantCounts, error) {
|
|
tenantID, ok := p.TenantIDBySlug[tenantSlug]
|
|
if !ok {
|
|
return TenantCounts{}, fmt.Errorf("migrationverify: kein nexarch_tenant_id fuer slug %q", tenantSlug)
|
|
}
|
|
|
|
var users int64
|
|
if err := p.RegistryPool.QueryRow(ctx, `
|
|
SELECT COUNT(*) FROM user_migration_map WHERE approved_at IS NOT NULL AND nexarch_tenant_id = $1
|
|
`, tenantID).Scan(&users); err != nil {
|
|
return TenantCounts{}, fmt.Errorf("migrationverify: freigegebene user-map-eintraege zaehlen (%q): %w", tenantSlug, err)
|
|
}
|
|
return TenantCounts{TenantSlug: tenantSlug, Users: users}, nil
|
|
}
|