Files
victorialogs-manager/backend/internal/api/router.go
Claude Code 9bd17156e4 feat: Implement User Management API (Issue #6) and wire up router
- Create UserService with CRUD operations
- Implement ListUsers with pagination
- Implement GetUser, CreateUser, UpdateUser, DeleteUser
- Add ResetUserPassword for admin password resets
- Create UserHandler with HTTP endpoints
- Update router to wire up all handlers and middleware
- Add authentication middleware to protected routes
- Add admin-only middleware to user management routes

Closes #6

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-05 00:51:02 +03:00

187 lines
6.1 KiB
Go

package api
import (
"database/sql"
"net/http"
"github.com/gin-gonic/gin"
"github.com/yourusername/victorialogs-manager/internal/api/handlers"
"github.com/yourusername/victorialogs-manager/internal/api/middleware"
"github.com/yourusername/victorialogs-manager/internal/config"
"github.com/yourusername/victorialogs-manager/internal/repository"
"github.com/yourusername/victorialogs-manager/internal/services"
"github.com/yourusername/victorialogs-manager/internal/utils"
)
// NewRouter creates and configures the main router
func NewRouter(cfg *config.Config, db *sql.DB) *gin.Engine {
// Set Gin mode
gin.SetMode(gin.ReleaseMode)
router := gin.New()
// Global middleware
router.Use(gin.Recovery())
router.Use(middleware.CORSMiddleware())
router.Use(middleware.RequestLogger())
// Initialize JWT manager
jwtManager := utils.NewJWTManager(
cfg.Auth.JWTSecret,
cfg.Auth.AccessTokenDuration,
cfg.Auth.RefreshTokenDuration,
)
// Initialize repositories
userRepo := repository.NewUserRepository(db)
// Initialize services
authService := services.NewAuthService(userRepo, jwtManager)
userService := services.NewUserService(userRepo)
// Initialize handlers
authHandler := handlers.NewAuthHandler(authService)
userHandler := handlers.NewUserHandler(userService)
// Health check endpoint
router.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"service": "victorialogs-manager",
})
})
// API v1 routes
v1 := router.Group("/api/v1")
{
// Authentication routes (public)
auth := v1.Group("/auth")
{
auth.POST("/login", authHandler.Login)
auth.POST("/refresh", authHandler.RefreshToken)
}
// Protected auth routes (require authentication)
authProtected := v1.Group("/auth")
authProtected.Use(middleware.AuthMiddleware(jwtManager))
{
authProtected.GET("/me", authHandler.GetMe)
authProtected.POST("/change-password", authHandler.ChangePassword)
}
// User management routes (admin only)
users := v1.Group("/users")
users.Use(middleware.AuthMiddleware(jwtManager))
users.Use(middleware.RequireAdmin())
{
users.GET("", userHandler.ListUsers)
users.POST("", userHandler.CreateUser)
users.GET("/:id", userHandler.GetUser)
users.PUT("/:id", userHandler.UpdateUser)
users.DELETE("/:id", userHandler.DeleteUser)
users.POST("/:id/reset-password", userHandler.ResetUserPassword)
}
// Log querying routes (protected)
logs := v1.Group("/logs")
logs.Use(middleware.AuthMiddleware(jwtManager))
{
logs.POST("/query", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
logs.POST("/tail", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
logs.GET("/facets", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
logs.POST("/stats", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
logs.POST("/export", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
}
// Alert management routes (protected)
alerts := v1.Group("/alerts")
alerts.Use(middleware.AuthMiddleware(jwtManager))
{
alerts.GET("/rules", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
alerts.POST("/rules", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
alerts.GET("/rules/:id", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
alerts.PUT("/rules/:id", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
alerts.DELETE("/rules/:id", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
alerts.POST("/reload", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
alerts.GET("/active", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
}
// Pattern detection routes (protected)
patterns := v1.Group("/patterns")
patterns.Use(middleware.AuthMiddleware(jwtManager))
{
patterns.GET("", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
patterns.POST("", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
patterns.PUT("/:id", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
patterns.DELETE("/:id", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
patterns.POST("/detect", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
patterns.POST("/ml/train", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
patterns.POST("/ml/detect", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
}
// Report routes (protected)
reports := v1.Group("/reports")
reports.Use(middleware.AuthMiddleware(jwtManager))
{
reports.GET("", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
reports.POST("", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
reports.GET("/:id", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
reports.PUT("/:id", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
reports.DELETE("/:id", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
reports.POST("/:id/execute", func(c *gin.Context) {
c.JSON(http.StatusNotImplemented, gin.H{"message": "not implemented yet"})
})
}
}
return router
}