From a818e7d8207d3fc859c7195e82af5e0fe409ca15 Mon Sep 17 00:00:00 2001 From: hpkoh <53825802+hpkoh@users.noreply.github.com> Date: Sun, 9 Oct 2022 01:36:21 +0800 Subject: [PATCH] [questions][feat] add questions models (#323) * [questions] [feat] add questions models * [questions][feat] add question types * [questions][chore] update schema naming scheme * [questions][chore] update naming scheme * [questions][chore] updating naming scheme * [questions][feat] add location, role and comapny * [questions][feat] update vote enum --- .../migration.sql | 171 ++++++++++++++++++ .../migration.sql | 11 ++ .../migration.sql | 12 ++ .../migration.sql | 30 +++ apps/portal/prisma/schema.prisma | 171 ++++++++++++++++-- .../router/questions-question-router.ts | 0 apps/portal/src/types/questions-question.d.ts | 0 7 files changed, 383 insertions(+), 12 deletions(-) create mode 100644 apps/portal/prisma/migrations/20221007110225_add_questions_model/migration.sql create mode 100644 apps/portal/prisma/migrations/20221008090846_add_question_types/migration.sql create mode 100644 apps/portal/prisma/migrations/20221008114522_add_questions_company_loaction_role/migration.sql create mode 100644 apps/portal/prisma/migrations/20221008165306_update_vote_enum/migration.sql create mode 100644 apps/portal/src/server/router/questions-question-router.ts create mode 100644 apps/portal/src/types/questions-question.d.ts diff --git a/apps/portal/prisma/migrations/20221007110225_add_questions_model/migration.sql b/apps/portal/prisma/migrations/20221007110225_add_questions_model/migration.sql new file mode 100644 index 00000000..5fdad411 --- /dev/null +++ b/apps/portal/prisma/migrations/20221007110225_add_questions_model/migration.sql @@ -0,0 +1,171 @@ +-- CreateEnum +CREATE TYPE "QuestionsVote" AS ENUM ('NO_VOTE', 'UPVOTE', 'DOWNVOTE'); + +-- CreateTable +CREATE TABLE "QuestionsQuestion" ( + "id" TEXT NOT NULL, + "userId" TEXT, + "content" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsQuestion_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "QuestionsQuestionEncounter" ( + "id" TEXT NOT NULL, + "questionId" TEXT NOT NULL, + "userId" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsQuestionEncounter_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "QuestionsQuestionVote" ( + "id" TEXT NOT NULL, + "questionId" TEXT NOT NULL, + "userId" TEXT, + "vote" "QuestionsVote" NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsQuestionVote_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "QuestionsQuestionComment" ( + "id" TEXT NOT NULL, + "questionId" TEXT NOT NULL, + "userId" TEXT, + "content" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsQuestionComment_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "QuestionsQuestionCommentVote" ( + "id" TEXT NOT NULL, + "questionCommentId" TEXT NOT NULL, + "userId" TEXT, + "vote" "QuestionsVote" NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsQuestionCommentVote_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "QuestionsAnswer" ( + "id" TEXT NOT NULL, + "questionId" TEXT NOT NULL, + "userId" TEXT, + "content" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsAnswer_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "QuestionsAnswerVote" ( + "id" TEXT NOT NULL, + "answerId" TEXT NOT NULL, + "userId" TEXT, + "vote" "QuestionsVote" NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsAnswerVote_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "QuestionsAnswerComment" ( + "id" TEXT NOT NULL, + "answerId" TEXT NOT NULL, + "userId" TEXT, + "content" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsAnswerComment_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "QuestionsAnswerCommentVote" ( + "id" TEXT NOT NULL, + "answerCommentId" TEXT NOT NULL, + "userId" TEXT, + "vote" "QuestionsVote" NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "QuestionsAnswerCommentVote_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "QuestionsQuestionVote_questionId_userId_key" ON "QuestionsQuestionVote"("questionId", "userId"); + +-- CreateIndex +CREATE UNIQUE INDEX "QuestionsQuestionCommentVote_questionCommentId_userId_key" ON "QuestionsQuestionCommentVote"("questionCommentId", "userId"); + +-- CreateIndex +CREATE UNIQUE INDEX "QuestionsAnswerVote_answerId_userId_key" ON "QuestionsAnswerVote"("answerId", "userId"); + +-- CreateIndex +CREATE UNIQUE INDEX "QuestionsAnswerCommentVote_answerCommentId_userId_key" ON "QuestionsAnswerCommentVote"("answerCommentId", "userId"); + +-- AddForeignKey +ALTER TABLE "QuestionsQuestion" ADD CONSTRAINT "QuestionsQuestion_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsQuestionEncounter" ADD CONSTRAINT "QuestionsQuestionEncounter_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsQuestionEncounter" ADD CONSTRAINT "QuestionsQuestionEncounter_questionId_fkey" FOREIGN KEY ("questionId") REFERENCES "QuestionsQuestion"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsQuestionVote" ADD CONSTRAINT "QuestionsQuestionVote_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsQuestionVote" ADD CONSTRAINT "QuestionsQuestionVote_questionId_fkey" FOREIGN KEY ("questionId") REFERENCES "QuestionsQuestion"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsQuestionComment" ADD CONSTRAINT "QuestionsQuestionComment_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsQuestionComment" ADD CONSTRAINT "QuestionsQuestionComment_questionId_fkey" FOREIGN KEY ("questionId") REFERENCES "QuestionsQuestion"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsQuestionCommentVote" ADD CONSTRAINT "QuestionsQuestionCommentVote_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsQuestionCommentVote" ADD CONSTRAINT "QuestionsQuestionCommentVote_questionCommentId_fkey" FOREIGN KEY ("questionCommentId") REFERENCES "QuestionsQuestionComment"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsAnswer" ADD CONSTRAINT "QuestionsAnswer_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsAnswer" ADD CONSTRAINT "QuestionsAnswer_questionId_fkey" FOREIGN KEY ("questionId") REFERENCES "QuestionsQuestion"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsAnswerVote" ADD CONSTRAINT "QuestionsAnswerVote_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsAnswerVote" ADD CONSTRAINT "QuestionsAnswerVote_answerId_fkey" FOREIGN KEY ("answerId") REFERENCES "QuestionsAnswer"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsAnswerComment" ADD CONSTRAINT "QuestionsAnswerComment_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsAnswerComment" ADD CONSTRAINT "QuestionsAnswerComment_answerId_fkey" FOREIGN KEY ("answerId") REFERENCES "QuestionsAnswer"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsAnswerCommentVote" ADD CONSTRAINT "QuestionsAnswerCommentVote_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "QuestionsAnswerCommentVote" ADD CONSTRAINT "QuestionsAnswerCommentVote_answerCommentId_fkey" FOREIGN KEY ("answerCommentId") REFERENCES "QuestionsAnswerComment"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/apps/portal/prisma/migrations/20221008090846_add_question_types/migration.sql b/apps/portal/prisma/migrations/20221008090846_add_question_types/migration.sql new file mode 100644 index 00000000..0b35f78d --- /dev/null +++ b/apps/portal/prisma/migrations/20221008090846_add_question_types/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - Added the required column `questionType` to the `QuestionsQuestion` table without a default value. This is not possible if the table is not empty. + +*/ +-- CreateEnum +CREATE TYPE "QuestionsQuestionType" AS ENUM ('CODING', 'SYSTEM_DESIGN', 'BEHAVIORAL'); + +-- AlterTable +ALTER TABLE "QuestionsQuestion" ADD COLUMN "questionType" "QuestionsQuestionType" NOT NULL; diff --git a/apps/portal/prisma/migrations/20221008114522_add_questions_company_loaction_role/migration.sql b/apps/portal/prisma/migrations/20221008114522_add_questions_company_loaction_role/migration.sql new file mode 100644 index 00000000..0a5830e1 --- /dev/null +++ b/apps/portal/prisma/migrations/20221008114522_add_questions_company_loaction_role/migration.sql @@ -0,0 +1,12 @@ +/* + Warnings: + + - Added the required column `company` to the `QuestionsQuestionEncounter` table without a default value. This is not possible if the table is not empty. + - Added the required column `location` to the `QuestionsQuestionEncounter` table without a default value. This is not possible if the table is not empty. + - Added the required column `role` to the `QuestionsQuestionEncounter` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "QuestionsQuestionEncounter" ADD COLUMN "company" TEXT NOT NULL, +ADD COLUMN "location" TEXT NOT NULL, +ADD COLUMN "role" TEXT NOT NULL; diff --git a/apps/portal/prisma/migrations/20221008165306_update_vote_enum/migration.sql b/apps/portal/prisma/migrations/20221008165306_update_vote_enum/migration.sql new file mode 100644 index 00000000..bd09564a --- /dev/null +++ b/apps/portal/prisma/migrations/20221008165306_update_vote_enum/migration.sql @@ -0,0 +1,30 @@ +/* + Warnings: + + - Changed the type of `vote` on the `QuestionsAnswerCommentVote` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `vote` on the `QuestionsAnswerVote` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `vote` on the `QuestionsQuestionCommentVote` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + - Changed the type of `vote` on the `QuestionsQuestionVote` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. + +*/ +-- CreateEnum +CREATE TYPE "Vote" AS ENUM ('UPVOTE', 'DOWNVOTE'); + +-- AlterTable +ALTER TABLE "QuestionsAnswerCommentVote" DROP COLUMN "vote", +ADD COLUMN "vote" "Vote" NOT NULL; + +-- AlterTable +ALTER TABLE "QuestionsAnswerVote" DROP COLUMN "vote", +ADD COLUMN "vote" "Vote" NOT NULL; + +-- AlterTable +ALTER TABLE "QuestionsQuestionCommentVote" DROP COLUMN "vote", +ADD COLUMN "vote" "Vote" NOT NULL; + +-- AlterTable +ALTER TABLE "QuestionsQuestionVote" DROP COLUMN "vote", +ADD COLUMN "vote" "Vote" NOT NULL; + +-- DropEnum +DROP TYPE "QuestionsVote"; diff --git a/apps/portal/prisma/schema.prisma b/apps/portal/prisma/schema.prisma index 7ece9c5d..13287fea 100644 --- a/apps/portal/prisma/schema.prisma +++ b/apps/portal/prisma/schema.prisma @@ -37,18 +37,32 @@ model Session { } model User { - id String @id @default(cuid()) - name String? - email String? @unique - emailVerified DateTime? - image String? - accounts Account[] - sessions Session[] - todos Todo[] - resumesResumes ResumesResume[] - resumesStars ResumesStar[] - resumesComments ResumesComment[] - resumesCommentVotes ResumesCommentVote[] + id String @id @default(cuid()) + name String? + email String? @unique + emailVerified DateTime? + image String? + accounts Account[] + sessions Session[] + todos Todo[] + resumesResumes ResumesResume[] + resumesStars ResumesStar[] + resumesComments ResumesComment[] + resumesCommentVotes ResumesCommentVote[] + questionsQuestions QuestionsQuestion[] + questionsQuestionEncounters QuestionsQuestionEncounter[] + questionsQuestionVotes QuestionsQuestionVote[] + questionsQuestionComments QuestionsQuestionComment[] + questionsQuestionCommentVotes QuestionsQuestionCommentVote[] + questionsAnswers QuestionsAnswer[] + questionsAnswerVotes QuestionsAnswerVote[] + questionsAnswerComments QuestionsAnswerComment[] + questionsAnswerCommentVotes QuestionsAnswerCommentVote[] +} + +enum Vote { + UPVOTE + DOWNVOTE } model VerificationToken { @@ -162,4 +176,137 @@ model ResumesCommentVote { // Add Questions project models here, prefix all models with "Questions", // use camelCase for field names, and try to name them consistently // across all models in this file. + +enum QuestionsQuestionType { + CODING + SYSTEM_DESIGN + BEHAVIORAL +} + +model QuestionsQuestion { + id String @id @default(cuid()) + userId String? + content String @db.Text + questionType QuestionsQuestionType + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + encounters QuestionsQuestionEncounter[] + votes QuestionsQuestionVote[] + comments QuestionsQuestionComment[] + answers QuestionsAnswer[] +} + +model QuestionsQuestionEncounter { + id String @id @default(cuid()) + questionId String + userId String? + // TODO: sync with models + company String @db.Text + location String @db.Text + role String @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade) +} + +model QuestionsQuestionVote { + id String @id @default(cuid()) + questionId String + userId String? + vote Vote + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade) + + @@unique([questionId, userId]) +} + +model QuestionsQuestionComment { + id String @id @default(cuid()) + questionId String + userId String? + content String @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade) + votes QuestionsQuestionCommentVote[] +} + +model QuestionsQuestionCommentVote { + id String @id @default(cuid()) + questionCommentId String + userId String? + vote Vote + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + comment QuestionsQuestionComment @relation(fields: [questionCommentId], references: [id], onDelete: Cascade) + + @@unique([questionCommentId, userId]) +} + +model QuestionsAnswer { + id String @id @default(cuid()) + questionId String + userId String? + content String @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + question QuestionsQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade) + votes QuestionsAnswerVote[] + comments QuestionsAnswerComment[] +} + +model QuestionsAnswerVote { + id String @id @default(cuid()) + answerId String + userId String? + vote Vote + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + answer QuestionsAnswer @relation(fields: [answerId], references: [id], onDelete: Cascade) + + @@unique([answerId, userId]) +} + +model QuestionsAnswerComment { + id String @id @default(cuid()) + answerId String + userId String? + content String @db.Text + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + answer QuestionsAnswer @relation(fields: [answerId], references: [id], onDelete: Cascade) + votes QuestionsAnswerCommentVote[] +} + +model QuestionsAnswerCommentVote { + id String @id @default(cuid()) + answerCommentId String + userId String? + vote Vote + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + user User? @relation(fields: [userId], references: [id], onDelete: SetNull) + comment QuestionsAnswerComment @relation(fields: [answerCommentId], references: [id], onDelete: Cascade) + + @@unique([answerCommentId, userId]) +} + // End of Questions project models. diff --git a/apps/portal/src/server/router/questions-question-router.ts b/apps/portal/src/server/router/questions-question-router.ts new file mode 100644 index 00000000..e69de29b diff --git a/apps/portal/src/types/questions-question.d.ts b/apps/portal/src/types/questions-question.d.ts new file mode 100644 index 00000000..e69de29b