175 lines
6.2 KiB
Go
175 lines
6.2 KiB
Go
package v1
|
|
|
|
import (
|
|
"api-service/internal/config"
|
|
"api-service/internal/database"
|
|
authHandlers "api-service/internal/handlers/auth"
|
|
healthcheckHandlers "api-service/internal/handlers/healthcheck"
|
|
retribusiHandlers "api-service/internal/handlers/retribusi"
|
|
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.InitializeAuth(cfg)
|
|
|
|
// 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)
|
|
|
|
// 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)))
|
|
}
|
|
})
|
|
}
|
|
|
|
return router
|
|
}
|