Files
erika/docs/adr/0003-personal-guild-profile.md
T
2026-08-06 22:46:47 +07:00

43 lines
2.2 KiB
Markdown

# 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.