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.
Not sure if this is meant to be implied in the above, but the "milestone badges" in step 4 could be limited to the primaryBadge(s) found in step 2, as opposed to all milestones in existence, right? Unless I am missing something.