Skip to content

Modernize app: deps, ESLint flat config, bug fixes, and security#20

Open
sirugh wants to merge 2 commits into
masterfrom
claude/app-modernization-yGUwY
Open

Modernize app: deps, ESLint flat config, bug fixes, and security#20
sirugh wants to merge 2 commits into
masterfrom
claude/app-modernization-yGUwY

Conversation

@sirugh

@sirugh sirugh commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Dependencies: Express 4→5, snoowrap/spotify-web-api-node to latest,
ESLint 6→9 with flat config (eslint.config.js replaces .eslintrc.json),
globals package added.

Bug fixes:

  • Filter for [removed]/[deleted] was broken — checked comment.body on an
    already-mapped string (always undefined), so nothing was ever filtered
  • Deduplication was broken for the same reason; now fixed using the array
    parameter in .filter() instead of the outer comments variable
  • "by" split matched substrings (e.g. "somebody"); changed to / by /i regex
  • return inside playlist loop stopped all remaining playlists; changed to continue
  • Removed unnecessary async from guessTrackAndArtist

Security:

  • OAuth state param (randomUUID) added to prevent CSRF on the callback route
  • Access/refresh tokens no longer logged to console

Code quality:

  • Removed --experimental-modules flag (not needed since Node 12.17)
  • Fixed main field in package.json (.js → .mjs)
  • Replaced path.resolve() with import.meta.url-relative URLs
  • Replaced custom delay() with built-in timers/promises setTimeout
  • Converted mixed .then()/.catch() in /spotify_auth to pure async/await
  • for...of loops throughout, for loop index variables removed
  • Node engine requirement bumped to >=18.0.0

https://claude.ai/code/session_01TBgDhQraEY3udNqx2MbqoR

claude added 2 commits June 1, 2026 03:59
Dependencies: Express 4→5, snoowrap/spotify-web-api-node to latest,
ESLint 6→9 with flat config (eslint.config.js replaces .eslintrc.json),
globals package added.

Bug fixes:
- Filter for [removed]/[deleted] was broken — checked comment.body on an
  already-mapped string (always undefined), so nothing was ever filtered
- Deduplication was broken for the same reason; now fixed using the array
  parameter in .filter() instead of the outer comments variable
- "by" split matched substrings (e.g. "somebody"); changed to / by /i regex
- return inside playlist loop stopped all remaining playlists; changed to continue
- Removed unnecessary async from guessTrackAndArtist

Security:
- OAuth state param (randomUUID) added to prevent CSRF on the callback route
- Access/refresh tokens no longer logged to console

Code quality:
- Removed --experimental-modules flag (not needed since Node 12.17)
- Fixed main field in package.json (.js → .mjs)
- Replaced path.resolve() with import.meta.url-relative URLs
- Replaced custom delay() with built-in timers/promises setTimeout
- Converted mixed .then()/.catch() in /spotify_auth to pure async/await
- for...of loops throughout, for loop index variables removed
- Node engine requirement bumped to >=18.0.0

https://claude.ai/code/session_01TBgDhQraEY3udNqx2MbqoR
Replaces Express + snoowrap + spotify-web-api-node (all deprecated/unmaintained)
with a single dependency: @anthropic-ai/sdk.

Architecture:
- src/reddit.mjs  — Reddit public JSON API via native fetch; no auth required
- src/spotify.mjs — Spotify Web API via native fetch; minimal http.createServer
                    for OAuth callback (no Express); state param for CSRF protection
- src/claude.mjs  — Claude Haiku extracts {title, artist} from comment batches
                    using tool use; system prompt cached for efficiency
- src/index.mjs   — Orchestrator: OAuth → Reddit search → Claude → Spotify

Key improvements over the old stack:
- config.json now uses search queries instead of hardcoded thread IDs; the bot
  automatically finds the most upvoted matching thread(s) on each run
- Claude parses freeform comments accurately (handles "Title - Artist",
  "Artist by Title", plain prose, markdown, multi-song comments)
- Field-filtered Spotify search (track:/artist:) when both are known; falls back
  to freeform with cover exclusion filters otherwise
- Secrets format updated: reddit credentials removed (not needed for public reads);
  Anthropic key read from ANTHROPIC_API_KEY env var or secrets.anthropic.apiKey
- process exits cleanly after a run; no persistent server process

https://claude.ai/code/session_01TBgDhQraEY3udNqx2MbqoR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants