From 62a223c2e6ae3d05accb0bddcd251e83a3401272 Mon Sep 17 00:00:00 2001 From: jamal abdirahim Date: Sat, 22 Nov 2025 22:07:01 +0300 Subject: [PATCH] Week-18 Done --- data/tasks.json | 63 ++++++++++++--------------------- package.json | 11 +++--- routes/tasks.js | 93 +++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 102 insertions(+), 65 deletions(-) diff --git a/data/tasks.json b/data/tasks.json index 3747a16..5117e47 100644 --- a/data/tasks.json +++ b/data/tasks.json @@ -1,10 +1,10 @@ [ { "id": "1", - "title": "Learn Node.js Fundamentals", + "title": "Learn Node.js Basics (Updated)", "description": "Complete the Node.js basics course and build a simple server", - "status": "in-progress", - "priority": "high", + "status": "completed", + "priority": "urgent", "dueDate": "2024-01-15", "assignedTo": "John Doe", "subtasks": [ @@ -34,7 +34,7 @@ } ], "createdAt": "2024-01-01T10:30:00.000Z", - "updatedAt": "2025-07-23T01:29:37.667Z" + "updatedAt": "2025-11-22T19:04:26.202Z" }, { "id": "2", @@ -73,43 +73,6 @@ "createdAt": "2024-01-02T11:00:00.000Z", "updatedAt": "2024-01-02T11:00:00.000Z" }, - { - "id": "3", - "title": "Database Integration", - "description": "Connect the API to a database system", - "status": "completed", - "priority": "low", - "dueDate": "2024-01-10", - "assignedTo": "Mike Johnson", - "subtasks": [ - { - "id": "3.1", - "title": "Choose Database", - "completed": true, - "description": "Select appropriate database (MongoDB/PostgreSQL)" - }, - { - "id": "3.2", - "title": "Setup Connection", - "completed": true, - "description": "Configure database connection" - }, - { - "id": "3.3", - "title": "Create Models", - "completed": true, - "description": "Define data models and schemas" - }, - { - "id": "3.4", - "title": "Update API", - "completed": true, - "description": "Modify API to use database instead of JSON files" - } - ], - "createdAt": "2024-01-03T09:15:00.000Z", - "updatedAt": "2024-01-08T16:45:00.000Z" - }, { "id": "4", "title": "Frontend Development", @@ -152,5 +115,23 @@ "subtasks": [], "createdAt": "2025-07-23T04:22:47.898Z", "updatedAt": "2025-07-23T04:22:47.899Z" + }, + { + "id": "6", + "title": "Create New Feature", + "description": "Build authentication module", + "status": "pending", + "priority": "high", + "dueDate": "2025-07-30", + "assignedTo": "Jamal", + "subtasks": [ + { + "id": "6.1", + "title": "Design UI", + "completed": false + } + ], + "createdAt": "2025-11-22T19:03:19.294Z", + "updatedAt": "2025-11-22T19:03:19.294Z" } ] \ No newline at end of file diff --git a/package.json b/package.json index 2327747..a5223ac 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "server.js", "type": "module", "scripts": { - "start": "node server.js", + "start": "nodemon server.js", "dev": "nodemon server.js", "test": "echo \"Error: no test specified\" && exit 1" }, @@ -19,12 +19,13 @@ "author": "Duraan", "license": "MIT", "dependencies": { - "express": "^4.18.2", - "cors": "^2.8.5", "body-parser": "^1.20.2", - "node-fetch": "^3.3.2" + "cors": "^2.8.5", + "express": "^4.18.2", + "node-fetch": "^3.3.2", + "nodeman": "^1.1.2" }, "devDependencies": { - "nodemon": "^3.0.1" + "nodemon": "^3.1.11" } } diff --git a/routes/tasks.js b/routes/tasks.js index b2bcfcb..3eb67ef 100644 --- a/routes/tasks.js +++ b/routes/tasks.js @@ -152,20 +152,38 @@ router.get("/tasks/:id", async (req, res) => { router.post("/tasks", async (req, res) => { try { // TODO: Implement task creation + // 1. Extract data from req.body (title, description, status, priority, etc.) + const newTaskData = req.body; // 2. Validate the data using validateTaskData function + const { isValid, error } = validateTaskData(newTaskData); + if (!isValid) return res.status(400).json({ success: false, error }); // 3. Get all existing tasks using getAllTasks() + const tasks = await getAllTasks(); // 4. Generate a new ID for the task + const newId = (tasks.length + 1).toString(); // 5. Create a new task object with all required fields + const newTask = { + id: newId, + title: newTaskData.title, + description: newTaskData.description, + status: newTaskData.status, + priority: newTaskData.priority, + dueDate: newTaskData.dueDate || null, + assignedTo: newTaskData.assignedTo || null, + subtasks: newTaskData.subtasks || [], + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + }; // 6. Add the task to the tasks array + tasks.push(newTask); // 7. Save to file using writeTasks() + await writeTasks(tasks); // 8. Send success response with status 201 - - // Temporary response - remove this when you implement the above - res.status(501).json({ - success: false, - error: - "POST endpoint not implemented yet - implement task creation above", + res.status(201).json({ + success: true, + message: "Task created successfully", + data: newTask, }); } catch (error) { res.status(500).json({ @@ -182,18 +200,44 @@ router.put("/tasks/:id", async (req, res) => { try { // TODO: Implement task update // 1. Extract the task ID from req.params + const taskId = req.params.id; // 2. Get the update data from req.body - // 3. Validate the data if status or priority is being updated - // 4. Get all tasks and find the task by ID + const updateData = req.body; + + // 3. Get all tasks and find the task by ID + const tasks = await getAllTasks(); + const taskIndex = tasks.findIndex((t) => t.id === taskId); + + // 4. Validate the data if status or priority is being updated + if (taskIndex === -1) + return res.status(404).json({ success: false, error: "Task not found" }); + // 5. Check if task exists, return 404 if not found + if (updateData.status || updateData.priority) { + const temp = { + title: tasks[taskIndex].title, + description: tasks[taskIndex].description, + status: updateData.status || tasks[taskIndex].status, + priority: updateData.priority || tasks[taskIndex].priority, + }; + const { isValid, error } = validateTaskData(temp); + if (!isValid) return res.status(400).json({ success: false, error }); + } // 6. Update the task with new data + const updatedTask = { + ...tasks[taskIndex], + ...updateData, + updatedAt: new Date().toISOString(), + }; + + tasks[taskIndex] = updatedTask; // 7. Save to file using writeTasks() + await writeTasks(tasks); // 8. Send success response with the updated task - - // Temporary response - remove this when you implement the above - res.status(501).json({ - success: false, - error: "PUT endpoint not implemented yet - implement task update above", + res.json({ + success: true, + message: "Task updated successfully", + data: updatedTask, }); } catch (error) { res.status(500).json({ @@ -209,18 +253,29 @@ router.delete("/tasks/:id", async (req, res) => { try { // TODO: Implement task deletion // 1. Extract the task ID from req.params + const taskId = req.params.id; // 2. Get all tasks and find the task by ID + const tasks = await getAllTasks(); + const taskIndex = tasks.findIndex((t) => t.id === taskId); // 3. Check if task exists, return 404 if not found + if (taskIndex === -1) + return res.status(404).json({ success: false, error: "Task not found" }); + // 4. Store the task before deletion (for response) + const deletedTask = tasks[taskIndex]; + // 5. Remove the task from the array + tasks.splice(taskIndex, 1); + // 6. Save to file using writeTasks() - // 7. Send success response with the deleted task - // Temporary response - remove this when you implement the above - res.status(501).json({ - success: false, - error: - "DELETE endpoint not implemented yet - implement task deletion above", + await writeTasks(tasks); + + // 7. Send success response with the deleted task + res.json({ + success: true, + message: "Task deleted successfully", + data: deletedTask, }); } catch (error) { res.status(500).json({