diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index 344dd54..cc82759 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -1,6 +1,7 @@ package main import ( + "errors" "log" "net/http" "os" @@ -11,14 +12,20 @@ import ( func main() { cfg, err := config.Load(configPath()) - if err != nil { + if err != nil && !errors.Is(err, config.ErrRequireSetup) { log.Fatalf("failed to load config: %v", err) } + // cfg may be nil when REQUIRE_SETUP — NewServer handles that gracefully. + addr := ":4000" + if cfg != nil && cfg.ListenAddr != "" { + addr = cfg.ListenAddr + } + srv := graph.NewServer(cfg) - log.Printf("Archivum listening on %s", cfg.ListenAddr) - if err := http.ListenAndServe(cfg.ListenAddr, srv); err != nil { + log.Printf("Archivum listening on %s", addr) + if err := http.ListenAndServe(addr, srv); err != nil { log.Fatal(err) } } diff --git a/backend/internal/graph/server.go b/backend/internal/graph/server.go index 4c50b8f..39e7a80 100644 --- a/backend/internal/graph/server.go +++ b/backend/internal/graph/server.go @@ -7,22 +7,38 @@ import ( ) // NewServer wires up the HTTP handler for the GraphQL endpoint. -// Replace the stub handler with the gqlgen-generated handler once -// `go generate ./...` has been run. +// cfg may be nil when the system has not been configured yet; in that case +// every GraphQL request returns {"data":{"systemStatus":"REQUIRE_SETUP"}} so +// the frontend can redirect to the Setup Wizard. func NewServer(cfg *config.Config) http.Handler { mux := http.NewServeMux() - // Placeholder — replace with generated gqlgen handler. mux.HandleFunc("/graphql", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") + if r.Method == http.MethodOptions { + w.WriteHeader(http.StatusNoContent) + return + } + + if cfg == nil { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{"data":{"systemStatus":"REQUIRE_SETUP"}}`)) + return + } + + // TODO: replace with gqlgen handler once generated. w.WriteHeader(http.StatusOK) - _, _ = w.Write([]byte(`{"data":{"systemStatus":"REQUIRE_SETUP"}}`)) + _, _ = w.Write([]byte(`{"data":{"systemStatus":"OK"}}`)) }) - // Simple health check. mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) + // Serve the embedded Vue SPA for every other path. + mux.Handle("/", http.FileServer(http.Dir("/srv/archivum/ui"))) + return mux }