Skip to content
Merged
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
184 changes: 59 additions & 125 deletions src/api/v1/posts/posts.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,9 @@ import { Router, Request, Response } from 'express';

export const postsRouter = Router();

const getPostAuthorIdAndInjectPostInResLocals = async (
req: Request,
res: Response
) => {
const getPostAuthorIdAndInjectPostInResLocals = async (req: Request, res: Response) => {
const userId = Utils.getCurrentUserIdFromReq(req);
const post = await Service._findPostWithAggregationOrThrow(
req.params.id,
userId
);
const post = await Service._findPostWithAggregationOrThrow(req.params.id, userId);
res.locals.post = post;
return post.authorId;
};
Expand All @@ -27,13 +21,13 @@ const getCommentAuthorId = async (req: Request) => {
const comment = await Service.findPostCommentByCompoundIdOrThrow(
req.params.pId,
req.params.cId,
userId
userId,
);
return comment.authorId;
};

const createHandlersForGettingPrivatePostData = (
postService: (postId: string, authorId?: string) => unknown
postService: (postId: string, authorId?: string) => unknown,
) => {
return [
Middlewares.optionalAuthValidator,
Expand All @@ -46,79 +40,53 @@ const createHandlersForGettingPrivatePostData = (

postsRouter.get('/', Middlewares.optionalAuthValidator, async (req, res) => {
const filters = Utils.getPostFiltersFromReqQuery(req);
const posts = await Service.findFilteredPosts(filters);
const posts = await Service.findFilteredPosts(filters, 'findMany');
res.json(posts);
});

postsRouter.get(
'/count',
Middlewares.optionalAuthValidator,
async (req, res) => {
const filters = Utils.getPostFiltersFromReqQuery(req);
res.json(await Service.findFilteredPosts(filters, 'count'));
}
);
postsRouter.get('/count', Middlewares.optionalAuthValidator, async (req, res) => {
const filters = Utils.getPostFiltersFromReqQuery(req);
res.json(await Service.findFilteredPosts(filters, 'count'));
});

postsRouter.get('/tags', async (req, res) => {
const tagsFilter = Utils.getTagsFilterFromReqQuery(req);
res.json(await Service.getTags(tagsFilter));
});

postsRouter.get(
'/comments',
Middlewares.optionalAuthValidator,
async (req, res) => {
const commentsFilter = Utils.getCommentFiltersFromReqQuery(req);
res.json(await Service.findFilteredComments(commentsFilter));
}
);
postsRouter.get('/comments', Middlewares.optionalAuthValidator, async (req, res) => {
const commentsFilter = Utils.getCommentFiltersFromReqQuery(req);
res.json(await Service.findFilteredComments(commentsFilter));
});

postsRouter.get(
'/votes',
Middlewares.optionalAuthValidator,
async (req, res) => {
const votesFilter = Utils.getVoteFiltersFromReqQuery(req);
res.json(await Service.findFilteredVotes(votesFilter));
}
);
postsRouter.get('/votes', Middlewares.optionalAuthValidator, async (req, res) => {
const votesFilter = Utils.getVoteFiltersFromReqQuery(req);
res.json(await Service.findFilteredVotes(votesFilter));
});

postsRouter.get('/tags/count', async (req, res) => {
const postAuthorId = Utils.getAuthorIdFilterFromReqQuery(req);
res.json(await Service.countTagsOnPosts(postAuthorId));
});

postsRouter.get(
'/comments/count',
Middlewares.optionalAuthValidator,
async (req, res) => {
const commentsFilter = Utils.getCommentFiltersFromReqQuery(req);
res.json(await Service.findFilteredComments(commentsFilter, 'count'));
}
);
postsRouter.get('/comments/count', Middlewares.optionalAuthValidator, async (req, res) => {
const commentsFilter = Utils.getCommentFiltersFromReqQuery(req);
res.json(await Service.findFilteredComments(commentsFilter, 'count'));
});

postsRouter.get(
'/votes/count',
Middlewares.optionalAuthValidator,
async (req, res) => {
const votesFilter = Utils.getVoteFiltersFromReqQuery(req);
res.json(await Service.findFilteredVotes(votesFilter, 'count'));
}
);
postsRouter.get('/votes/count', Middlewares.optionalAuthValidator, async (req, res) => {
const votesFilter = Utils.getVoteFiltersFromReqQuery(req);
res.json(await Service.findFilteredVotes(votesFilter, 'count'));
});

postsRouter.get(
'/:id',
createHandlersForGettingPrivatePostData(Service.findPostByIdOrThrow)
);
postsRouter.get('/:id', createHandlersForGettingPrivatePostData(Service.findPostByIdOrThrow));

postsRouter.get(
'/:id/votes/count',
createHandlersForGettingPrivatePostData(Service.countPostVotes)
createHandlersForGettingPrivatePostData(Service.countPostVotes),
);

postsRouter.get(
'/:id/tags',
createHandlersForGettingPrivatePostData(Service.findPostTags)
);
postsRouter.get('/:id/tags', createHandlersForGettingPrivatePostData(Service.findPostTags));

postsRouter.get(
'/:id/comments',
Expand All @@ -127,7 +95,7 @@ postsRouter.get(
const postId = req.params.id;
const filters = { ...Utils.getCommentFiltersFromReqQuery(req), postId };
res.json(await Service.findFilteredComments(filters));
}
},
);

postsRouter.get(
Expand All @@ -139,33 +107,22 @@ postsRouter.get(
postId: req.params.id,
};
res.json(await Service.findFilteredVotes(filters));
}
},
);

postsRouter.get(
'/:id/tags/count',
createHandlersForGettingPrivatePostData(Service.countPostTags)
);
postsRouter.get('/:id/tags/count', createHandlersForGettingPrivatePostData(Service.countPostTags));

postsRouter.get(
'/:id/comments/count',
createHandlersForGettingPrivatePostData(Service.countPostComments)
createHandlersForGettingPrivatePostData(Service.countPostComments),
);

postsRouter.get(
'/:pId/comments/:cId',
Middlewares.optionalAuthValidator,
async (req, res) => {
const userId = Utils.getCurrentUserIdFromReq(req);
res.json(
await Service.findPostCommentByCompoundIdOrThrow(
req.params.pId,
req.params.cId,
userId
)
);
}
);
postsRouter.get('/:pId/comments/:cId', Middlewares.optionalAuthValidator, async (req, res) => {
const userId = Utils.getCurrentUserIdFromReq(req);
res.json(
await Service.findPostCommentByCompoundIdOrThrow(req.params.pId, req.params.cId, userId),
);
});

postsRouter.post(
'/',
Expand All @@ -182,17 +139,12 @@ postsRouter.post(
...Image.getImageMetadata(file),
};
const uploadedImage = await Storage.uploadImage(file, user);
createdPost = await Service.createPostWithImage(
postData,
user,
imageData,
uploadedImage
);
createdPost = await Service.createPostWithImage(postData, user, imageData, uploadedImage);
} else {
createdPost = await Service.createPost(postData, user);
}
res.status(201).json(createdPost);
}
},
);

