aboutsummaryrefslogtreecommitdiff
path: root/backend/cmd/server/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'backend/cmd/server/main.go')
-rw-r--r--backend/cmd/server/main.go109
1 files changed, 109 insertions, 0 deletions
diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go
new file mode 100644
index 0000000..f734885
--- /dev/null
+++ b/backend/cmd/server/main.go
@@ -0,0 +1,109 @@
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+
+ "os/signal"
+ "syscall"
+
+ "github.com/joho/godotenv"
+ "golang.org/x/crypto/bcrypt"
+
+ "yaum/internal/alerts"
+ "yaum/internal/api"
+ "yaum/internal/config"
+ "yaum/internal/monitor"
+ "yaum/internal/sse"
+ "yaum/internal/store"
+)
+
+func main() {
+ godotenv.Load()
+
+ cfgPath := os.Getenv("CONFIG_PATH")
+ cfg, err := config.Load(cfgPath)
+ if err != nil {
+ log.Fatalf("config: %v", err)
+ }
+
+ passwordHash := cfg.AdminPasswordHash()
+ if passwordHash == "" {
+ if pw := os.Getenv("ADMIN_PASSWORD"); pw != "" {
+ hash, err := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.DefaultCost)
+ if err != nil {
+ log.Fatalf("erro ao gerar hash da senha: %v", err)
+ }
+ passwordHash = string(hash)
+ }
+ }
+ if passwordHash == "" {
+ log.Fatal("ADMIN_PASSWORD_HASH ou ADMIN_PASSWORD nao definido — defina no .env ou config.json")
+ }
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ var st store.Store
+
+ if dbURL := cfg.DatabaseURL(); dbURL != "" {
+ log.Println("conectando ao postgres...")
+ pg, err := store.NewPostgresStore(ctx, dbURL)
+ if err != nil {
+ log.Fatalf("banco: %v", err)
+ }
+ defer pg.Close()
+ st = pg
+ log.Println("conectado ao postgres")
+ } else {
+ log.Println("database.url vazio — usando store em memoria")
+ ms := store.NewMemoryStore()
+ ms.SeedMockData()
+ st = ms
+ }
+
+ broadcaster := sse.NewBroadcaster()
+
+ worker := monitor.NewWorker(st, cfg.CheckInterval(), cfg.CheckTimeout(), broadcaster)
+ if cfg.SMTP.From != "" {
+ smtpCfg := &alerts.SMTPConfig{
+ Host: cfg.SMTP.Host,
+ Port: cfg.SMTP.Port,
+ Username: cfg.SMTP.Username,
+ Password: cfg.SMTP.Password,
+ From: cfg.SMTP.From,
+ }
+ worker.WithSMTP(smtpCfg)
+ }
+ handler := api.NewHandler(st, int(cfg.CheckTimeout().Seconds()))
+ streamHandler := api.NewStreamHandler(broadcaster)
+ authHandler := api.NewAuthHandler(
+ cfg.AdminUsername(),
+ passwordHash,
+ cfg.JWTSecret(),
+ )
+
+ server := &http.Server{
+ Addr: cfg.ServerAddr(),
+ Handler: api.NewRouter(handler, streamHandler, authHandler),
+ }
+
+ go worker.Start(ctx)
+
+ go func() {
+ sigCh := make(chan os.Signal, 1)
+ signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
+ sig := <-sigCh
+ log.Printf("sinal recebido: %s. desligando...", sig)
+ worker.Stop()
+ server.Shutdown(context.Background())
+ }()
+
+ log.Printf("yaum rodando em %s", cfg.ServerAddr())
+ if err := server.ListenAndServe(); err != http.ErrServerClosed {
+ log.Fatalf("erro ao iniciar servidor: %v", err)
+ }
+ log.Println("servidor encerrado com sucesso")
+}