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
96 changes: 65 additions & 31 deletions src/modules/comments/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,22 @@ import { createComment, deleteComment, getComment, listComments, updateComment }
export const createCommentHandler = async (req: Request, res: Response) => {
const { threadId } = req.params

throw new Error('Not implemented')

// TODO: Validate the request body using CommentCreateSchema

// TODO: If the request body is invalid, return a 400 response with the error

// TODO: Create the comment using the createComment service

// TODO: Return the created comment in the response
// throw new Error('Not implemented')
try {
// TODO: Validate the request body using CommentCreateSchema
const validateData = CommentCreateSchema.parse(req.body)
// TODO: If the request body is invalid, return a 400 response with the error
if (!req.body) {
return res.status(400).json({ success: false, message: "Invalid request" })
}
// TODO: Create the comment using the createComment service
const commentcreated = await createComment(threadId, validateData)
// TODO: Return the created comment in the response
return res.status(200).json({ success: true, data: commentcreated })
} catch (error) {
console.error(error)
res.status(400).json({ success: false, message: "Invalid request data" })
}
}

/**
Expand All @@ -31,11 +38,16 @@ export const createCommentHandler = async (req: Request, res: Response) => {
export const listCommentsHandler = async (req: Request, res: Response) => {
const { threadId } = req.params

throw new Error('Not implemented')

// TODO: Fetch the list of comments using the listComments service

// TODO: Return the list of comments in the response
// throw new Error('Not implemented')
try {
// TODO: Fetch the list of comments using the listComments service
const listComment = await listComments(threadId)
// TODO: Return the list of comments in the response
return res.status(200).json({ success: true, message: listComment })
} catch (error) {
console.log(error)
res.status(400).json({ success: false, message: "error occured" })
}
}

/**
Expand All @@ -47,11 +59,16 @@ export const listCommentsHandler = async (req: Request, res: Response) => {
export const getCommentHandler = async (req: Request, res: Response) => {
const { threadId, commentId } = req.params

throw new Error('Not implemented')

// TODO: Fetch the comment by ID using the getComment service

// TODO: Return the comment in the response
// throw new Error('Not implemented')
try {
// TODO: Fetch the comment by ID using the getComment service
const getData = await getComment(threadId, commentId)
// TODO: Return the comment in the response
return res.status(200).json({ success: true, message: getData });
} catch (error) {
console.error(error);
res.status(400).json({ message: "error occured" })
}
}

/**
Expand All @@ -63,15 +80,22 @@ export const getCommentHandler = async (req: Request, res: Response) => {
export const updateCommentHandler = async (req: Request, res: Response) => {
const { threadId, commentId } = req.params

throw new Error('Not implemented')

// TODO: Validate the request body using CommentUpdateSchema

// TODO: If the request body is invalid, return a 400 response with the error

// TODO: Update the comment by ID using the updateComment service

// TODO: Return the updated comment in the response
// throw new Error('Not implemented')
try {
// TODO: Validate the request body using CommentUpdateSchema
const validateData = CommentUpdateSchema.parse(req.body)
// TODO: If the request body is invalid, return a 400 response with the error
if (!validateData) {
return res.status(400).json({ success: false, message: "invalid request" })
}
// TODO: Update the comment by ID using the updateComment service
const updateData = await updateComment(threadId, commentId, validateData)
// TODO: Return the updated comment in the response
return res.status(200).json({ success: true, updateData })
} catch (error) {
console.error(error)
res.status(400).json({ message: "error occured" })
}
}

/**
Expand All @@ -83,9 +107,19 @@ export const updateCommentHandler = async (req: Request, res: Response) => {
export const deleteCommentHandler = async (req: Request, res: Response) => {
const { threadId, commentId } = req.params

throw new Error('Not implemented')
// throw new Error('Not implemented')

try {

// TODO: Delete the comment by ID using the deleteComment service

await deleteComment(threadId, commentId)

// TODO: Delete the comment by ID using the deleteComment service
// TODO: Return a void success response

// TODO: Return a void success response
return res.status(200).json({ success: true })
} catch (error) {
console.log(error)
res.status(400).json({ success: false, message: "error occured" })
}
}
4 changes: 4 additions & 0 deletions src/modules/comments/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { z } from 'zod'
// TODO: Add the fields you need to the Comment schema
export const CommentSchema = z.object({
id: z.string(),
threadId: z.string(),
comment: z.string(),
createdAt: z.date(),
createdBy: z.string()
})
export type Comment = z.infer<typeof CommentSchema>

Expand Down
54 changes: 49 additions & 5 deletions src/modules/comments/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FieldValue } from 'firebase-admin/firestore'
import { db } from '../../services/firebase'
import { Thread } from '../threads/schema'
import { CommentUpdate, type Comment, type CommentCreate } from './schema'
import * as admin from 'firebase-admin';

// Utility function to get the comments collection for a given thread
const commentCollection = (threadId: Thread['id']) => db.collection(`threads/${threadId}/comments`)
Expand All @@ -26,7 +27,16 @@ const fromFirestore = (snapshot: FirebaseFirestore.DocumentSnapshot<FirebaseFire
*/
export const listComments = async (threadId: Thread['id']): Promise<Comment[]> => {
// TODO: Fetch the list of comments for the given thread
throw new Error('Not implemented')
// throw new Error('Not implemented')
const commentRef = await commentCollection(threadId).get()

const comments: Comment[] = []

commentRef.forEach((doc) => {
comments.push(fromFirestore(doc));
})

return comments
}

