2.2 KiB
2.2 KiB
ADR 0003: Personal guild profile read model
- Status: Accepted
- Date: 2026-08-06
Context
Signed-in members need one private page that combines their Discord identity with XP,
level progress, voice time, and leaderboard standing. The Discord bot remains the
authoritative writer for user_levels and voice_time, while the website has only a
read-only connection to those tables. XP values use numeric(40,0), which may exceed
JavaScript's safe integer range.
Decision
/profileidentifies the current member from the server-side NextAuth session and Discord provider account. Anonymous visitors receive a Discord login prompt that returns them to/profile; profiles cannot be selected by URL parameter.- Discord identity, XP, and voice data load independently. Session identity is the fallback when Discord member metadata is unavailable, and unavailable activity sources report section-level errors.
- The stored bot level remains authoritative. Next-level progress duplicates the
bot's documented XP formula and performs all XP arithmetic with
bigintbefore converting the bounded percentage to a number. Level 200 is the maximum and does not display a progress bar. - XP and voice ranks use the public leaderboards' shared competition ranking. XP rank excludes level-0 members. Voice time and rank include only voice and Stage channels that currently exist in the guild.
- Missing activity rows display zero activity and no rank. The website does not create rows or write inferred values back to the bot database.
- One public leaderboard SSE subscription refreshes an open profile after either an XP event or a voice-time event. Redis remains a notification path rather than the source of truth.
Consequences
- A signed-in member sees only the profile associated with their own Discord account.
- Profile totals and public leaderboard values share ranking and voice-channel scope.
- The bot formula is a cross-service contract. Formula or maximum-level changes must update the bot integration document and website helper together.
- Large cumulative XP values remain exact through database reads, calculations, and formatting.