Files
websocket-qris/internal/routes/v1/routes.go
2025-11-17 15:04:27 +07:00

193 lines
7.1 KiB
Go

package v1
import (
"api-service/internal/config"
"api-service/internal/database"
healthcheckHandlers "api-service/internal/handlers/healthcheck"
websocketHandlers "api-service/internal/handlers/websocket"
"api-service/internal/middleware"
services "api-service/internal/services/auth"
websocketServices "api-service/internal/services/websocket"
"api-service/pkg/logger"
"time"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)
func RegisterRoutes(cfg *config.Config) *gin.Engine {
router := gin.New()
// Initialize auth middleware configuration
middleware.AuthJWTMiddleware()
// Add global middleware
router.Use(middleware.CORSConfig())
router.Use(middleware.ErrorHandler())
router.Use(logger.RequestLoggerMiddleware(logger.Default()))
router.Use(gin.Recovery())
// Initialize services with error handling
authService := services.NewAuthService(cfg)
if authService == nil {
logger.Fatal("Failed to initialize auth service")
}
// Initialize database service
dbService := database.New(cfg)
// =============================================================================
// HEALTH CHECK & SYSTEM ROUTES
// =============================================================================
healthCheckHandler := healthcheckHandlers.NewHealthCheckHandler(dbService)
sistem := router.Group("/api/sistem")
{
sistem.GET("/health", healthCheckHandler.CheckHealth)
sistem.GET("/databases", func(c *gin.Context) {
c.JSON(200, gin.H{
"databases": dbService.ListDBs(),
"health": dbService.Health(),
"timestamp": time.Now().Unix(),
})
})
sistem.GET("/info", func(c *gin.Context) {
c.JSON(200, gin.H{
"service": "API Service v1.0.0",
"websocket_active": true,
"connected_clients": 0, // TODO: implement websocket handler
"databases": dbService.ListDBs(),
"timestamp": time.Now().Unix(),
})
})
}
// =============================================================================
// SWAGGER DOCUMENTATION
// =============================================================================
router.GET("/swagger/*any", ginSwagger.WrapHandler(
swaggerFiles.Handler,
ginSwagger.DefaultModelsExpandDepth(-1),
ginSwagger.DeepLinking(true),
))
// =============================================================================
// WEBSOCKET TEST CLIENT
// =============================================================================
// =============================================================================
// API v1 GROUP
// =============================================================================
v1 := router.Group("/api/v1")
// =============================================================================
// PUBLIC ROUTES (No Authentication Required)
// =============================================================================
// Authentication routes
// authHandler := authHandlers.NewAuthHandler(authService)
// tokenHandler := authHandlers.NewTokenHandler(authService)
// Basic auth routes
// v1.POST("/auth/login", authHandler.Login)
// v1.POST("/auth/register", authHandler.Register)
// v1.POST("/auth/refresh", authHandler.RefreshToken)
// Token generation routes
// v1.POST("/token/generate", tokenHandler.GenerateToken)
// v1.POST("/token/generate-direct", tokenHandler.GenerateTokenDirect)
// =============================================================================
// WEBSOCKET ROUTES
// =============================================================================
// WebSocket handler will be initialized after websocketHub is defined
// =============================================================================
// PUBLISHED ROUTES
// =============================================================================
// Initialize WebSocket hub with database service
websocketHub := websocketServices.NewHub(cfg.WebSocket)
go websocketHub.Run() // Start WebSocket hub in background
// Initialize WebSocket handler
websocketHandler := websocketHandlers.NewWebSocketHandler(websocketHub, cfg.WebSocket)
// WebSocket routes
v1.GET("/ws", websocketHandler.HandleWebSocket)
v1.GET("/ws/test", websocketHandler.TestWebSocketConnection)
v1.GET("/ws/stats", websocketHandler.GetWebSocketStats)
v1.POST("/ws/broadcast/qris", websocketHandler.BroadcastQris)
v1.POST("/ws/broadcast/check", websocketHandler.BroadcastCheck)
// Retribusi endpoints with WebSocket notifications
// retribusiHandler := retribusiHandlers.NewRetribusiHandler()
// retribusiGroup := v1.Group("/retribusi")
// {
// retribusiGroup.GET("", retribusiHandler.GetRetribusi)
// retribusiGroup.GET("/dynamic", retribusiHandler.GetRetribusiDynamic)
// retribusiGroup.GET("/search", retribusiHandler.SearchRetribusiAdvanced)
// retribusiGroup.GET("/id/:id", retribusiHandler.GetRetribusiByID)
// // POST/PUT/DELETE with automatic WebSocket notifications
// retribusiGroup.POST("", func(c *gin.Context) {
// retribusiHandler.CreateRetribusi(c)
// // Trigger WebSocket notification after successful creation
// if c.Writer.Status() == 200 || c.Writer.Status() == 201 {
// // Notify database change via WebSocket
// // websocketHub.NotifyDatabaseChange("postgres_satudata", "retribusi_changes",
// // fmt.Sprintf(`{"action": "created", "timestamp": "%s"}`, time.Now().Format(time.RFC3339)))
// }
// })
// retribusiGroup.PUT("/id/:id", func(c *gin.Context) {
// // id := c.Param("id")
// retribusiHandler.UpdateRetribusi(c)
// // Trigger WebSocket notification after successful update
// if c.Writer.Status() == 200 {
// // Notify database change via WebSocket
// // websocketHub.NotifyDatabaseChange("postgres_satudata", "retribusi_changes",
// // fmt.Sprintf(`{"action": "updated", "id": "%s", "timestamp": "%s"}`, id, time.Now().Format(time.RFC3339)))
// }
// })
// retribusiGroup.DELETE("/id/:id", func(c *gin.Context) {
// // id := c.Param("id")
// retribusiHandler.DeleteRetribusi(c)
// // Trigger WebSocket notification after successful deletion
// if c.Writer.Status() == 200 {
// // Notify database change via WebSocket
// // websocketHub.NotifyDatabaseChange("postgres_satudata", "retribusi_changes",
// // fmt.Sprintf(`{"action": "deleted", "id": "%s", "timestamp": "%s"}`, id, time.Now().Format(time.RFC3339)))
// }
// })
// }
// =============================================================================
// PROTECTED ROUTES (Authentication Required)
// =============================================================================
// Create protected group with configurable authentication
protected := v1.Group("/")
protected.Use(middleware.AuthJWTMiddleware()) // Use configurable authentication
// User profile (protected)
// protected.GET("/auth/me", authHandler.Me)
// Retribusi endpoints (CRUD operations - should be protected)
// protectedQris := protected.Group("/ws")
// {
// protectedQris.POST("/qris/broadcast", websocketHandler.BroadcastQris) // POST /api/v1/ws/
// protectedQris.POST("/check/broadcast", websocketHandler.BroadcastCheck) // POST /api/v1/ws/
// }
return router
}