feat(gmw): public features #2-#6 — live moderation feed, toxic topic trends, channel timeline, CSV export, activity heatmap

- Live Moderation Feed: gateway publishes discord:moderation:action (Redis) → backend WS emits moderation_action → public web shows realtime stream.
- Toxic Topic Trends: backend moderation.trends aggregates categories/severity/action_type (read-only) → SVG bar + donut.
- Channel Timeline: messages view gets Feed/Timeline toggle with date-grouped separators.
- CSV Export: client-side downloadCsv for moderation actions (no backend write scope).
- Activity Heatmap: backend messages.activity (per-hour volume by channel) → pure-SVG grid.

User reputation deliberately excluded — no such feature exists in the codebase.
All read-only / public-facing / fully automatic per project rules.
This commit is contained in:
asepharyana
2026-08-18 17:43:02 +07:00
parent 36363fa3db
commit 9b3134d767
26 changed files with 854 additions and 44 deletions
@@ -1,6 +1,7 @@
import { orpc } from "@/lib/orpc/client";
import type {
AttachmentRecord,
MessageActivityBucket,
MessageRecord,
SemanticSearchResult,
} from "@/lib/types";
@@ -73,4 +74,10 @@ export const messagesApi = {
results: SemanticSearchResult[];
nextCursor: null;
}>,
// Public, read-only activity heatmap data (per-hour volume by channel).
getActivity: (days = 30) =>
orpc.messages.activity({ days }) as unknown as Promise<
MessageActivityBucket[]
>,
};
+8 -1
View File
@@ -1,5 +1,9 @@
import { orpc } from "@/lib/orpc/client";
import type { ModerationStats, PaginatedModerationActions } from "@/lib/types";
import type {
ModerationStats,
ModerationTrends,
PaginatedModerationActions,
} from "@/lib/types";
export const moderationApi = {
getStats: () =>
@@ -17,4 +21,7 @@ export const moderationApi = {
actionType,
cursor,
}) as unknown as Promise<PaginatedModerationActions>,
getTrends: (days = 30) =>
orpc.moderation.trends({ days }) as unknown as Promise<ModerationTrends>,
};