diff --git a/apps/api/.env b/apps/api/.env index ecaf5a7c..fd64c678 100644 --- a/apps/api/.env +++ b/apps/api/.env @@ -1,3 +1,3 @@ ACCESS_TOKEN_SECRET=[YOUR_ACCESS_TOKEN_SECRET_HERE] REFRESH_TOKEN_SECRET=[YOUR_REFRESH_TOKEN_SECRET_HERE] -MONGO_URL=[YOUR_MONGO_CONNECTION_STRING_HERE] \ No newline at end of file +MONGO_URL=[YOUR_MONGO_CONNECTION_STRING_HERE] diff --git a/apps/api/src/controllers/post.ts b/apps/api/src/controllers/post.ts new file mode 100644 index 00000000..b798d40a --- /dev/null +++ b/apps/api/src/controllers/post.ts @@ -0,0 +1,103 @@ +import { RequestHandler } from 'express'; +import Post from '../models/posts'; +import Comment from '../models/comment'; + +// Get all posts +const getAllPosts: RequestHandler = async (req, res) => { + // Return all the posts with a 200 status code + try { + const posts = await Post.find(); + return res.status(200).json(posts); + } catch (error) { + const { message } = error; + return res.status(500).json({ message }); + } +}; + +// Get post by category +const getPostByCategory: RequestHandler = async (req, res) => { + const { categoryId } = req.params; + try { + const posts = await Post.find({ category: categoryId }); + return res.status(200).json(posts); + } catch (error) { + const { message } = error; + return res.status(500).json({ message }); + } +}; + +// Get post by id +const getPostById: RequestHandler = async (req, res) => { + const { id } = req.params; + try { + const post = await Post.findById(id); + return res.status(200).json(post); + } catch (error) { + const { message } = error; + return res.status(500).json({ message }); + } +}; + +// Create post +const createPost: RequestHandler = async (req, res) => { + const postData = req.body; + try { + const newPost = await Post.create(postData); + return res.status(201).json(newPost); + } catch (error) { + const { message } = error; + return res.status(500).json({ message }); + } +}; + +// Create comments +const createComments: RequestHandler = async (req, res) => { + const { id } = req.params; + const commentData = req.body; + try { + const post = await Post.findById(id); + const comment = await Comment.create(commentData); + post.comments.push(comment._id); + await post.save(); + return res.status(201).json(comment); + } catch (error) { + const { message } = error; + return res.status(500).json({ message }); + } +}; + +// Update posts by id +const updatePostById: RequestHandler = async (req, res) => { + const { id } = req.params; + const newPostData = req.body; + try { + const modifiedPost = await Post.findByIdAndUpdate(id, newPostData, { new: true, runValidators: true }); + return res.status(200).json(modifiedPost); + } catch (error) { + const { message } = error; + return res.status(500).json({ message }); + } +}; + +// Delete post by id +const deletePost: RequestHandler = async (req, res) => { + const { id } = req.params; + try { + const deletedPost = await Post.findByIdAndDelete(id, {}); + await Comment.deleteMany({ _id: { $in: deletedPost.comments } }); + return res.status(200).json(deletedPost); + } catch (error) { + const { message } = error; + return res.status(500).json({ message }); + } +}; + +export default { + getAllPosts, + getPostByCategory, + getPostById, + createPost, + createComments, + updatePostById, + deletePost +}; diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index daf9dc2e..96888e1e 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -8,6 +8,7 @@ import { verifyToken } from './middleware/auth'; import { errorHandler } from './middleware/errorHandler'; import auth from './routes/auth'; import categories from './routes/categories'; +import posts from './routes/posts'; const host = process.env.HOST ?? 'localhost'; const port = process.env.PORT ? Number(process.env.PORT) : 3000; @@ -22,6 +23,7 @@ app.use('/api/auth', auth); app.use(verifyToken); app.use('/api/categories', categories); +app.use('/api/posts', posts); app.use(errorHandler); diff --git a/apps/api/src/models/comment.ts b/apps/api/src/models/comment.ts new file mode 100644 index 00000000..83c87bba --- /dev/null +++ b/apps/api/src/models/comment.ts @@ -0,0 +1,26 @@ +import mongoose, { Document, Schema } from 'mongoose'; + +interface IComment extends Document { + author: string; + content: string; +} + +export const commentSchema = new Schema( + { + author: { + type: String, + required: [true, 'Author is required'] + }, + content: { + type: String, + required: [true, 'Content is missing'] + } + }, + { + timestamps: true + } +); + +const Comment = mongoose.model('Comment', commentSchema); + +export default Comment; diff --git a/apps/api/src/models/posts.ts b/apps/api/src/models/posts.ts new file mode 100644 index 00000000..e743c2d2 --- /dev/null +++ b/apps/api/src/models/posts.ts @@ -0,0 +1,44 @@ +import mongoose, { Document, Schema } from 'mongoose'; + +interface IPost extends Document { + title: string; + image: string; + description: string; + category: string; + comments: string[]; +} + +export const postSchema = new Schema( + { + title: { + type: String, + required: [true, 'Title is required'], + maxlength: [256, 'title should be no greater than 256 characters'] + }, + image: { + type: String, + required: [true, 'image URL is missing'] + }, + description: { + type: String, + required: [true, 'Description is required'] + }, + category: { + type: String, + required: [true, 'Category Id is missing'] + }, + comments: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: 'Comment' + } + ] + }, + { + timestamps: true + } +); + +const Post = mongoose.model('Post', postSchema); + +export default Post; diff --git a/apps/api/src/routes/posts.ts b/apps/api/src/routes/posts.ts new file mode 100644 index 00000000..f0876617 --- /dev/null +++ b/apps/api/src/routes/posts.ts @@ -0,0 +1,28 @@ +import express from 'express'; + +import postController from '../controllers/post'; + +const router = express.Router(); + +// Get all posts +router.get('/', postController.getAllPosts); + +// Get post by category +router.get('/category/:category', postController.getPostByCategory); + +// Get post by id +router.get('/:id', postController.getPostById); + +// Create post +router.post('/', postController.createPost); + +// Create comments +router.post('/:id/comments', postController.createComments); + +// Update posts by id +router.patch('/:id', postController.updatePostById); + +// Delete post by id +router.delete('/:id', postController.deletePost); + +export default router;