core/crm-core/cmd/api/main.go
2025-12-27 14:32:00 -03:00

101 lines
3 KiB
Go

package main
import (
"context"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"crm-core/internal/api/handlers"
"crm-core/internal/api/router"
"crm-core/internal/application/accounts"
"crm-core/internal/application/activities"
"crm-core/internal/application/contacts"
"crm-core/internal/application/deals"
"crm-core/internal/application/notes"
"crm-core/internal/application/stages"
"crm-core/internal/application/tags"
"crm-core/internal/config"
"crm-core/internal/infrastructure/auth"
"crm-core/internal/infrastructure/postgres"
"crm-core/internal/infrastructure/repositories"
"crm-core/internal/observability"
)
func main() {
cfg := config.MustLoad()
logger := observability.NewLogger(cfg.Env)
ctx := context.Background()
pool, err := postgres.NewPool(ctx, cfg.DatabaseURL)
if err != nil {
logger.Error("database connection failed", slog.Any("error", err))
os.Exit(1)
}
defer pool.Close()
jwtMiddleware, err := auth.NewMiddleware(cfg.JWKSURL)
if err != nil {
logger.Error("jwks init failed", slog.Any("error", err))
os.Exit(1)
}
accountsRepo := repositories.NewAccountsRepository(pool)
contactsRepo := repositories.NewContactsRepository(pool)
dealsRepo := repositories.NewDealsRepository(pool)
stagesRepo := repositories.NewStagesRepository(pool)
activitiesRepo := repositories.NewActivitiesRepository(pool)
notesRepo := repositories.NewNotesRepository(pool)
tagsRepo := repositories.NewTagsRepository(pool)
accountsService := accounts.NewService(accountsRepo)
contactsService := contacts.NewService(contactsRepo)
dealsService := deals.NewService(dealsRepo)
stagesService := stages.NewService(stagesRepo)
activitiesService := activities.NewService(activitiesRepo)
notesService := notes.NewService(notesRepo)
tagsService := tags.NewService(tagsRepo)
handlerSet := handlers.HandlerSet{
Accounts: handlers.NewAccountsHandler(accountsService),
Contacts: handlers.NewContactsHandler(contactsService),
Deals: handlers.NewDealsHandler(dealsService),
Stages: handlers.NewStagesHandler(stagesService),
Activities: handlers.NewActivitiesHandler(activitiesService),
Notes: handlers.NewNotesHandler(notesService),
Tags: handlers.NewTagsHandler(tagsService),
}
r := router.NewRouter(logger, jwtMiddleware, handlerSet)
srv := &http.Server{
Addr: cfg.HTTPAddr,
Handler: r,
ReadTimeout: cfg.RequestTimeout,
WriteTimeout: cfg.RequestTimeout,
IdleTimeout: 30 * time.Second,
}
go func() {
logger.Info("api started", slog.String("addr", cfg.HTTPAddr))
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Error("http server error", slog.Any("error", err))
os.Exit(1)
}
}()
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
ctxShutdown, cancel := context.WithTimeout(context.Background(), cfg.ShutdownTimeout)
defer cancel()
if err := srv.Shutdown(ctxShutdown); err != nil {
logger.Error("http shutdown error", slog.Any("error", err))
os.Exit(1)
}
logger.Info("api stopped")
}