API-11: wiederanlauf-nachsynchronisierungs-endpunkt-starten

- Merge API-02 (bereits Vorfahre), AUD-01, LIC-03 in API-06-Branch, um
  echte Produktionsimplementierungen fuer resync.Handler zu erhalten
  (moduleregistry.Registry, audit.Log, usage.Store) - go.mod/go.sum/
  scripts/reset-test-env.sh additiv zusammengefuehrt, keine Logikkonflikte
- cmd/resync-api: startet internal/resync.Handler (API-06) als
  eigenstaendigen HTTP-Dienst, kleiner auditAdapter fuer Signatur-
  Anpassung (kein neuer Fachcode)
- reines Wiring, kein Diff an internal/resync|audit|usage|moduleregistry
  (verifiziert)
- real deployed auf 131, end-zu-ende per curl mit echtem, ueber
  moduleregistry.Registry.Provision ausgestelltem Service-Credential:
  angewendetes usage-delta real in usage_counters bestaetigt, falsches
  Credential -> 401
- reale Grant-Luecke gefunden und behoben (nexarch_core auf modules/
  module_credentials/audit_events/feature_flags/usage_counters/
  resync_*_buffer), ueber information_schema verifiziert

Pruefungen siehe docs/API-11-PRUEFPROTOKOLL.md
This commit is contained in:
sysops
2026-08-30 20:14:07 +02:00
parent e6892535ed
commit d6e9412043
4 changed files with 190 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
// resync-api ist der Aufrufpunkt fuer API-11: startet den bereits
// fertigen internal/resync.Handler (API-06) als eigenstaendigen
// HTTP-Dienst. REINES WIRING — keine Aenderung an internal/resync/,
// internal/audit/, internal/usage/ oder internal/moduleregistry/.
package main
import (
"context"
"log"
"net/http"
"os"
"time"
"github.com/jackc/pgx/v5/pgxpool"
"gitea.perlbach24.de/scripte/nexarch/internal/audit"
"gitea.perlbach24.de/scripte/nexarch/internal/flag"
"gitea.perlbach24.de/scripte/nexarch/internal/moduleregistry"
"gitea.perlbach24.de/scripte/nexarch/internal/resync"
"gitea.perlbach24.de/scripte/nexarch/internal/usage"
)
// auditAdapter erfüllt resync.AuditRecorder über den bestehenden
// audit.Log-Schreibpfad — kein neuer Audit-Code, nur Signatur-Anpassung
// (audit.Log.Record nimmt ein Event-Struct, resync.AuditRecorder einzelne
// Felder).
type auditAdapter struct{ log *audit.Log }
func (a auditAdapter) Record(ctx context.Context, tenantSlug, actor, action, target string, metadata map[string]any, occurredAt time.Time) error {
return a.log.Record(ctx, audit.Event{
TenantSlug: tenantSlug, Actor: actor, Action: action, Target: target,
Metadata: metadata, OccurredAt: occurredAt,
})
}
func main() {
registryDSN := os.Getenv("NEXARCH_RESYNC_REGISTRY_DSN")
if registryDSN == "" {
log.Fatal("NEXARCH_RESYNC_REGISTRY_DSN muss gesetzt sein")
}
addr := os.Getenv("NEXARCH_RESYNC_API_LISTEN_ADDR")
if addr == "" {
addr = "127.0.0.1:8098"
}
ctx := context.Background()
pool, err := pgxpool.New(ctx, registryDSN)
if err != nil {
log.Fatalf("datenbankverbindung: %v", err)
}
defer pool.Close()
flagStore := flag.NewStore(pool)
flagService := flag.NewService(flagStore, 30*time.Second)
registry := moduleregistry.NewRegistry(pool, flagService)
auditLog := audit.NewLog(pool)
usageStore := usage.NewStore(pool)
handler := resync.NewHandler(registry, auditAdapter{log: auditLog}, usageStore)
mux := http.NewServeMux()
mux.HandleFunc("/internal/resync/audit", handler.AuditHandler)
mux.HandleFunc("/internal/resync/usage", handler.UsageHandler)
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })
log.Printf("resync-api: listening on %s", addr)
if err := http.ListenAndServe(addr, mux); err != nil {
log.Fatalf("http server: %v", err)
}
}