Skip to content

Commit

Permalink
Merge pull request #193 from makeopensource/154-sticky-notes-endpoints
Browse files Browse the repository at this point in the history
154 sticky notes endpoints
  • Loading branch information
jessehartloff authored Nov 12, 2024
2 parents 1a9610b + e5d7cd8 commit e3b467b
Show file tree
Hide file tree
Showing 15 changed files with 246 additions and 0 deletions.
4 changes: 4 additions & 0 deletions devU-api/src/entities/role/role.defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const student: Role = {
submissionCreateAll: false,
submissionCreateSelf: true,
submissionViewAll: false,
stickyNoteViewAll: false,
stickyNoteEditAll: false,
userCourseEditAll: false,
}

Expand All @@ -39,6 +41,8 @@ const instructor: Role = {
submissionCreateAll: true,
submissionCreateSelf: true,
submissionViewAll: true,
stickyNoteViewAll: true,
stickyNoteEditAll: true,
userCourseEditAll: true,
}

Expand Down
6 changes: 6 additions & 0 deletions devU-api/src/entities/role/role.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,10 @@ export default class RoleModel {

@Column({ name: 'user_course_edit_all' }) // TODO: Don't let the last instructor change their role
userCourseEditAll: boolean

@Column({ name: 'sticky_note_view_all' })
stickyNoteViewAll: boolean

@Column({ name: 'sticky_note_edit_all' })
stickyNoteEditAll: boolean
}
2 changes: 2 additions & 0 deletions devU-api/src/entities/role/role.serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ export function serialize(role: RoleModel): Role {
submissionCreateSelf: role.submissionCreateSelf,
submissionViewAll: role.submissionViewAll,
userCourseEditAll: role.userCourseEditAll,
stickyNoteViewAll: role.stickyNoteViewAll,
stickyNoteEditAll: role.stickyNoteEditAll,
}
}
79 changes: 79 additions & 0 deletions devU-api/src/entities/stickyNote/stickyNote.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {NextFunction, Request, Response} from 'express'

import StickyNoteService from './stickyNote.service'

import {NotFound, Updated} from '../../utils/apiResponse.utils'

import {serialize} from './stickyNote.serializer'

export async function retrieve(req: Request, res: Response, next: NextFunction) {
try {
const id = parseInt(req.params.id)
const stickyNote = await StickyNoteService.retrieve(id)

if (!stickyNote) return res.status(404).json(NotFound)

const response = serialize(stickyNote)

res.status(200).json(response)
} catch (err) {
next(err)
}
}

export async function post(req: Request, res: Response, next: NextFunction) {
try {
const reqStickyNote = req.body
const stickyNote = await StickyNoteService.create(reqStickyNote)
const response = serialize(stickyNote)

res.status(201).json(response)
} catch (err) {
next(err)
}
}

export async function put(req: Request, res: Response, next: NextFunction) {
try {
const id = parseInt(req.params.id)
const reqStickyNote = req.body
const stickyNote = await StickyNoteService.update(id, reqStickyNote)

if (!stickyNote.affected) return res.status(404).json(NotFound)

res.status(200).json(Updated)
} catch (err) {
next(err)
}
}

export async function remove(req: Request, res: Response, next: NextFunction) {
try {
const id = parseInt(req.params.id)
await StickyNoteService._delete(id)

res.status(204).send()
} catch (err) {
next(err)
}
}

export async function listBySubmission(req: Request, res: Response, next: NextFunction) {
try {
const submissionId = parseInt(req.params.submissionId)
const stickyNotes = await StickyNoteService.listBySubmission(submissionId)
const response = stickyNotes.map(serialize)

res.status(200).json(response)
} catch (err) {
next(err)
}
}

export default {
retrieve,
post,
put,
remove,
listBySubmission,
}
28 changes: 28 additions & 0 deletions devU-api/src/entities/stickyNote/stickyNote.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {
JoinColumn,
ManyToOne,
Entity,
Column,
DeleteDateColumn,
PrimaryGeneratedColumn,
} from 'typeorm'

import SubmissionModel from '../submission/submission.model'

@Entity('sticky_notes')
export default class StickyNotesModel {

@PrimaryGeneratedColumn()
id: number

@Column({ name: 'submissionId' })
@JoinColumn({ name: 'submissionId' })
@ManyToOne(() => SubmissionModel)
submissionId: number

@Column({ name: 'content' })
content: string

@DeleteDateColumn({ name: 'deleted_at' })
deletedAt?: Date
}
25 changes: 25 additions & 0 deletions devU-api/src/entities/stickyNote/stickyNote.router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import express from 'express'

// Middleware
import validator from './stickyNote.validator'
import { isAuthorized } from '../../authorization/authorization.middleware'
import { asInt } from '../../middleware/validator/generic.validator'

// Controller
import StickyNoteController from './stickyNote.controller'

const Router = express.Router({ mergeParams: true })

Router.get('/all', isAuthorized("stickyNoteViewAll"), validator , StickyNoteController.listBySubmission)