postsRouter.post('/:id/upvote', Middlewares.authValidator, async (req, res) => {
Expand All @@ -201,15 +153,11 @@ postsRouter.post('/:id/upvote', Middlewares.authValidator, async (req, res) => {
res.json(upvotedPost);
});

postsRouter.post(
'/:id/downvote',
Middlewares.authValidator,
async (req, res) => {
const user = req.user as Types.PublicUser;
const downvotedPost = await Service.downvotePost(req.params.id, user.id);
res.json(downvotedPost);
}
);
postsRouter.post('/:id/downvote', Middlewares.authValidator, async (req, res) => {
const user = req.user as Types.PublicUser;
const downvotedPost = await Service.downvotePost(req.params.id, user.id);
res.json(downvotedPost);
});

postsRouter.post('/:id/unvote', Middlewares.authValidator, async (req, res) => {
const user = req.user as Types.PublicUser;
Expand All @@ -226,23 +174,18 @@ postsRouter.post(
const newComment = await Service.findPostByIdAndCreateComment(
req.params.id,
user.id,
commentData
commentData,
);
res.status(200).json(newComment);
}
},
);

postsRouter.put(
'/:id',
Middlewares.authValidator,
Middlewares.createAdminOrOwnerValidator(
getPostAuthorIdAndInjectPostInResLocals
),
Middlewares.createAdminOrOwnerValidator(getPostAuthorIdAndInjectPostInResLocals),
Middlewares.createFileProcessor('image'),
async (
req: Request,
res: Response<unknown, { post: Service._PostFullData }>
) => {
async (req: Request, res: Response<unknown, { post: Service._PostFullData }>) => {
const user = req.user as Types.PublicUser;
const { post } = res.locals;
const { imagedata, ...postData } = Schema.postSchema.parse(req.body);
Expand All @@ -259,13 +202,13 @@ postsRouter.put(
user,
postData,
imageData,
uploadedImage
uploadedImage,
);
} else {
updatedPost = await Service.updatePost(post, postData, imagedata);
updatedPost = await Service.updatePost(post, user, postData, imagedata);
}
res.json(updatedPost);
}
},
);

postsRouter.put(
Expand All @@ -275,26 +218,22 @@ postsRouter.put(
async (req, res) => {
const user = req.user as Types.PublicUser;
const commentData = Schema.commentSchema.parse(req.body);
const updatedComment = await Service.findCommentAndUpdate(
req.params.cId,
user.id,
commentData
);
const updatedComment = await Service.findCommentAndUpdate(req.params.cId, user.id, commentData);
res.json(updatedComment);
}
},
);

postsRouter.delete(
'/:id',
Middlewares.authValidator,
Middlewares.createAdminOrOwnerValidator(
async (req, res) => await getPostAuthorIdAndInjectPostInResLocals(req, res)
async (req, res) => await getPostAuthorIdAndInjectPostInResLocals(req, res),
),
async (req, res: Response<unknown, { post: Service._PostFullData }>) => {
const userId = Utils.getCurrentUserIdFromReq(req);
await Service.deletePost(res.locals.post, userId);
res.status(204).end();
}
},
);

postsRouter.delete(
Expand All @@ -303,17 +242,12 @@ postsRouter.delete(
Middlewares.createAdminOrOwnerValidator(async (req, res) => {
const userId = Utils.getCurrentUserIdFromReq(req);
req.params.id = req.params.pId; // For `getPostAuthorId(req)`
const postAuthorId = await getPostAuthorIdAndInjectPostInResLocals(
req,
res
);
return postAuthorId === userId
? postAuthorId
: await getCommentAuthorId(req);
const postAuthorId = await getPostAuthorIdAndInjectPostInResLocals(req, res);
return postAuthorId === userId ? postAuthorId : await getCommentAuthorId(req);
}),
async (req, res) => {
const userId = Utils.getCurrentUserIdFromReq(req);
await Service.findCommentAndDelete(req.params.cId, userId);
res.status(204).end();
}
},
);
Loading