// Service: VClaim (vclaim) // Description: BPJS VClaim service for eligibility and SEP management package sep import ( "context" "strings" "net/http" "time" "api-service/internal/config" "api-service/internal/models" "api-service/internal/models/vclaim/sep" "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, } } // GetSepSep godoc // @Summary Get SepSep data // @Description Manage SEP (Surat Eligibilitas Peserta) // @Tags Sep // @Accept json // @Produce json // @Security ApiKeyAuth // @Param X-Request-ID header string false "Request ID for tracking" // @Param nosep path string true "nosep" example("example_value") // @Success 200 {object} sep.SepResponse "Successfully retrieved SepSep data" // @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters" // @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials" // @Failure 404 {object} models.ErrorResponseBpjs "Not found - SepSep not found" // @Failure 500 {object} models.ErrorResponseBpjs "Internal server error" // @Router /sep/:nosep [get] func (h *VClaimHandler) GetSepSep(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) } h.logger.Info("Processing GetSepSep request", map[string]interface{}{ "request_id": requestID, "endpoint": "/sep/:nosep", "nosep": c.Param("nosep"), }) // Extract path parameters nosep := c.Param("nosep") if nosep == "" { h.logger.Error("Missing required parameter nosep", map[string]interface{}{ "request_id": requestID, }) c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{ Status: "error", Message: "Missing required parameter nosep", RequestID: requestID, }) return } // Call service method var response sep.SepResponse endpoint := "/sep/:nosep" endpoint = strings.Replace(endpoint, ":nosep", nosep, 1) err := h.service.Get(ctx, endpoint, &response) if err != nil { h.logger.Error("Failed to get SepSep", map[string]interface{}{ "error": err.Error(), "request_id": requestID, }) c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } // Ensure response has proper fields response.Status = "success" response.RequestID = requestID c.JSON(http.StatusOK, response) } // CreateSepSep godoc // @Summary Create new SepSep // @Description Manage SEP (Surat Eligibilitas Peserta) // @Tags Sep // @Accept json // @Produce json // @Security ApiKeyAuth // @Param X-Request-ID header string false "Request ID for tracking" // @Param request body sep.SepRequest true "SepSep data" // @Success 201 {object} sep.SepResponse "Successfully created SepSep" // @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid request body or validation error" // @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials" // @Failure 409 {object} models.ErrorResponseBpjs "Conflict - SepSep already exists" // @Failure 500 {object} models.ErrorResponseBpjs "Internal server error" // @Router /sep [post] func (h *VClaimHandler) CreateSepSep(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) } h.logger.Info("Processing CreateSepSep request", map[string]interface{}{ "request_id": requestID, }) var req sep.SepRequest if err := c.ShouldBindJSON(&req); err != nil { h.logger.Error("Invalid request body", map[string]interface{}{ "error": err.Error(), "request_id": requestID, }) c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{ 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", map[string]interface{}{ "error": err.Error(), "request_id": requestID, }) c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{ Status: "error", Message: "Validation failed: " + err.Error(), RequestID: requestID, }) return } // Call service method var response sep.SepResponse err := h.service.Post(ctx, "/sep", &req, &response) if err != nil { h.logger.Error("Failed to create SepSep", map[string]interface{}{ "error": err.Error(), "request_id": requestID, }) c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } // Ensure response has proper fields response.Status = "success" response.RequestID = requestID c.JSON(http.StatusCreated, response) } // UpdateSepSep godoc // @Summary Update existing SepSep // @Description Manage SEP (Surat Eligibilitas Peserta) // @Tags Sep // @Accept json // @Produce json // @Security ApiKeyAuth // @Param X-Request-ID header string false "Request ID for tracking" // @Param nosep path string true "nosep" example("example_value") // @Param request body sep.SepRequest true "SepSep data" // @Success 200 {object} sep.SepResponse "Successfully updated SepSep" // @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters or request body" // @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials" // @Failure 404 {object} models.ErrorResponseBpjs "Not found - SepSep not found" // @Failure 500 {object} models.ErrorResponseBpjs "Internal server error" // @Router /sep/:nosep [put] func (h *VClaimHandler) UpdateSepSep(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) } h.logger.Info("Processing UpdateSepSep request", map[string]interface{}{ "request_id": requestID, }) nosep := c.Param("nosep") if nosep == "" { h.logger.Error("Missing required parameter nosep", map[string]interface{}{ "request_id": requestID, }) c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{ Status: "error", Message: "Missing required parameter nosep", RequestID: requestID, }) return } var req sep.SepRequest if err := c.ShouldBindJSON(&req); err != nil { h.logger.Error("Invalid request body", map[string]interface{}{ "error": err.Error(), "request_id": requestID, }) c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{ 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", map[string]interface{}{ "error": err.Error(), "request_id": requestID, }) c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{ Status: "error", Message: "Validation failed: " + err.Error(), RequestID: requestID, }) return } // Call service method var response sep.SepResponse endpoint := "/sep/:nosep" endpoint = strings.Replace(endpoint, ":nosep", nosep, 1) err := h.service.Put(ctx, endpoint, &req, &response) if err != nil { h.logger.Error("Failed to update SepSep", map[string]interface{}{ "error": err.Error(), "request_id": requestID, }) c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } // Ensure response has proper fields response.Status = "success" response.RequestID = requestID c.JSON(http.StatusOK, response) } // DeleteSepSep godoc // @Summary Delete existing SepSep // @Description Manage SEP (Surat Eligibilitas Peserta) // @Tags Sep // @Accept json // @Produce json // @Security ApiKeyAuth // @Param X-Request-ID header string false "Request ID for tracking" // @Param nosep path string true "nosep" example("example_value") // @Success 200 {object} sep.SepResponse "Successfully deleted SepSep" // @Failure 400 {object} models.ErrorResponseBpjs "Bad request - invalid parameters" // @Failure 401 {object} models.ErrorResponseBpjs "Unauthorized - invalid API credentials" // @Failure 404 {object} models.ErrorResponseBpjs "Not found - SepSep not found" // @Failure 500 {object} models.ErrorResponseBpjs "Internal server error" // @Router /sep/:nosep [delete] func (h *VClaimHandler) DeleteSepSep(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) } h.logger.Info("Processing DeleteSepSep request", map[string]interface{}{ "request_id": requestID, }) nosep := c.Param("nosep") if nosep == "" { h.logger.Error("Missing required parameter nosep", map[string]interface{}{ "request_id": requestID, }) c.JSON(http.StatusBadRequest, models.ErrorResponseBpjs{ Status: "error", Message: "Missing required parameter nosep", RequestID: requestID, }) return } // Call service method var response sep.SepResponse endpoint := "/sep/:nosep" endpoint = strings.Replace(endpoint, ":nosep", nosep, 1) err := h.service.Delete(ctx, endpoint, &response) if err != nil { h.logger.Error("Failed to delete SepSep", map[string]interface{}{ "error": err.Error(), "request_id": requestID, }) c.JSON(http.StatusInternalServerError, models.ErrorResponseBpjs{ Status: "error", Message: "Internal server error", RequestID: requestID, }) return } // Ensure response has proper fields response.Status = "success" response.RequestID = requestID c.JSON(http.StatusOK, response) }