This will be triggered whenever a user earns a badge. Also, assume all relationships for each query are fulfilled.
- Find related milestones,
relatedMilestones
:MilestoneBadges.get({ badgeId: <badgeId> })
- Return early if there are no related milestones.
- Get list of user's badges,
userBadges
:BadgeInstances.get({ email: <userEmail> })
- Get the relative complement of
userBadges
andrelatedMilestones
(related milestone badges the user has not earned yet) to make set ofunearnedMilestones
.
- Return early if the relative complement set is empty.
- Filter
unearnedMilestones
by eligibility for fulfillment to geteligibleMilestones
- Get the intersection between
userBadges
and support badges of specific milestone fromunearnedMilestones
. - If the number of items in the intersection set is greater than number of badges required, accept milestone. Otherwise, reject.
- Award set of
eligibleMilestones
(which might be an empty set).
It actually shouldn't be that bad as there are only two IO operations: getting the milestones related to the initial award, and getting the rest of the user's awarded badges (both require fulfilled relationships, but that's done by JOIN
s under the hood so each still counts as a single IO operation). Given that the sets will be at most in the hundreds, the rest of the operations should be fairly speedy.
Yep, where I say "milestone badges" below, I mean the ones that were found in the first step. I'll try to make that clearer.