fix(dashboard): infinite scroll, auto-refetch, analytics cache invalidation, remove topic row cap
Frontend: - Cursor pagination (100/page) replacing hardcoded 80 message limit - Removed .slice(0,200) cap on mergeMessages - IntersectionObserver infinite scroll with skeleton loading - 15s periodic refetch for message list sync Backend: - Removed LIMIT 2000 from topic trends SQL query - Added invalidateAnalyticsCache on message capture (messageCreated) - Added invalidateAnalyticsCache on batch analysis completion Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
5078b34ac2
commit
4117f83c1b
@@ -21,6 +21,7 @@ import {
|
||||
updateMessageAIAnalysis,
|
||||
updateMessagesAIAnalysisBulk,
|
||||
} from "./messageStore.js";
|
||||
import { invalidateAnalyticsCache } from "./analyticsStore.js";
|
||||
import type {
|
||||
AnalysisQueueStatus,
|
||||
MessageRecord,
|
||||
@@ -374,6 +375,7 @@ async function processIndividualFallback(
|
||||
const rows = await updateMessagesAIAnalysisBulk(updates);
|
||||
for (const row of rows) {
|
||||
getModerationBroadcaster()?.messageAnalyzed(row);
|
||||
invalidateAnalyticsCache(row.guild_id);
|
||||
scheduleAutoDelete(row);
|
||||
}
|
||||
|
||||
|
||||
@@ -424,8 +424,8 @@ export async function getTopicTrends(input: {
|
||||
try {
|
||||
const since = Date.now() - hours * 3600_000;
|
||||
|
||||
// Only fetch messages that have ai_analysis (the ones that actually have topics)
|
||||
// This dramatically reduces rows for large guilds
|
||||
// Fetch all analyzed messages within the time window (no hard row cap).
|
||||
// Messages without ai_analysis are excluded which naturally limits rows.
|
||||
const rows = (await executeAll(
|
||||
`
|
||||
SELECT
|
||||
@@ -438,7 +438,6 @@ export async function getTopicTrends(input: {
|
||||
AND ai_analysis IS NOT NULL
|
||||
${channelId ? `AND (channel_id = ? OR thread_id = ?)` : ""}
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 2000
|
||||
`,
|
||||
channelId ? [guildId, since, channelId, channelId] : [guildId, since],
|
||||
)) as MessageRecord[];
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -16,6 +16,7 @@ import {
|
||||
updateMessageAsEdited,
|
||||
upsertMessageForCapture,
|
||||
} from "./messageStore.js";
|
||||
import { invalidateAnalyticsCache } from "./analyticsStore.js";
|
||||
import type { AttachmentRecord, MessageRecord } from "./types.js";
|
||||
|
||||
const logger = createChildLogger("message-capture");
|
||||
@@ -127,6 +128,9 @@ export async function captureMessage(
|
||||
broadcaster.messageCreated(messageRecord);
|
||||
}
|
||||
|
||||
// Invalidate analytics cache so real-time stats reflect the new message
|
||||
invalidateAnalyticsCache(messageRecord.guild_id);
|
||||
|
||||
const attachmentUploadTasks: Promise<void>[] = [];
|
||||
|
||||
// Insert attachments before queuing analysis to avoid race condition
|
||||
|
||||
Reference in New Issue
Block a user