package main import ( "context" "log" "net/http" "os/signal" "syscall" "time" "bookra/apps/backend/internal/api" "bookra/apps/backend/internal/config" "bookra/apps/backend/internal/db" sentry "github.com/getsentry/sentry-go" ) func initSentry(cfg config.Config) { if cfg.SentryDSN == "" { log.Println("Sentry DSN not configured - skipping initialization") return } err := sentry.Init(sentry.ClientOptions{ Dsn: cfg.SentryDSN, Environment: cfg.Environment, Release: "bookra@1.0.0", // Set TracesSampleRate to 1.0 to capture 100% of transactions for testing TracesSampleRate: 1.0, }) if err != nil { log.Fatalf("Sentry initialization failed: %v", err) } log.Println("Sentry initialized") } func main() { cfg, err := config.Load() if err != nil { log.Fatalf("load config: %v", err) } initSentry(cfg) pools, err := db.NewPools(cfg) if err != nil { log.Fatalf("create database pools: %v", err) } defer pools.Close() server, err := api.NewServer(cfg, pools) if err != nil { log.Fatalf("create server: %v", err) } defer server.Close() // Start background job for trial ending emails go server.StartBackgroundJobs() httpServer := &http.Server{ Addr: ":" + cfg.Port, Handler: server.Handler(), ReadHeaderTimeout: 5 * time.Second, } go func() { log.Printf("bookra api listening on :%s (%s)", cfg.Port, cfg.Environment) if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { log.Fatalf("listen: %v", err) } }() ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGTERM, syscall.SIGINT) defer stop() <-ctx.Done() shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := httpServer.Shutdown(shutdownCtx); err != nil { log.Printf("shutdown error: %v", err) } }