feat(integration-discord): normalize Discord entities for community health metrics#261
Conversation
…ation Tables: discord_guilds, discord_channels, discord_roles, discord_members, discord_member_roles (pivot), discord_member_role_history (append-only log).
Models: DiscordGuild, DiscordChannel, DiscordRole, DiscordMember, DiscordMemberRoleHistory with full relationships and PHPDoc annotations. Factories with useful states (voice/category channels, bot/pending/left members). Also adds @Property annotations to DiscordEventLog for PHPStan.
GetGuild, ListGuildChannels, ListGuildRoles, ListGuildMembers (paginated).
…mmand
SyncDiscordGuildAction: full API sync (guild, channels, roles, members).
SyncDiscordGuildCommand: `php artisan discord:sync {guild_id?} --fresh`.
DiscordEventLogObserver: routes gateway events to normalize tables in real-time.
Handlers: HandleMemberAdd, HandleMemberRemove, HandleMemberUpdate,
HandleAuditLogEntry (role changes), HandleVoiceStateUpdate.
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR implements normalized Discord entity storage for the Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
discord_guilds,discord_channels,discord_roles,discord_members,discord_member_roles,discord_member_role_history) to replace JSONB-only storage of Discord entitiesphp artisan discord:syncthat fetches guild state from Discord REST API (channels, roles, paginated members)DiscordEventLogObserverthat normalizes gateway events (GUILD_MEMBER_ADD/REMOVE/UPDATE,GUILD_AUDIT_LOG_ENTRY_CREATE,VOICE_STATE_UPDATE) into relational tables as they arrivediscord_guildstotenantsanddiscord_memberstoexternal_identitiesvia optional FKsMotivation
The
discord_event_logstable stores raw JSONB payloads — great for a data lake, but impossible to query efficiently for community health dashboards (e.g., "messages per channel", "role growth trends", "member retention funnels"). These normalized tables enable SQL-native analytics without JSON parsing at query time.New files
DiscordChannelType(12 types),RoleHistoryAction(assigned/removed)DiscordGuild,DiscordChannel,DiscordRole,DiscordMember,DiscordMemberRoleHistoryvoice(),category(),bot(),pending(),left())GetGuild,ListGuildChannels,ListGuildRoles,ListGuildMembers(paginated)SyncDiscordGuildAction,SyncDiscordGuildCommand,DiscordEventLogObserver, 5 event handlersTest plan
php artisan discord:syncagainst the He4rt guild and verify tables are populated--freshflag truncates and re-imports cleanly