# 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 1. `/profile` identifies 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. 2. 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. 3. The stored bot level remains authoritative. Next-level progress duplicates the bot's documented XP formula and performs all XP arithmetic with `bigint` before converting the bounded percentage to a number. Level 200 is the maximum and does not display a progress bar. 4. 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. 5. Missing activity rows display zero activity and no rank. The website does not create rows or write inferred values back to the bot database. 6. 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.