Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: incorporate referral points to leaderboard score #506

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

IfyNdu
Copy link
Contributor

@IfyNdu IfyNdu commented Nov 14, 2023

Status Type Env Vars Change Ticket
Ready Refactor No Closes #484

Problem

Include referral points in leaderboard calculation

Solution

Calculated referral points on the fly when leaderboard rankings are requested

QA

  • Unit test

Other changes (e.g. bug fixes, UI tweaks, small refactors)

Improved userRanking (getLeaderboard controller) object typing by using Array.find to return an owner ranking thereby preserving UserRanking type definition

@@ -70,8 +70,8 @@ describe('crowdsourcer', () => {

// assert
expect(mockResponse.status).toHaveBeenCalledWith(403);
expect(sendMock).toHaveBeenCalledWith({
error: `Users cannot be referred twice. Referral code [${referralCode}] will be ignored`,
expect(sendMock).toHaveBeenNthCalledWith(1, {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why change to toHaveBeenNthCalledWith?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually my bad! i need to update the controller to return early (i personally don't like doing) so send is only called once if its a 403. Ideally we should throw an error but i dont think express will intercept it and relay the correct message to the client

@@ -1,5 +1,6 @@
import { cloneDeep, times } from 'lodash';
import { sortLeaderboards, sortRankings, splitRankings } from '../utils';
import * as database from '../../../utils/database';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: let's use absolute paths since it makes refactoring easier (i believe VSCode should be able to do this automatically if you press tab when the suggested import is shown)

model: () => ({
count: countMock,
}),
}) as any,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why add as any?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prevent the typescript compiler from throwing error because i did not provide the MongdoDB connection properties. I am only interested in model and count functions for the feature in progress.

Comment on lines +145 to +148
for (let i = 0; i < rankings.length; i += 1) {
const ranking = rankings[i];
ranking.count += await getReferralPoints(ranking.uid);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be re-written to use a map loop so that we can encourage a more immutable approach to updating ranking objects

Suggested change
for (let i = 0; i < rankings.length; i += 1) {
const ranking = rankings[i];
ranking.count += await getReferralPoints(ranking.uid);
}
const finalRankings = await Promise.all(rankings.map(async (ranking) => ({
...ranking,
count: ranking.count + await getReferralPoints(ranking.uid),
})))

@@ -130,18 +130,23 @@ export const getLeaderboard = async (
sortLeaderboards(leaderboards);

const allRankings = leaderboards.map(({ rankings }) => rankings).flat();
const userIndex = allRankings.findIndex(({ uid }) => uid === user.uid);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i take the approach of using findIndex instead of just find to encourage treating variables as immutable objects - this prevents unexpected situations where data is updated in unexpected places

let's use findIndex so that will encourage an immutable data update pattern

@@ -90,3 +93,12 @@ export const sortLeaderboards = (leaderboards: Interfaces.Leaderboard[]): void =
return 0;
});
};

export const getReferralPoints = async (id: string): Promise<number> => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: add a comment for this function

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the naming conventions for files is camel case, so the file name should be ReferralPoints.ts

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you'll also want to update/create a test for the getLeadboard method

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Referral points incorporation
2 participants