feat(api): daily challenge api (#61346)

Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>
This commit is contained in:
Tom
2025-07-17 04:34:46 -05:00
committed by GitHub
parent 3bcd6bbaf1
commit 29cd2d227d
13 changed files with 678 additions and 22 deletions

View File

@@ -37,7 +37,6 @@ query {
id
title
description
instructions
fields {
tests {
testString
@@ -79,7 +78,6 @@ export function combineChallenges({
id: jsId,
title: jsTitle,
description: jsDescription,
instructions: jsInstructions,
fields: { tests: jsTests },
challengeFiles: jsChallengeFiles
} = jsChallenge;
@@ -87,7 +85,6 @@ export function combineChallenges({
const {
title: pyTitle,
description: pyDescription,
instructions: pyInstructions,
fields: { tests: pyTests },
challengeFiles: pyChallengeFiles
} = pyChallenge;
@@ -104,12 +101,6 @@ export function combineChallenges({
);
}
if (jsInstructions !== pyInstructions) {
throw new Error(
`JavaScript and Python instructions do not match for challenge ${challengeNumber}`
);
}
if (jsTests.length !== pyTests.length) {
throw new Error(
`JavaScript and Python do not have the same number of tests for challenge ${challengeNumber}: ${jsTests.length} JavaScript vs ${pyTests.length} Python tests`
@@ -118,15 +109,12 @@ export function combineChallenges({
// Use the JS challenge info for the new challenge meta - e.g. id, title, description, etc
const challengeData = {
// **DO NOT CHANEGE THE ID** it's used as the challenge ID - and what gets added to completedDailyCodingChallenges[]
// **DO NOT CHANGE THE ID** it's used as the challenge ID - and what gets added to completedDailyCodingChallenges[]
_id: new ObjectId(`${jsId}`),
challengeNumber,
title: jsTitle.replace(`JavaScript Challenge ${challengeNumber}: `, ''),
date,
description: removeSection(jsDescription),
...(jsInstructions && {
instructions: removeSection(jsInstructions)
}),
javascript: {
tests: jsTests,
challengeFiles: jsChallengeFiles
@@ -154,9 +142,9 @@ export function handleError(err: Error, client: MongoClient) {
}
}
// Remove the <section id="description/instructions"> that our parser adds.
// Remove the <section id="description"> that our parser adds.
export function removeSection(str: string) {
return str
.replace(/^<section id="(description|instructions)">\n?/, '')
.replace(/^<section id="description">\n?/, '')
.replace(/\n?<\/section>$/, '');
}

View File

@@ -16,16 +16,16 @@ const { MONGOHQ_URL } = process.env;
const EXPECTED_CHALLENGE_COUNT = 24;
// Date to set for the first challenge, second challenge will be one day later, etc...
// **DO NOT CHANGE THIS AFTER RELEASE**
// **DO NOT CHANGE THIS AFTER RELEASE (if seeding production - okay for local dev)**
const year = 2025;
const monthIndex = 5; // 0-indexed -> 5 = June
const day = 10;
const monthIndex = 6; // 0-indexed -> 5 = June
const day = 15;
const START_DATE = new Date(Date.UTC(year, monthIndex, day));
const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000;
// Sanity check to make sure the start date hasn't unintentionally changed
// **IT SHOULD NOT CHANGE AFTER RELEASE**
const startDateString = '2025-06-10T00:00:00.000Z';
const startDateString = '2025-07-15T00:00:00.000Z';
if (START_DATE.toISOString() !== startDateString) {
throw new Error(
`It appears the start date has changed from "${startDateString}".
@@ -99,8 +99,13 @@ const seed = async () => {
const count = await dailyCodingChallenges.countDocuments();
if (count !== EXPECTED_CHALLENGE_COUNT) {
throw new Error(
`Expected ${EXPECTED_CHALLENGE_COUNT} challenges in the database, but found ${count} documents`
console.warn(
'\n********** WARNING *********\n' +
'*\n' +
`* Expected ${EXPECTED_CHALLENGE_COUNT} challenges in the database,\n` +
`* but found ${count} documents\n` +
'*\n' +
'********** WARNING *********\n'
);
}
};

View File

@@ -15,7 +15,6 @@ export type Challenge = {
title: string;
date: Date;
description: string;
instructions?: string;
fields: {
tests: {
testString: string;