Merge pull request #4 from elizabeth-ikechukwu/feat/week1-backend-foundation
feat: week 1 backend foundation
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
PORT=3000
|
||||||
Generated
+16
-3
@@ -8,6 +8,7 @@
|
|||||||
"name": "task-backend",
|
"name": "task-backend",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"dotenv": "^17.4.0",
|
||||||
"express": "^4.21.2"
|
"express": "^4.21.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -156,6 +157,18 @@
|
|||||||
"npm": "1.2.8000 || >= 1.4.16"
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dotenv": {
|
||||||
|
"version": "17.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.0.tgz",
|
||||||
|
"integrity": "sha512-kCKF62fwtzwYm0IGBNjRUjtJgMfGapII+FslMHIjMR5KTnwEmBmWLDRSnc3XSNP8bNy34tekgQyDT0hr7pERRQ==",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://dotenvx.com"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dunder-proto": {
|
"node_modules/dunder-proto": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
@@ -559,9 +572,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.12",
|
"version": "0.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
|
||||||
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
|
"integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/proxy-addr": {
|
"node_modules/proxy-addr": {
|
||||||
|
|||||||
@@ -4,9 +4,11 @@
|
|||||||
"description": "Backend API for scalable task platform",
|
"description": "Backend API for scalable task platform",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js"
|
"start": "node server.js",
|
||||||
|
"dev": "node --watch server.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"dotenv": "^17.4.0",
|
||||||
"express": "^4.21.2"
|
"express": "^4.21.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+48
-3
@@ -1,16 +1,61 @@
|
|||||||
|
require("dotenv").config();
|
||||||
const express = require("express");
|
const express = require("express");
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const PORT = 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
|
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
|
// In-memory task store
|
||||||
|
let tasks = [];
|
||||||
|
let nextId = 1;
|
||||||
|
|
||||||
|
// Routes
|
||||||
app.get("/", (req, res) => {
|
app.get("/", (req, res) => {
|
||||||
res.send("Task backend is running");
|
res.json({ message: "Task API is running", version: "1.0.0" });
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/health", (req, res) => {
|
app.get("/health", (req, res) => {
|
||||||
res.status(200).json({ status: "healthy" });
|
res.status(200).json({ status: "healthy", uptime: process.uptime() });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/tasks", (req, res) => {
|
||||||
|
res.json(tasks);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post("/tasks", (req, res) => {
|
||||||
|
const { title } = req.body;
|
||||||
|
if (!title) {
|
||||||
|
return res.status(400).json({ error: "Title is required" });
|
||||||
|
}
|
||||||
|
const task = { id: nextId++, title, completed: false, createdAt: new Date() };
|
||||||
|
tasks.push(task);
|
||||||
|
res.status(201).json(task);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.patch("/tasks/:id", (req, res) => {
|
||||||
|
const task = tasks.find((t) => t.id === parseInt(req.params.id));
|
||||||
|
if (!task) return res.status(404).json({ error: "Task not found" });
|
||||||
|
task.completed = !task.completed;
|
||||||
|
res.json(task);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.delete("/tasks/:id", (req, res) => {
|
||||||
|
const index = tasks.findIndex((t) => t.id === parseInt(req.params.id));
|
||||||
|
if (index === -1) return res.status(404).json({ error: "Task not found" });
|
||||||
|
tasks.splice(index, 1);
|
||||||
|
res.status(204).send();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 404 handler
|
||||||
|
app.use((req, res) => {
|
||||||
|
res.status(404).json({ error: "Route not found" });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Global error handler
|
||||||
|
app.use((err, req, res, next) => {
|
||||||
|
console.error(err.stack);
|
||||||
|
res.status(500).json({ error: "Internal server error" });
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(PORT, () => {
|
app.listen(PORT, () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user