package main import ( "fmt" "net/http" "os" "git.pengzhan.dev/noteplace-server/internal/api" "git.pengzhan.dev/noteplace-server/internal/auth" "git.pengzhan.dev/noteplace-server/internal/store" "github.com/gin-gonic/gin" "github.com/joho/godotenv" "go.uber.org/zap" ) func main() { logger, _ := zap.NewProduction() defer func() { _ = logger.Sync() }() // flushes buffer, if any zap.ReplaceGlobals(logger) // Load .env file first if err := godotenv.Load(); err != nil { zap.S().Infof("No .env file found, using environment variables") } // Initialize the data store dbPath := "db.json" s, err := store.New(dbPath) if err != nil { zap.S().Fatalf("Failed to initialize store: %v", err) } zap.S().Infof("Successfully loaded data from %s", dbPath) // Setup the HTTP server and register handlers router := gin.Default() router.GET("/api/health", func(ctx *gin.Context) { ctx.JSON(http.StatusOK, gin.H{ "status": "ok", }) }) placesHandler := &api.PlacesHandler{Store: s} router.GET("/api/places", placesHandler.HandleGetPlaces) router.POST("/api/places", api.AuthMiddleware(s), placesHandler.HandleCreatePlace) router.GET("/api/places/:id", placesHandler.HandleGetPlaceByID) router.GET("/api/places/:id/ratings", placesHandler.HandleGetPlaceRatings) router.GET("/api/places/:id/attributes", placesHandler.HandleGetPlaceAttributes) // Register Auth API routes authenticator, err := auth.NewAuthenticator() if err != nil { zap.S().Fatalf("Failed to initialize authenticator: %v", err) } // Get Frontend URL from environment frontendURL := os.Getenv("FRONTEND_URL") if frontendURL == "" { frontendURL = "http://localhost:5173" } authHandler := &api.AuthHandler{Store: s, Authenticator: authenticator, FrontendURL: frontendURL} router.GET("/api/auth/google/login", authHandler.HandleGoogleLogin) router.GET("/api/auth/google/callback", authHandler.HandleGoogleCallback) router.GET("/api/auth/google/cli/login", authHandler.HandleCliLogin) router.POST("/api/auth/google/cli/callback", authHandler.HandleCliCallback) router.GET("/api/auth/user", api.AuthMiddleware(s), authHandler.HandleGetUser) // Register Attributes API routes attributesHandler := &api.AttributesHandler{Store: s} router.POST("/api/attributes", api.AuthMiddleware(s), attributesHandler.HandleCreateAttribute) // Register Ratings API routes ratingsHandler := &api.RatingsHandler{Store: s} router.POST("/api/ratings", api.AuthMiddleware(s), ratingsHandler.HandleCreateRating) router.PUT("/api/ratings/:id", api.AuthMiddleware(s), ratingsHandler.HandleUpdateRating) router.DELETE("/api/ratings/:id", api.AuthMiddleware(s), ratingsHandler.HandleDeleteRating) router.GET("/api/ratings/my-ratings", api.AuthMiddleware(s), ratingsHandler.HandleGetMyRatings) // Determine port for HTTP service. ip := os.Getenv("IP") port := os.Getenv("PORT") if port == "" { port = "3001" } addr := fmt.Sprintf("%s:%s", ip, port) zap.S().Infof("starting server and listen to %s", addr) if err = router.Run( addr, ); err != nil { zap.S().Fatalf("failed to start server: %+v", err) } }