feat(ai-moderation): add user profile self-learning system

Add user_profiles table, store, and background learner worker
that summarizes user communication style, topics, and personality.

- New user_profiles table (user_id PK, guild_id, profile_summary, last_analyzed_at)
- userProfileStore.ts — CRUD (get/update) following channelCultureStore pattern
- userProfileLearner.ts — background worker: queries 100 recent msgs per user,
  calls LLM for personality summary, updates every 12h
- Inject <user_profile> XML tag per-message in moderation prompt
- Start worker alongside cultureLearner in aiAnalyzer.ts
- Migration 0008 for user_profiles table

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
MythEclipse
2026-06-12 20:11:34 +07:00
co-authored by Claude
parent 6effb51b5d
commit fbc2184c6e
8 changed files with 270 additions and 2 deletions
@@ -365,6 +365,27 @@ export const pgCorrectedModerationsTable = pgTable(
}),
);
/**
* User Profiles Table (PostgreSQL)
* Stores AI-generated summaries of user personality, communication style,
* and behavior patterns based on their message history.
* Injected as context for AI moderation like channel cultures.
*/
export const pgUserProfilesTable = pgTable(
"user_profiles",
{
user_id: pgText("user_id").primaryKey(),
guild_id: pgText("guild_id").notNull(),
profile_summary: pgText("profile_summary").notNull(),
last_analyzed_at: pgBigint("last_analyzed_at", {
mode: "number",
}).notNull(),
},
(table) => ({
guildIdx: pgIndex("idx_user_profiles_guild_id").on(table.guild_id),
}),
);
/**
* Mascot Chat Messages Table (PostgreSQL)
* Stores AI mascot chat conversation history
@@ -406,6 +427,7 @@ export const stickerCacheTable = pgStickerCacheTable;
export const correctedModerationsTable = pgCorrectedModerationsTable;
export const userReputationsTable = pgUserReputationsTable;
export const channelCulturesTable = pgChannelCulturesTable;
export const userProfilesTable = pgUserProfilesTable;
export const mascotChatMessagesTable = pgMascotChatMessagesTable;
// Export table types for use in queries
@@ -449,6 +471,9 @@ export type UserReputationInsert = typeof userReputationsTable.$inferInsert;
export type ChannelCulture = typeof channelCulturesTable.$inferSelect;
export type ChannelCultureInsert = typeof channelCulturesTable.$inferInsert;
export type UserProfile = typeof userProfilesTable.$inferSelect;
export type UserProfileInsert = typeof userProfilesTable.$inferInsert;
export type MascotChatMessage = typeof mascotChatMessagesTable.$inferSelect;
export type MascotChatMessageInsert =
typeof mascotChatMessagesTable.$inferInsert;