From ee6a7fd57db5aaefa83d678ed616315e23e93c97 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 12:42:11 +0000 Subject: [PATCH 1/3] config: retire the core.* logging namespace (closes #443, Path A) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After #440 removed every unread core.* key, the namespace was down to a single survivor: core.cleanup.channel_id. Audit shows it's vestigial. VoiceChannelTruncationService.getNotificationChannel() reads it, but nothing in the service ever actually sends a notification to that channel — the value flows only into the Database admin page renderer to display "Notification channel: #X" next to a feature that doesn't post anything. Setting or unsetting the key produces no observable behavior. Per Path A from the issue (delete it; the v1.0 admin panel is the right place to surface bot events, not a parallel sprawl of Discord channels), removing the whole thing. Schema (src/services/config-schema.ts): - Drop core.cleanup.channel_id from ConfigSchema, defaultConfig, settingsMetadata. - Drop the `core` entry from categoryMetadata (no keys left in it). - cleanupUnknownSettings() will purge any orphan DB rows on next start; the Config mongoose model keeps `"core"` in its category enum so the validator accepts those rows during the transition window (same pattern as the retired `amikool` / `fun` enum slots). Service (src/services/voice-channel-truncation.ts): - Remove getNotificationChannel(). It had a single caller that itself used the result only for display, with no real downstream effect. Database admin page (src/web/admin-views.ts, read-only-routes.ts): - DatabaseProps.trunk loses the notificationChannel field; the page no longer shows the "Notification channel" row. Other dbtrunk diagnostics (schedule, last run, retention) unchanged. - Route handler drops the corresponding await + destructure + fetchChannelData call. Docs (SETTINGS.md): - Drop the entire "📝 Discord Logging" section (which also documented the four other core.* sub-namespaces #440 had already removed — longstanding doc drift cleaned up here). - Drop matching TOC entry and quick-reference block. Tests: - Drop the two now-bogus config-schema.test.ts assertions on core.cleanup.channel_id. - Drop notificationChannel: null from the two renderDatabasePage fixtures in admin-views.test.ts. 743 tests pass; typecheck / lint / format clean. --- SETTINGS.md | 58 ------------------------ __tests__/services/config-schema.test.ts | 6 --- __tests__/web/admin-views.test.ts | 2 - src/services/config-schema.ts | 20 -------- src/services/voice-channel-truncation.ts | 15 ------ src/web/admin-views.ts | 2 - src/web/read-only-routes.ts | 52 +++++++-------------- 7 files changed, 17 insertions(+), 138 deletions(-) diff --git a/SETTINGS.md b/SETTINGS.md index 281529d..8e4a145 100644 --- a/SETTINGS.md +++ b/SETTINGS.md @@ -36,7 +36,6 @@ Complete configuration reference for all KoolBot settings. - [Achievements System](#-achievements-system) - [Reaction Roles](#-reaction-roles) - [Leaderboard Role Rewards](#-leaderboard-role-rewards) -- [Discord Logging](#-discord-logging) - [Rate Limiting](#-rate-limiting) - [Permissions & Access Control](#-permissions--access-control) - [Configuration Management](#-configuration-management) — Using the Web UI @@ -570,50 +569,6 @@ calculations: --- -## 📝 Discord Logging - -Send bot events and logs to Discord channels. - -### Startup / shutdown logging - -| Setting | Default | Description | -| --- | --- | --- | -| `core.startup.enabled` | `false` | Enable startup/shutdown event logging | -| `core.startup.channel_id` | `""` | Channel ID for startup/shutdown logs | - -### Error logging - -| Setting | Default | Description | -| --- | --- | --- | -| `core.errors.enabled` | `false` | Enable error logging | -| `core.errors.channel_id` | `""` | Channel ID for error logs | - -### Cleanup logging - -| Setting | Default | Description | -| --- | --- | --- | -| `core.cleanup.enabled` | `false` | Enable cleanup operation logging | -| `core.cleanup.channel_id` | `""` | Channel ID for cleanup logs | - -### Configuration logging - -| Setting | Default | Description | -| --- | --- | --- | -| `core.config.enabled` | `false` | Enable configuration change logging | -| `core.config.channel_id` | `""` | Channel ID for config logs | - -### Cron job logging - -| Setting | Default | Description | -| --- | --- | --- | -| `core.cron.enabled` | `false` | Enable scheduled task logging | -| `core.cron.channel_id` | `""` | Channel ID for cron logs | - -You can point every category at the same channel for a consolidated log, -or split them across `#bot-status`, `#admin-alerts`, `#bot-logs`, etc. - ---- - ## 🔒 Rate Limiting Protect your bot from command spam with global rate limiting. @@ -820,19 +775,6 @@ above). - `voicetracking.cleanup.retention.monthly_summaries_months` (number, default: 6) - `voicetracking.cleanup.retention.yearly_summaries_years` (number, default: 1) -#### Discord Logging - -- `core.startup.enabled` (bool, default: false) -- `core.startup.channel_id` (string, default: "") -- `core.errors.enabled` (bool, default: false) -- `core.errors.channel_id` (string, default: "") -- `core.cleanup.enabled` (bool, default: false) -- `core.cleanup.channel_id` (string, default: "") -- `core.config.enabled` (bool, default: false) -- `core.config.channel_id` (string, default: "") -- `core.cron.enabled` (bool, default: false) -- `core.cron.channel_id` (string, default: "") - #### Rate Limiting - `ratelimit.enabled` (bool, default: false) diff --git a/__tests__/services/config-schema.test.ts b/__tests__/services/config-schema.test.ts index d89f42c..d3f38c4 100644 --- a/__tests__/services/config-schema.test.ts +++ b/__tests__/services/config-schema.test.ts @@ -14,11 +14,6 @@ describe('Config Schema', () => { expect(defaultConfig['quotes.enabled']).toBe(false); }); - it('should have core.cleanup.channel_id empty by default', () => { - // Other core.* keys were declared but never read and have been removed. - expect(defaultConfig['core.cleanup.channel_id']).toBe(''); - }); - it('should have reasonable default values for voice channel settings', () => { expect(defaultConfig['voicechannels.category.name']).toBe('Voice Channels'); expect(defaultConfig['voicechannels.lobby.name']).toBe('Lobby'); @@ -43,7 +38,6 @@ describe('Config Schema', () => { }); it('should have channel_id fields as strings', () => { - expect(typeof defaultConfig['core.cleanup.channel_id']).toBe('string'); expect(typeof defaultConfig['quotes.channel_id']).toBe('string'); expect(typeof defaultConfig['reactionroles.message_channel_id']).toBe('string'); }); diff --git a/__tests__/web/admin-views.test.ts b/__tests__/web/admin-views.test.ts index 51417ad..2ec8e69 100644 --- a/__tests__/web/admin-views.test.ts +++ b/__tests__/web/admin-views.test.ts @@ -846,7 +846,6 @@ describe("renderDatabasePage", () => { isScheduled: false, isRunning: false, lastRun: "—", - notificationChannel: null, detailedDays: 30, monthlyMonths: 6, yearlyYears: 1, @@ -874,7 +873,6 @@ describe("renderDatabasePage", () => { isScheduled: true, isRunning: false, lastRun: "—", - notificationChannel: null, detailedDays: 30, monthlyMonths: 6, yearlyYears: 1, diff --git a/src/services/config-schema.ts b/src/services/config-schema.ts index b4000d9..7e7eb54 100644 --- a/src/services/config-schema.ts +++ b/src/services/config-schema.ts @@ -40,10 +40,6 @@ export interface ConfigSchema { "quotes.header_message_id": string; // Message ID of the header post "quotes.header_pin_enabled": boolean; // Pin the header post - // Core Bot Logging (Discord) - only cleanup is wired up; other core.* keys - // were declared but never read and have been removed. See issues #440/#443. - "core.cleanup.channel_id": string; - // Rate Limiting "ratelimit.enabled": boolean; "ratelimit.max_commands": number; // Maximum commands per time window @@ -126,9 +122,6 @@ export const defaultConfig: ConfigSchema = { "quotes.header_message_id": "", // Stores header message ID "quotes.header_pin_enabled": true, // Pin header for easy access - // Core Bot Logging (Discord) - only cleanup is wired up. - "core.cleanup.channel_id": "", - // Rate Limiting defaults "ratelimit.enabled": false, "ratelimit.max_commands": 5, // 5 commands @@ -238,11 +231,6 @@ export const categoryMetadata: Record = { title: "Quotes", description: "Collect and curate memorable quotes in a dedicated channel.", }, - core: { - title: "Core Logging", - description: - "Discord-channel notifications for selected bot events. Most of this namespace was retired in #440 / #443; only the cleanup-job notification channel remains.", - }, ratelimit: { title: "Rate Limiting", description: @@ -500,14 +488,6 @@ export const settingsMetadata: Record = { type: "boolean", }, - // Core Bot Logging (Discord) - "core.cleanup.channel_id": { - label: "Cleanup-job notifications channel", - description: "Channel ID for cleanup-job notifications.", - category: "core", - type: "channel", - }, - // Rate Limiting "ratelimit.enabled": { label: "Rate limiting enabled", diff --git a/src/services/voice-channel-truncation.ts b/src/services/voice-channel-truncation.ts index 553ca6f..c739dac 100644 --- a/src/services/voice-channel-truncation.ts +++ b/src/services/voice-channel-truncation.ts @@ -86,21 +86,6 @@ export class VoiceChannelTruncationService { }; } - /** - * Get the notification channel ID - */ - public async getNotificationChannel(): Promise { - try { - return await this.configService.getString("core.cleanup.channel_id", ""); - } catch (error) { - logger.debug( - "Failed to get notification channel, defaulting to null:", - error, - ); - return null; - } - } - /** * Get the cleanup schedule */ diff --git a/src/web/admin-views.ts b/src/web/admin-views.ts index 7cfb383..34683fa 100644 --- a/src/web/admin-views.ts +++ b/src/web/admin-views.ts @@ -1416,7 +1416,6 @@ export interface DatabaseProps extends CommonProps { isScheduled: boolean; isRunning: boolean; lastRun: string; - notificationChannel: { name: string; id: string } | null; detailedDays: number; monthlyMonths: number; yearlyYears: number; @@ -1476,7 +1475,6 @@ ${renderFlash(props.flash)}
Scheduled
${props.trunk.isScheduled ? 'yes' : 'no'}
Currently running
${props.trunk.isRunning ? 'yes' : 'idle'}
Last run
${escapeHtml(props.trunk.lastRun)}
-
Notification channel
${props.trunk.notificationChannel ? `#${escapeHtml(props.trunk.notificationChannel.name)} ${escapeHtml(props.trunk.notificationChannel.id)}` : 'unset'}
Detailed sessions retention
${props.trunk.detailedDays} days
Monthly summaries retention
${props.trunk.monthlyMonths} months
Yearly summaries retention
${props.trunk.yearlyYears} years
diff --git a/src/web/read-only-routes.ts b/src/web/read-only-routes.ts index 28bc233..370e2f8 100644 --- a/src/web/read-only-routes.ts +++ b/src/web/read-only-routes.ts @@ -703,33 +703,23 @@ export function createReadOnlyRouter( const config = ConfigService.getInstance(); const status = truncation.getStatus(); - const [ - enabled, - schedule, - notificationChannelId, - detailedDays, - monthlyMonths, - yearlyYears, - channelData, - ] = await Promise.all([ - truncation.isEnabled(), - truncation.getSchedule(), - truncation.getNotificationChannel(), - config.getNumber( - "voicetracking.cleanup.retention.detailed_sessions_days", - 30, - ), - config.getNumber( - "voicetracking.cleanup.retention.monthly_summaries_months", - 6, - ), - config.getNumber( - "voicetracking.cleanup.retention.yearly_summaries_years", - 1, - ), - fetchChannelData(client, common.guildId), - ]); - const channelNames = channelData.names; + const [enabled, schedule, detailedDays, monthlyMonths, yearlyYears] = + await Promise.all([ + truncation.isEnabled(), + truncation.getSchedule(), + config.getNumber( + "voicetracking.cleanup.retention.detailed_sessions_days", + 30, + ), + config.getNumber( + "voicetracking.cleanup.retention.monthly_summaries_months", + 6, + ), + config.getNumber( + "voicetracking.cleanup.retention.yearly_summaries_years", + 1, + ), + ]); const collections: Array<{ name: string; count: number }> = []; if (mongoose.connection.readyState === 1 && mongoose.connection.db) { @@ -802,14 +792,6 @@ export function createReadOnlyRouter( lastRun: status.lastCleanupDate ? status.lastCleanupDate.toISOString() : "—", - notificationChannel: notificationChannelId - ? { - name: - channelNames.get(notificationChannelId) ?? - notificationChannelId, - id: notificationChannelId, - } - : null, detailedDays, monthlyMonths, yearlyYears, From fa5b31b229b42f0ef61a0abe1b81a374fc422758 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 26 May 2026 12:44:04 +0000 Subject: [PATCH 2/3] ci: re-trigger after transient GitHub 403s on #468 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three checks (Dependency Review, Test Node 24, Typecheck) failed at the checkout / action-download step with HTTP 403 — pure GitHub infrastructure flakiness. The other four jobs (Test Node 22, Lint, markdownlint, Analyze) ran the same code and passed. Empty commit to re-trigger. From 8f0b034040057dd8d68aa1523ca67d0c95b3f6bc Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 27 May 2026 07:12:30 +0000 Subject: [PATCH 3/3] ci: re-trigger after GitHub Actions infra incident cleared Previous CI runs hit transient HTTP 403s during git checkout and action download. GitHub status page confirmed the issue; now resolved.