simplify: prune dead code, dedup gmail send, drop neutered log stubs

- Remove no-op log stubs (logGmail, logAutomation, logSecurity, logSystem)
  and ~17 callsites; dead counters in tickets.js and gmail-poll.js go too
- Dedup three near-identical Gmail send paths into sendThreadedEmail helper
- Drop dead Mongoose fields: broccoliniTicketId, lastSyncedBroccoliniArticleId,
  renameCount, renameWindowStart, reminderSent, staffChannelId,
  unclaimedRemindersSent, lastMessageAuthorIsStaff
- Drop dead config fields and their .env.example entries
- Inline api/botClient.js (3-line wrapper, 2 callers)
- Trim unused exports across utils.js, tickets.js, configSchema.js, debugLog.js
- Fix handlers/messages.js to use isStaff() — old partial check ignored
  ADDITIONAL_STAFF_ROLES, so those members were treated as customers
- Drop unused deps p-queue + dotenv-expand; move mongodb to devDependencies

Net: -583 LOC source + -57 LOC lockfile. All 23 modules load clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-07 18:37:14 +00:00
parent d5547e5eea
commit 840b6bfcf8
18 changed files with 165 additions and 805 deletions

View File

@@ -19,8 +19,7 @@
const ALLOWED_CONFIG_KEYS = new Set([
// Ticket settings
'TICKET_CATEGORY_ID', 'TICKET_CATEGORY_NAME', 'TICKET_T2_CATEGORY_NAME', 'TICKET_T3_CATEGORY_NAME',
'EMAIL_TICKET_OVERFLOW_CATEGORY_IDS', 'DISCORD_TICKET_CATEGORY_ID', 'DISCORD_TICKET_OVERFLOW_CATEGORY_IDS',
'TICKET_CATEGORY_ID', 'TICKET_CATEGORY_NAME', 'DISCORD_TICKET_CATEGORY_ID',
// Escalation categories
'EMAIL_ESCALATED2_CHANNEL_ID', 'DISCORD_ESCALATED2_CHANNEL_ID',
'EMAIL_ESCALATED3_CHANNEL_ID', 'DISCORD_ESCALATED3_CHANNEL_ID',
@@ -29,12 +28,11 @@ const ALLOWED_CONFIG_KEYS = new Set([
'ADMIN_ID',
// Channel IDs
'TRANSCRIPT_CHANNEL_ID', 'LOGGING_CHANNEL_ID', 'DEBUGGING_CHANNEL_ID',
'DISCORD_CHANNEL_ID',
'RENAME_LOG_CHANNEL_ID',
// Messages and labels
'ESCALATION_MESSAGE', 'TICKET_CLOSE_SUBJECT_PREFIX', 'TICKET_CLOSE_MESSAGE', 'TICKET_CLOSE_SIGNATURE',
'DISCORD_CLOSE_MESSAGE', 'DISCORD_TRANSCRIPT_MESSAGE', 'DISCORD_AUTO_CLOSE_MESSAGE',
'AUTO_CLOSE_MESSAGE', 'TICKET_WELCOME_MESSAGE', 'TICKET_CLAIMED_MESSAGE', 'TICKET_UNCLAIMED_MESSAGE',
'TICKET_WELCOME_MESSAGE', 'TICKET_CLAIMED_MESSAGE', 'TICKET_UNCLAIMED_MESSAGE',
'REMINDER_MESSAGE', 'BUTTON_LABEL_CLOSE', 'BUTTON_LABEL_CLAIM', 'BUTTON_LABEL_UNCLAIM',
'BUTTON_EMOJI_CLOSE', 'BUTTON_EMOJI_CLAIM', 'BUTTON_EMOJI_UNCLAIM',
// Branding
@@ -46,11 +44,11 @@ const ALLOWED_CONFIG_KEYS = new Set([
'STAFF_THREAD_ENABLED', 'STAFF_THREAD_NAME', 'STAFF_THREAD_AUTO_ADD_ROLE', 'STAFF_THREAD_ROLE_ID',
'PIN_INITIAL_MESSAGE_ENABLED', 'PIN_ESCALATION_MESSAGE_ENABLED', 'PIN_SUPPRESS_SYSTEM_MESSAGE',
// Limits and thresholds
'GLOBAL_TICKET_LIMIT', 'TICKET_LIMIT_PER_CATEGORY',
'GLOBAL_TICKET_LIMIT',
'RATE_LIMIT_TICKETS_PER_USER', 'RATE_LIMIT_WINDOW_MINUTES',
'FORCE_CLOSE_TIMER_SECONDS', 'GMAIL_POLL_INTERVAL_SECONDS',
// Embed colors
'EMBED_COLOR_OPEN', 'EMBED_COLOR_CLOSED', 'EMBED_COLOR_CLAIMED', 'EMBED_COLOR_ESCALATED', 'EMBED_COLOR_INFO',
'EMBED_COLOR_OPEN', 'EMBED_COLOR_CLAIMED', 'EMBED_COLOR_ESCALATED', 'EMBED_COLOR_INFO',
'PRIORITY_HIGH_EMOJI', 'PRIORITY_MEDIUM_EMOJI', 'PRIORITY_LOW_EMOJI'
]);
@@ -201,32 +199,7 @@ function getValidator(key) {
return VALIDATORS[inferType(key)];
}
// Pre-build per-key validator map for callers that want O(1) lookup
// (and for the smoke test / boot log).
const ALL_VALIDATORS = {};
for (const key of ALLOWED_CONFIG_KEYS) {
ALL_VALIDATORS[key] = getValidator(key);
}
// ---------- Startup log (no-op if console.log is suppressed) ----------
(function logDistribution() {
const dist = {};
const fallback = [];
for (const [key, v] of Object.entries(ALL_VALIDATORS)) {
dist[v.type] = (dist[v.type] || 0) + 1;
if (v.type === 'string') fallback.push(key);
}
console.log('[configSchema] type distribution:', JSON.stringify(dist));
if (fallback.length) {
console.log(`[configSchema] ${fallback.length} keys use fallback 'string' validator:`, fallback.join(', '));
}
})();
module.exports = {
ALLOWED_CONFIG_KEYS,
VALIDATORS,
ALL_VALIDATORS,
getValidator,
inferType
getValidator
};