avicenna/service/data-hub/business-engine/cmd/api/server.go

89 lines
2.1 KiB
Go

package main
import (
"business-engine/internal/config"
"business-engine/internal/database"
"business-engine/internal/payroll"
"context"
"log/slog"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
// Server contains all dependencies of the application
type Server struct {
config *config.Config
logger *slog.Logger
db *pgxpool.Pool
router *http.ServeMux
}
// NewServer constructs a new server
func NewServer(cfg *config.Config, logger *slog.Logger) (*Server, error) {
dbpool, err := pgxpool.New(context.Background(), cfg.DatabaseURL)
if err != nil {
logger.Error("failed to connect to database", "error", err)
os.Exit(1)
}
server := &Server{
config: cfg,
logger: logger,
db: dbpool,
router: http.NewServeMux(),
}
server.setupRoutes()
return server, nil
}
// setupRoutes initializes all routes and handlers
func (s *Server) setupRoutes() {
employeeRepo := database.New(s.db)
zuschlagParser := payroll.NewZuschlagParser(s.logger)
employeeService := payroll.NewService(employeeRepo, s.logger, zuschlagParser)
employeeHandler := payroll.NewEmployeeHandler(*employeeService, s.logger)
s.router.HandleFunc("GET /health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("OK"))
})
s.router.HandleFunc("GET /api/v1/payroll", employeeHandler.RunPayroll)
}
func (s *Server) Start() {
httpServer := &http.Server{
Addr: ":" + s.config.Port,
Handler: s.router,
}
go func() {
s.logger.Info("server starting", "port", s.config.Port)
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
s.logger.Error("server failed to start", "error", err)
os.Exit(1)
}
}()
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
<-stop
s.logger.Info("shutting down server gracefully")
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := httpServer.Shutdown(ctx); err != nil {
s.logger.Error("server shutdown failed", "error", err)
} else {
s.logger.Info("server stopped")
}
}