Files
freeCodeCamp/api/prisma/schema.prisma
2025-07-17 02:34:46 -07:00

549 lines
18 KiB
Plaintext

generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
}
datasource db {
provider = "mongodb"
url = env("MONGOHQ_URL")
}
// USER COLLECTION ---------------------
type File {
contents String
ext String
key String
name String
path String? // Undefined | Null
}
type CompletedChallenge {
challengeType Json? // Null | Undefined | String | Int
completedDate Json // DateTime | Float, but not, as far as we know, Null
files File[]
githubLink String? // Undefined
id String
isManuallyApproved Boolean? // Undefined
solution String? // Null | Undefined
examResults ExamResults? // Undefined
}
enum DailyCodingChallengeLanguage {
javascript
python
}
type CompletedDailyCodingChallenge {
id String @db.ObjectId
/// Date in milliseconds since epoch
/// This is not a DateTime, because DateTime does not serialize directly to JSON
completedDate Int
languages DailyCodingChallengeLanguage[]
}
type PartiallyCompletedChallenge {
id String
completedDate Float
}
type Portfolio {
description String
id String
image String
title String
url String
}
type ProfileUI {
isLocked Boolean? // Undefined
showAbout Boolean? // Undefined
showCerts Boolean? // Undefined
showDonation Boolean? // Undefined
showHeatMap Boolean? // Undefined
showLocation Boolean? // Undefined
showName Boolean? // Undefined
showPoints Boolean? // Undefined
showPortfolio Boolean? // Undefined
showTimeLine Boolean? // Undefined
}
type SavedChallengeFile {
contents String
ext String
history String[]
key String
name String
}
type SavedChallenge {
files SavedChallengeFile[]
id String
lastSavedDate Float
}
type QuizAttempt {
challengeId String
quizId String
timestamp Float
}
/// Corresponds to the `user` collection.
model user {
id String @id @default(auto()) @map("_id") @db.ObjectId
about String
acceptedPrivacyTerms Boolean
completedChallenges CompletedChallenge[]
completedDailyCodingChallenges CompletedDailyCodingChallenge[]
completedExams CompletedExam[] // Undefined
quizAttempts QuizAttempt[] // Undefined
currentChallengeId String?
donationEmails String[] // Undefined | String[] (only possible for built in Types like String)
email String?
emailAuthLinkTTL DateTime? // Null | Undefined
emailVerified Boolean?
emailVerifyTTL DateTime? // Null | Undefined
externalId String
githubProfile String? // Undefined
isApisMicroservicesCert Boolean? // Undefined
isBackEndCert Boolean? // Undefined
isBanned Boolean? // Undefined
isCheater Boolean? // Undefined
isDataAnalysisPyCertV7 Boolean? // Undefined
isDataVisCert Boolean? // Undefined
isDonating Boolean
isFoundationalCSharpCertV8 Boolean? // Undefined
isFrontEndCert Boolean? // Undefined
isFrontEndLibsCert Boolean? // Undefined
isFullStackCert Boolean? // Undefined
isHonest Boolean?
isInfosecCertV7 Boolean? // Undefined
isInfosecQaCert Boolean? // Undefined
isJsAlgoDataStructCert Boolean? // Undefined
isJsAlgoDataStructCertV8 Boolean? // Undefined
isMachineLearningPyCertV7 Boolean? // Undefined
isQaCertV7 Boolean? // Undefined
isRelationalDatabaseCertV8 Boolean? // Undefined
isRespWebDesignCert Boolean? // Undefined
isSciCompPyCertV7 Boolean? // Undefined
is2018DataVisCert Boolean? // Undefined
is2018FullStackCert Boolean? // Undefined
isCollegeAlgebraPyCertV8 Boolean? // Undefined
// isUpcomingPythonCertV8 Boolean? // Undefined. It is in the db but has never been used.
keyboardShortcuts Boolean? // Undefined
linkedin String? // Null | Undefined
location String? // Null
name String? // Null
needsModeration Boolean? // Undefined
newEmail String? // Null | Undefined
partiallyCompletedChallenges PartiallyCompletedChallenge[] // Undefined | PartiallyCompletedChallenge[]
password String? // Undefined
picture String?
portfolio Portfolio[]
profileUI ProfileUI? // Undefined
progressTimestamps Json? // ProgressTimestamp[] | Null[] | Int64[] | Double[] - TODO: NORMALIZE
/// A random number between 0 and 1.
///
/// Valuable for selectively performing random logic.
rand Float?
savedChallenges SavedChallenge[] // Undefined | SavedChallenge[]
sendQuincyEmail Boolean
theme String? // Undefined
timezone String? // Undefined
twitter String? // Null | Undefined
unsubscribeId String
/// Used to track the number of times the user's record was written to.
///
/// This has the main benefit of allowing concurrent ops to check for race conditions.
updateCount Int? @default(0)
username String // TODO(Post-MVP): make this unique
usernameDisplay String? // Undefined
verificationToken String? // Undefined
website String? // Undefined
yearsTopContributor String[] // Undefined | String[]
isClassroomAccount Boolean? // Undefined
// Relations
examAttempts ExamEnvironmentExamAttempt[]
examEnvironmentAuthorizationToken ExamEnvironmentAuthorizationToken?
}
// -----------------------------------
/// An exam for the Exam Environment App as designed by the examiners
model ExamEnvironmentExam {
/// Globally unique exam id
id String @id @default(auto()) @map("_id") @db.ObjectId
/// All questions for a given exam
questionSets ExamEnvironmentQuestionSet[]
/// Configuration for exam metadata
config ExamEnvironmentConfig
/// ObjectIds for required challenges/blocks to take the exam
prerequisites String[] @db.ObjectId
/// If `deprecated`, the exam should no longer be considered for users
deprecated Boolean
// Relations
generatedExams ExamEnvironmentGeneratedExam[]
examAttempts ExamEnvironmentExamAttempt[]
}
/// A grouping of one or more questions of a given type
type ExamEnvironmentQuestionSet {
/// Unique question type id
id String @db.ObjectId
type ExamEnvironmentQuestionType
/// Content related to all questions in set
context String?
questions ExamEnvironmentMultipleChoiceQuestion[]
}
/// A multiple choice question for the Exam Environment App
type ExamEnvironmentMultipleChoiceQuestion {
/// Unique question id
id String @db.ObjectId
/// Main question paragraph
text String
/// Zero or more tags given to categorize a question
tags String[]
/// Optional audio for a question
audio ExamEnvironmentAudio?
/// Available possible answers for an exam
answers ExamEnvironmentAnswer[]
/// TODO Possible "deprecated_time" to remove after all exams could possibly have been taken
deprecated Boolean
}
/// Audio for an Exam Environment App multiple choice question
type ExamEnvironmentAudio {
/// Optional text for audio
captions String?
/// URL to audio file
///
/// Expected in the format: `<url>#t=<start_time_in_seconds>,<end_time_in_seconds>`
/// Where `start_time_in_seconds` and `end_time_in_seconds` are optional floats.
url String
}
/// Type of question for the Exam Environment App
enum ExamEnvironmentQuestionType {
/// Single question with one or more answers
MultipleChoice
/// Mass text
Dialogue
}
/// Answer for an Exam Environment App multiple choice question
type ExamEnvironmentAnswer {
/// Unique answer id
id String @db.ObjectId
/// Whether the answer is correct
isCorrect Boolean
/// Answer paragraph
text String
}
/// Configuration for an exam in the Exam Environment App
type ExamEnvironmentConfig {
/// Human-readable exam name
name String
/// Notes given about exam
note String
/// Category configuration for question selection
tags ExamEnvironmentTagConfig[]
/// Total time allocated for exam in milliseconds
totalTimeInMS Int
/// Configuration for sets of questions
questionSets ExamEnvironmentQuestionSetConfig[]
/// Duration after exam completion before a retake is allowed in milliseconds
retakeTimeInMS Int
/// Passing percent for the exam
passingPercent Float
}
/// Configuration for a set of questions in the Exam Environment App
type ExamEnvironmentQuestionSetConfig {
type ExamEnvironmentQuestionType
/// Number of this grouping of questions per exam
numberOfSet Int
/// Number of multiple choice questions per grouping matching this set config
numberOfQuestions Int
/// Number of correct answers given per multiple choice question
numberOfCorrectAnswers Int
/// Number of incorrect answers given per multiple choice question
numberOfIncorrectAnswers Int
}
/// Configuration for tags in the Exam Environment App
///
/// This configures the number of questions that should resolve to a given tag set criteria.
type ExamEnvironmentTagConfig {
/// Group of multiple choice question tags
group String[]
/// Number of multiple choice questions per exam that should meet the group criteria
numberOfQuestions Int
}
/// An attempt at an exam in the Exam Environment App
model ExamEnvironmentExamAttempt {
id String @id @default(auto()) @map("_id") @db.ObjectId
/// Foriegn key to user
userId String @db.ObjectId
/// Foreign key to exam
examId String @db.ObjectId
/// Foreign key to generated exam id
generatedExamId String @db.ObjectId
questionSets ExamEnvironmentQuestionSetAttempt[]
/// Time exam was started as milliseconds since epoch
startTimeInMS Int
// Relations
user user @relation(fields: [userId], references: [id], onDelete: Cascade)
exam ExamEnvironmentExam @relation(fields: [examId], references: [id], onDelete: Cascade)
generatedExam ExamEnvironmentGeneratedExam @relation(fields: [generatedExamId], references: [id])
ExamEnvironmentExamModeration ExamEnvironmentExamModeration[]
}
type ExamEnvironmentQuestionSetAttempt {
id String @db.ObjectId
questions ExamEnvironmentMultipleChoiceQuestionAttempt[]
}
type ExamEnvironmentMultipleChoiceQuestionAttempt {
/// Foreign key to question
id String @db.ObjectId
/// An array of foreign keys to answers
answers String[] @db.ObjectId
/// Time answers to question were submitted as milliseconds since epoch
///
/// If the question is later revisited, this field is updated
submissionTimeInMS Int
}
/// A generated exam for the Exam Environment App
///
/// This is the user-facing information for an exam.
model ExamEnvironmentGeneratedExam {
id String @id @default(auto()) @map("_id") @db.ObjectId
/// Foreign key to exam
examId String @db.ObjectId
questionSets ExamEnvironmentGeneratedQuestionSet[]
/// If `deprecated`, the generation should not longer be considered for users
deprecated Boolean
// Relations
exam ExamEnvironmentExam @relation(fields: [examId], references: [id], onDelete: Cascade)
EnvExamAttempt ExamEnvironmentExamAttempt[]
}
type ExamEnvironmentGeneratedQuestionSet {
id String @db.ObjectId
questions ExamEnvironmentGeneratedMultipleChoiceQuestion[]
}
type ExamEnvironmentGeneratedMultipleChoiceQuestion {
/// Foreign key to question id
id String @db.ObjectId
/// Each item is a foreign key to an answer
answers String[] @db.ObjectId
}
// -----------------------------------
model AccessToken {
id String @id @map("_id")
created DateTime @db.Date
ttl Int
userId String @db.ObjectId
@@index([userId], map: "userId_1")
}
model AuthToken {
id String @id @map("_id")
created DateTime @db.Date
ttl Int
userId String @db.ObjectId
}
model Donation {
id String @id @default(auto()) @map("_id") @db.ObjectId
amount Int @db.Int
customerId String
duration String?
email String
endDate DonationEndDate?
provider String
startDate DonationStartDate
subscriptionId String
userId String @db.ObjectId
@@index([email], map: "email_1")
@@index([userId], map: "userId_1")
}
model UserToken {
id String @id @map("_id")
created DateTime @db.Date
ttl Float
userId String @db.ObjectId
@@index([userId], map: "userId_1")
}
model ExamEnvironmentAuthorizationToken {
/// An ObjectId is used to provide access to the created timestamp
id String @id @default(auto()) @map("_id") @db.ObjectId
/// Used to set an `expireAt` index to delete documents
expireAt DateTime @db.Date
userId String @unique @db.ObjectId
// Relations
user user @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model sessions {
id String @id @map("_id")
expires DateTime @db.Date
session String
@@index([expires], map: "expires_1")
}
model MsUsername {
id String @id @default(auto()) @map("_id") @db.ObjectId
userId String @db.ObjectId
ttl Int
msUsername String
@@index([userId, id], map: "userId_1__id_1")
@@index([msUsername], map: "msUsername_1")
}
model Exam {
id String @id @map("_id") @db.ObjectId
numberOfQuestionsInExam Int @db.Int
passingPercent Int @db.Int
prerequisites Prerequisite[] // undefined | Prerequisite[]
title String
questions Question[]
}
type CompletedExam {
id String
challengeType Int
completedDate Float // TODO(Post-MVP): Change to DateTime?
examResults ExamResults
}
type ExamResults {
numberOfCorrectAnswers Int
numberOfQuestionsInExam Int
percentCorrect Float
passingPercent Int
passed Boolean
examTimeInSeconds Int
}
type Question {
id String
question String
wrongAnswers Answer[]
correctAnswers Answer[]
deprecated Boolean? // undefined
}
type Answer {
id String
answer String
deprecated Boolean? // undefined
}
type Prerequisite {
id String @db.ObjectId
title String
}
type DonationEndDate {
date DateTime @map("_date") @db.Date
when String @map("_when")
}
type DonationStartDate {
date DateTime @map("_date") @db.Date
when String @map("_when")
}
model Survey {
id String @id @default(auto()) @map("_id") @db.ObjectId
userId String @db.ObjectId
title String
responses SurveyResponse[]
@@index([userId], map: "userId_1")
}
type SurveyResponse {
question String
response String
}
// ----------------------
model DailyCodingChallenges {
id String @id @default(auto()) @map("_id") @db.ObjectId
challengeNumber Int
date DateTime
title String
description String
javascript DailyCodingChallengeApiLanguage
python DailyCodingChallengeApiLanguage
}
type DailyCodingChallengeApiLanguage {
tests DailyCodingChallengeApiLanguageTests[]
challengeFiles DailyCodingChallengeApiLanguageChallengeFiles[]
}
type DailyCodingChallengeApiLanguageTests {
text String
testString String
}
type DailyCodingChallengeApiLanguageChallengeFiles {
contents String
fileKey String
}
// ----------------------
model ExamEnvironmentExamModeration {
id String @id @default(auto()) @map("_id") @db.ObjectId
/// Whether or not the item is approved
status ExamEnvironmentExamModerationStatus
/// Foreign key to exam attempt
examAttemptId String @unique @db.ObjectId
/// Optional feedback/note about the moderation decision
feedback String?
/// Date the exam attempt was moderated
moderationDate DateTime?
/// Foreign key to moderator. This is `null` until the item is moderated.
moderatorId String? @db.ObjectId
/// Date the exam attempt was added to the moderation queue
submissionDate DateTime @default(now()) @db.Date
// Relations
examAttempt ExamEnvironmentExamAttempt @relation(fields: [examAttemptId], references: [id], onDelete: Cascade)
}
enum ExamEnvironmentExamModerationStatus {
/// Attempt is determined to be valid
Approved
/// Attempt is determined to be invalid
Denied
/// Attempt has yet to be moderated
Pending
}