feat(04-03): implement listsRouter POST/GET/PATCH/DELETE /api/lists (LIST-01)

- GET /: scoped access (owner + list_shares); activeCount/doneCount per list
- POST /: auto-populates list_shares for all other members when isShared=true (D-01/D-02)
- PATCH /🆔 rename + isShared toggle; reconciles list_shares on visibility change
- DELETE /🆔 owner-only; cascade handles items/shares via FK onDelete cascade
- resolveUserId helper copied verbatim from events.ts per project convention
- zod createListSchema (name 1..255, isShared default true) + patchListSchema
- T-04-02 / T-04-05 / T-04-07 / T-04-08 mitigations applied
- listsRouter mounted at /api/lists in index.ts (after sseRouter)
- Plan 06 SSE seam comments left at every mutation handler
- [Rule 1 - Fix] zValidator returns 400 (not 422); tests corrected to match convention
- All 23 tests green; full API suite 140 passed no regressions
This commit is contained in:
Lucas Berger
2026-06-09 12:38:05 -04:00
parent 2b3d7896f1
commit 9546b747d2
3 changed files with 407 additions and 6 deletions
+2
View File
@@ -7,6 +7,7 @@ import { healthRouter } from './routes/health.js'
import { meRouter } from './routes/me.js'
import { eventsRouter } from './routes/events.js'
import { sseRouter } from './routes/sse.js'
import { listsRouter } from './routes/lists.js'
import { oidcAuthMiddleware, processOAuthCallback } from './auth/middleware.js'
import { devAuthBypass } from './auth/devBypass.js'
import { startBrokerPoller } from './broker/poller.js'
@@ -61,6 +62,7 @@ app.get('/api/login', (c) => c.redirect('/'))
app.route('/api/me', meRouter)
app.route('/api/events', eventsRouter)
app.route('/api/sse', sseRouter)
app.route('/api/lists', listsRouter)
// WR-04: background worker startup (cron schedules) moved into the isMainModule()
// guard below. Calling them at top level registered real node-cron schedules whenever