// statuspage-devserver stellt das OPS-02-Backend (internal/statuspage) fuer // die Next.js-Statusseite bereit und startet den periodischen Poller. // Getrennt von cmd/core aus demselben Grund wie die anderen *-devserver. package main import ( "context" "log" "net/http" "os" "strconv" "time" "gitea.perlbach24.de/scripte/nexarch/internal/db" "gitea.perlbach24.de/scripte/nexarch/internal/statuspage" ) func main() { dsn := os.Getenv("NEXARCH_REGISTRY_DSN") if dsn == "" { log.Fatal("NEXARCH_REGISTRY_DSN nicht gesetzt") } addr := os.Getenv("NEXARCH_STATUSPAGE_LISTEN_ADDR") if addr == "" { addr = ":8084" } intervalSeconds := 10 if v := os.Getenv("NEXARCH_STATUSPAGE_POLL_INTERVAL_SECONDS"); v != "" { if parsed, err := strconv.Atoi(v); err == nil { intervalSeconds = parsed } } ctx := context.Background() pool, err := db.Connect(ctx, dsn) if err != nil { log.Fatalf("db: %v", err) } defer pool.Close() store := statuspage.NewStore(pool) checker := statuspage.NewHTTPChecker(2 * time.Second) poller := statuspage.NewPoller(store, checker) go poller.Run(ctx, time.Duration(intervalSeconds)*time.Second) mux := http.NewServeMux() mux.HandleFunc("/status/overview", withCORS(store.OverviewHandler)) mux.HandleFunc("/status/history", withCORS(store.HistoryHandler)) mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) log.Printf("statuspage-devserver listening on %s (poll-intervall: %ds)", addr, intervalSeconds) log.Fatal(http.ListenAndServe(addr, mux)) } func withCORS(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type") if r.Method == http.MethodOptions { w.WriteHeader(http.StatusOK) return } next(w, r) } }