Files
be-service-qris/vclaim_handler.go
2025-08-28 18:03:38 +07:00

574 lines
15 KiB
Go

// 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)
}