Skip to content

Conversation

vcarl
Copy link
Member

@vcarl vcarl commented Jul 26, 2025

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.

Screenshot 2025-07-28 at 2 10 45 AM Screenshot 2025-07-28 at 2 10 53 AM

vcarl and others added 14 commits July 25, 2025 19:30
…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 <noreply@anthropic.com>
… 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 <noreply@anthropic.com>
- 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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
@vcarl vcarl requested a review from Copilot July 26, 2025 20:47
Copy link
Contributor

@Copilot Copilot AI left a 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…");
Copy link
Preview

Copilot AI Jul 26, 2025

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.

Suggested change
throw new Error("Race condition detected in reportUser, retrying");
throw new Error("Race condition detected in reportUser, retrying...");

Copilot uses AI. Check for mistakes.

vcarl and others added 5 commits July 26, 2025 16:48
…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 <noreply@anthropic.com>
@vcarl vcarl changed the title Claude track users Revise Track/Report to use a single persistent thread for each user Jul 28, 2025
@vcarl vcarl merged commit ad302ed into main Jul 28, 2025
5 checks passed
@vcarl vcarl deleted the claude-track-users branch July 28, 2025 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Track revision: threads for each user, not for each report
1 participant