Files
ShbDiscordBot/AGENTS.md
2026-08-07 13:41:43 +03:00

51 lines
3.5 KiB
Markdown

# ShbDiscordBot contributor guide
## Purpose and invariants
This repository builds one Paper plugin which embeds a JDA Discord bot. Discord is the entry point for issuing short-lived link codes, Minecraft is the only place where a code can be consumed, and ShbUtils Core API is the source of truth for persistent Discord-to-Minecraft links.
- `/auth` is a global Discord slash command intended for bot DMs.
- `/link <six-digit-code>` is a player-only Paper command.
- `/sdb reload` is the operator-only full runtime/config reload command. Do not override Paper's built-in `/reload` command.
- Link codes are process-local, single-use, active for ten minutes by default, and must never be logged.
- Existing Discord or Minecraft links must not be overwritten.
- Discord roles only grant LuckPerms nodes. This project deliberately does not revoke them.
## Build and verification
- Use Java 25 and the checked-in Gradle wrapper.
- `./gradlew test` runs the automated test suite.
- `./gradlew shadowJar` creates the deployable plugin JAR; the plain JAR does not include JDA/Jackson.
- `./gradlew build` must pass before handing work off.
- LuckPerms and Paper are compile-only/server-provided dependencies. Do not shade either of them.
## Architecture rules
- Keep configuration parsing, Discord/JDA integration, ShbUtils HTTP transport, link orchestration, Paper commands, and LuckPerms synchronization in separate classes.
- Do not perform network requests, JDA waits, or LuckPerms user loads on the Paper main thread.
- Only touch Bukkit player/server state on the Paper main thread. Capture UUIDs and immutable values before crossing thread boundaries.
- Make scheduled role scans non-overlapping and bound API concurrency.
- Treat API `401` and validation/conflict responses as permanent failures; treat I/O, timeouts, `429`, and `5xx` as retryable.
- On disable, cancel tasks and close JDA plus plugin-owned executors.
- A runtime reload must validate the new config before stopping the current runtime, invalidate pending codes, await JDA shutdown off the Paper thread, recreate all config-bound services, and immediately run role synchronization.
## Security and configuration
- Never commit real Discord tokens or `X-Internal-Secret` values. The resource `config.yml` contains empty placeholders only.
- Never include secrets, bearer tokens, full HTTP headers, or active link codes in logs or exceptions shown to players.
- Parse Discord snowflakes as strings/unsigned IDs and Minecraft identifiers as UUIDs.
- Generate codes with `SecureRandom`; preserve leading zeroes and enforce rate limiting when consuming invalid codes.
## API contract and documentation
- The local API reference is `docs/API.md`, based on `https://api.shlakoblock.com/api.json`.
- Runtime code uses only internal status and Discord-link endpoints. Do not use the API verification-code endpoints for the Discord-to-Minecraft flow: those endpoints implement the reverse direction.
- When the upstream OpenAPI version changes, compare every path/schema and update `docs/API.md`, DTOs, tests, and the recorded snapshot date together.
## Testing expectations
- Cover code uniqueness, expiry, replacement, rate limiting, reservation/release, and concurrent single-use behavior.
- Test HTTP paths, JSON fields, internal-secret headers, status handling, and timeout/error classification without contacting production.
- Test role-to-permission union, idempotent grants, unlinked users, and grant-only behavior.
- A feature is incomplete if it can block the Paper main thread or leak a secret/code to logs.