Skip to content

Commit

Permalink
Dev (#165)
Browse files Browse the repository at this point in the history
* fix: remove unused validate

* fix: add subject into userExam

* feat: create api get all documents by subjectId

* fix: remove validation for author field in DocumentDto

* fix: update response of verifyAccessToken

* fix: update response of verifyAccessToken

* fix: add userInfo into response refreshToken

* fix: add subject to response of getDocumentBySubject api

* feat: create api get a subject by id

* feat: create unique for subject_name

* fix: return code and message error when create duplicate subject

* feat: update auth api for the admin

* fix: refreshToken response

* feat: [update api approve subject]

* fix: error response

* fix: [TOKEN_EXPIRED response]

* feat: [add api update is_approved for admin]

* feat: api create new document for admin

* feat: [Pagination for all of api get all]

* feat: [update metadata(total, currentPage, pageSize) in response]

* fix: [resolve conflict]

* fix: [resolve conflict]

* feat: [default sort with desc]

* feat/#135 (#136)

* feat/#138 (#139)

* feat: allow users outside the organization

* fix: typo

* feat: softDelete

* feat: [delete plugin]

* feat: [api update document & exam by admin and own]

* feat: [Update api documentation and exam by admin and owner]

* feat: [...]

* feat: [:boom:][change the structure, logic, algorithms related to userExam and scoring]

* feat: [...]

* feat: [test workflows]

* feat: [test workflows]

* feat: [test workflows]

* feat: [:zap:][add is_show_info & nickname to user and handle hide userinfo if required]

* fix: [convert pageSize & currentPage from string to number in pipeline]

* fix: [change Dockfile]

* fix: [author array to object in response]

* feat: [...]

* feat/#146 (#151)

* feat: [add questions into response of draft exam]

* fix: return wrong hideUserInfoIfRequired

* fix: missing hideUserInfoIfRequired() in GetAllDocumentByAdmin()

* feat/#155 (#156)

* feat/#155

* fix resolve conflicts [feat/#155]

* fix feat/#155 reslove conflicts

* feat/#160 (#161)

* feat/#160

* fix [feat/#160]

* fix [feat/#160] 2

* fix [feat/#160] 3

* Feat/#162 (#163)

* feat/#162

* fix feat/#162

---------

Co-authored-by: Loc Xuan Dao <[email protected]>
Co-authored-by: dungnguyenn1103 <[email protected]>
  • Loading branch information
3 people authored Apr 14, 2023
1 parent 04118e1 commit ef490a1
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/apis/v1/documents/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,9 @@ export const getDocumentsBySubjectId = async (req: RequestWithUser, res: Respons
const result = await service.getDocumentsBySubjectId(input.id);
res.send(fmt.formatResponse(result, Date.now() - req.startTime, 'OK'));
};

export const getDocumentsByOwner = async (req: RequestWithUser, res: Response) => {
const author: ObjectId = req?.user?._id;
const result = await service.getDocumentsByOwner(author);
res.send(fmt.formatResponse(result, Date.now() - req.startTime, 'OK'));
};
3 changes: 3 additions & 0 deletions src/apis/v1/documents/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ const router = Router();

router.get('/', authMiddleware, asyncRouteHandler(controller.getDocuments));

router.get('/owner', authMiddleware, asyncRouteHandler(controller.getDocumentsByOwner));

router.post(
'/',
authMiddleware,
Expand Down Expand Up @@ -46,4 +48,5 @@ router.get(
validationMiddleware(ParamsDocumentDto, APP_CONSTANTS.params),
asyncRouteHandler(controller.getDocumentsBySubjectId)
);

export default router;
17 changes: 17 additions & 0 deletions src/apis/v1/documents/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,23 @@ export const getDocumentsBySubjectId = async (subjectId: string) => {
}
};

export const getDocumentsByOwner = async (authorId: ObjectId) => {
try {
const results = await DocumentModel.find({ author: authorId })
.populate('author', '-is_blocked -roles -created_at -updated_at -__v')
.populate('subject', '-is_deleted -created_at -updated_at -__v');

return {
documents: results.map((document) => {
return { ...document.toObject(), author: hideUserInfoIfRequired(document?.author) };
}),
};
} catch (error) {
logger.error(`Error while get documents by Owner: ${error}`);
throw new HttpException(400, ErrorCodes.BAD_REQUEST.MESSAGE, ErrorCodes.BAD_REQUEST.CODE);
}
};

export const updateDocumentByAdmin = async (input: UpdateDocumentByAdminDto, documentId: string) => {
try {
const document = await DocumentModel.findByIdAndUpdate(
Expand Down
7 changes: 7 additions & 0 deletions src/apis/v1/exam/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,10 @@ export const getDraftExam = async (req: RequestWithUser, res: Response) => {

res.send(fmt.formatResponse(result, Date.now() - req.startTime, 'OK'));
};

export const getExamsByOwner = async (req: RequestWithUser, res: Response) => {
const author = req?.user?._id;
const result = await service.getExamsByOwner(String(author));

res.send(fmt.formatResponse(result, Date.now() - req.startTime, 'OK'));
};
2 changes: 2 additions & 0 deletions src/apis/v1/exam/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ router.get('/', authMiddleware, asyncRouteHandler(controller.getExams));

router.get('/draft-exam', authMiddleware, asyncRouteHandler(controller.getDraftExam));

router.get('/owner', authMiddleware, asyncRouteHandler(controller.getExamsByOwner));

router.get(
'/:id',
authMiddleware,
Expand Down
67 changes: 65 additions & 2 deletions src/apis/v1/exam/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export const getExamById = async (id: string) => {
_id: 1,
title: 1,
description: 1,
is_approved: 1,
author: {
_id: '$author._id',
fullname: '$author.fullname',
Expand Down Expand Up @@ -180,7 +181,7 @@ export const getExamsBySubjectId = async (subjectId: string, urlParams: URLParam
const count = ExamModel.countDocuments({ subject: subjectId });
const data = ExamModel.aggregate([
{
$match: { subject: _id },
$match: { subject: _id, is_approved: true },
},
{
$lookup: {
Expand Down Expand Up @@ -254,7 +255,69 @@ export const getExamsBySubjectId = async (subjectId: string, urlParams: URLParam
throw new HttpException(400, ErrorCodes.BAD_REQUEST.MESSAGE, ErrorCodes.BAD_REQUEST.CODE);
}
};

export const getExamsByOwner = async (authorId: string) => {
try {
const _id = new ObjectId(authorId);
const count = ExamModel.countDocuments({ author: authorId });
const data = ExamModel.aggregate([
{
$match: { author: _id },
},
{
$lookup: {
from: 'question',
localField: '_id',
foreignField: 'exam_id',
as: 'questions',
},
},
{
$lookup: {
from: 'user',
localField: 'author',
foreignField: '_id',
as: 'author',
},
},
{
$lookup: {
from: 'subject',
localField: 'subject',
foreignField: '_id',
as: 'subject',
},
},
{
$unwind: '$subject',
},
{
$unwind: '$author',
},
{
$project: {
'author.is_blocked': 0,
'author.roles': 0,
'author.created_at': 0,
'author.updated_at': 0,
'author.__v': 0,
'questions.author': 0,
},
},
{
$sort: { created_at: -1 },
},
]);
const resolveAll = await Promise.all([count, data]);
return {
exams: resolveAll[1].map((exam: Exam) => {
return { ...exam, author: hideUserInfoIfRequired(exam?.author) };
}),
};
} catch (error) {
logger.error(`Error while get exam by Owner: ${error}`);
throw new HttpException(400, ErrorCodes.BAD_REQUEST.MESSAGE, ErrorCodes.BAD_REQUEST.CODE);
}
};
export const createExam = async (input: ExamDto, author: ObjectIdType) => {
try {
const exam = {
Expand Down
7 changes: 7 additions & 0 deletions src/apis/v1/questions/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,10 @@ export const deleteQuestion = async (req: RequestWithUser, res: Response) => {
const result = await service.deleteQuestion(params.id);
res.send(fmt.formatResponse(result, Date.now() - req.startTime, 'OK'));
};

export const getQuestionsByExamId = async (req: RequestWithUser, res: Response) => {
const params: ParamsQuestionDto = req.params;

const result = await service.getQuestionsByExamId(params.id);
res.send(fmt.formatResponse(result, Date.now() - req.startTime, 'OK'));
};
6 changes: 6 additions & 0 deletions src/apis/v1/questions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import { QuestionDto, UpdateQuestionDto, ParamsQuestionDto } from './dto/Questio
const router = Router();

router.get('/', authMiddleware, asyncRouteHandler(controller.getQuestions));
router.get(
'/exam/:id',
authMiddleware,
validationMiddleware(ParamsQuestionDto, APP_CONSTANTS.params),
asyncRouteHandler(controller.getQuestionsByExamId)
);

router.post(
'/',
Expand Down
24 changes: 24 additions & 0 deletions src/apis/v1/questions/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import QuestionModel from 'models/schema/Question';
import { DEFAULT_PAGING } from 'utils/constants';
import { logger } from 'utils/logger';
import URLParams from 'utils/rest/urlparams';
import { hideUserInfoIfRequired } from 'utils';

import { QuestionDto, UpdateQuestionDto } from './dto/QuestionDto';
import { ExamModel } from 'models';

export const createQuestion = async function (input: QuestionDto, author: ObjectId) {
try {
Expand Down Expand Up @@ -96,3 +98,25 @@ export const deleteQuestion = async function (id: string) {
throw new HttpException(400, ErrorCodes.BAD_REQUEST.MESSAGE, ErrorCodes.BAD_REQUEST.CODE);
}
};

export const getQuestionsByExamId = async function (examId: string) {
try {
const data = await QuestionModel.find({ exam_id: examId });

const exam = ExamModel.findOne({ _id: examId })
.populate('subject', '-is_deleted -created_at -updated_at -__v')
.populate('author', '-is_blocked -roles -created_at -updated_at -__v');
const resultAll = await Promise.all([data, exam]);

return {
questions: resultAll[0],
exam: {
...resultAll[1].toObject(),
author: hideUserInfoIfRequired(resultAll[1].author),
},
};
} catch (error) {
logger.error(`Error while get questions by examId: ${error}`);
throw new HttpException(400, ErrorCodes.BAD_REQUEST.MESSAGE, ErrorCodes.BAD_REQUEST.CODE);
}
};

0 comments on commit ef490a1

Please sign in to comment.