Skip to content
Closed
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
43 changes: 43 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# NOTES

## Plan

The target was defined by the already-written `tests/update-user.test.js`: a
`PUT /users/:id` endpoint that updates a user (200), 400s on a missing
`name`/`email` field, and 404s for an unknown id. I read `routes/users.js`
and `db/store.js` first and planned to mirror the existing patterns exactly
rather than invent new ones: the same `!name || !email` validation already
used by `POST /users`, and the same `find`-by-id + `undefined`-means-missing
approach already used by `getUserById`. No part of the plan needed editing —
the existing code gave a clear template for the new route and store helper.

## Model

Sonnet 5. This is a small, well-specified CRUD addition to an existing
codebase with tests already dictating the contract — it doesn't need a
heavier model's judgment, just careful pattern-matching against the code
that's already there.

## Commit split

Two commits for the feature, plus this notes file:

1. `db/store.js` — add the `updateUser` helper (data layer).
2. `routes/users.js` — add the `PUT /:id` route that validates input and
wires up the helper (API layer).

Splitting store from route keeps each commit reviewable on its own — the
data-access change and the HTTP/validation change are different concerns,
and this mirrors how `createUser`/`POST` and `getUserById`/`GET :id` are
already split across the two files.

## Review

I ran a self-review of the diff (correctness, cross-file callers, removed
behavior, reuse/simplification, efficiency) before writing this file. It
turned up no issues: the new route reuses the existing validation and
not-found conventions instead of introducing new ones, `express.json()`
already guarantees `req.body` defaults to `{}` on an empty body (so
destructuring is safe, matching the existing `POST` handler), and the store
mutates the same in-memory object reference `getUserById` already returns,
consistent with how the rest of the store works. `npm test` is green.
14 changes: 13 additions & 1 deletion db/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,16 @@ function createUser({ name, email }) {
return user;
}

module.exports = { getAllUsers, getUserById, createUser };
function updateUser(id, { name, email }) {
const user = getUserById(id);

if (!user) {
return undefined;
}

user.name = name;
user.email = email;
return user;
}

module.exports = { getAllUsers, getUserById, createUser, updateUser };
18 changes: 18 additions & 0 deletions routes/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,22 @@ router.post("/", (req, res) => {
res.status(201).json(user);
});

// PUT /users/:id — update an existing user; name and email are required
router.put("/:id", (req, res) => {
const id = Number(req.params.id);
const { name, email } = req.body;

if (!name || !email) {
return res.status(400).json({ error: "name and email are required" });
}

const user = store.updateUser(id, { name, email });

if (!user) {
return res.status(404).json({ error: "User not found" });
}

res.json(user);
});

module.exports = router;