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
10 changes: 2 additions & 8 deletions migration/etuutt_old/make-migration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ const prisma = _prisma.$extends({
body,
createdAt,
updatedAt,
isValid,
ue,
semesterCode,
}: {
Expand All @@ -316,23 +315,18 @@ const prisma = _prisma.$extends({
isAnonymous: true,
createdAt,
updatedAt,
validatedAt: isValid ? updatedAt : null,
ueof: { connect: { code: codes.ueof } },
semester: { connect: { code: semesterCode } },
},
}),
operation: 'created',
};
}
if (
comment.body !== body ||
comment.updatedAt !== updatedAt ||
(comment.validatedAt === null ? 0 : 1) !== isValid
) {
if (comment.body !== body || comment.updatedAt !== updatedAt) {
return {
data: await _prisma.ueComment.update({
where: { id: comment.id },
data: { body, updatedAt, validatedAt: isValid ? updatedAt : null },
data: { body, updatedAt },
}),
operation: 'updated',
};
Expand Down
52 changes: 26 additions & 26 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -340,18 +340,16 @@ model UeAnnalReportReason {
}

model UeComment {
id String @id @default(uuid())
body String @db.Text
isAnonymous Boolean
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
id String @id @default(uuid())
body String @db.Text
isAnonymous Boolean
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
// Removed @updatedAt because the property is used to display the last datetime the content of the comment was altered on
deletedAt DateTime?
validatedAt DateTime?
authorId String?
lastValidatedBody String?
semesterId String
ueofCode String
deletedAt DateTime?
authorId String?
semesterId String
ueofCode String

author User? @relation(fields: [authorId], references: [id], onDelete: SetNull)
semester Semester @relation(fields: [semesterId], references: [code])
Expand All @@ -377,13 +375,14 @@ model UeCommentReply {
}

model UeCommentReport {
id String @id @default(uuid())
body String @db.Text
createdAt DateTime @default(now())
mitigated Boolean @default(false)
commentId String
reasonId String
userId String
id String @id @default(uuid())
body String @db.Text
createdAt DateTime @default(now())
mitigated Boolean @default(false)
commentId String
reasonId String
userId String
reportedBody String

comment UeComment @relation(fields: [commentId], references: [id], onDelete: Cascade)
reason UeCommentReportReason @relation(fields: [reasonId], references: [name], onDelete: Cascade)
Expand All @@ -393,16 +392,17 @@ model UeCommentReport {
}

model UeCommentReplyReport {
id String @id @default(uuid())
body String @db.Text
createdAt DateTime @default(now())
mitigated Boolean @default(false)
reasonId String
replyId String
userId String
id String @id @default(uuid())
body String @db.Text
createdAt DateTime @default(now())
mitigated Boolean @default(false)
replyId String
reasonId String
userId String
reportedBody String

reason UeCommentReportReason @relation(fields: [reasonId], references: [name], onDelete: Cascade)
reply UeCommentReply @relation(fields: [replyId], references: [id], onDelete: Cascade)
reason UeCommentReportReason @relation(fields: [reasonId], references: [name], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)

@@unique([userId, replyId, reasonId]) // Prevent from spam
Expand Down
10 changes: 10 additions & 0 deletions src/exceptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export const enum ERROR_CODE {
NO_SUCH_UE_AT_SEMESTER = 4414,
NO_SUCH_ASSO_ROLE = 4415,
NO_SUCH_ASSO_MEMBERSHIP = 4416,
NO_SUCH_REPORT = 4417,
NO_SUCH_REPORT_REASON = 4418,
ANNAL_ALREADY_UPLOADED = 4901,
RESOURCE_UNAVAILABLE = 4902,
RESOURCE_INVALID_TYPE = 4903,
Expand Down Expand Up @@ -382,6 +384,14 @@ export const ErrorData = Object.freeze({
message: 'No such membership in asso: %',
httpCode: HttpStatus.NOT_FOUND,
},
[ERROR_CODE.NO_SUCH_REPORT]: {
message: 'The report does not exist',
httpCode: HttpStatus.NOT_FOUND,
},
[ERROR_CODE.NO_SUCH_REPORT_REASON]: {
message: 'The report reason does not exist',
httpCode: HttpStatus.NOT_FOUND,
},
[ERROR_CODE.ANNAL_ALREADY_UPLOADED]: {
message: 'A file has alreay been uploaded for this annal',
httpCode: HttpStatus.CONFLICT,
Expand Down
2 changes: 2 additions & 0 deletions src/prisma/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export {
UeComment as RawUeComment,
UeCommentReply as RawUeCommentReply,
UeCommentUpvote as RawUeCommentUpvote,
UeCommentReport as RawUeCommentReport,
UeCommentReplyReport as RawUeCommentReplyReport,
UeAnnalType as RawAnnalType,
UeAnnal as RawAnnal,
UeCourse as RawUeCourse,
Expand Down
4 changes: 2 additions & 2 deletions src/ue/annals/annals.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { UUIDParam } from '../../app.pipe';
import { GetUser, RequireApiPermission } from '../../auth/decorator';
import { AppException, ERROR_CODE } from '../../exceptions';
import { FileSize, MulterWithMime, UploadRoute, UserFile } from '../../upload.interceptor';
import { CommentStatus } from '../comments/interfaces/comment.interface';
import { CreateAnnalReqDto } from './dto/req/create-annal-req.dto';
import { UpdateAnnalReqDto } from './dto/req/update-annal-req.dto';
import { User } from '../../users/interfaces/user.interface';
Expand All @@ -19,6 +18,7 @@ import UeAnnalMetadataResDto from './dto/res/ue-annal-metadata-res.dto';
import { GetPermissions } from '../../auth/decorator/get-permissions.decorator';
import { Permission } from '@prisma/client';
import { omit, PermissionManager } from '../../utils';
import { AnnalStatus } from './interfaces/annal.interface';

@Controller('ue/annals')
@ApiTags('Annal')
Expand Down Expand Up @@ -131,7 +131,7 @@ export class AnnalsController {
throw new AppException(ERROR_CODE.NOT_ANNAL_SENDER);
if (
(await this.annalsService.getUeAnnal(annalId, user.id, permissions.can(Permission.API_MODERATE_ANNALS)))
.status !== CommentStatus.PROCESSING
.status !== AnnalStatus.PROCESSING
)
throw new AppException(ERROR_CODE.ANNAL_ALREADY_UPLOADED);
return omit(await this.annalsService.uploadAnnalFile(await file, annalId, rotate), 'ueof');
Expand Down
1 change: 1 addition & 0 deletions src/ue/annals/annals.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ export class AnnalsService {
annal.semesterId.slice(0, 1) === 'A' ? 1 : 0, // P should be listed before A
annal.type.name,
annal.createdAt.getTime(),
annal.id,
]);
}

Expand Down
16 changes: 11 additions & 5 deletions src/ue/annals/interfaces/annal.interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Prisma, PrismaClient } from '@prisma/client';
import { omit } from '../../../utils';
import { CommentStatus } from '../../comments/interfaces/comment.interface';
import { generateCustomModel } from '../../../prisma/prisma.service';

const UE_ANNAL_SELECT_FILTER = {
Expand Down Expand Up @@ -31,7 +30,7 @@ const UE_ANNAL_SELECT_FILTER = {

type UnformattedUeAnnal = Prisma.UeAnnalGetPayload<typeof UE_ANNAL_SELECT_FILTER>;
export type UeAnnalFile = Omit<UnformattedUeAnnal, 'validatedAt' | 'deletedAt' | 'uploadComplete'> & {
status: CommentStatus;
status: AnnalStatus;
};

export function generateCustomUeAnnalModel(prisma: PrismaClient) {
Expand All @@ -42,8 +41,15 @@ export function formatAnnal(_: PrismaClient, annal: UnformattedUeAnnal): UeAnnal
return {
...omit(annal, 'deletedAt', 'validatedAt', 'uploadComplete'),
status:
(annal.deletedAt && CommentStatus.DELETED) |
(annal.validatedAt && CommentStatus.VALIDATED) |
(!annal.uploadComplete && CommentStatus.PROCESSING),
(annal.deletedAt && AnnalStatus.DELETED) |
(annal.validatedAt && AnnalStatus.VALIDATED) |
(!annal.uploadComplete && AnnalStatus.PROCESSING),
};
}

export const enum AnnalStatus {
UNVERIFIED = 0b000, // For typing only
VALIDATED = 0b001,
PROCESSING = 0b010,
DELETED = 0b100,
}
Loading