Files
antrean-anjungan/internal/models/validation.go
2025-09-01 15:01:30 +07:00

107 lines
2.5 KiB
Go

package models
import (
"regexp"
"strings"
"time"
"github.com/go-playground/validator/v10"
)
// CustomValidator wraps the validator
type CustomValidator struct {
Validator *validator.Validate
}
// Validate validates struct
func (cv *CustomValidator) Validate(i interface{}) error {
return cv.Validator.Struct(i)
}
// RegisterCustomValidations registers custom validation rules
func RegisterCustomValidations(v *validator.Validate) {
// Validate Indonesian phone number
v.RegisterValidation("indonesian_phone", validateIndonesianPhone)
// Validate BPJS card number format
v.RegisterValidation("bpjs_card", validateBPJSCard)
// Validate Indonesian NIK
v.RegisterValidation("indonesian_nik", validateIndonesianNIK)
// Validate date format YYYY-MM-DD
v.RegisterValidation("date_format", validateDateFormat)
// Validate ICD-10 code format
v.RegisterValidation("icd10", validateICD10)
// Validate ICD-9-CM procedure code
v.RegisterValidation("icd9cm", validateICD9CM)
}
func validateIndonesianPhone(fl validator.FieldLevel) bool {
phone := fl.Field().String()
if phone == "" {
return true // Optional field
}
// Indonesian phone number pattern: +62, 62, 08, or 8
pattern := `^(\+?62|0?8)[1-9][0-9]{7,11}$`
matched, _ := regexp.MatchString(pattern, phone)
return matched
}
func validateBPJSCard(fl validator.FieldLevel) bool {
card := fl.Field().String()
if len(card) != 13 {
return false
}
// BPJS card should be numeric
pattern := `^\d{13}$`
matched, _ := regexp.MatchString(pattern, card)
return matched
}
func validateIndonesianNIK(fl validator.FieldLevel) bool {
nik := fl.Field().String()
if len(nik) != 16 {
return false
}
// NIK should be numeric
pattern := `^\d{16}$`
matched, _ := regexp.MatchString(pattern, nik)
return matched
}
func validateDateFormat(fl validator.FieldLevel) bool {
dateStr := fl.Field().String()
_, err := time.Parse("2006-01-02", dateStr)
return err == nil
}
func validateICD10(fl validator.FieldLevel) bool {
code := fl.Field().String()
if code == "" {
return true
}
// Basic ICD-10 pattern: Letter followed by 2 digits, optional dot and more digits
pattern := `^[A-Z]\d{2}(\.\d+)?$`
matched, _ := regexp.MatchString(pattern, strings.ToUpper(code))
return matched
}
func validateICD9CM(fl validator.FieldLevel) bool {
code := fl.Field().String()
if code == "" {
return true
}
// Basic ICD-9-CM procedure pattern: 2-4 digits with optional decimal
pattern := `^\d{2,4}(\.\d+)?$`
matched, _ := regexp.MatchString(pattern, code)
return matched
}