Switch discord channels to exclusion list

What does this MR do and why?

Discord channel ingestion was controlled by a hardcoded inclusion list (DiscordMessage::CHANNELS), so any new channel (e.g. a hackathon channel) went untracked until someone remembered to add it, undercounting contributors' "discuss" activity.

This MR switches to an exclusion-list model, plus a safety-net alert for channels nobody has looked at yet:

  • DiscordService#guild_channels fetches all live text channels from the guild via the Discord API (GET /guilds/{guild_id}/channels), instead of relying on a static id list.
  • DiscordMessage::CHANNELS is replaced by DiscordMessage::EXCLUDED_CHANNELS (id list). Every channel is ingested by default now; only channels listed there are skipped.
  • Added a channel_name column to discord_messages, populated at ingest time from the API response, so channel display names work for any channel. Backfilled the 4 previously-tracked channels' names in the migration.
  • data:discord rake task now loops over guild_channels, skipping anything in EXCLUDED_CHANNELS.
  • New data:discord_channel_check rake task + discord-channel-check CI job (gated by $EXECUTE_DISCORD_CHANNEL_CHECK): compares live guild channels against channels that are already ingested or excluded, and fails the job listing any that are neither.
  • Seeded EXCLUDED_CHANNELS with the inverted selection of previously included channels (#observability, #off-topic, #discord, #thanks, #help-request-notifications, #welcome).

Changelog: Maintenance

Validation steps

  1. bundle exec rspec spec/models/discord_message_spec.rb spec/services/discord_service_spec.rb spec/tasks/data_spec.rb spec/presenters/users/profile_presenter_spec.rb all green.
  2. bundle exec rubocop on the changed files, no offenses.
  3. bundle exec rails db:migrate applies cleanly and backfills channel_name for the 4 previously-known channels; bundle exec rails db:rollback cleanly drops the column.
  4. In a Rails console, stub HTTParty.get to return a fake guild_channels response including a channel not in EXCLUDED_CHANNELS, then run Rake::Task['data:discord'].invoke('1') to confirm fetch_all_messages is called for the new channel without any code change.
  5. Run bundle exec rake data:discord_channel_check against a guild with an unclassified channel, confirms it prints the channel name/id and exits non-zero (CI job goes red).

/cc @leetickett-gitlab

Closes #528 (closed)

Merge request reports

Loading