/**
Expand All @@ -37,7 +47,10 @@ export const listComments = async (threadId: Thread['id']): Promise<Comment[]> =
*/
export const getComment = async (threadId: Thread['id'], id: Comment['id']): Promise<Comment> => {
// TODO: Fetch the comment by ID
throw new Error('Not implemented')
// throw new Error('Not implemented')
const singleComment = await commentCollection(threadId).doc(id).get()

return fromFirestore(singleComment)
}

/**
Expand All @@ -48,7 +61,21 @@ export const getComment = async (threadId: Thread['id'], id: Comment['id']): Pro
*/
export const createComment = async (threadId: Thread['id'], data: CommentCreate): Promise<Comment> => {
// TODO: Create the comment in Firestore and return the newly created comment
throw new Error('Not implemented')
// throw new Error('Not implemented')
const threadid = threadId
const docRef = commentCollection(threadId).doc();

const comment: Comment = {
id: docRef.id,
threadId,
...data,
createdAt: new Date(),
}

await docRef.set(comment)

return comment;

}

/**
Expand All @@ -60,7 +87,17 @@ export const createComment = async (threadId: Thread['id'], data: CommentCreate)
*/
export const updateComment = async (threadId: Thread['id'], id: Comment['id'], data: CommentUpdate): Promise<Comment> => {
// TODO: Update the comment in Firestore and return the updated comment
throw new Error('Not implemented')
// throw new Error('Not implemented')

const commentRef = commentCollection(threadId).doc(id)

await commentRef.update(data)

const updatedComment = await commentRef.get()

const updComment = fromFirestore(updatedComment)

return updComment
}

/**
Expand All @@ -71,5 +108,12 @@ export const updateComment = async (threadId: Thread['id'], id: Comment['id'], d
*/
export const deleteComment = async (threadId: Thread['id'], id: Comment['id']): Promise<FirebaseFirestore.WriteResult> => {
// TODO: Delete the comment from Firestore and return the result
throw new Error('Not implemented')
// throw new Error('Not implemented')
try {
const commentRef = commentCollection(threadId).doc(id)
const deleted = await commentRef.delete();
return deleted;
} catch (error) {
throw Error("Unabe to delete the comment")
}
}
97 changes: 64 additions & 33 deletions src/modules/threads/controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Request, Response } from 'express'
import { threadCreateSchema, threadUpdateSchema } from './schema'
import { createThread, deleteThread, getThread, listThreads, updateThread } from './service'
import { messaging } from 'firebase-admin'

/**
* Create a thread
Expand All @@ -9,15 +10,22 @@ import { createThread, deleteThread, getThread, listThreads, updateThread } from
* @returns Success object of created thread
*/
export const createThreadHandler = async (req: Request, res: Response) => {
throw new Error('Not implemented')

// TODO: Validate the request body using threadCreateSchema

// TODO: If the request body is invalid, return a 400 response with the error

// TODO: Create the thread using the createThread service

// TODO: Return the created thread in the response
// throw new Error('Not implemented')
try {
// TODO: Validate the request body using threadCreateSchema
const validateData = threadCreateSchema.parse(req.body)
// TODO: If the request body is invalid, return a 400 response with the error
if (!req.body) {
return res.status(400).json({ success: false, message: 'Invalid request data' })
}
// TODO: Create the thread using the createThread service
const createdSchema = await createThread(validateData)
// TODO: Return the created thread in the response
return res.status(200).json({ success: true, data: createdSchema })
} catch (error) {
console.error(error)
res.status(400).json({ success: false, message: "invalid request data" })
}
}

