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

  // subscription preparation to verify if can pursue and give shorthand variables
  const subscription = prepareSubscription(action, collection, itemId, user);

  // Abort process if the situation matches one of these cases:
  // - subscription preparation failed (ex: no user, no item, subscriber is author's item, ... see all cases above)
  // - the action is subscribe but the user has already subscribed to this item
  // - the action is unsubscribe but the user hasn't subscribed to this item
  if (!subscription || (action === 'subscribe' && subscription.hasSubscribedItem) || (action === 'unsubscribe' && !subscription.hasSubscribedItem)) {
    throw Error(Utils.encodeIntlError({id: 'app.mutation_not_allowed', value: 'Already subscribed'}));
  }

  // shorthand for useful variables
  const { collectionName, fields, item, findOperator, updateOperator, updateCount } = subscription;

  // Perform the action, eg. operate on the item's collection
  const result = Connectors.update(collection, {
    _id: itemId,
    // if it's a subscription, find  where there are not the user (ie. findOperator = $ne), else it will be $in
    [fields.subscribers]: { [findOperator]: user._id }
  }, {
    // if it's a subscription, add a subscriber (ie. updateOperator = $addToSet), else it will be $pull
    [updateOperator]: { [fields.subscribers]: user._id },
    // if it's a subscription, the count is incremented of 1, else decremented of 1
    $inc: { [fields.subscriberCount]: updateCount },
  });

  // log the operation on the subscriber if it has succeeded
  if (result > 0) {
    // id of the item subject of the action
    let loggedItem = {
      itemId: item._id,
    };

    // in case of subscription, log also the date
    if (action === 'subscribe') {
      loggedItem = {
        ...loggedItem,
        subscribedAt: new Date()
      };
    }

    // update the user's list of subscribed items
    Users.update({
      _id: user._id
    }, {
      [updateOperator]: { [`subscribedItems.${collectionName}`]: loggedItem }
    });

    const updatedUser = Users.findOne({_id: user._id}, {fields: {_id:1, subscribedItems: 1}});
    
    return updatedUser;
  } else {
    throw Error(Utils.encodeIntlError({id: 'app.something_bad_happened'}));
  }
}
@summary Perform the un/subscription after verification: update the collection item & the user
@param {String} action
@param {Collection} collection
@param {String} itemId
@param {Object} user: current user (xxx: legacy, to replace with this.userId)
@returns {Boolean}