package main // @title Tender Management API // @version 1.0.0 // @description This is the API documentation for the Tender Management System. // @termsOfService http://swagger.io/terms/ // @contact.name API Support // @contact.url http://www.swagger.io/support // @contact.email support@swagger.io // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html // @host localhost:8081 // @securityDefinitions.apikey BearerAuth // @in header // @name Authorization // @description Type "Bearer" followed by a space and JWT token. // @tag.name Users // @tag.description User management operations including authentication, profile management, and admin operations // @tag.name Authorization // @tag.description Authentication operations including login, logout, and token management // @tag.name Customers-Admin // @tag.description Customer management operations including authentication, profile management, and admin operations // @tag.name Customers-Authorization // @tag.description Customer authentication operations including login, logout, and token management // @tag.name Health // @tag.description Health check operations import ( "context" "fmt" "net/http" "time" "tm/internal/customer" "tm/internal/user" _ "tm/cmd/web/docs" // This is generated by swag ) func main() { conf := initConfig() logger := initLogger(conf.Logging) defer logger.Sync() // Initialize MongoDB connection manager mongoManager := initMongoDB(conf.Database.MongoDB, logger) defer func() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() if err := mongoManager.Close(ctx); err != nil { logger.Error("Failed to close MongoDB connection", map[string]interface{}{ "error": err.Error(), }) } }() // Initialize Redis connection manager redisClient := initRedis(conf.Cache.Redis, logger) defer func() { if err := redisClient.Close(); err != nil { logger.Error("Failed to close Redis connection", map[string]interface{}{ "error": err.Error(), }) } }() // Initialize authorization service userAuthService := initAuthorizationService(conf.UserAuthorization.JWT, redisClient, logger) customerAuthService := initAuthorizationService(conf.CustomerAuthorization.JWT, redisClient, logger) // Initialize repositories with MongoDB connection manager userRepository := user.NewUserRepository(mongoManager, logger) customerRepository := customer.NewCustomerRepository(mongoManager, logger) logger.Info("Repositories initialized successfully", map[string]interface{}{ "repositories": []string{"customer", "user"}, }) // Initialize validation service userValidator := user.NewValidationService() // Initialize services with repositories userService := user.NewUserService(userRepository, logger, userAuthService, userValidator) customerService := customer.NewCustomerService(customerRepository, logger, customerAuthService) logger.Info("Services initialized successfully", map[string]interface{}{ "services": []string{"customer", "user"}, }) // Initialize handlers with services userHandler := user.NewUserHandler(userService, logger, userValidator, userAuthService) customerHandler := customer.NewHandler(customerService, userHandler, customerAuthService, logger) logger.Info("Handlers initialized successfully", map[string]interface{}{ "handlers": []string{"customer", "user"}, }) // Initialize HTTP server e := initHTTPServer(conf, logger) // Register routes userHandler.RegisterRoutes(e) customerHandler.RegisterRoutes(e) // Start server serverAddr := fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port) logger.Info("HTTP server starting", map[string]interface{}{ "address": serverAddr, "version": "1.0.0", "host": conf.Server.Host, "port": conf.Server.Port, }) if err := e.Start(serverAddr); err != nil && err != http.ErrServerClosed { logger.Error("Failed to start HTTP server", map[string]interface{}{ "error": err.Error(), "address": serverAddr, "version": "1.0.0", "host": conf.Server.Host, "port": conf.Server.Port, }) panic(fmt.Sprintf("Failed to start HTTP server: %v", err)) } }