98 lines
2.4 KiB
Go
98 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
"time"
|
|
|
|
"doormile/config"
|
|
"doormile/controllers"
|
|
"doormile/db"
|
|
"doormile/internal/worker"
|
|
"doormile/middlewares"
|
|
"doormile/migrations"
|
|
"doormile/routes"
|
|
"doormile/utils"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/gofiber/fiber/v2/middleware/cors"
|
|
"github.com/joho/godotenv"
|
|
)
|
|
|
|
func main() {
|
|
// 1. Load configuration env variables
|
|
_ = godotenv.Load()
|
|
cfg := config.Load()
|
|
|
|
utils.Info("Starting Doormile Backend...")
|
|
|
|
// 2. Connect to Postgres, Redis & NATS
|
|
db.Connect(cfg)
|
|
db.InitRedis(cfg)
|
|
db.InitNATS(cfg)
|
|
|
|
// 3. Run GORM migrations for logistics tables
|
|
if db.DB != nil {
|
|
err := migrations.Migrate(db.DB)
|
|
if err != nil {
|
|
utils.Error("⚠️ Migration failed, continuing server boot...", "error", err.Error())
|
|
}
|
|
}
|
|
|
|
// 4. Initialize Fiber App
|
|
app := fiber.New(fiber.Config{
|
|
AppName: "Doormile Logistics Service API v1",
|
|
})
|
|
|
|
// CORS policy
|
|
app.Use(cors.New(cors.Config{
|
|
AllowHeaders: "Origin,Content-Type,Accept,Authorization",
|
|
AllowOrigins: "http://localhost:5173,http://localhost:5174,http://localhost:3000,http://localhost:3001,http://localhost:3002,http://localhost:8080,http://localhost:8081,https://doormile.com,https://www.doormile.com,https://admin.doormile.com,https://api.doormile.com,https://crm.doormile.com,https://console.doormile.com",
|
|
AllowCredentials: true,
|
|
AllowMethods: "GET,POST,PUT,DELETE,PATCH,OPTIONS",
|
|
}))
|
|
|
|
// Structured Zap logger middleware
|
|
app.Use(middlewares.ZapLogger())
|
|
|
|
// 5. Register routes
|
|
routes.RegisterRoutes(app, cfg)
|
|
|
|
// 6. Pre-warm Redis pricing cache from Postgres
|
|
controllers.WarmPricingCache()
|
|
|
|
// 7. Start NATS booking worker in background
|
|
go worker.StartBookingWorker()
|
|
|
|
// 7. Startup server in a background thread
|
|
go func() {
|
|
utils.Info("Server starting", "port", cfg.Port)
|
|
if err := app.Listen(":" + cfg.Port); err != nil {
|
|
utils.Logger.Fatalf("Server failed to bind: %v", err)
|
|
}
|
|
}()
|
|
|
|
// Graceful shutdown listener
|
|
gracefulShutdown(app)
|
|
}
|
|
|
|
func gracefulShutdown(app *fiber.App) {
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
|
|
|
<-c
|
|
utils.Info("Shutting down Doormile Backend...")
|
|
|
|
// Shutdown fiber
|
|
if err := app.Shutdown(); err != nil {
|
|
utils.Error("Fiber shutdown failed", "error", err)
|
|
}
|
|
|
|
// Close database pools
|
|
db.CloseDB()
|
|
|
|
time.Sleep(1 * time.Second)
|
|
utils.Info("Shutdown completed cleanly.")
|
|
}
|