Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions .github/workflows/code_reviewer.yml

This file was deleted.

50 changes: 48 additions & 2 deletions src/api/challenges/challenges.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('ChallengesService', () => {
expect(prisma.challenge_lock.create).not.toHaveBeenCalled();
});

it('maps task challenges with taas metadata to TAAS_PAYMENT', () => {
it('maps task challenges with taas metadata to TAAS_PAYMENT and OWED status', () => {
const service = new ChallengesService(
{} as any,
{} as any,
Expand All @@ -87,6 +87,7 @@ describe('ChallengesService', () => {
expect(payments).toEqual([
expect.objectContaining({
type: WinningsCategory.TAAS_PAYMENT,
status: PaymentStatus.OWED,
}),
]);
});
Expand Down Expand Up @@ -170,7 +171,52 @@ describe('ChallengesService', () => {
]);
});

it('defaults task challenge winnings to ON_HOLD_ADMIN status', async () => {
it('defaults TAAS task challenge winnings to OWED status', async () => {
const service = new ChallengesService(
{} as any,
{} as any,
{} as any,
{} as any,
{} as any,
);

jest
.spyOn(service, 'getChallengeResources')
.mockResolvedValue({ winner: [] } as any);
jest.spyOn(service, 'generatePlacementWinnersPayments').mockReturnValue([
{
userId: '40158994',
amount: 500,
type: WinningsCategory.TAAS_PAYMENT,
currency: PrizeType.USD,
},
] as any);
jest
.spyOn(service, 'generateCheckpointWinnersPayments')
.mockReturnValue([]);
jest.spyOn(service, 'generateCopilotPayment').mockReturnValue([]);
jest.spyOn(service, 'generateReviewersPayments').mockResolvedValue([]);

const winnings = await service.getChallengePayments({
id: '11111111-1111-1111-1111-111111111111',
name: 'TAAS Task Challenge',
type: 'Task',
task: { isTask: true },
billing: { billingAccountId: '1234', markup: 0.2 },
} as any);

expect(winnings).toEqual([
expect.objectContaining({
category: WinningsCategory.TAAS_PAYMENT,
status: PaymentStatus.OWED,
}),
]);
expect(winnings[0].attributes).toMatchObject({
[CHALLENGE_BUDGET_SYNC_SKIP_ATTRIBUTE]: true,
});
});

it('defaults non-TAAS task challenge winnings to ON_HOLD_ADMIN status', async () => {
const service = new ChallengesService(
{} as any,
{} as any,
Expand Down
45 changes: 39 additions & 6 deletions src/api/challenges/challenges.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,31 @@ export class ChallengesService {
: WinningsCategory.REVIEW_BOARD_PAYMENT;
}

/**
* Resolves the explicit payment status for task payments generated from
* challenge-api-v6 challenge data.
*
* @param challenge Challenge details returned by challenge-api-v6.
* @param category Winnings category selected for the generated payment.
* @param currency Prize currency selected for the generated payment.
* @returns OWED for USD TAAS task payments, ON_HOLD_ADMIN for other USD task
* payments, and undefined when standard payout-readiness rules should apply.
* @throws This method does not throw.
*/
private getTaskPaymentStatus(
challenge: Challenge,
category: WinningsCategory,
currency?: PrizeType,
): PaymentStatus | undefined {
if (!challenge.task?.isTask || currency !== PrizeType.USD) {
return undefined;
}

return category === WinningsCategory.TAAS_PAYMENT
? PaymentStatus.OWED
: PaymentStatus.ON_HOLD_ADMIN;
}

async getChallenge(challengeId: string) {
if (!isUUID(challengeId)) {
throw new BadRequestException(
Expand Down Expand Up @@ -232,15 +257,15 @@ export class ChallengesService {
? (type ?? defaultCategory)
: WinningsCategory.POINTS_AWARD;

const status = this.getTaskPaymentStatus(challenge, winType, currency);

return {
handle: winner.handle,
amount: prizes[winner.placement - 1].value,
userId: winner.userId.toString(),
type: winType,
currency,
...(challenge.task?.isTask && currency === PrizeType.USD
? { status: PaymentStatus.ON_HOLD_ADMIN }
: {}),
...(status ? { status } : {}),
description:
challenge.type === 'Task'
? challenge.name
Expand Down Expand Up @@ -434,6 +459,12 @@ export class ChallengesService {
currency,
);

const status = this.getTaskPaymentStatus(
challenge,
winType,
currency,
);

return {
handle: reviewer.memberHandle,
userId: reviewer.memberId.toString(),
Expand All @@ -446,9 +477,7 @@ export class ChallengesService {
),
type: winType,
currency: placementPrizes?.[0]?.type ?? PrizeType.USD,
...(challenge.task?.isTask && currency === PrizeType.USD
? { status: PaymentStatus.ON_HOLD_ADMIN }
: {}),
...(status ? { status } : {}),
description: `${challenge.name} - ${phaseReviews[0].phaseName}`,
};
},
Expand Down Expand Up @@ -513,6 +542,10 @@ export class ChallengesService {
);

return payments.map((payment) => {
const paymentStatus =
payment.status ??
this.getTaskPaymentStatus(challenge, payment.type, payment.currency);

return {
winnerId: payment.userId.toString(),
type:
Expand Down
Loading