Files
tm_back/cmd/web/bootstrap.go
T
n.nakhostin 98f581ec97 Enhance cursor rules and add user management functionality
- Updated cursor rules to emphasize the importance of dependency injection and logging practices.
- Introduced a new user management domain, including entities, services, handlers, and validation.
- Implemented user authentication features such as login, registration, and role-based access control.
- Added Redis integration for token management and caching.
- Enhanced API documentation with Swagger for user-related endpoints.
- Updated configuration to support new JWT settings and Redis connection parameters.
2025-08-10 14:09:17 +03:30

186 lines
5.3 KiB
Go

package main
import (
"fmt"
"net/http"
"time"
"tm/infra"
"tm/pkg/authorization"
"tm/pkg/logger"
"tm/pkg/mongo"
"tm/pkg/redis"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
echoSwagger "github.com/swaggo/echo-swagger"
)
// Init Application Configuration
func initConfig() infra.Config {
config, err := infra.LoadConfig(".")
if err != nil {
panic(fmt.Sprintf("Failed to load config: %v", err))
}
return *config
}
// Init Logger Service
func initLogger(conf infra.LoggingConfig) logger.Logger {
return logger.NewLogger(&logger.Config{
Level: conf.Level,
Format: conf.Format,
Output: conf.Output,
File: logger.FileConfig{
Path: conf.File.Path,
MaxSize: conf.File.MaxSize,
MaxBackups: conf.File.MaxBackups,
MaxAge: conf.File.MaxAge,
Compress: conf.File.Compress,
},
})
}
// Init MongoDB Connection Manager
func initMongoDB(conf infra.MongoConfig, log logger.Logger) *mongo.ConnectionManager {
// Convert infra.MongoConfig to mongo.ConnectionConfig
connectionConfig := mongo.ConnectionConfig{
URI: conf.URI,
Database: conf.Name,
MaxPoolSize: uint64(conf.MaxPoolSize),
MinPoolSize: 5, // Default minimum pool size
MaxConnIdleTime: 30 * time.Minute, // Default idle time
ConnectTimeout: conf.Timeout,
ServerSelectionTimeout: 5 * time.Second, // Default server selection timeout
}
// Create MongoDB connection manager
connectionManager, err := mongo.NewConnectionManager(connectionConfig, log)
if err != nil {
log.Error("Failed to initialize MongoDB connection", map[string]interface{}{
"error": err.Error(),
"uri": conf.URI,
"db": conf.Name,
})
panic(fmt.Sprintf("Failed to initialize MongoDB connection: %v", err))
}
log.Info("MongoDB connection manager initialized successfully", map[string]interface{}{
"database": conf.Name,
"uri": conf.URI,
"pool_size": conf.MaxPoolSize,
})
return connectionManager
}
// initHTTPServer initializes the Echo HTTP server with middleware
func initHTTPServer(conf infra.Config, log logger.Logger) *echo.Echo {
e := echo.New()
// Configure Echo
// e.HideBanner = true
// e.HidePort = true
// Add middleware
e.Use(middleware.Recover())
e.Use(middleware.RequestID())
e.Use(middleware.Logger())
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"*"}, // TODO: Configure properly for production
AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodOptions},
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept, echo.HeaderAuthorization},
}))
// Add custom middleware for logging
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
start := time.Now()
// Process request
err := next(c)
// Log request details
duration := time.Since(start)
log.Info("HTTP request processed", map[string]interface{}{
"method": c.Request().Method,
"path": c.Request().URL.Path,
"status": c.Response().Status,
"duration": duration.String(),
"user_agent": c.Request().UserAgent(),
"remote_ip": c.RealIP(),
})
return err
}
})
// Add health check endpoint
e.GET("/health", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]interface{}{
"status": "healthy",
"time": time.Now().Unix(),
"version": "1.0.0",
})
})
// Add Swagger documentation endpoint
e.GET("/swagger/*", echoSwagger.WrapHandler)
log.Info("HTTP server initialized successfully", map[string]interface{}{
"middleware": []string{"recover", "request_id", "logger", "cors", "custom_logging"},
})
return e
}
// Init Redis Connection Manager
func initRedis(conf infra.RedisConfig, log logger.Logger) redis.Client {
connectionConfig := &redis.Config{
Host: conf.Host,
Port: conf.Port,
Password: conf.Password,
DB: conf.DB,
PoolSize: conf.PoolSize,
}
redisClient, err := redis.NewClient(connectionConfig, log)
if err != nil {
log.Error("Failed to initialize Redis connection", map[string]interface{}{
"error": err.Error(),
"host": conf.Host,
"port": conf.Port,
})
panic(fmt.Sprintf("Failed to initialize Redis connection: %v", err))
}
log.Info("Redis connection manager initialized successfully", map[string]interface{}{
"host": conf.Host,
"port": conf.Port,
"pool_size": conf.PoolSize,
})
return redisClient
}
// Init Authorization Service
func initAuthorizationService(conf infra.JWTConfig, redisClient redis.Client, log logger.Logger) authorization.AuthorizationService {
authConfig := &authorization.AuthorizationConfig{
AccessTokenSecret: conf.AccessSecret,
RefreshTokenSecret: conf.RefreshSecret,
AccessTokenExpiry: time.Duration(conf.AccessExpiresIn) * time.Second,
RefreshTokenExpiry: time.Duration(conf.RefreshExpiresIn) * time.Second,
Issuer: "tender-management-system",
Audience: "tender-management-users",
}
authService := authorization.NewAuthorizationService(authConfig, log, redisClient)
log.Info("Authorization service initialized successfully", map[string]interface{}{
"access_expires_in": conf.AccessExpiresIn,
"refresh_expires_in": conf.RefreshExpiresIn,
})
return authService
}