-
Notifications
You must be signed in to change notification settings - Fork 4
Revise Track/Report to use a single persistent thread for each user #174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ding - Create migration for user_threads table (user_id, guild_id, thread_id, created_at) - Add unique composite index on user_id, guild_id - Implement userThreads.server.ts model with CRUD operations - Generate updated TypeScript database types - Update notes with comprehensive refactor plan This supports the modlog refactor to use persistent user threads instead of per-message threads. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
… threads Major changes: - Replace makeLogThread() with getOrCreateUserThread() for persistent threads - Update reportUser() to lookup/create user threads from database - Change thread naming from date-based to "Username Moderation History" - Post notifications in main channel that link to user threads - Send detailed reports + individual messages to user threads - Update both cached and new report flows to use persistent threading This consolidates all moderation history for a user into a single discoverable thread per guild, reducing channel clutter and improving historical context. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Add comprehensive completion notes documenting all changes - Verify TypeScript compliance and linting passes - Confirm API compatibility with all existing integrations - Document benefits and production deployment considerations The refactor successfully transitions from per-message threads to persistent user-based threads while maintaining full backward compatibility. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Changes: - Switch from message-based threads to freestanding private threads using channel.threads.create() - Remove placeholder message creation, threads are now truly independent - Add visual connection between warning message and moderator controls with footer - Update constructLog to include "Moderator controls follow below" indicator - Maintain proper thread flow: detailed report → moderator controls → individual report This creates cleaner threads without the initial placeholder message and provides better visual connection between the warning content and moderation actions. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
trackPerformance will issue named logs at start/end, so the included logs are redundant. Less code!
Phase 2 complete: - Replace queryReportCache/queryCacheMetadata/trackReport with database functions - Update reportUser() to use getReportsForMessage() and getUserReportStats() - Simplify logic by removing content grouping (each message reported separately) - Record all reports in database with recordReport() function - Maintain same API surface for backward compatibility This eliminates the ephemeral TTL cache and provides persistent report storage while maintaining all existing functionality. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Replace Reacord-based escalation controls with native Discord.js ButtonBuilder components to fix server restart persistence issues. This enables moderation actions to work correctly across server restarts. Changes: - Create escalationControls.ts with native component handlers for all escalation actions - Update escalationControls() to use ButtonBuilder with customId pattern escalate-{action}|{userId} - Replace Reacord Button components with ActionRowBuilder/ButtonBuilder - Add proper permission checking and error handling for all moderation actions - Register EscalationCommands in main server configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR majorly refactors the Track command to create persistent threads for each user rather than for each reported message, while transitioning from in-memory TTL cache to database storage for reported message tracking. Key changes include implementing user-based moderation threads, database-backed report tracking, and persistent Discord button controls.
- Replaces per-message threads with persistent user-based moderation history threads
- Migrates from TTL cache to database storage for reported messages with unique constraints
- Implements native Discord button components with persistent handlers for escalation controls
Reviewed Changes
Copilot reviewed 27 out of 30 changed files in this pull request and generated 5 comments.
Show a summary per file
File | Description |
---|---|
package.json | Updates discord.js version to ^14.21.0 |
app/helpers/modLog.ts | Core refactoring to user-based threading with database integration |
app/models/reportedMessages.server.ts | New database model for persistent report tracking |
app/commands/escalationControls.ts | Native Discord component handlers replacing Reacord |
migrations/ | Database schema migrations for user threads and reported messages |
app/helpers/escalate.tsx | Updates escalation controls to use native Discord components |
"reportUser", | ||
"duplicate detected at database level after sending detailed log", | ||
); | ||
throw new Error("Race condition detected in reportUser, retrying…"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The error message uses an ellipsis character (…) which may not display properly in all contexts. Consider using three periods (...) for better compatibility.
throw new Error("Race condition detected in reportUser, retrying…"); | |
throw new Error("Race condition detected in reportUser, retrying..."); |
Copilot uses AI. Check for mistakes.
…ages Implement database tracking of deleted messages to improve "delete all reported messages" functionality and prevent attempts to delete already-deleted messages. Database changes: - Add deleted_at column to reported_messages table - Add markMessageAsDeleted() function to flag deleted messages - Update getUserReportStats() to exclude deleted messages from counts - Add includeDeleted parameter to getReportsForMessage() Code improvements: - Refactor deleteAllReportedForUser() to eliminate antipatterns: * Remove dynamic imports in .map() * Use SQL DISTINCT instead of manual deduplication * Sequential processing to avoid Discord rate limits * Proper error handling and separation of concerns - Update all message deletion points to mark messages as deleted: * Track command "Delete message" button * Automod spam deletion * "Delete all reported messages" escalation button Features: - Skip already deleted messages in bulk operations - Handle "Unknown Message" errors gracefully - Maintain accurate user statistics excluding deleted content 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Closes #172
This PR majorly alters the Track command so that it creates threads for each user, rather than for each reported message, while still recording each new report at the top-level of our #mod-log channel by forwarding the message (only once per message ID). This lets us read a single thread of reports to evaluate how someone's participation has been received in general.
A major change: This PR does away with our in-memory LRU cache of reported messages in favor of storing IDs in the database. This will enable us to develop more features to review the totality of someone's behavior in e.g. a web app, by retrieving those messages from Discord, without requiring a complete archive of the message contents.