package main import ( "context" "log/slog" "net/http" "os" "os/signal" "syscall" "time" "person-home/internal/db" "person-home/internal/router" ) func main() { addr := envOrDefault("ADDR", ":8882") dbPath := envOrDefault("DB_PATH", "data/person-home.db") uploadDir := envOrDefault("UPLOAD_DIR", "uploads") jwtSecretStr := envOrDefault("JWT_SECRET", "change-me-in-production") dbase, err := db.Open(dbPath) if err != nil { slog.Error("open database", "error", err) os.Exit(1) } defer dbase.Close() handler := router.New(dbase, []byte(jwtSecretStr), uploadDir, frontendFS()) server := &http.Server{ Addr: addr, Handler: handler, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, } stop := make(chan os.Signal, 1) signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) go func() { slog.Info("server starting", "addr", addr) if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { slog.Error("server error", "error", err) os.Exit(1) } }() <-stop slog.Info("shutting down...") ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() server.Shutdown(ctx) slog.Info("stopped") } func envOrDefault(key, def string) string { if v := os.Getenv(key); v != "" { return v } return def }