/**
Expand All @@ -27,11 +35,16 @@ export const createThreadHandler = async (req: Request, res: Response) => {
* @returns Success object of list of threads
*/
export const listThreadsHandler = async (req: Request, res: Response) => {
throw new Error('Not implemented')

// TODO: Fetch the list of threads using the listThreads service

// TODO: Return the list of threads in the response
// throw new Error('Not implemented')
try {
// TODO: Fetch the list of threads using the listThreads service
const listThread = await listThreads();
// TODO: Return the list of threads in the response
return res.status(200).json({ success: true, message: listThread })
} catch (error) {
console.error(error)
res.status(400).json({ success: false, message: "error occured" })
}
}

/**
Expand All @@ -43,11 +56,16 @@ export const listThreadsHandler = async (req: Request, res: Response) => {
export const getThreadHandler = async (req: Request, res: Response) => {
const { threadId } = req.params

throw new Error('Not implemented')

// TODO: Fetch the thread using the getThread service

// TODO: Return the thread in the response
// throw new Error('Not implemented')
try {
// TODO: Fetch the thread using the getThread service
const getData = await getThread(threadId)
// TODO: Return the thread in the response
return res.status(200).json({ success: true, getData });
} catch (error) {
console.error(error);
res.status(400).json({ success: true, message: "error occured" })
}
}

/**
Expand All @@ -59,15 +77,22 @@ export const getThreadHandler = async (req: Request, res: Response) => {
export const updateThreadHandler = async (req: Request, res: Response) => {
const { threadId } = req.params

throw new Error('Not implemented')

// TODO: Validate the request body using threadUpdateSchema

// TODO: If the request body is invalid, return a 400 response with the error

// TODO: Update the thread using the updateThread service

// TODO: Return the updated thread in the response
// throw new Error('Not implemented')
try {
// TODO: Validate the request body using threadUpdateSchema
const validateData = await threadUpdateSchema.parse(req.body)
// TODO: If the request body is invalid, return a 400 response with the error
if (!validateData) {
return res.status(400).json({ success: false, message: "invalid request" })
}
// TODO: Update the thread using the updateThread service
const updateData = await updateThread(threadId, validateData)
// TODO: Return the updated thread in the response
return res.status(200).json({ success: true, updateData })
} catch (error) {
console.error(error)
res.status(400).json({ success: false, message: "error occured" })
}
}

/**
Expand All @@ -79,9 +104,15 @@ export const updateThreadHandler = async (req: Request, res: Response) => {
export const deleteThreadHandler = async (req: Request, res: Response) => {
const { threadId } = req.params

throw new Error('Not implemented')

// TODO: Delete the thread using the deleteThread service

// TODO: Return a success response
// throw new Error('Not implemented')

try {
// TODO: Delete the thread using the deleteThread service
await deleteThread(threadId)
// TODO: Return a success response
return res.status(200).json({ success: true, message: "thread deleted successfully" })
} catch (error) {
console.log(error)
res.status(400).json({ success: false, message: "error occured" })
}
}
8 changes: 6 additions & 2 deletions src/modules/threads/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ import { z } from 'zod'
// TODO: Add the fields you need to the Thread schema
export const threadSchema = z.object({
id: z.string(),
name: z.string(),
description: z.string(),
createdAt: z.date(),
createdBy: z.string()
})
export type Thread = z.infer<typeof threadSchema>

// ? These schemas are provided for you, but you may need to add more fields to them
export const threadCreateSchema = threadSchema.omit({ id: true, createdAt: true })
export const threadCreateSchema = threadSchema.omit({ id: true, createdAt: true, })
export type ThreadCreate = z.infer<typeof threadCreateSchema>

export const threadUpdateSchema = threadSchema.omit({ id: true, createdAt: true, createdBy: true })
export const threadUpdateSchema = threadSchema.omit({ id: true, createdAt: true, createdBy: true, })
export type ThreadUpdate = z.infer<typeof threadUpdateSchema>
Loading