62 lines
2.0 KiB
Markdown
62 lines
2.0 KiB
Markdown
# Leaderboard bot integration
|
||
|
||
The Discord bot owns all writes to `user_levels` and `voice_time`. The website only
|
||
subscribes to notifications and then reads the committed database state.
|
||
|
||
## Redis channel
|
||
|
||
Publish leaderboard notifications to exactly:
|
||
|
||
```text
|
||
erika:sse:leaderboards
|
||
```
|
||
|
||
The bot and website use the same Redis deployment. Do not add Redis credentials to
|
||
source code or event payloads.
|
||
|
||
## Event envelopes
|
||
|
||
XP changes use this exact JSON envelope:
|
||
|
||
```json
|
||
{"event":"xp","data":{}}
|
||
```
|
||
|
||
Voice-time changes use the affected Discord channel ID:
|
||
|
||
```json
|
||
{"event":"vc","data":{"channelId":"123456789012345678"}}
|
||
```
|
||
|
||
No additional envelope or data fields are accepted. `channelId` is a Discord
|
||
snowflake represented as a decimal string.
|
||
|
||
## Publish ordering
|
||
|
||
1. Start and complete the bot’s database transaction.
|
||
2. Confirm that the transaction committed successfully.
|
||
3. Publish the corresponding Redis event or events.
|
||
|
||
Never publish before commit, from a rollback path, or from a `finally` block. The
|
||
notification tells an open website page to read the database again, so publishing
|
||
before commit can produce a stale refresh.
|
||
|
||
## Event cardinality
|
||
|
||
- Publish one XP event when one transaction changes XP data.
|
||
- Publish one VC event per affected channel when one transaction changes voice time.
|
||
- When one transaction changes both XP and voice time, publish one XP event and one VC
|
||
event for each affected channel.
|
||
- For a bulk transaction, deduplicate affected scopes and channel IDs. Publish per
|
||
affected scope/channel, never per user.
|
||
|
||
Example: a bulk transaction changes XP for 200 users and voice time in channels `111`
|
||
and `222`. After commit, publish three events: one XP event, one VC event for `111`,
|
||
and one VC event for `222`.
|
||
|
||
## Error handling
|
||
|
||
Publishing is best-effort. Log Redis failures with enough context to identify the
|
||
event scope, but do not roll back or report a successfully committed database
|
||
transaction as failed. Open pages recover on SSE reconnection or the next navigation.
|