implement payroll generator v0.9
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"business-engine/internal/config"
|
||||
"log/slog"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
|
||||
Level: slog.LevelDebug,
|
||||
})
|
||||
|
||||
logger := slog.New(handler)
|
||||
slog.SetDefault(logger)
|
||||
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
logger.Error("failed to load configuration", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
server, err := NewServer(cfg, logger)
|
||||
if err != nil {
|
||||
logger.Error("failed to create server", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
server.Start()
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
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)
|
||||
employeeService := payroll.NewService(employeeRepo, s.logger)
|
||||
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/employees", employeeHandler.ListEmployees)
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user