main.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "net/http"
  6. "os"
  7. "time"
  8. "github.com/gin-gonic/gin"
  9. "github.com/golang-migrate/migrate/v4"
  10. _ "github.com/golang-migrate/migrate/v4/database/postgres"
  11. _ "github.com/golang-migrate/migrate/v4/source/file"
  12. "ems-backend/models"
  13. "ems-backend/routes"
  14. )
  15. func initSchema() {
  16. // Construct DB URL from env vars or use a default one suitable for the container environment
  17. // Expected format: postgres://user:password@host:port/dbname?sslmode=disable
  18. dbUser := os.Getenv("POSTGRES_USER")
  19. if dbUser == "" { dbUser = "ems" }
  20. dbPass := os.Getenv("DB_PASSWORD") // Note: inconsistent naming in env, checking plan
  21. if dbPass == "" { dbPass = "ems_pass" } // Fallback
  22. dbHost := os.Getenv("POSTGRES_HOST")
  23. if dbHost == "" { dbHost = "postgres" }
  24. dbPort := os.Getenv("POSTGRES_PORT")
  25. if dbPort == "" { dbPort = "5432" }
  26. dbName := os.Getenv("POSTGRES_DB")
  27. if dbName == "" { dbName = "ems" }
  28. // If DB_PASSWORD env var is not set but POSTGRES_PASSWORD is (from docker-compose)
  29. if dbPass == "ems_pass" && os.Getenv("POSTGRES_PASSWORD") != "" {
  30. dbPass = os.Getenv("POSTGRES_PASSWORD")
  31. }
  32. dbUrl := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=disable",
  33. dbUser, dbPass, dbHost, dbPort, dbName)
  34. log.Printf("Initializing schema migration...")
  35. // Point to the migration files inside the container
  36. var m *migrate.Migrate
  37. var err error
  38. maxRetries := 30
  39. for i := 0; i < maxRetries; i++ {
  40. m, err = migrate.New("file:///app/migrations", dbUrl)
  41. if err == nil {
  42. break
  43. }
  44. log.Printf("Migration initialization failed (attempt %d/%d): %v. Retrying in 2 seconds...", i+1, maxRetries, err)
  45. time.Sleep(2 * time.Second)
  46. }
  47. if err != nil {
  48. log.Printf("Migration initialization finally failed (might be in dev or path missing): %v", err)
  49. return
  50. }
  51. if err := m.Up(); err != nil && err != migrate.ErrNoChange {
  52. log.Fatal("Database migration failed:", err)
  53. }
  54. log.Println("Database schema is up to date.")
  55. }
  56. func main() {
  57. initSchema()
  58. models.InitDB()
  59. r := gin.Default()
  60. // Setup Routes
  61. routes.SetupRoutes(r)
  62. // Health Check
  63. r.GET("/ping", func(c *gin.Context) {
  64. c.JSON(http.StatusOK, gin.H{
  65. "message": "pong",
  66. "system": "EMS Backend",
  67. })
  68. })
  69. // API Group
  70. v1 := r.Group("/api/v1")
  71. {
  72. v1.GET("/info", func(c *gin.Context) {
  73. c.JSON(http.StatusOK, gin.H{
  74. "version": "1.0.0",
  75. "env": os.Getenv("GIN_MODE"),
  76. })
  77. })
  78. }
  79. port := os.Getenv("PORT")
  80. if port == "" {
  81. port = "8080"
  82. }
  83. fmt.Printf("Server starting on port %s...\n", port)
  84. r.Run(":" + port)
  85. }