feat(curriculum): add relational databases cert as upcoming change (#41658)

This commit is contained in:
Tom
2021-06-15 10:37:13 -05:00
committed by GitHub
parent ae0d34359a
commit 067761f2f6
30 changed files with 597 additions and 19 deletions

View File

@ -247,6 +247,7 @@ exports.createSchemaCustomization = ({ actions }) => {
const typeDefs = ` const typeDefs = `
type ChallengeNode implements Node { type ChallengeNode implements Node {
files: ChallengeFile files: ChallengeFile
url: String
} }
type ChallengeFile { type ChallengeFile {
indexcss: FileContents indexcss: FileContents

View File

@ -275,6 +275,16 @@
} }
} }
}, },
"relational-databases": {
"title": "Relational Databases",
"intro": ["placeholder"],
"blocks": {
"learn-relational-databases": {
"title": "Learn Relational Databases",
"intro": ["placeholder"]
}
}
},
"apis-and-microservices": { "apis-and-microservices": {
"title": "APIs and Microservices", "title": "APIs and Microservices",
"intro": [ "intro": [

View File

@ -3,6 +3,7 @@ const crypto = require('crypto');
function createChallengeNode(challenge, reporter) { function createChallengeNode(challenge, reporter) {
// challengeType 11 is for video challenges (they only have instructions) // challengeType 11 is for video challenges (they only have instructions)
// challengeType 7 is for certificates (they only have tests) // challengeType 7 is for certificates (they only have tests)
// challengeType 12 is for CodeAlly/CodeRoad challenge
// TODO: either handle empty descriptions inside Gatsby OR ensure that // TODO: either handle empty descriptions inside Gatsby OR ensure that
// description defaults to '' when creating challenges. // description defaults to '' when creating challenges.
@ -12,7 +13,8 @@ function createChallengeNode(challenge, reporter) {
if ( if (
typeof challenge.description !== 'string' && typeof challenge.description !== 'string' &&
challenge.challengeType !== 11 && challenge.challengeType !== 11 &&
challenge.challengeType !== 7 challenge.challengeType !== 7 &&
challenge.challengeType !== 12
) { ) {
reporter.warn(` reporter.warn(`

View File

@ -0,0 +1,10 @@
---
title: Relational Databases
superBlock: relational-databases
---
## Introduction to Relational Databases
This introduction is a stub
Help us make it real on [GitHub](https://github.com/freeCodeCamp/learn/tree/master/src/introductions).

View File

@ -0,0 +1,9 @@
---
title: Introduction to Relational Databases
block: Learn Relational Databases
superBlock: Relational Databases
---
## Placeholder
Placeholder

View File

@ -234,7 +234,8 @@ export const certificatesByNameSelector = username => state => {
isFullStackCert, isFullStackCert,
isSciCompPyCertV7, isSciCompPyCertV7,
isDataAnalysisPyCertV7, isDataAnalysisPyCertV7,
isMachineLearningPyCertV7 isMachineLearningPyCertV7,
isRelationalDatabasesCertV8
} = userByNameSelector(username)(state); } = userByNameSelector(username)(state);
return { return {
hasModernCert: hasModernCert:
@ -248,7 +249,8 @@ export const certificatesByNameSelector = username => state => {
isFullStackCert || isFullStackCert ||
isSciCompPyCertV7 || isSciCompPyCertV7 ||
isDataAnalysisPyCertV7 || isDataAnalysisPyCertV7 ||
isMachineLearningPyCertV7, isMachineLearningPyCertV7 ||
isRelationalDatabasesCertV8,
hasLegacyCert: hasLegacyCert:
isFrontEndCert || isBackEndCert || isDataVisCert || isInfosecQaCert, isFrontEndCert || isBackEndCert || isDataVisCert || isInfosecQaCert,
isFullStackCert, isFullStackCert,
@ -302,6 +304,11 @@ export const certificatesByNameSelector = username => state => {
show: isMachineLearningPyCertV7, show: isMachineLearningPyCertV7,
title: 'Machine Learning with Python Certification', title: 'Machine Learning with Python Certification',
certSlug: 'machine-learning-with-python-v7' certSlug: 'machine-learning-with-python-v7'
},
{
show: isRelationalDatabasesCertV8,
title: 'Relational Databases Certification',
certSlug: 'relational-databases-v8'
} }
], ],
legacyCerts: [ legacyCerts: [

View File

@ -5,6 +5,8 @@ const jsAlgoBase =
'javascript-algorithms-and-data-structures-projects'; 'javascript-algorithms-and-data-structures-projects';
const feLibsBase = '/learn/front-end-libraries/front-end-libraries-projects'; const feLibsBase = '/learn/front-end-libraries/front-end-libraries-projects';
const dataVisBase = '/learn/data-visualization/data-visualization-projects'; const dataVisBase = '/learn/data-visualization/data-visualization-projects';
const relationalDatabasesBase =
'/learn/relational-databases/learn-relational-databases';
const apiMicroBase = const apiMicroBase =
'/learn/apis-and-microservices/apis-and-microservices-projects'; '/learn/apis-and-microservices/apis-and-microservices-projects';
const qaBase = '/learn/quality-assurance/quality-assurance-projects'; const qaBase = '/learn/quality-assurance/quality-assurance-projects';
@ -435,6 +437,44 @@ const certMap = [
} }
] ]
}, },
{
id: '606243f50267e718b1e755f4',
title: 'Relational Databases',
slug: 'relational-databases',
flag: 'isRelationalDatabasesCert',
projects: [
{
id: '5f1a4ef5d5d6b5ab580fc6ae',
title: 'Celestial Bodies Database',
link: `${relationalDatabasesBase}/celestial-bodies-database`,
superBlock: 'relational-databases'
},
{
id: '5f87ac112ae598023a42df1a',
title: 'Salon Appointment Scheduler',
link: `${relationalDatabasesBase}/salon-appointment-scheduler`,
superBlock: 'relational-databases'
},
{
id: '5f9771307d4d22b9d2b75a94',
title: 'World Cup Database',
link: `${relationalDatabasesBase}/world-cup-database`,
superBlock: 'relational-databases'
},
{
id: '602d9ff222201c65d2a019f2',
title: 'Periodic Table Database',
link: `${relationalDatabasesBase}/periodic-table-database`,
superBlock: 'relational-databases'
},
{
id: '602da04c22201c65d2a019f4',
title: 'Final Boss',
link: `${relationalDatabasesBase}/final-boss`,
superBlock: 'relational-databases'
}
]
},
{ {
id: '561add10cb82ac38a17523bc', id: '561add10cb82ac38a17523bc',
title: 'APIs and Microservices', title: 'APIs and Microservices',
@ -675,7 +715,9 @@ certMap.forEach(cert => {
if (cert.title !== 'Legacy Full Stack') { if (cert.title !== 'Legacy Full Stack') {
if (cert.title.startsWith('Legacy')) { if (cert.title.startsWith('Legacy')) {
legacyProjectMap[cert.title] = cert.projects; legacyProjectMap[cert.title] = cert.projects;
} else { // temporary hiding of RDBMS cert
// should do suggestion on line 33 and use front matter to hide it
} else if (!cert.title.startsWith('Relational')) {
projectMap[cert.title] = cert.projects; projectMap[cert.title] = cert.projects;
} }
} }

View File

@ -0,0 +1,99 @@
/* eslint-disable max-len */
// Package Utilities
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import Helmet from 'react-helmet';
import { graphql } from 'gatsby';
// Local Utilities
import LearnLayout from '../../../components/layouts/Learn';
import { ChallengeNode } from '../../../redux/prop-types';
import { updateChallengeMeta, challengeMounted } from '../redux';
// Redux
const mapStateToProps = () => ({});
const mapDispatchToProps = dispatch =>
bindActionCreators(
{
updateChallengeMeta,
challengeMounted
},
dispatch
);
// Proptypes
const propTypes = {
data: PropTypes.shape({
challengeNode: ChallengeNode
}),
pageContext: PropTypes.shape({
challengeMeta: PropTypes.shape({
id: PropTypes.string,
introPath: PropTypes.string,
nextChallengePath: PropTypes.string,
prevChallengePath: PropTypes.string
})
}),
updateChallengeMeta: PropTypes.func.isRequired
};
// Component
class ShowCodeAlly extends Component {
componentDidMount() {
const {
updateChallengeMeta,
data: {
challengeNode: { challengeType, title }
},
pageContext: { challengeMeta }
} = this.props;
updateChallengeMeta({ ...challengeMeta, title, challengeType });
}
render() {
const {
title,
fields: { blockName },
url
} = this.props.data.challengeNode;
return (
<LearnLayout>
<Helmet title={`${blockName}: ${title} | freeCodeCamp.org`} />
<iframe
sandbox='allow-modals allow-forms allow-popups allow-scripts allow-same-origin'
src={`http://codeally.io/embed/?repoUrl=${url}`}
style={{
width: '100%',
height: 'calc(100vh - 38px)',
overflow: 'hidden',
border: 0
}}
title='Editor'
/>
</LearnLayout>
);
}
}
ShowCodeAlly.displayName = 'ShowCodeAlly';
ShowCodeAlly.propTypes = propTypes;
export default connect(mapStateToProps, mapDispatchToProps)(ShowCodeAlly);
// GraphQL
export const query = graphql`
query CodeAllyChallenge($slug: String!) {
challengeNode(fields: { slug: { eq: $slug } }) {
title
challengeType
url
fields {
blockName
}
}
}
`;

View File

@ -11,6 +11,7 @@ const quiz = 8;
const invalid = 9; const invalid = 9;
const pythonProject = 10; const pythonProject = 10;
const video = 11; const video = 11;
const codeally = 12;
// individual exports // individual exports
exports.backend = backend; exports.backend = backend;
@ -31,7 +32,8 @@ exports.challengeTypes = {
step, step,
quiz, quiz,
invalid, invalid,
video video,
codeally
}; };
// turn challengeType to file ext // turn challengeType to file ext
@ -52,7 +54,8 @@ exports.viewTypes = {
[step]: 'step', [step]: 'step',
[quiz]: 'quiz', [quiz]: 'quiz',
[backend]: 'backend', [backend]: 'backend',
[video]: 'video' [video]: 'video',
[codeally]: 'codeally'
}; };
// determine the type of submit function to use for the challenge on completion // determine the type of submit function to use for the challenge on completion

View File

@ -15,6 +15,10 @@ const frontend = path.resolve(
__dirname, __dirname,
'../../src/templates/Challenges/projects/frontend/Show.js' '../../src/templates/Challenges/projects/frontend/Show.js'
); );
const codeally = path.resolve(
__dirname,
'../../src/templates/Challenges/codeally/show.js'
);
const intro = path.resolve( const intro = path.resolve(
__dirname, __dirname,
'../../src/templates/Introduction/Intro.js' '../../src/templates/Introduction/Intro.js'
@ -33,7 +37,8 @@ const views = {
classic, classic,
modern: classic, modern: classic,
frontend, frontend,
video video,
codeally
// quiz: Quiz // quiz: Quiz
}; };

View File

@ -59,5 +59,21 @@
"basic-javascript-rpg-game": "JavaScript", "basic-javascript-rpg-game": "JavaScript",
"functional-programming-spreadsheet": "JavaScript", "functional-programming-spreadsheet": "JavaScript",
"intermediate-javascript-calorie-counter": "JavaScript", "intermediate-javascript-calorie-counter": "JavaScript",
"d3-dashboard": "JavaScript" "d3-dashboard": "JavaScript",
"learn-bash-by-building-a-boilerplate": "Relational Databases",
"learn-relational-databases-by-building-a-mario-database":
"Relational Databases",
"celestial-bodies-database": "Relational Databases",
"learn-bash-scripting-by-building-five-programs": "Relational Databases",
"learn-bash-and-sql-by-building-a-bike-rental-shop": "Relational Databases",
"salon-appointment-scheduler": "Relational Databases",
"learn-sql-by-building-a-student-database": "Relational Databases",
"learn-advanced-bash-by-building": "Relational Databases",
"world-cup-database": "Relational Databases",
"learn-nano-by-building-a-castle": "Relational Databases",
"learn-git-by-building-an-sql-reference-object": "Relational Databases",
"periodic-table-database": "Relational Databases",
"learn-github-by-building-a-list-of-inspirational-quotes":
"Relational Databases",
"final-boss": "Relational Databases"
} }

View File

@ -13,7 +13,8 @@ const certTypes = {
sciCompPyV7: 'isSciCompPyCertV7', sciCompPyV7: 'isSciCompPyCertV7',
dataAnalysisPyV7: 'isDataAnalysisPyCertV7', dataAnalysisPyV7: 'isDataAnalysisPyCertV7',
machineLearningPyV7: 'isMachineLearningPyCertV7', machineLearningPyV7: 'isMachineLearningPyCertV7',
fullStack: 'isFullStackCert' fullStack: 'isFullStackCert',
relationalDatabasesV8: 'isRelationalDatabasesCertV8'
}; };
const certIds = { const certIds = {
@ -31,7 +32,8 @@ const certIds = {
infosecV7Id: '5e6021435ac9d0ecd8b94b00', infosecV7Id: '5e6021435ac9d0ecd8b94b00',
sciCompPyV7Id: '5e44431b903586ffb414c951', sciCompPyV7Id: '5e44431b903586ffb414c951',
dataAnalysisPyV7Id: '5e46fc95ac417301a38fb934', dataAnalysisPyV7Id: '5e46fc95ac417301a38fb934',
machineLearningPyV7Id: '5e46fc95ac417301a38fb935' machineLearningPyV7Id: '5e46fc95ac417301a38fb935',
relationalDatabasesV8Id: '606243f50267e718b1e755f4'
}; };
const completionHours = { const completionHours = {
@ -49,7 +51,8 @@ const completionHours = {
[certTypes.infosecV7]: 300, [certTypes.infosecV7]: 300,
[certTypes.sciCompPyV7]: 300, [certTypes.sciCompPyV7]: 300,
[certTypes.dataAnalysisPyV7]: 300, [certTypes.dataAnalysisPyV7]: 300,
[certTypes.machineLearningPyV7]: 300 [certTypes.machineLearningPyV7]: 300,
[certTypes.relationalDatabasesV8]: 300
}; };
const certSlugTypeMap = { const certSlugTypeMap = {
@ -72,7 +75,8 @@ const certSlugTypeMap = {
'information-security-v7': certTypes.infosecV7, 'information-security-v7': certTypes.infosecV7,
'scientific-computing-with-python-v7': certTypes.sciCompPyV7, 'scientific-computing-with-python-v7': certTypes.sciCompPyV7,
'data-analysis-with-python-v7': certTypes.dataAnalysisPyV7, 'data-analysis-with-python-v7': certTypes.dataAnalysisPyV7,
'machine-learning-with-python-v7': certTypes.machineLearningPyV7 'machine-learning-with-python-v7': certTypes.machineLearningPyV7,
'relational-databases-v8': certTypes.relationalDatabasesV8
}; };
const superBlockCertTypeMap = { const superBlockCertTypeMap = {
@ -93,7 +97,8 @@ const superBlockCertTypeMap = {
'information-security': certTypes.infosecV7, 'information-security': certTypes.infosecV7,
'scientific-computing-with-python': certTypes.sciCompPyV7, 'scientific-computing-with-python': certTypes.sciCompPyV7,
'data-analysis-with-python': certTypes.dataAnalysisPyV7, 'data-analysis-with-python': certTypes.dataAnalysisPyV7,
'machine-learning-with-python': certTypes.machineLearningPyV7 'machine-learning-with-python': certTypes.machineLearningPyV7,
'relational-databases': certTypes.relationalDatabasesV8
}; };
const certTypeIdMap = { const certTypeIdMap = {
@ -111,7 +116,8 @@ const certTypeIdMap = {
[certTypes.infosecV7]: certIds.infosecV7Id, [certTypes.infosecV7]: certIds.infosecV7Id,
[certTypes.sciCompPyV7]: certIds.sciCompPyV7Id, [certTypes.sciCompPyV7]: certIds.sciCompPyV7Id,
[certTypes.dataAnalysisPyV7]: certIds.dataAnalysisPyV7Id, [certTypes.dataAnalysisPyV7]: certIds.dataAnalysisPyV7Id,
[certTypes.machineLearningPyV7]: certIds.machineLearningPyV7Id [certTypes.machineLearningPyV7]: certIds.machineLearningPyV7Id,
[certTypes.relationalDatabasesV8]: certIds.relationalDatabasesV8Id
}; };
const certTypeTitleMap = { const certTypeTitleMap = {
@ -129,7 +135,8 @@ const certTypeTitleMap = {
[certTypes.infosecV7]: 'Information Security', [certTypes.infosecV7]: 'Information Security',
[certTypes.sciCompPyV7]: 'Scientific Computing with Python', [certTypes.sciCompPyV7]: 'Scientific Computing with Python',
[certTypes.dataAnalysisPyV7]: 'Data Analysis with Python', [certTypes.dataAnalysisPyV7]: 'Data Analysis with Python',
[certTypes.machineLearningPyV7]: 'Machine Learning with Python' [certTypes.machineLearningPyV7]: 'Machine Learning with Python',
[certTypes.relationalDatabasesV8]: 'Relational Databases'
}; };
exports.oldDataVizId = '561add10cb82ac38a17513b3'; exports.oldDataVizId = '561add10cb82ac38a17513b3';

View File

@ -0,0 +1,71 @@
{
"name": "Learn Relational Databases",
"isUpcomingChange": true,
"dashedName": "learn-relational-databases",
"order": 2,
"time": "",
"template": "",
"required": [],
"superBlock": "relational-databases",
"superOrder": 12,
"challengeOrder": [
[
"5ea8adfab628f68d805bfc5e",
"Learn Bash by Building a Boilerplate"
],
[
"5f2c289f164c29556da632fd",
"Learn Relational Databases by Building a Mario Database"
],
[
"5f1a4ef5d5d6b5ab580fc6ae",
"Celestial Bodies Database"
],
[
"5f5904ac738bc2fa9efecf5a",
"Learn Bash Scripting by Building Five Programs"
],
[
"602da0c222201c65d2a019f5",
"Learn SQL by Building a Student Database"
],
[
"5f9771307d4d22b9d2b75a94",
"World Cup Database"
],
[
"602da0de22201c65d2a019f6",
"Learn Advanced Bash by Building"
],
[
"5f5b969a05380d2179fe6e18",
"Learn Bash and SQL by Building a Bike Rental Shop"
],
[
"5f87ac112ae598023a42df1a",
"Salon Appointment Scheduler"
],
[
"5f32db63eb37f7e17323f459",
"Learn Nano by Building a Castle"
],
[
"5fa323cdaf6a73463d590659",
"Learn Git by Building an SQL Reference Object"
],
[
"602d9ff222201c65d2a019f2",
"Periodic Table Database"
],
[
"602da04222201c65d2a019f3",
"Learn GitHub by Building a List of Inspirational Quotes"
],
[
"602da04c22201c65d2a019f4",
"Final Boss"
]
],
"helpRoom": "HelpBackend",
"fileName": "13-relational-databases/learn-relational-databases.json"
}

View File

@ -0,0 +1,20 @@
{
"name": "Relational Databases Certificate",
"isUpcomingChange": true,
"dashedName": "relational-databases-v8-certificate",
"order": 11,
"time": "",
"template": "",
"required": [],
"superBlock": "certificates",
"superOrder": 12,
"challengeOrder": [
[
"606243f50267e718b1e755f4",
"Relational Databases Certificate"
]
],
"isPrivate": true,
"fileName": "12-certificates/relational-databases-v8-certificate.json"
}

View File

@ -0,0 +1,15 @@
id: 606243f50267e718b1e755f4
title: Relational Databases Certificate
challengeType: 7
isPrivate: true
tests:
- id: 5f1a4ef5d5d6b5ab580fc6ae
title: Celestial Bodies Database
- id: 5f9771307d4d22b9d2b75a94
title: World Cup Database
- id: 5f87ac112ae598023a42df1a
title: Salon Appointment Scheduler
- id: 602d9ff222201c65d2a019f2
title: Periodic Table Database
- id: 602da04c22201c65d2a019f4
title: Final Boss

View File

@ -0,0 +1,19 @@
---
id: 5f1a4ef5d5d6b5ab580fc6ae
title: Celestial Bodies Database
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.celestial-bodies-database
dashedName: celestial-bodies-database
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 602da04c22201c65d2a019f4
title: Final Boss
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.final-boss
dashedName: final-boss
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 602da0de22201c65d2a019f6
title: Learn Advanced Bash by Building
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.learn-advanced-bash-by-building
dashedName: learn-advanced-bash-by-building
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,17 @@
---
id: 5f5b969a05380d2179fe6e18
title: Learn Bash and SQL by Building a Bike Rental Shop
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.learn-bash-and-sql-by-building-a-bike-rental-shop
dashedName: learn-bash-and-sql-by-building-a-bike-rental-shop
---
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 5ea8adfab628f68d805bfc5e
title: Learn Bash by Building a Boilerplate
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/freeCodeCamp/.learn-bash-by-building-a-boilerplate
dashedName: learn-bash-by-building-a-boilerplate
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 5f5904ac738bc2fa9efecf5a
title: Learn Bash Scripting by Building Five Programs
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.learn-bash-scripting-by-building-five-programs
dashedName: learn-bash-scripting-by-building-five-programs
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 5fa323cdaf6a73463d590659
title: Learn Git by Building an SQL Reference Object
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.learn-git-by-building-an-sql-reference-object
dashedName: learn-git-by-building-an-sql-reference-object
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 602da04222201c65d2a019f3
title: Learn GitHub by Building a List of Inspirational Quotes
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.learn-github-by-building-a-list-of-inspirational-quotes
dashedName: learn-github-by-building-a-list-of-inspirational-quotes
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 5f32db63eb37f7e17323f459
title: Learn Nano by Building a Castle
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.learn-nano-by-building-a-castle
dashedName: learn-nano-by-building-a-castle
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 5f2c289f164c29556da632fd
title: Learn Relational Databases by Building a Mario Database
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.learn-relational-databases-by-building-a-mario-database
dashedName: learn-relational-databases-by-building-a-mario-database
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 602da0c222201c65d2a019f5
title: Learn SQL by Building a Student Database
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.learn-sql-by-building-a-student-database
dashedName: learn-sql-by-building-a-student-database
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 602d9ff222201c65d2a019f2
title: Periodic Table Database
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.periodic-table-database
dashedName: periodic-table-database
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 5f87ac112ae598023a42df1a
title: Salon Appointment Scheduler
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.salon-appointment-scheduler
dashedName: salon-appointment-scheduler
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -0,0 +1,18 @@
---
id: 5f9771307d4d22b9d2b75a94
title: World Cup Database
challengeType: 12
helpCategory: Relational Databases
url: https://github.com/moT01/.world-cup-database
dashedName: world-cup-database
---
# --description--
# --instructions--
# --hints--
# --seed--
# --solutions--

View File

@ -26,14 +26,14 @@ const schema = Joi.object()
blockId: Joi.objectId(), blockId: Joi.objectId(),
challengeOrder: Joi.number(), challengeOrder: Joi.number(),
removeComments: Joi.bool(), removeComments: Joi.bool(),
challengeType: Joi.number().min(0).max(11).required(), challengeType: Joi.number().min(0).max(12).required(),
checksum: Joi.number(), checksum: Joi.number(),
// __commentCounts is only used to test the comment replacement // __commentCounts is only used to test the comment replacement
__commentCounts: Joi.object(), __commentCounts: Joi.object(),
// TODO: require this only for normal challenges, not certs // TODO: require this only for normal challenges, not certs
dashedName: Joi.string().regex(slugRE), dashedName: Joi.string().regex(slugRE),
description: Joi.when('challengeType', { description: Joi.when('challengeType', {
is: [challengeTypes.step, challengeTypes.video], is: [challengeTypes.step, challengeTypes.video, challengeTypes.codeally],
then: Joi.string().allow(''), then: Joi.string().allow(''),
otherwise: Joi.string().required() otherwise: Joi.string().required()
}), }),
@ -44,7 +44,12 @@ const schema = Joi.object()
indexjsx: fileJoi indexjsx: fileJoi
}), }),
guideUrl: Joi.string().uri({ scheme: 'https' }), guideUrl: Joi.string().uri({ scheme: 'https' }),
helpCategory: Joi.valid('JavaScript', 'HTML-CSS', 'Python'), helpCategory: Joi.valid(
'JavaScript',
'HTML-CSS',
'Python',
'Relational Databases'
),
videoUrl: Joi.string().allow(''), videoUrl: Joi.string().allow(''),
forumTopicId: Joi.number(), forumTopicId: Joi.number(),
id: Joi.objectId().required(), id: Joi.objectId().required(),
@ -99,7 +104,11 @@ const schema = Joi.object()
template: Joi.string().allow(''), template: Joi.string().allow(''),
time: Joi.string().allow(''), time: Joi.string().allow(''),
title: Joi.string().required(), title: Joi.string().required(),
translationPending: Joi.bool().required() translationPending: Joi.bool().required(),
url: Joi.when('challengeType', {
is: challengeTypes.codeally,
then: Joi.string().required()
})
}) })
.xor('helpCategory', 'isPrivate'); .xor('helpCategory', 'isPrivate');