Skip to content

Commit

Permalink
Merge pull request #153 from GeneralMagicio/feat/q-acc-stat
Browse files Browse the repository at this point in the history
Added qacc status endpoint
  • Loading branch information
lovelgeorge99 authored Dec 18, 2024
2 parents 586747c + 7aadbcf commit a1ab6d7
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 0 deletions.
97 changes: 97 additions & 0 deletions src/resolvers/qAccResolver.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
import {
projectUserDonationCap,
projectUserTotalDonationAmounts,
qAccStat,
userCaps,
} from '../../test/graphqlQueries';
import { ProjectRoundRecord } from '../entities/projectRoundRecord';
Expand All @@ -33,6 +34,7 @@ import {
GITCOIN_PASSPORT_MIN_VALID_SCORER_SCORE,
} from '../constants/gitcoin';
import { PrivadoAdapter } from '../adapters/privado/privadoAdapter';
import { AppDataSource } from '../orm';

describe(
'projectUserTotalDonationAmount() test cases',
Expand All @@ -46,6 +48,8 @@ describe(

describe('userCaps() test cases', userCapsTestCases);

describe('qAccStat() test cases', qAccStatTestCases);

function projectUserTotalDonationAmountTestCases() {
it('should return total donation amount of a user for a project', async () => {
it('should return total donation amount of a user for a project', async () => {
Expand Down Expand Up @@ -491,3 +495,96 @@ function userCapsTestCases() {
}
});
}

function qAccStatTestCases() {
let project;
let user;
let qfRound1: QfRound;
beforeEach(async () => {
project = await saveProjectDirectlyToDb(createProjectData());
user = await saveUserDirectlyToDb(generateRandomEtheriumAddress());
qfRound1 = await QfRound.create({
roundNumber: 1,
isActive: true,
name: new Date().toString() + ' - 1',
allocatedFund: 100,
minimumPassportScore: 12,
slug: new Date().getTime().toString() + ' - 1',
beginDate: new Date('2001-01-14'),
endDate: new Date('2001-01-16'),
roundUSDCapPerProject: 10000,
roundUSDCapPerUserPerProject: 2500,
roundUSDCapPerUserPerProjectWithGitcoinScoreOnly: 1000,
tokenPrice: 0.5,
}).save();
sinon.useFakeTimers({
now: new Date('2001-01-15').getTime(),
});
});
afterEach(async () => {
// Clean up the database after each test
await ProjectRoundRecord.delete({});
await Donation.delete({ projectId: project.id });
await QfRound.delete(qfRound1.id);

sinon.restore();
});
it('should return correct qacc stats', async () => {
const qfDonationAmount = Math.round(Math.random() * 1_000_000_00) / 100;
const nonQfDonationAmount = Math.round(Math.random() * 1_000_000_00) / 100;

await saveDonationDirectlyToDb(
{
...createDonationData(),
amount: nonQfDonationAmount,
status: DONATION_STATUS.VERIFIED,
},
user.id,
project.id,
);
await saveDonationDirectlyToDb(
{
...createDonationData(),
amount: qfDonationAmount,
status: DONATION_STATUS.VERIFIED,
qfRoundId: qfRound1.id,
},
user.id,
project.id,
);
const result: AxiosResponse<
ExecutionResult<{
qAccStat: {
totalCollected: number;
qfTotalCollected: number;
contributorsCount: number;
};
}>
> = await axios.post(graphqlUrl, {
query: qAccStat,
});

assert.isOk(result.data);

const dataSource = AppDataSource.getDataSource();
const totalDonations = await dataSource.query(`
SELECT COALESCE(SUM(amount), 0) as totalCollected from donation where status = '${DONATION_STATUS.VERIFIED}'
`);
const qfTotalDonations = await dataSource.query(`
SELECT COALESCE(SUM(amount), 0) as qfTotalCollected from donation where status = '${DONATION_STATUS.VERIFIED}' AND "qfRoundId" IS NOT NULL
`);
// count unique contributors
const contributorsCount = await Donation.createQueryBuilder('donation')
.select('COUNT(DISTINCT "userId")', 'contributorsCount')
.where('donation.status = :status', {
status: DONATION_STATUS.VERIFIED,
})
.getRawOne();

assert.deepEqual(result.data.data?.qAccStat, {
totalCollected: totalDonations[0].totalcollected,
qfTotalCollected: qfTotalDonations[0].qftotalcollected,
contributorsCount: +contributorsCount?.contributorsCount,
});
});
}
22 changes: 22 additions & 0 deletions src/resolvers/qAccResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ class ProjectUserRecordAmounts {
qfTotalDonationAmount: number;
}

@ObjectType()
class QaccStat {
@Field(_type => Float)
totalCollected: number;

@Field(_type => Float)
qfTotalCollected: number;

@Field(_type => Int)
contributorsCount: number;
}

@ObjectType()
class UnusedCapResponse {
@Field(_type => Float)
Expand Down Expand Up @@ -118,4 +130,14 @@ export class QAccResolver {

return response;
}

@Query(_returns => QaccStat)
async qAccStat() {
const state = await qAccService.getQAccStat();
return {
totalCollected: state.totalCollected,
qfTotalCollected: state.qfTotalCollected,
contributorsCount: state.totalContributors,
};
}
}
42 changes: 42 additions & 0 deletions src/services/qAccService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
GITCOIN_PASSPORT_MIN_VALID_ANALYSIS_SCORE,
GITCOIN_PASSPORT_MIN_VALID_SCORER_SCORE,
} from '../constants/gitcoin';
import { Donation, DONATION_STATUS } from '../entities/donation';

const getEaProjectRoundRecord = async ({
projectId,
Expand Down Expand Up @@ -270,8 +271,49 @@ const validDonationAmountBasedOnKYCAndScore = async ({
return true;
};

const getQAccStat = async (): Promise<{
totalCollected: number;
qfTotalCollected: number;
totalContributors: number;
}> => {
const [qfTotalCollected, totalCollected, totalContributors] =
await Promise.all([
Donation.createQueryBuilder('donation')
.select('COALESCE(sum(donation.amount), 0)', 'total_qf_collected')
.where('donation.status = :status', {
status: DONATION_STATUS.VERIFIED,
})
.andWhere('donation."qfRoundId" IS NOT NULL')
.cache('qf_total_collected_donation', 1000)
.getRawOne(),

Donation.createQueryBuilder('donation')
.select('COALESCE(sum(donation.amount), 0)', 'total_collected')
.where('donation.status = :status', {
status: DONATION_STATUS.VERIFIED,
})
.cache('total_collected_donation', 1000)
.getRawOne(),

Donation.createQueryBuilder('donation')
.select('count(distinct donation."userId")', 'total_contributors')
.where('donation.status = :status', {
status: DONATION_STATUS.VERIFIED,
})
.cache('total_contributors', 1000)
.getRawOne(),
]);

return {
totalCollected: totalCollected.total_collected,
qfTotalCollected: qfTotalCollected.total_qf_collected,
totalContributors: totalContributors.total_contributors,
};
};

export default {
getQAccDonationCap,
validDonationAmountBasedOnKYCAndScore,
getUserRemainedCapBasedOnGitcoinScore,
getQAccStat,
};
10 changes: 10 additions & 0 deletions test/graphqlQueries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2186,3 +2186,13 @@ export const userCaps = `
}
}
`;

export const qAccStat = `
query {
qAccStat {
totalCollected
qfTotalCollected
contributorsCount
}
}
`;

0 comments on commit a1ab6d7

Please sign in to comment.