{"slug":"watches","total":11,"limit":100,"offset":0,"since":null,"commits":[{"hash":"9430e0e","date":"2026-06-21 18:53:07 -0700","author":"Steve Abrams","subject":"auto-save: 2026-06-21T18:53:05 (1 files) — .env.example","body":""},{"hash":"e4d2c68","date":"2026-05-30 21:24:46 -0700","author":"Steve Abrams","subject":"fix: restore missing dependencies in package.json and respect PORT env var","body":"- package.json had empty dependencies{} so npm install was a no-op; restored\n  all 54 deps from package-lock.json so the project is installable fresh\n- added \"type\":\"module\" and corrected main/start entries (server.js, not index.js)\n- server.js hardcoded PORT=7600 ignoring the PORT env var; changed to\n  process.env.PORT with 7600 fallback so pm2/test runners can override the port\n\nCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"},{"hash":"9177627","date":"2026-05-30 09:32:40 -0700","author":"Steve","subject":"security: strip hardcoded dw_admin DSN password -> env-first. No rotation/deploy.","body":""},{"hash":"10ed798","date":"2026-05-19 21:51:38 -0700","author":"Steve Abrams","subject":"fix(app.js): /api/watches now returns paginated wrapper, not bare array","body":"loadWatches() was doing `allWatches = await response.json()` against\n/api/watches, but server.js:442 returns `{total, page, limit, totalPages, watches: [...]}`\n(default limit=50). So allWatches was getting the wrapper object, and every\nsubsequent .forEach/.filter on it was broken (silently — Array.prototype\nmethods don't exist on plain objects so the comparison list on index.html\nwas non-functional).\n\nDefensive fix: extract .watches if the response is an object (handles old\nbare-array API too), and request ?limit=9999 so we still get the whole\ncatalog now that the endpoint paginates.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"db8e98e","date":"2026-05-19 21:41:17 -0700","author":"Steve Abrams","subject":"Add snapshot-file 404 guard for .bak/.pre-/.orig/.rej paths","body":"Returns plain 404 for any request matching editor or merge-leftover\nextensions before reaching express.static. Backstop in case a snapshot\nfile ever lands inside dist/ or public/ via deploy/rsync.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"1f77b3d","date":"2026-05-19 21:39:32 -0700","author":"Steve Abrams","subject":"Add rel=noopener noreferrer + serve /docs static for api-playground links","body":"api-playground.html had three target=_blank quick-links without rel\nattrs (window.opener exploit risk pre-2021 browsers). Added rel on all\nthree. The \"Full Guide\" link points at /docs/API_COMPLETE_GUIDE.md but\nno static handler served /docs — added express.static for ./docs with\ntext/markdown content-type so the link no longer dead-404s.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"6aff506","date":"2026-05-19 21:38:29 -0700","author":"Steve Abrams","subject":"Add /api 404 guard before SPA catch-all","body":"Unknown /api/* paths were being swallowed by the app.get('*') fallback\nthat serves dist/index.html, so a typo'd API URL returned the React shell\n(200 with HTML) instead of a proper 404. JSON 404 makes API misuse\ndetectable on the client + in logs.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"253afbe","date":"2026-05-19 21:37:53 -0700","author":"Steve Abrams","subject":"Broaden .gitignore: snapshot leftovers + SQLite WAL/SHM","body":"Adds *.bak.*, *.pre-*, *.orig, *.rej plus SQLite WAL/SHM/journal so the\nsearch FTS db's transient sidecar files don't show up as untracked.\n*~ and *.swp already covered under IDE block above.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"08f02d6","date":"2026-05-19 21:37:15 -0700","author":"Steve Abrams","subject":"Add sort + density slider with localStorage persistence to watch search","body":"Sort hydrates BEFORE first /api/advanced-search call. Default sort flipped\nfrom \"relevance\" to \"Newest (Year)\". Density slider rewrites a CSS var so\nthe auto-fill min card width updates without re-rendering.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>"},{"hash":"96a9a73","date":"2026-05-13 08:58:43 -0700","author":"Steve","subject":"snapshot: 1 file(s) changed, ~1 modified","body":""},{"hash":"08ed49d","date":"2026-05-06 10:25:51 -0700","author":"Steve Abrams","subject":"initial scaffold (gitify-all 2026-05-06)","body":""}]}