feat: Todo MVP — REST API, in-memory store, and vanilla JS frontend#1
feat: Todo MVP — REST API, in-memory store, and vanilla JS frontend#1algorithm-conduction wants to merge 2 commits into
Conversation
Adds the full Todo application as specified in openspec/specs/api.md: - src/store.js: in-memory CRUD store (ES module) - src/server.js: Express REST API (GET/POST/PATCH/DELETE /api/todos) - public/index.html: vanilla JS single-page frontend - test/api.test.js: integration tests via supertest + vitest (7 tests, all passing) - package.json: project manifest with express, supertest, vitest Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PR: algorithm-conduction/todo-app#1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
[WARNING] Mass Assignment — Unfiltered PATCH body applied to todo object const { title, completed } = fields;
const allowed = {};
if (title !== undefined) allowed.title = title;
if (completed !== undefined) allowed.completed = !!completed;
Object.assign(todo, allowed); |
|
[SUGGESTION] Missing HTTP security headers import helmet from 'helmet';
app.use(helmet());This sets all recommended security headers with safe defaults in a single line. |
|
[CRITICAL] PATCH endpoint allows mass-assignment — spec deviation |
|
[SUGGESTION] No authentication or authorization on any API endpoint |
|
[CRITICAL] |
|
Tool scan summary (Semgrep · Gitleaks · Trivy)
No automated findings to triage. The WARNING and SUGGESTIONs above are from manual review of the diff. [FALSE POSITIVE] — N/A: no Semgrep or Gitleaks findings were raised. |
|
[WARNING] No ESLint (lint) script defined in |
{ "pass": true, "blocking": [] }Verdict: PASS — No critical or blocking security issues found. The mass-assignment WARNING ( |
|
[WARNING] Unused import |
|
[SUGGESTION] No error handling in frontend async fetch calls |
|
{ "pass": false, "blocking": ["PATCH endpoint allows mass-assignment of arbitrary todo fields — spec only permits { completed: boolean } (src/server.js:31)", "package.json missing EUPL-1.2 license declaration (no "license" field)"] } |
Summary
Implements the Todo MVP as described in the OpenSpec change proposal. The app exposes a four-endpoint REST API backed by an in-memory store, served alongside a vanilla HTML/JS single-page frontend. No database or authentication is required for this MVP. All files carry EUPL-1.2 license headers per Conduction B.V. conventions.
Spec Reference
https://github.com/algorithm-conduction/todo-app/blob/hydra/spec/openspec/design.md
Changes
package.json— project manifest; declares express as runtime dep, supertest + vitest as dev deps; sets type:module for ESMsrc/store.js— in-memory todo store with list, create, update, remove, and reset exportssrc/server.js— Express app wiring GET/POST/PATCH/DELETE on /api/todos; exported for testing, self-starts when run directlypublic/index.html— vanilla JS SPA that fetches from the API; supports add, toggle-complete, and deletetest/api.test.js— integration tests using supertest + vitest covering all four spec scenariosTest Coverage
test/api.test.js— POST /api/todos returns 201 with id/title/completed:falsetest/api.test.js— GET /api/todos returns 200 and array containing created todotest/api.test.js— PATCH /api/todos/:id marks todo completed, returns 200test/api.test.js— PATCH /api/todos/:id returns 404 for unknown idtest/api.test.js— DELETE /api/todos/:id returns 204test/api.test.js— todo absent from GET list after deletiontest/api.test.js— DELETE /api/todos/:id returns 404 for unknown id