Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
-- CreateTable
CREATE TABLE "Course" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3),

CONSTRAINT "Course_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Module" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3),

CONSTRAINT "Module_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Unit" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"moduleId" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3),

CONSTRAINT "Unit_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Exercise" (
"id" SERIAL NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT NOT NULL,
"githubRepo" TEXT NOT NULL,
"unitId" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3),

CONSTRAINT "Exercise_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "StudentExercise" (
"id" SERIAL NOT NULL,
"exerciseId" INTEGER NOT NULL,
"studentId" INTEGER NOT NULL,
"isComplete" BOOLEAN NOT NULL DEFAULT false,

CONSTRAINT "StudentExercise_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Tag" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3),

CONSTRAINT "Tag_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "_CohortToCourse" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);

-- CreateTable
CREATE TABLE "_CourseToModule" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);

-- CreateTable
CREATE TABLE "_ExerciseToTag" (
"A" INTEGER NOT NULL,
"B" INTEGER NOT NULL
);

-- CreateIndex
CREATE UNIQUE INDEX "Unit_moduleId_key" ON "Unit"("moduleId");

-- CreateIndex
CREATE UNIQUE INDEX "Exercise_unitId_key" ON "Exercise"("unitId");

-- CreateIndex
CREATE UNIQUE INDEX "_CohortToCourse_AB_unique" ON "_CohortToCourse"("A", "B");

-- CreateIndex
CREATE INDEX "_CohortToCourse_B_index" ON "_CohortToCourse"("B");

-- CreateIndex
CREATE UNIQUE INDEX "_CourseToModule_AB_unique" ON "_CourseToModule"("A", "B");

-- CreateIndex
CREATE INDEX "_CourseToModule_B_index" ON "_CourseToModule"("B");

-- CreateIndex
CREATE UNIQUE INDEX "_ExerciseToTag_AB_unique" ON "_ExerciseToTag"("A", "B");

-- CreateIndex
CREATE INDEX "_ExerciseToTag_B_index" ON "_ExerciseToTag"("B");

-- AddForeignKey
ALTER TABLE "Unit" ADD CONSTRAINT "Unit_moduleId_fkey" FOREIGN KEY ("moduleId") REFERENCES "Module"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "Exercise" ADD CONSTRAINT "Exercise_unitId_fkey" FOREIGN KEY ("unitId") REFERENCES "Unit"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "StudentExercise" ADD CONSTRAINT "StudentExercise_exerciseId_fkey" FOREIGN KEY ("exerciseId") REFERENCES "Exercise"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "StudentExercise" ADD CONSTRAINT "StudentExercise_studentId_fkey" FOREIGN KEY ("studentId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_CohortToCourse" ADD CONSTRAINT "_CohortToCourse_A_fkey" FOREIGN KEY ("A") REFERENCES "Cohort"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_CohortToCourse" ADD CONSTRAINT "_CohortToCourse_B_fkey" FOREIGN KEY ("B") REFERENCES "Course"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_CourseToModule" ADD CONSTRAINT "_CourseToModule_A_fkey" FOREIGN KEY ("A") REFERENCES "Course"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_CourseToModule" ADD CONSTRAINT "_CourseToModule_B_fkey" FOREIGN KEY ("B") REFERENCES "Module"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_ExerciseToTag" ADD CONSTRAINT "_ExerciseToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Exercise"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_ExerciseToTag" ADD CONSTRAINT "_ExerciseToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
84 changes: 72 additions & 12 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ enum UserRole {
}

model User {
id Int @id @default(autoincrement())
email String @unique
password String
role UserRole @default(STUDENT)
profile Profile?
comments Comment[]
id Int @id @default(autoincrement())
email String @unique
password String
role UserRole @default(STUDENT)
profile Profile?
comments Comment[]
postLikes PostReaction[]
cohortId Int?
cohort Cohort? @relation(fields: [cohortId], references: [id])
posts Post[]
deliveryLogs DeliveryLog[]
notesCreated Note[] @relation("TeacherNotes")
notesReceived Note[] @relation("StudentNotes")
cohortId Int?
cohort Cohort? @relation(fields: [cohortId], references: [id])
posts Post[]
deliveryLogs DeliveryLog[]
notesCreated Note[] @relation("TeacherNotes")
notesReceived Note[] @relation("StudentNotes")
studentExercise StudentExercise[]
}

model Profile {
Expand All @@ -46,6 +47,7 @@ model Profile {
model Cohort {
id Int @id @default(autoincrement())
name String?
courses Course[]
users User[]
deliveryLogs DeliveryLog[]
startDate DateTime? @db.Date
Expand All @@ -54,6 +56,64 @@ model Cohort {
updatedAt DateTime? @updatedAt
}

model Course {
id Int @id @default(autoincrement())
name String
modules Module[]
cohorts Cohort[]
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
}

model Module {
id Int @id @default(autoincrement())
name String
units Unit[]
courses Course[]
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
}

model Unit {
id Int @id @default(autoincrement())
name String
module Module @relation(fields: [moduleId], references: [id])
moduleId Int @unique
exercises Exercise[]
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
}

model Exercise {
id Int @id @default(autoincrement())
title String
description String
githubRepo String
tags Tag[]
unit Unit @relation(fields: [unitId], references: [id])
unitId Int @unique
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
studentExercise StudentExercise[]
}

model StudentExercise {
id Int @id @default(autoincrement())
exercise Exercise @relation(fields: [exerciseId], references: [id])
exerciseId Int
student User @relation(fields: [studentId], references: [id])
studentId Int
isComplete Boolean @default(false)
}

model Tag {
id Int @id @default(autoincrement())
name String
exercises Exercise[]
createdAt DateTime @default(now())
updatedAt DateTime? @updatedAt
}

model Post {
id Int @id @default(autoincrement())
content String
Expand Down
4 changes: 3 additions & 1 deletion prisma/seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ async function createPost(userId, content) {

async function createCohort() {
const cohort = await prisma.cohort.create({
data: {}
data: {
name: 'Cohort 1'
}
})

console.info('Cohort created', cohort)
Expand Down
7 changes: 4 additions & 3 deletions src/controllers/cohort.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import ERR from '../utils/errors.js'
import { dateRegex } from '../utils/regexMatchers.js'

export const create = async (req, res) => {
const { startDate, endDate } = req.body
const { name, startDate, endDate } = req.body

if (!startDate || !endDate) {
if (!name || !startDate || !endDate) {
return sendMessageResponse(res, 400, { error: ERR.DATE_REQUIRED })
}

if (!dateRegex.test(startDate) || !dateRegex.test(endDate)) {
return sendMessageResponse(res, 400, { error: ERR.DATE_FORMATTING })
}
Expand All @@ -19,7 +20,7 @@ export const create = async (req, res) => {
startDate,
endDate
)
const createdCohort = await createCohort(parsedStartDate, parsedEndDate)
const createdCohort = createCohort(name, parsedStartDate, parsedEndDate)

return sendDataResponse(res, 201, createdCohort)
} catch (e) {
Expand Down
27 changes: 27 additions & 0 deletions src/controllers/course.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import dbClient from '../utils/dbClient.js'
import { sendDataResponse, sendMessageResponse } from '../utils/responses.js'
import ERR from '../utils/errors.js'

const getAllCourses = async (req, res) => {
const courses = await dbClient.course.findMany()

return sendDataResponse(res, 200, courses)
}

const createCourse = async (req, res) => {
const { name } = req.body

if (!name) {
return sendMessageResponse(res, 400, { error: ERR.INCOMPLETE_REQUEST })
}

const course = await dbClient.course.create({
data: {
name: name
}
})

return sendDataResponse(res, 201, course)
}

export { getAllCourses, createCourse }
4 changes: 2 additions & 2 deletions src/controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export const create = async (req, res) => {
const existingUser = await User.findByEmail(userToCreate.email)

if (existingUser) {
return sendDataResponse(res, 400, { error: ERR.EMAIL_IN_USE })
return sendMessageResponse(res, 400, { error: ERR.EMAIL_IN_USE })
}

const createdUser = await userToCreate.save()
const createdUser = userToCreate.save()

return sendDataResponse(res, 201, createdUser)
} catch (error) {
Expand Down
4 changes: 3 additions & 1 deletion src/domain/cohort.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import dbClient from '../utils/dbClient.js'
* Create a new Cohort in the database
* @returns {Cohort}
*/
export async function createCohort(startDate, endDate) {
export async function createCohort(name, startDate, endDate) {
const createdCohort = await dbClient.cohort.create({
data: {
name,
startDate,
endDate
},
Expand All @@ -28,6 +29,7 @@ export class Cohort {
return {
cohort: {
id: this.id,
name: this.name,
startDate: this.startDate,
endDate: this.endDate
}
Expand Down
10 changes: 10 additions & 0 deletions src/routes/course.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Router } from 'express'
import { validateAuthentication } from '../middleware/auth.js'
import { createCourse, getAllCourses } from '../controllers/course.js'

const route = Router()

route.get('/', validateAuthentication, getAllCourses)
route.post('/', validateAuthentication, createCourse)

export default route
2 changes: 2 additions & 0 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import cohortRouter from './routes/cohort.js'
import deliveryLogRouter from './routes/deliveryLog.js'
import noteRouter from './routes/note.js'
import commentRouter from './routes/comment.js'
import courseRouter from './routes/course.js'
import reactionsRouter from './routes/postReactions.js'

const app = express()
Expand All @@ -29,6 +30,7 @@ app.use('/posts', postRouter)
app.use('/comments', commentRouter)
app.use('/react', reactionsRouter)
app.use('/cohorts', cohortRouter)
app.use('/courses', courseRouter)
app.use('/logs', deliveryLogRouter)
app.use('/notes', noteRouter)
app.use('/', authRouter)
Expand Down