Router.get('/:id' ,isAuthorized("stickyNoteViewAll") , asInt("id"), validator , StickyNoteController.retrieve)

Router.post('/',isAuthorized("stickyNoteEditAll") ,validator, StickyNoteController.post)

Router.put('/:id',isAuthorized("stickyNoteEditAll") , validator, StickyNoteController.put)

Router.delete('/:id',isAuthorized("stickyNoteEditAll") , asInt("id"), validator, StickyNoteController.remove)

export default Router


11 changes: 11 additions & 0 deletions devU-api/src/entities/stickyNote/stickyNote.serializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {StickyNote} from 'devu-shared-modules'

import StickyNoteModel from './stickyNote.model'

export function serialize(stickyNote: StickyNoteModel): StickyNote {
return {
id: stickyNote.id,
submissionId: stickyNote.submissionId,
content: stickyNote.content,
}
}
37 changes: 37 additions & 0 deletions devU-api/src/entities/stickyNote/stickyNote.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {IsNull} from 'typeorm'
import {dataSource} from '../../database'

import StickyNotesModel from './stickyNote.model'
import {StickyNote} from 'devu-shared-modules'

const StickyNoteConn = () => dataSource.getRepository(StickyNotesModel)

export async function create(stickyNote: StickyNote) {
return await StickyNoteConn().save(stickyNote)
}

export async function update(id : number,stickyNote: StickyNote) {
const {submissionId, content} = stickyNote
if (!id) throw new Error('Missing Id')
return await StickyNoteConn().update(id, {submissionId, content})
}

export async function _delete(id: number) {
return await StickyNoteConn().softDelete({id, deletedAt: IsNull()})
}

export async function retrieve(id: number) {
return await StickyNoteConn().findOneBy({id, deletedAt: IsNull()})
}

export async function listBySubmission(submissionId: number) {
return await StickyNoteConn().findBy({submissionId: submissionId , deletedAt: IsNull()})
}

export default {
create,
update,
_delete,
retrieve,
listBySubmission,
}
10 changes: 10 additions & 0 deletions devU-api/src/entities/stickyNote/stickyNote.validator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {check} from 'express-validator'

import validate from '../../middleware/validator/generic.validator'

const submissionId = check('submissionId').isNumeric()
const content = check('content').isString()

const validator = [submissionId, content, validate]

export default validator
14 changes: 14 additions & 0 deletions devU-api/src/migration/1731427638811-add-sticky-note-endpoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class AddStickyNoteEndpoints1731427638811 implements MigrationInterface {
name = 'AddStickyNoteEndpoints1731427638811'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "sticky_notes" ADD "deleted_at" TIMESTAMP`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "sticky_notes" DROP COLUMN "deleted_at"`);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class UpdatedRolesWithStickyNotes1731433278166 implements MigrationInterface {
name = 'UpdatedRolesWithStickyNotes1731433278166'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "role" ADD "sticky_note_view_all" boolean NOT NULL`);
await queryRunner.query(`ALTER TABLE "role" ADD "sticky_note_edit_all" boolean NOT NULL`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "sticky_note_edit_all"`);
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "sticky_note_view_all"`);
}

}
6 changes: 6 additions & 0 deletions devU-api/src/router/courseData.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,19 @@ import categoryScores from '../entities/categoryScore/categoryScore.router'
import courseScores from '../entities/courseScore/courseScore.router'
import assignmentScore from '../entities/assignmentScore/assignmentScore.router'
import role from '../entities/role/role.router'
import stickyNotes from '../entities/stickyNote/stickyNote.router'

import nonContainerAutoGraderRouter from '../entities/nonContainerAutoGrader/nonContainerAutoGrader.router'

import { asInt } from '../middleware/validator/generic.validator'
import webhooksRouter from '../entities/webhooks/webhooks.router'

const submissionRouter = express.Router({ mergeParams: true })
submissionRouter.use('/sticky-notes', stickyNotes)

const assignmentRouter = express.Router({ mergeParams: true })
assignmentRouter.use('/submission/:submissionId', asInt('submissionId'), submissionRouter)

assignmentRouter.use('/assignment-problems', assignmentProblem)
assignmentRouter.use('/container-auto-graders', containerAutoGrader)
assignmentRouter.use('/deadline-extensions', deadlineExtensions)
Expand Down
1 change: 1 addition & 0 deletions devU-shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from './types/deadlineExtensions.types'
export * from './types/grader.types'
export * from './types/role.types'
export * from './types/webhooks.types'
export * from './types/stickyNote.types'

export * from './utils/object.utils'
export * from './utils/string.utils'
2 changes: 2 additions & 0 deletions devU-shared/src/types/role.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ export type Role = {
submissionCreateSelf: boolean
submissionViewAll: boolean
userCourseEditAll: boolean
stickyNoteViewAll: boolean
stickyNoteEditAll: boolean
}
5 changes: 5 additions & 0 deletions devU-shared/src/types/stickyNote.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type StickyNote = {
id?: number
submissionId: number
content: string
}

0 comments on commit e3b467b

Please sign in to comment.