package validator import ( "apskel-pos-be/internal/constants" "apskel-pos-be/internal/contract" "fmt" "strings" "github.com/go-playground/validator/v10" "github.com/google/uuid" ) type TableValidator struct { validate *validator.Validate } func NewTableValidator() *TableValidator { return &TableValidator{ validate: validator.New(), } } func (v *TableValidator) ValidateCreateTableRequest(req contract.CreateTableRequest) error { if err := v.validate.Struct(req); err != nil { return formatValidationError(err) } // Additional custom validations if req.OutletID == uuid.Nil { return fmt.Errorf("outlet_id is required") } if strings.TrimSpace(req.TableName) == "" { return fmt.Errorf("table_name cannot be empty") } if req.Capacity < 1 || req.Capacity > 20 { return fmt.Errorf("capacity must be between 1 and 20") } return nil } func (v *TableValidator) ValidateUpdateTableRequest(req contract.UpdateTableRequest) error { if err := v.validate.Struct(req); err != nil { return formatValidationError(err) } // Additional custom validations if req.TableName != nil && strings.TrimSpace(*req.TableName) == "" { return fmt.Errorf("table_name cannot be empty") } if req.Capacity != nil && (*req.Capacity < 1 || *req.Capacity > 20) { return fmt.Errorf("capacity must be between 1 and 20") } if req.Status != nil { if !isValidTableStatus(*req.Status) { return fmt.Errorf("invalid table status: %s", *req.Status) } } return nil } func (v *TableValidator) ValidateOccupyTableRequest(req contract.OccupyTableRequest) error { if err := v.validate.Struct(req); err != nil { return formatValidationError(err) } // Additional custom validations if req.OrderID == uuid.Nil { return fmt.Errorf("order_id is required") } return nil } func (v *TableValidator) ValidateReleaseTableRequest(req contract.ReleaseTableRequest) error { if err := v.validate.Struct(req); err != nil { return formatValidationError(err) } // Additional custom validations if req.PaymentAmount < 0 { return fmt.Errorf("payment_amount cannot be negative") } return nil } func (v *TableValidator) ValidateTableID(id string) error { if id == "" { return fmt.Errorf("table ID is required") } if _, err := uuid.Parse(id); err != nil { return fmt.Errorf("invalid table ID format") } return nil } func (v *TableValidator) ValidateOutletID(id string) error { if id == "" { return fmt.Errorf("outlet ID is required") } if _, err := uuid.Parse(id); err != nil { return fmt.Errorf("invalid outlet ID format") } return nil } func (v *TableValidator) ValidateListTablesQuery(query contract.ListTablesQuery) error { // Validate pagination if query.Page < 1 { return fmt.Errorf("page must be greater than 0") } if query.Limit < 1 || query.Limit > 100 { return fmt.Errorf("limit must be between 1 and 100") } // Validate organization_id if provided if query.OrganizationID != "" { if _, err := uuid.Parse(query.OrganizationID); err != nil { return fmt.Errorf("invalid organization_id format") } } // Validate outlet_id if provided if query.OutletID != "" { if _, err := uuid.Parse(query.OutletID); err != nil { return fmt.Errorf("invalid outlet_id format") } } // Validate status if provided if query.Status != "" { if !isValidTableStatus(query.Status) { return fmt.Errorf("invalid table status: %s", query.Status) } } // Validate is_active if provided if query.IsActive != "" { if query.IsActive != "true" && query.IsActive != "false" { return fmt.Errorf("is_active must be 'true' or 'false'") } } return nil } func isValidTableStatus(status string) bool { validStatuses := []string{ string(constants.TableStatusAvailable), string(constants.TableStatusOccupied), string(constants.TableStatusReserved), string(constants.TableStatusCleaning), string(constants.TableStatusMaintenance), } for _, validStatus := range validStatuses { if status == validStatus { return true } } return false }