Modernize: Bolt 4, Node 24, error handling + GHCR/Coolify deploy - #8
Open
ddbruce wants to merge 1 commit into
Open
Modernize: Bolt 4, Node 24, error handling + GHCR/Coolify deploy#8ddbruce wants to merge 1 commit into
ddbruce wants to merge 1 commit into
Conversation
Behavior-preserving modernization. Same monitoring behavior: messages from non-admin/non-moderator users in monitored channels are deleted and the user gets the same ephemeral warning; thread replies and deletions are ignored. Runtime / SDK: - @slack/bolt 3.6 -> 4.4; dotenv 10 -> 17; Dockerfile node:16-alpine (EOL) -> node:24-alpine, npm ci, non-root, HEALTHCHECK. - Custom HTTPReceiver adds a GET /health route; /slack/events and its signing-secret verification are unchanged. Correctness / robustness: - Make the app.message handler async and await processMessage; add app.error so listener errors surface instead of rejecting unhandled. - await chat.delete inside try/catch (was fire-and-forget). - Guard MONITORED_CHANNELS parsing so a missing env var no longer throws at startup. Testability / tooling: - Extract pure decision logic (isMonitoredChannel, isModerator, buildEphemeralBlocks) into src/utilities/moderation.js with no Slack import; add Jest tests (8). The admin-list short-circuit in isNotModerator is preserved exactly. - ESLint 7 (EOL) -> ESLint 9 flat config. - Replace dead Drone CI with GitHub Actions (lint + test + amd64 build). - Add scripts/deploy.sh + config.example.sh (amd64 -> GHCR -> Coolify redeploy); secrets in gitignored scripts/config.sh. Verified: 8 unit tests pass; app boots on Bolt 4, /health -> 200, unsigned /slack/events -> 401; amd64 image builds with 0 npm vulnerabilities. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lramos15
approved these changes
Jul 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Behavior-preserving modernization of
watchdog. Same behavior: a message from a non-admin/non-moderator in a monitored channel is deleted and the user gets the same ephemeral warning; thread replies andmessage_deletedevents are ignored. Verified: 8 unit tests pass; app boots on Bolt 4 with/health→ 200 and unsigned/slack/events→ 401; amd64 image builds with 0 npm vulnerabilities.Changes
@slack/bolt3.6 → 4.4,dotenv10 → 17; Dockerfilenode:16-alpine(EOL 2023) → pinnednode:24-alpine,npm ci, non-root,HEALTHCHECK.HTTPReceiverwith aGET /healthroute. The Slack events path (/slack/events) and its signing-secret verification are unchanged.app.messagehandler is nowasyncandawaitsprocessMessage; added anapp.errorhandler;chat.deleteis nowawaited inside try/catch (was fire-and-forget);MONITORED_CHANNELSparsing is guarded so a missing env var no longer throws at startup.src/utilities/moderation.js(no Slack import) with Jest tests. The admin-list short-circuit inisNotModerator(mod group only fetched if the user isn't an admin) is preserved exactly.scripts/deploy.sh+config.example.sh(amd64 → GHCR → CoolifyPOST /api/v1/deploy?uuid=); secrets in gitignoredscripts/config.sh.Notes
auth.teston start). With valid creds this is a no-op; worth knowing for crash-loop debugging.Recommended follow-up (NOT done — would change behavior)