Skip to content

Better handling of phase short circuiting#26

Merged
jmgasper merged 5 commits into
masterfrom
develop
Jan 19, 2026
Merged

Better handling of phase short circuiting#26
jmgasper merged 5 commits into
masterfrom
develop

Conversation

@jmgasper

Copy link
Copy Markdown
Contributor

});
describe('handleReviewCompleted (review phase)', () => {
const buildReviewPhase = (): IPhase => ({
const buildReviewPhase = (name = 'Review'): IPhase => ({

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[⚠️ correctness]
The buildReviewPhase function now accepts a name parameter with a default value of 'Review'. Ensure that all places where buildReviewPhase is called are updated to pass the correct phase name if needed, to avoid unexpected behavior.

'Checkpoint Screening',
'Checkpoint Review',
])(
'closes the %s phase once all reviews are completed',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[💡 maintainability]
The use of it.each with a list of phase names is a good approach to test multiple scenarios. However, ensure that the list of phase names is comprehensive and covers all possible phase names that the system might encounter.


let canOpen = true;
try {
canOpen = await this.reviewAssignmentService.ensureAssignmentsOrSchedule(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[⚠️ correctness]
The ensureAssignmentsOrSchedule method is called within a try-catch block, but if it throws an error, the loop continues without handling the error case for the specific phase. Consider adding logic to handle the error scenario, such as logging the phase ID or taking corrective action.

};

try {
await this.advancePhase(openPayload);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[⚠️ correctness]
The advancePhase method is called within a try-catch block, but if it throws an error, the function returns false, which might not be sufficient to handle all error scenarios. Consider adding more detailed error handling or retry logic to ensure robustness.


let updatedPhase: IPhase | null = null;
try {
updatedPhase = await this.challengeApiService.getPhaseDetails(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[⚠️ correctness]
The getPhaseDetails method is called to update the phase information, but if it fails, the function returns false. This could lead to incomplete phase handling. Consider implementing a retry mechanism or alternative logic to handle transient errors.

};

try {
await this.schedulePhaseTransitionWithCancellation(closePayload);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[💡 maintainability]
The schedulePhaseTransitionWithCancellation method attempts to cancel an existing schedule before scheduling a new one. If the cancellation fails, it logs a warning but proceeds with scheduling. Consider whether this behavior is acceptable or if additional handling is needed to ensure consistency.

@jmgasper jmgasper merged commit 009d1bf into master Jan 19, 2026
6 of 7 checks passed

this.checkpointWinnerQueryLoggerAttached = true;

const prismaWithLogger = this.prisma as unknown as PrismaQueryLogger;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[⚠️ correctness]
Casting this.prisma to PrismaQueryLogger using as unknown as could lead to runtime errors if this.prisma does not actually implement PrismaQueryLogger. Consider adding a type guard or ensuring that this.prisma is of the correct type before casting.

return;
}

let matchedChallengeId: string | undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[💡 performance]
The loop to find matchedChallengeId could be optimized by using a Set lookup instead of iterating over checkpointWinnerQueryLogIds. This would improve performance, especially if the set is large.

url: databaseUrl,
},
},
...(dbDebugEnabled ? { log: logConfig } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[💡 maintainability]
The use of the spread operator ...(dbDebugEnabled ? { log: logConfig } : {}) is correct, but it could be simplified by directly assigning log: logConfig when dbDebugEnabled is true. This would improve readability and maintainability by reducing unnecessary complexity.

...(dbDebugEnabled ? { log: logConfig } : {}),
}
: undefined,
: dbDebugEnabled

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[💡 readability]
The logic for setting the log configuration when databaseUrl is falsy and dbDebugEnabled is true is correct, but it might be clearer to handle this case explicitly rather than relying on the ternary operator. Consider restructuring this logic to improve clarity.

{ memberId: '123', submissionId: 'submission-1', score: 92 },
]);

const rawQuery = prismaMock.$queryRaw.mock.calls[0][0] as {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[⚠️ correctness]
The type assertion for rawQuery as { strings?: TemplateStringsArray | string[]; } might be too specific and could lead to runtime errors if the structure of the query changes. Consider using a more flexible type or adding runtime checks to ensure safety.

AND GREATEST(
COALESCE(r."finalScore", 0),
COALESCE(r."initialScore", 0)
) >= COALESCE(sc."minimumPassingScore", sc."minScore", 50)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[⚠️ correctness]
The use of GREATEST with COALESCE to compare scores against sc."minimumPassingScore", sc."minScore", 50 could lead to unexpected behavior if sc."minimumPassingScore" or sc."minScore" are negative or null. Ensure that these fields are validated to prevent incorrect filtering of submissions.

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.

1 participant