// Code generated by generate-dynamic-handler.go; DO NOT EDIT. // Generated at: 2025-08-28 14:59:09 // Service: VClaim (vclaim) // Description: BPJS VClaim service for eligibility and SEP management package handlers import ( "context" "fmt" "net/http" "strings" "time" "api-service/internal/config" "api-service/internal/models/reference" services "api-service/internal/services/bpjs" "api-service/pkg/logger" "github.com/gin-gonic/gin" "github.com/go-playground/validator/v10" "github.com/google/uuid" ) // VClaimHandler handles VClaim BPJS services type VClaimHandler struct { service services.VClaimService validator *validator.Validate logger logger.Logger config *config.BpjsConfig } // VClaimHandlerConfig contains configuration for VClaimHandler type VClaimHandlerConfig struct { BpjsConfig *config.BpjsConfig Logger logger.Logger Validator *validator.Validate } // NewVClaimHandler creates a new VClaimHandler func NewVClaimHandler(cfg VClaimHandlerConfig) *VClaimHandler { return &VClaimHandler{ service: services.NewService(*cfg.BpjsConfig), validator: cfg.Validator, logger: cfg.Logger, config: cfg.BpjsConfig, } } // GetPESERTA retrieves Peserta data // @Summary Get Peserta data // @Description Get participant eligibility information // @Tags vclaim,peserta // @Accept json // @Produce json // @Security ApiKeyAuth // @Param nokartu path string true "Nokartu" // @Success 200 {object} reference.PesertaResponse // @Failure 400 {object} reference.ErrorResponse // @Failure 500 {object} reference.ErrorResponse // @Router /Peserta/:nokartu [get] func (h *VClaimHandler) GetPESERTA(c *gin.Context) { ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second) defer cancel() // Generate request ID if not present requestID := c.GetHeader("X-Request-ID") if requestID == "" { requestID = uuid.New().String() c.Header("X-Request-ID", requestID) } // Authentication check if err := h.authenticateRequest(c); err != nil { h.logger.Error("Authentication failed", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusUnauthorized, reference.ErrorResponse{ Status: "error", Message: "Authentication failed", RequestID: requestID, }) return } // Extract path parameters nokartu := c.Param("nokartu") if nokartu == "" { h.logger.Error("Missing required parameter: nokartu", "request_id", requestID) c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Missing required parameter: nokartu", RequestID: requestID, }) return } // Check cache first cacheKey := fmt.Sprintf("vclaim:peserta:%s", nokartu) if cached, found := h.getCachedResponse(cacheKey); found { h.logger.Info("Cache hit for GetPESERTA", "request_id", requestID, "cache_key", cacheKey) c.Header("X-Cache", "HIT") c.JSON(http.StatusOK, cached) return } h.logger.Info("Processing GetPESERTA request", "request_id", requestID, "endpoint", "/Peserta/:nokartu", "nokartu", nokartu) // Call service method result, err := h.service.GetPESERTA(ctx, nokartu) if err != nil { h.logger.Error("Failed to get Peserta", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusInternalServerError, reference.ErrorResponse{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } // Prepare response response := reference.PesertaResponse{ Status: "success", Data: result, RequestID: requestID, } // Cache successful response h.setCachedResponse(cacheKey, response, 300) c.Header("X-Cache", "MISS") c.JSON(http.StatusOK, response) } // GetSEP retrieves Sep data // @Summary Get Sep data // @Description Manage SEP (Surat Eligibilitas Peserta) // @Tags vclaim,sep // @Accept json // @Produce json // @Security ApiKeyAuth // @Param nosep path string true "Nosep" // @Success 200 {object} reference.SEPResponse // @Failure 400 {object} reference.ErrorResponse // @Failure 500 {object} reference.ErrorResponse // @Router /SEP/:nosep [get] func (h *VClaimHandler) GetSEP(c *gin.Context) { ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second) defer cancel() // Generate request ID if not present requestID := c.GetHeader("X-Request-ID") if requestID == "" { requestID = uuid.New().String() c.Header("X-Request-ID", requestID) } // Authentication check if err := h.authenticateRequest(c); err != nil { h.logger.Error("Authentication failed", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusUnauthorized, reference.ErrorResponse{ Status: "error", Message: "Authentication failed", RequestID: requestID, }) return } // Extract path parameters nosep := c.Param("nosep") if nosep == "" { h.logger.Error("Missing required parameter: nosep", "request_id", requestID) c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Missing required parameter: nosep", RequestID: requestID, }) return } // Check cache first cacheKey := fmt.Sprintf("vclaim:sep:%s", nosep) if cached, found := h.getCachedResponse(cacheKey); found { h.logger.Info("Cache hit for GetSEP", "request_id", requestID, "cache_key", cacheKey) c.Header("X-Cache", "HIT") c.JSON(http.StatusOK, cached) return } h.logger.Info("Processing GetSEP request", "request_id", requestID, "endpoint", "/SEP/:nosep", "nosep", nosep) // Call service method result, err := h.service.GetSEP(ctx, nosep) if err != nil { h.logger.Error("Failed to get Sep", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusInternalServerError, reference.ErrorResponse{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } // Prepare response response := reference.SEPResponse{ Status: "success", Data: result, RequestID: requestID, } // Cache successful response h.setCachedResponse(cacheKey, response, 180) c.Header("X-Cache", "MISS") c.JSON(http.StatusOK, response) } // CreateSEP creates new Sep // @Summary Create Sep // @Description Manage SEP (Surat Eligibilitas Peserta) // @Tags vclaim,sep // @Accept json // @Produce json // @Security ApiKeyAuth // @Param request body reference.SEPRequest true "Sep data" // @Success 201 {object} reference.SEPResponse // @Failure 400 {object} reference.ErrorResponse // @Failure 500 {object} reference.ErrorResponse // @Router /sep [post] func (h *VClaimHandler) CreateSEP(c *gin.Context) { ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second) defer cancel() requestID := c.GetHeader("X-Request-ID") if requestID == "" { requestID = uuid.New().String() c.Header("X-Request-ID", requestID) } // Authentication check if err := h.authenticateRequest(c); err != nil { h.logger.Error("Authentication failed", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusUnauthorized, reference.ErrorResponse{ Status: "error", Message: "Authentication failed", RequestID: requestID, }) return } var req reference.SEPRequest if err := c.ShouldBindJSON(&req); err != nil { h.logger.Error("Invalid request body", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Invalid request body: " + err.Error(), RequestID: requestID, }) return } // Validate request if err := h.validator.Struct(&req); err != nil { h.logger.Error("Validation failed", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Validation failed: " + err.Error(), RequestID: requestID, }) return } h.logger.Info("Processing CreateSEP request", "request_id", requestID) // Call service method result, err := h.service.CreateSEP(ctx, &req) if err != nil { h.logger.Error("Failed to create Sep", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusInternalServerError, reference.ErrorResponse{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } response := reference.SEPResponse{ Status: "success", Data: result, RequestID: requestID, } c.JSON(http.StatusCreated, response) } // UpdateSEP updates existing Sep // @Summary Update Sep // @Description Manage SEP (Surat Eligibilitas Peserta) // @Tags vclaim,sep // @Accept json // @Produce json // @Security ApiKeyAuth // @Param nosep path string true "Nosep" // @Param request body reference.SEPRequest true "Sep data" // @Success 200 {object} reference.SEPResponse // @Failure 400 {object} reference.ErrorResponse // @Failure 500 {object} reference.ErrorResponse // @Router /sep/:nosep [put] func (h *VClaimHandler) UpdateSEP(c *gin.Context) { ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second) defer cancel() requestID := c.GetHeader("X-Request-ID") if requestID == "" { requestID = uuid.New().String() c.Header("X-Request-ID", requestID) } // Extract path parameters nosep := c.Param("nosep") if nosep == "" { c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Missing required parameter: nosep", RequestID: requestID, }) return } var req reference.SEPRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Invalid request body: " + err.Error(), RequestID: requestID, }) return } if err := h.validator.Struct(&req); err != nil { c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Validation failed: " + err.Error(), RequestID: requestID, }) return } // Invalidate cache cacheKey := fmt.Sprintf("vclaim:sep:%s", nosep) h.invalidateCache(cacheKey) // Call service method result, err := h.service.UpdateSEP(ctx, nosep, &req) if err != nil { h.logger.Error("Failed to update Sep", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusInternalServerError, reference.ErrorResponse{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } response := reference.SEPResponse{ Status: "success", Data: result, RequestID: requestID, } c.JSON(http.StatusOK, response) } // DeleteSEP deletes existing Sep // @Summary Delete Sep // @Description Manage SEP (Surat Eligibilitas Peserta) // @Tags vclaim,sep // @Accept json // @Produce json // @Security ApiKeyAuth // @Param nosep path string true "Nosep" // @Success 200 {object} reference.BaseResponse // @Failure 400 {object} reference.ErrorResponse // @Failure 500 {object} reference.ErrorResponse // @Router /sep/:nosep [delete] func (h *VClaimHandler) DeleteSEP(c *gin.Context) { ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second) defer cancel() requestID := c.GetHeader("X-Request-ID") if requestID == "" { requestID = uuid.New().String() c.Header("X-Request-ID", requestID) } // Extract path parameters nosep := c.Param("nosep") if nosep == "" { c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Missing required parameter: nosep", RequestID: requestID, }) return } // Invalidate cache cacheKey := fmt.Sprintf("vclaim:sep:%s", nosep) h.invalidateCache(cacheKey) // Call service method err := h.service.DeleteSEP(ctx, nosep) if err != nil { h.logger.Error("Failed to delete Sep", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusInternalServerError, reference.ErrorResponse{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } response := reference.BaseResponse{ Status: "success", Message: "Sep deleted successfully", RequestID: requestID, } c.JSON(http.StatusOK, response) } // GetRUJUKAN retrieves Rujukan data // @Summary Get Rujukan data // @Description Get referral information // @Tags vclaim,rujukan // @Accept json // @Produce json // @Security ApiKeyAuth // @Param norujukan path string true "Norujukan" // @Success 200 {object} reference.RujukanResponse // @Failure 400 {object} reference.ErrorResponse // @Failure 500 {object} reference.ErrorResponse // @Router /rujukan/:norujukan [get] func (h *VClaimHandler) GetRUJUKAN(c *gin.Context) { ctx, cancel := context.WithTimeout(c.Request.Context(), 30*time.Second) defer cancel() // Generate request ID if not present requestID := c.GetHeader("X-Request-ID") if requestID == "" { requestID = uuid.New().String() c.Header("X-Request-ID", requestID) } // Authentication check if err := h.authenticateRequest(c); err != nil { h.logger.Error("Authentication failed", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusUnauthorized, reference.ErrorResponse{ Status: "error", Message: "Authentication failed", RequestID: requestID, }) return } // Extract path parameters norujukan := c.Param("norujukan") if norujukan == "" { h.logger.Error("Missing required parameter: norujukan", "request_id", requestID) c.JSON(http.StatusBadRequest, reference.ErrorResponse{ Status: "error", Message: "Missing required parameter: norujukan", RequestID: requestID, }) return } // Check cache first cacheKey := fmt.Sprintf("vclaim:rujukan:%s", norujukan) if cached, found := h.getCachedResponse(cacheKey); found { h.logger.Info("Cache hit for GetRUJUKAN", "request_id", requestID, "cache_key", cacheKey) c.Header("X-Cache", "HIT") c.JSON(http.StatusOK, cached) return } h.logger.Info("Processing GetRUJUKAN request", "request_id", requestID, "endpoint", "/rujukan/:norujukan", "norujukan", norujukan) // Call service method result, err := h.service.GetRUJUKAN(ctx, norujukan) if err != nil { h.logger.Error("Failed to get Rujukan", "error", err.Error(), "request_id", requestID) c.JSON(http.StatusInternalServerError, reference.ErrorResponse{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } // Prepare response response := reference.RujukanResponse{ Status: "success", Data: result, RequestID: requestID, } // Cache successful response h.setCachedResponse(cacheKey, response, 600) c.Header("X-Cache", "MISS") c.JSON(http.StatusOK, response) } // RegisterRoutes registers all VClaim routes func (h *VClaimHandler) RegisterRoutes(router *gin.RouterGroup) { router.GET("/Peserta/:nokartu", h.GetPESERTA) router.GET("/SEP/:nosep", h.GetSEP) router.POST("/sep", h.CreateSEP) router.PUT("/sep/:nosep", h.UpdateSEP) router.DELETE("/sep/:nosep", h.DeleteSEP) router.GET("/rujukan/:norujukan", h.GetRUJUKAN) } // Helper methods func (h *VClaimHandler) authenticateRequest(c *gin.Context) error { token := c.GetHeader("Authorization") if token == "" { return fmt.Errorf("missing authorization header") } if strings.HasPrefix(token, "Bearer ") { token = strings.TrimPrefix(token, "Bearer ") } return h.auth.ValidateToken(token) } func (h *VClaimHandler) getCachedResponse(key string) (interface{}, bool) { if h.cache == nil { return nil, false } return h.cache.Get(key) } func (h *VClaimHandler) setCachedResponse(key string, data interface{}, ttl int) { if h.cache == nil { return } h.cache.Set(key, data, time.Duration(ttl)*time.Second) } func (h *VClaimHandler) invalidateCache(key string) { if h.cache == nil { return } h.cache.Delete(key) }