getRecentEdits SELECT ... m.content AS new_content returned the message's
ORIGINAL content (never updated on edit) instead of the post-edit content.
messages.content stores the original body; the current/last-edited body lives
in messages.edited_content. So before===after in the Message Edits diff.
Fix: COALESCE(m.edited_content, m.content) AS new_content so 'After' shows the
edited text and diffs against the captured before-content are meaningful.
Prevent recurring infinite restart loop (389x crash) caused by drizzle
re-applying already-applied migrations when public.__drizzle_migrations
tracking is empty/partial.
- 0017/0018: ADD COLUMN IF NOT EXISTS (re-run safe)
- 0019: DO-block rename that handles all prior states (server_name-only,
both columns, or server_nick-only) so it never errors or double-renames
- seedDrizzleHistory: reconcile tracked created_at to the journal's latest
'when' when the schema already reflects the latest migration, instead of
early-returning on an existing-but-empty/partial tracking table
Extract server_nick from metadata.member.displayName in backend messageMapper,
add server_nick to frontend MessageRecord type, and update messages view +
analysis view to display the member's server-specific nickname (with @username
as secondary context) instead of the global username.
Rename server_name (guild name) to server_nick and populate it from
the member's server-specific display name (metadata.member.displayName)
at write time. This is what the moderation dashboard should show as
TARGET — e.g. server nick 'Bandar Togel「✔ ᵛᵉʳᶦᶠᶦᵉᵈ 」' for global
username '.nichiyobi'. Backfilled 210 existing actions from messages
metadata (reset_nickname rows now show 'Sarjana .jav', 'Penindas
Minoritas', etc). Frontend TARGET shows server nick with global
username as secondary context.
Replace static OFFENSIVE_USERNAME_KEYWORDS substring matching with a
lightweight LLM call that evaluates whether a global username violates
server rules (gambling, scam, NSFW, SARA, etc). Fail-open design:
if the LLM call fails/times out, the nickname reset still completes.
After resetting an offensive server nickname to the global username,
check the global username against gambling/scam keyword list. If it
also violates, generate a random 'UserXXXXX' nickname to prevent
circumvention via offensive global usernames.
Denormalize guild name alongside username so the moderation dashboard
shows both TARGET and server even after message table purges.
Migration 0018. Frontend displays 'username · server_name' in TARGET.
Gateway (transmitter.ts):
- Auto-stop on FFmpeg crash: non-zero exit triggers stop() to prevent
silent audio loss and resource leaks
- Voice activity timeout (10s): auto-stops transmitter when no PCM
received, preventing dead-air CPU waste on backgrounded tabs
- Stderr cap (4KB): prevents unbounded memory growth in long sessions
Gateway (voice.handler.ts):
- Double-check voiceController.getStatus().connected before starting
transmitter — detects stale player state after gateway disconnect
Frontend (context.tsx):
- Force-refetch voice status on WS reconnect — UI converges in <1s
instead of waiting up to 4s for SWR poll interval
All: tsc clean, biome clean
- Updated RootLayout to include a noise overlay class.
- Refactored LiveModerationFeed to use CSS animations for item entry.
- Simplified AmbientCanvas by removing WebGL and using pure CSS for ambient effects.
- Converted Chatbot to use CSS for floating window animations.
- Updated Card component to include a gradient border.
- Refactored PageTransition to use CSS for fade-scale animations.
- Enhanced SectionHeader with reveal-up animation class.
- Replaced GSAP animations in NavRail with CSS animations for item entry.
- Refactored VoiceStage to use CSS for speaker node animations and pulse rings.
- Removed GSAP dependencies from use-gsap-animation hook, implementing CSS-based stagger reveal.
- getMessageById: run findById and getEditHistory in parallel via
Promise.all instead of sequential awaits (halves latency for
message detail view)
- Drop 3 unused indexes on messages table: idx_messages_guild_ai_status_created
(0 scans), idx_messages_guild_ai_status_analyzed (97 scans),
idx_messages_guild_created_deleted (95 scans, superseded by covering index)
— saves ~5.9MB index space + reduces write amplification
- Add covering index idx_messages_guild_created_covering for the primary
findMany query pattern (guild_id + created_at DESC with INCLUDE columns)
Two bugs causing 23 spurious 'error' logs after successful deletions:
1. batchProcessor switch missing 'completed' case: partitionBatchOutcome
returns 'completed' for successful messages, but the switch only handled
'upload_pending' and 'api_failed'. Successful messages fell through to
default → re-enqueued to individual fallback → re-analyzed → re-delete
attempt → error (message already gone from Discord). Now explicitly
skips 'completed' messages.
2. isAlreadyDeletedError only caught codes 10008/404. Discord also returns
10003 (Unknown Channel) and 50001 (Missing Access) when a message or
channel is gone. Added these codes plus text-based fallback matching
'Unknown Message'/'Unknown Channel'.
Impact: eliminates ~23 redundant error logs per day + stops wasted LLM
calls re-analyzing already-processed messages.
isEligibleForAutoDelete was rejecting messages where recommendedAction
was 'warn' or 'review' — only 'delete' and 'escalate' were accepted.
This caused 28+ medium-severity flagged messages to be logged as
'not_eligible' instead of being auto-deleted.
Changes:
- deriveRecommendedAction: return 'delete' for flagged+medium severity
(previously only critical/high triggered delete; medium got 'review')
- isEligibleForAutoDelete: accept 'warn' as valid recommendedAction
alongside 'delete' and 'escalate'
Impact: ~28 pending medium-severity flagged messages + all future
'warn'-action flagged messages will now be eligible for auto-deletion.
- Refactored ChannelCultureGlossary, LiveModerationFeed, TermGlossary, and Chatbot components to use new design tokens and styles.
- Updated button, badge, and section components to align with the new design system.
- Enhanced the visual hierarchy and accessibility of various UI elements.
- Improved responsiveness and hover states across components.
- Replaced hardcoded colors with design tokens for better maintainability.
- Cleaned up imports and removed unused hooks in ModerationView and RecordingsView.
- Updated UI elements for better visual consistency and accessibility.
- Improved performance by optimizing rendering logic and reducing unnecessary state updates.
- Added filtering functionality in ChannelCultureGlossary and TermGlossary components.
- Enhanced LiveModerationFeed with GSAP animations for smoother transitions.
- Updated chatbot component for better user experience and responsiveness.
- Refined NavRail component for cleaner code and improved navigation item rendering.