Add GET /tags, POST /todos/:id/tags, DELETE /todos/:id/tags/:tag #17

Open
danny8632 wants to merge 2 commits from agent/issue-15-add-get-tags-post-todos-id-tags-delete-todos-id-ta into main
Owner

Resolves #15

Automated PR from agent dev-01.

  • model: sonnet
  • log: /var/agent/logs/issue-15-20260512T072835.log
  • claude rc: 0
Resolves #15 Automated PR from agent dev-01. - model: `sonnet` - log: `/var/agent/logs/issue-15-20260512T072835.log` - claude rc: `0`
danny8632 added 2 commits 2026-05-12 07:30:28 +00:00
Add tags field to todos and ?tag= filter on GET /todos
All checks were successful
Auditor / audit (pull_request) Successful in 51s
e50dc2447e
- Add tags:[] to all seed todo objects
- POST /todos accepts optional tags array (defaults to [])
- GET /todos?tag=<value> filters to todos whose tags include that value (case-sensitive)

Closes #14
Add GET /tags, POST /todos/:id/tags, DELETE /todos/:id/tags/:tag
All checks were successful
Auditor / audit (pull_request) Successful in 57s
3bf965ddef
- GET /tags returns deduplicated sorted array of all tags across todos
- POST /todos/:id/tags attaches a tag to a todo (idempotent, ignores duplicates)
- DELETE /todos/:id/tags/:tag removes a specific tag from a todo
- Both /todos/:id/tags routes return 404 for non-existent todos
Author
Owner

Auditor review — 💬 COMMENT

All seven Done criteria are satisfied by the implementation. GET /tags uses flatMap+Set+sort correctly, POST /todos/:id/tags handles deduplication and 404, and DELETE /todos/:id/tags/:tag filters and returns 204/404 as required. One code-quality bug exists that was not part of the issue spec but matters for merge.

Criteria

  • PASS — GET /tags returns 200 with Content-Type application/json and an array (empty [] when no todos have tags) res.json() sets Content-Type automatically; initial todos have tags:[] so flatMap yields [] which Set+sort returns as [].
  • PASS — POST /todos/:id/tags with body {"tag":"urgent"} on an existing todo returns 200 or 201 and the todo's tags array includes "urgent" Handler pushes the tag and returns res.json(todo) which is HTTP 200 with the updated todo object.
  • PASS — POST /todos/:id/tags called twice with the same tag does not duplicate the tag in the todo's tags array Explicit if (!todo.tags.includes(tag)) guard prevents duplicates.
  • PASS — POST /todos/:id/tags with a non-existent :id returns 404 Returns res.status(404).end() when todos.find returns undefined.
  • PASS — DELETE /todos/:id/tags/:tag on an existing todo that has the tag returns 200 or 204 and subsequent GET /todos no longer includes that tag on that todo Uses Array.filter to remove the tag in-place on the shared todos array, then returns 204.
  • PASS — DELETE /todos/:id/tags/:tag on a non-existent :id returns 404 Same 404 guard as the POST handler.
  • PASS — After attaching tag "alpha" to two todos and "beta" to one, GET /tags returns ["alpha","beta"] (sorted, deduplicated) [...new Set(todos.flatMap(t => t.tags))].sort() correctly deduplicates and sorts lexicographically.

Other issues found

  • POST /todos/:id/tags performs no validation on the tag field. If the request body omits tag (or sends a non-string value), undefined (or the raw value) is silently stored in the tags array. A minimum guard such as if (typeof tag !== 'string' || !tag) return res.status(400).json({error:'tag required'}) should be added before the includes check.

model: sonnet · log: /var/agent/logs/audit-pr17-20260512T073041.log

## Auditor review — :speech_balloon: COMMENT All seven Done criteria are satisfied by the implementation. GET /tags uses flatMap+Set+sort correctly, POST /todos/:id/tags handles deduplication and 404, and DELETE /todos/:id/tags/:tag filters and returns 204/404 as required. One code-quality bug exists that was not part of the issue spec but matters for merge. ### Criteria - **PASS** — GET /tags returns 200 with Content-Type application/json and an array (empty [] when no todos have tags) _res.json() sets Content-Type automatically; initial todos have tags:[] so flatMap yields [] which Set+sort returns as []._ - **PASS** — POST /todos/:id/tags with body {"tag":"urgent"} on an existing todo returns 200 or 201 and the todo's tags array includes "urgent" _Handler pushes the tag and returns res.json(todo) which is HTTP 200 with the updated todo object._ - **PASS** — POST /todos/:id/tags called twice with the same tag does not duplicate the tag in the todo's tags array _Explicit `if (!todo.tags.includes(tag))` guard prevents duplicates._ - **PASS** — POST /todos/:id/tags with a non-existent :id returns 404 _Returns res.status(404).end() when todos.find returns undefined._ - **PASS** — DELETE /todos/:id/tags/:tag on an existing todo that has the tag returns 200 or 204 and subsequent GET /todos no longer includes that tag on that todo _Uses Array.filter to remove the tag in-place on the shared todos array, then returns 204._ - **PASS** — DELETE /todos/:id/tags/:tag on a non-existent :id returns 404 _Same 404 guard as the POST handler._ - **PASS** — After attaching tag "alpha" to two todos and "beta" to one, GET /tags returns ["alpha","beta"] (sorted, deduplicated) _[...new Set(todos.flatMap(t => t.tags))].sort() correctly deduplicates and sorts lexicographically._ ### Other issues found - POST /todos/:id/tags performs no validation on the `tag` field. If the request body omits `tag` (or sends a non-string value), `undefined` (or the raw value) is silently stored in the tags array. A minimum guard such as `if (typeof tag !== 'string' || !tag) return res.status(400).json({error:'tag required'})` should be added before the includes check. --- _model: sonnet · log: `/var/agent/logs/audit-pr17-20260512T073041.log`_
All checks were successful
Auditor / audit (pull_request) Successful in 57s
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin agent/issue-15-add-get-tags-post-todos-id-tags-delete-todos-id-ta:agent/issue-15-add-get-tags-post-todos-id-tags-delete-todos-id-ta
git checkout agent/issue-15-add-get-tags-post-todos-id-tags-delete-todos-id-ta
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: danny8632/todo-app#17