diff --git a/api/tasks.js b/api/tasks.js index 17a66ba..1aa6d44 100644 --- a/api/tasks.js +++ b/api/tasks.js @@ -2,22 +2,84 @@ const express = require("express"); const router = express.Router(); const { Task, User } = require("../database"); -// TASK 4: Add the necessary routes here -// This time, use your newly created Sequelize models instead of the dummy database // GET all tasks router.get("/", async (req, res) => { - // Replace this with your code! - res.status(501).send("Not implemented"); + const tasks = await Task.findAll(); + res.json(tasks); }); // GET a single task by id +router.get("/:id", async (req, res) => +{ + try + { + const id = Number(req.params.id); + const task = await Task.findByPk(req.params.id); + res.json(task); + } + catch(error) + { + res.status(501).json({message: "Server Error", error: error.message}) + } +} +) + // Patch a task by id +router.patch("/:id", async (req, res) => +{ + try + { + const id = Number(req.params.id); + const {task, complete} = req.body; + const updateTask = await Task.update(id, {task, complete}); + res.json(updateTask) + } + catch(error) + { + res.status(501).json({message: "Server Error", error: error.message}) + } +} +) + // Delete a task by id +router.delete("/:id", async (req, res) => +{ + try + { + const id = Number(req.params.id); + const deleteTask = await Task.delete(id); + res.json(deleteTask) + } + catch(error) + { + res.status(501).json({message: "Server Error", error: error.message}) + } + +} +) // Create a new task +router.post("/", async (req,res) => +{ + try + { + // Need stuff to go in the task body + const { title, description, completed = false } = req.body; + if (!title || !description) { + return res.status(400).json({ error: "Title and description are required please" }); + } + //Removed createTask from the Task.create call. Will cause runtime error, trying to use it before it gets defined. + const createTask = await Task.create({ title, description, completed }); + } + catch(error) + { + res.status(501).json({message: "Server Error", error: error.message}) + } +} +) module.exports = router; diff --git a/database/db.js b/database/db.js index 611d1b0..44c13f4 100644 --- a/database/db.js +++ b/database/db.js @@ -8,4 +8,6 @@ const db = new Sequelize( } ); + module.exports = db; + diff --git a/database/index.js b/database/index.js index 5bdf687..1d8a2ff 100644 --- a/database/index.js +++ b/database/index.js @@ -4,6 +4,15 @@ const User = require("./user"); // TASK 3: Set up associations here // What kind of relationship is there between a user and a task? +User.hasMany(Task, { + foreignKey: "userId", + onDelete: "CASCADE" } +); +Task.belongsTo(User, { + foreignKey: "userId" +} +); + // Export everything needed module.exports = { diff --git a/database/task.js b/database/task.js index 49b1b18..4b9a3af 100644 --- a/database/task.js +++ b/database/task.js @@ -3,6 +3,22 @@ const db = require("./db"); // TASK 1: Define the Task model here const Task = db.define("task", { + title: + { + type: DataTypes.STRING, + allowNull: false, + }, + description: + { + type: DataTypes.STRING, + allowNull: false, + }, + completed: + { + type: DataTypes.BOOLEAN, + allowNull: false, + } + // You should define the following columns: // - title: string, required // - description: string, required diff --git a/database/user.js b/database/user.js index 70abf66..e9db624 100644 --- a/database/user.js +++ b/database/user.js @@ -3,8 +3,16 @@ const db = require("./db"); // TASK 2: Define the User model here const User = db.define("user", { - // You should define the following columns: - // - name: string, required + user_id: + { + type: DataTypes.INTEGER, + autoIncrement: true, + primaryKey: true, + }, + name: + { + type: DataTypes.STRING, + }, }); module.exports = User; diff --git a/test.md b/test.md new file mode 100644 index 0000000..0bbcb32 --- /dev/null +++ b/test.md @@ -0,0 +1,79 @@ +# Sequelize + PostgreSQL Task Manager - No `.env` Version +### Group Work Breakdown (3 People) + +## 👩‍💻 Person 1: Database & Models + +### Files to Work On: +- `/database/db.js` +- `/database/task.js` +- `/database/user.js` +- `/database/index.js` (associations) +- `/database/seed.js` + +### Tasks: +- Hardcode the PostgreSQL connection in `db.js` like this: + ```js + const db = new Sequelize('postgres://postgres:password@localhost:5432/ttp_backend', { + logging: false, + }); + ``` +- Define the `Task` model with: + - `title` (required string) + - `description` (required string) + - `completed` (boolean, default: false) +- Define the `User` model with: + - `name` (required string) +- Set up associations: + ```js + User.hasMany(Task, { foreignKey: "userId" }); + Task.belongsTo(User, { foreignKey: "userId" }); + ``` +- In `seed.js`, create a few Users and Tasks. Confirm seed works with `npm run seed`. + +--- + +## 👨‍💻 Person 2: Express API Routes + +### Files to Work On: +- `/api/tasks.js` +- `/api/index.js` + +### Tasks: +- Build the following routes in `tasks.js`: + - `GET /api/tasks` (returns all tasks) + - `GET /api/tasks/:id` (returns task with user) + - `POST /api/tasks` (creates a new task) + - `PATCH /api/tasks/:id` (updates a task) + - `DELETE /api/tasks/:id` (deletes a task) +- Include error handling for invalid/missing input +- Mount routes in `api/index.js` +- Test routes using Postman + +--- + +## 👩‍💻 Person 3: Frontend + Testing + CORS + +### Files to Work On: +- Frontend repo (React) +- `index.js` (Express entrypoint if CORS setup is needed) + +### Tasks: +- Make sure all frontend fetch requests go to `http://localhost:8080/api` +- Remove `.env` usage from frontend (`VITE_API_BASE` not needed) +- If CORS is enabled in backend, change to: + ```js + const cors = require("cors"); + app.use(cors()); // Allow all during dev + ``` +- Run frontend locally with `npm run dev` +- Test full workflow (create/edit/delete tasks) +- Verify persistence (data stays after server restarts) + +--- + +## Group Testing Checklist: +- [ ] Can seed the DB with `npm run seed` +- [ ] All CRUD routes tested in Postman +- [ ] Frontend correctly displays all tasks +- [ ] Tasks persist after server restart +- [ ] Project works with NO `.env` file or `dotenv` dependency \ No newline at end of file