diff --git a/package.json b/package.json index bb95fa3..a843d38 100644 --- a/package.json +++ b/package.json @@ -33,4 +33,4 @@ "babel-preset-env": "^1.7.0", "babel-watch": "^7.0.0" } -} +} \ No newline at end of file diff --git a/server.js b/server.js index 7ba16d7..43dd0f1 100644 --- a/server.js +++ b/server.js @@ -1,21 +1,24 @@ -import express from 'express'; -import Database from 'better-sqlite3'; +import express from "express"; + +import Database from "better-sqlite3"; const app = express(); app.use(express.json()); -app.get('/', (req, res) => { - return res.status(200).send({'message': 'SHIPTIVITY API. Read documentation to see API docs'}); +app.get("/", (req, res) => { + return res + .status(200) + .send({ message: "SHIPTIVITY API. Read documentation to see API docs" }); }); // We are keeping one connection alive for the rest of the life application for simplicity -const db = new Database('./clients.db'); +const db = new Database("./clients.db"); // Don't forget to close connection when server gets terminated const closeDb = () => db.close(); -process.on('SIGTERM', closeDb); -process.on('SIGINT', closeDb); +process.on("SIGTERM", closeDb); +process.on("SIGINT", closeDb); /** * Validate id input @@ -26,25 +29,27 @@ const validateId = (id) => { return { valid: false, messageObj: { - 'message': 'Invalid id provided.', - 'long_message': 'Id can only be integer.', + message: "Invalid id provided.", + long_message: "Id can only be integer.", }, }; } - const client = db.prepare('select * from clients where id = ? limit 1').get(id); + const client = db + .prepare("select * from clients where id = ? limit 1") + .get(id); if (!client) { return { valid: false, messageObj: { - 'message': 'Invalid id provided.', - 'long_message': 'Cannot find client with that id.', + message: "Invalid id provided.", + long_message: "Cannot find client with that id.", }, }; } return { valid: true, }; -} +}; /** * Validate priority input @@ -55,34 +60,41 @@ const validatePriority = (priority) => { return { valid: false, messageObj: { - 'message': 'Invalid priority provided.', - 'long_message': 'Priority can only be positive integer.', + message: "Invalid priority provided.", + long_message: "Priority can only be positive integer.", }, }; } return { valid: true, - } -} + }; +}; /** * Get all of the clients. Optional filter 'status' * GET /api/v1/clients?status={status} - list all clients, optional parameter status: 'backlog' | 'in-progress' | 'complete' */ -app.get('/api/v1/clients', (req, res) => { +app.get("/api/v1/clients", (req, res) => { const status = req.query.status; if (status) { // status can only be either 'backlog' | 'in-progress' | 'complete' - if (status !== 'backlog' && status !== 'in-progress' && status !== 'complete') { + if ( + status !== "backlog" && + status !== "in-progress" && + status !== "complete" + ) { return res.status(400).send({ - 'message': 'Invalid status provided.', - 'long_message': 'Status can only be one of the following: [backlog | in-progress | complete].', + message: "Invalid status provided.", + long_message: + "Status can only be one of the following: [backlog | in-progress | complete].", }); } - const clients = db.prepare('select * from clients where status = ?').all(status); + const clients = db + .prepare("select * from clients where status = ?") + .all(status); return res.status(200).send(clients); } - const statement = db.prepare('select * from clients'); + const statement = db.prepare("select * from clients"); const clients = statement.all(); return res.status(200).send(clients); }); @@ -91,13 +103,15 @@ app.get('/api/v1/clients', (req, res) => { * Get a client based on the id provided. * GET /api/v1/clients/{client_id} - get client by id */ -app.get('/api/v1/clients/:id', (req, res) => { - const id = parseInt(req.params.id , 10); +app.get("/api/v1/clients/:id", (req, res) => { + const id = parseInt(req.params.id, 10); const { valid, messageObj } = validateId(id); if (!valid) { res.status(400).send(messageObj); } - return res.status(200).send(db.prepare('select * from clients where id = ?').get(id)); + return res + .status(200) + .send(db.prepare("select * from clients where id = ?").get(id)); }); /** @@ -114,23 +128,69 @@ app.get('/api/v1/clients/:id', (req, res) => { * priority (optional): integer, * */ -app.put('/api/v1/clients/:id', (req, res) => { - const id = parseInt(req.params.id , 10); +app.put("/api/v1/clients/:id", (req, res) => { + const id = parseInt(req.params.id, 10); const { valid, messageObj } = validateId(id); if (!valid) { res.status(400).send(messageObj); } let { status, priority } = req.body; - let clients = db.prepare('select * from clients').all(); - const client = clients.find(client => client.id === id); + let clients = db.prepare("select * from clients").all(); + const client = clients.find((client) => client.id === id); /* ---------- Update code below ----------*/ + // Check if 'status' is provided and validate its value. + +if (status && !["backlog", "in-progress", "complete"].includes(status)) { + return res.status(400).send({ + message: "Invalid status provided.", + long_message: "Status can only be one of the following: [backlog | in-progress | complete].", + }); +} + +// Store the new status, existing status, and existing priority. +const newStatus = status; +const oldStatus = client.status; +const oldPriority = client.priority; + +// Check if the status and priority are changing. +const statusChanged = oldStatus !== newStatus; +const priorityChanged = priority !== undefined && oldPriority !== priority; + +// Update conditions based on the simplified logic. +if (statusChanged || priorityChanged) { + // Reorder clients based on the changes. + client.status = newStatus; + client.priority = priorityChanged ? priority - 0.5 : Number.MAX_SAFE_INTEGER; + + const clientsWithDifferentStatus = clients.filter((client) => client.status !== oldStatus && client.status !== newStatus); + + const clientsWithOldStatus = clients + .filter((client) => client.status === oldStatus) + .sort((a, b) => a.priority - b.priority) + .map((client, index) => ({ ...client, priority: index + 1 })); + + const clientsWithNewStatus = clients + .filter((client) => client.status === newStatus) + .sort((a, b) => a.priority - b.priority) + .map((client, index) => ({ ...client, priority: index + 1 })); + + client.priority = clientsWithNewStatus.length; + clients = [...clientsWithDifferentStatus, ...clientsWithOldStatus, ...clientsWithNewStatus]; + + // Update the entire rows of the table in the database. + const updateStmt = db.prepare("update clients set status = ?, priority = ? where id = ?"); + clients.forEach((client) => { + updateStmt.run(client.status, client.priority, client.id); + }); +} + +return res.status(200).send(clients); - return res.status(200).send(clients); }); app.listen(3001); -console.log('app running on port ', 3001); +console.log("app running on port ", 3001); \ No newline at end of file