#Paradigm shift: Table-driven methods
Paradigm shift: Table-driven methods
#Paradigm shift: Table-driven methods
Paradigm shift: Table-driven methods
#Paradigm shift: Table-driven methods
Once logic becomes complex enough, you may find it easier to manage the rules from a data structure than from code. Here's how I picture that working for you here.
Disclaimer: I made some assumptions about your business processes that may not be correct. Definitely review this code for correctness, and maybe rewrite it so that it makes more sense to you.
// For each data field we care about, at what level do various
// conditions on that field become available?
const LEVEL_REQUIREMENTS = [
({description}) => {
if (description.length >= 80) return 5; // or maybe Infinity?
if (description.length >= 50) return 4;
if (description.length >= 30) return 3;
if (description) return 2;
return 0;
},
({certifications}) => {
if (certifications.length > 5) return 5;
if (certifications.length > 3) return 4;
if (certifications.length > 0) return 3;
return 0;
},
({teaser}) => teaser ? 3 : 0,
({social}) => social.length > 0 ? 3 : 0,
({locationLat}) => locationLat ? 2 : 0,
({locationLong}) => locationLong ? 2 : 0,
({workingHourEnd}) => workingHourEnd ? 2 : 0,
({workingHourStart}) => workingHourStart ? 2 : 0,
];
function validate(data) {
return LEVEL_REQUIREMENTS.every(levelRequirement => data.level >= levelRequirement(data));
}
...
providerSchema.pre('save', function(next) {
if (validate(this)) {
next();
} else {
next(new Error('your current plan does not have this feature'));
}
});
Here, LEVEL_REQUIREMENTS
is an array of functions (ES6 arrow functions with parameter destructuring, because I think they look nice - feel free to refactor if you disagree, or if you are restricted to ES5). All of the logic for whether a given data blob is allowed at a given plan level is contained within this array.
That reduces the validation function to a simple "Is your level at or above the plan level required to use each feature?"
You may wish to structure the data differently, to make it easier to tell why a given save request was rejected.
Hopefully this looks similar to how the rest of the business thinks about this feature; the more closely your code matches their conceptions, the easier it will be for them to communicate requirements to you, for you to respond to their requirements, for those requirements to change, and so on.