prepareSubscription = (action, collection, itemId, user) => {

  // get item's collection name
  const collectionName = collection._name.slice(0,1).toUpperCase() + collection._name.slice(1);

  // get item data
  const item = collection.findOne(itemId);

  // there no user logged in or no item, abort process
  if (!user || !item) {
    return false;
  }

  // edge case: Users collection
  if (collectionName === 'Users') {
    // someone can't subscribe to themself, abort process
    if (item._id === user._id) {
      return false;
    }
  } else {
    // the item's owner is the subscriber, abort process
    if (item.userId && item.userId === user._id) {
      return false;
    }
  }

  // assign the right fields depending on the collection
  const fields = {
    subscribers: 'subscribers',
    subscriberCount: 'subscriberCount',
  };

  // return true if the item has the subscriber's id in its fields
  const hasSubscribedItem = !!_.deep(item, fields.subscribers) && _.deep(item, fields.subscribers) && _.deep(item, fields.subscribers).indexOf(user._id) !== -1;

  // assign the right update operator and count depending on the action type
  const updateQuery = action === 'subscribe' ? {
    findOperator: '$ne', // where 'IT' isn't...
    updateOperator: '$addToSet', // ...add 'IT' to the array...
    updateCount: 1, // ...and log the addition +1
  } : {
    findOperator: '$eq', // where 'IT' is...
    updateOperator: '$pull', // ...remove 'IT' from the array...
    updateCount: -1, // ...and log the subtraction -1
  };

  // return the utility object to pursue
  return {
    collectionName,
    fields,
    item,
    hasSubscribedItem,
    ...updateQuery,
  };
}
@summary Verify that the un/subscription can be performed
@param {String} action
@param {Collection} collection
@param {String} itemId
@param {Object} user
@returns {Object} collectionName, fields: object, item, hasSubscribedItem: boolean