Files
discord-rpg-concept/docs/guild-settings.md
syntaxbullet d15d53e839 docs: update guild settings documentation with migrated files
List all files that have been updated to use getGuildConfig().
2026-02-12 16:10:59 +01:00

200 lines
6.6 KiB
Markdown

# Guild Settings System
The guild settings system enables per-guild configuration stored in the database, eliminating environment-specific config files and enabling runtime updates without redeployment.
## Overview
Guild settings allow you to:
- Store per-guild configuration in the database
- Update settings at runtime without code changes
- Support multiple guilds with different configurations
- Maintain backward compatibility with file-based config
## Architecture
### Database Schema
**`guild_settings` table:**
| Column | Type | Description |
|--------|------|-------------|
| `guild_id` | bigint | Primary key (Discord guild ID) |
| `student_role_id` | bigint | Student role ID |
| `visitor_role_id` | bigint | Visitor role ID |
| `color_role_ids` | jsonb | Array of color role IDs |
| `welcome_channel_id` | bigint | Welcome message channel |
| `welcome_message` | text | Custom welcome message |
| `feedback_channel_id` | bigint | Feedback channel |
| `terminal_channel_id` | bigint | Terminal channel |
| `terminal_message_id` | bigint | Terminal message ID |
| `moderation_log_channel_id` | bigint | Moderation log channel |
| `moderation_dm_on_warn` | jsonb | DM user on warn |
| `moderation_auto_timeout_threshold` | jsonb | Auto timeout after N warnings |
| `feature_overrides` | jsonb | Feature flag overrides |
| `created_at` | timestamp | Creation time |
| `updated_at` | timestamp | Last update time |
### Service Layer
The `guildSettingsService` (`shared/modules/guild-settings/guild-settings.service.ts`) provides:
```typescript
// Get settings for a guild (returns null if not configured)
await guildSettingsService.getSettings(guildId);
// Create or update settings
await guildSettingsService.upsertSettings({
guildId: "123456789",
studentRoleId: "987654321",
visitorRoleId: "111222333",
});
// Update a single setting
await guildSettingsService.updateSetting(guildId, "welcomeChannel", "456789123");
// Delete all settings for a guild
await guildSettingsService.deleteSettings(guildId);
// Color role helpers
await guildSettingsService.addColorRole(guildId, roleId);
await guildSettingsService.removeColorRole(guildId, roleId);
```
## Usage
### Getting Guild Configuration
Use `getGuildConfig()` instead of direct `config` imports for guild-specific settings:
```typescript
import { getGuildConfig } from "@shared/lib/config";
// In a command or interaction
const guildConfig = await getGuildConfig(interaction.guildId);
// Access settings
const studentRole = guildConfig.studentRole;
const welcomeChannel = guildConfig.welcomeChannelId;
```
### Fallback Behavior
`getGuildConfig()` returns settings in this order:
1. **Database settings** (if guild is configured in DB)
2. **File config fallback** (during migration period)
This ensures backward compatibility while migrating from file-based config.
### Cache Invalidation
Settings are cached for 60 seconds. After updating settings, invalidate the cache:
```typescript
import { invalidateGuildConfigCache } from "@shared/lib/config";
await guildSettingsService.upsertSettings({ guildId, ...settings });
invalidateGuildConfigCache(guildId);
```
## Admin Commands
The `/settings` command (Administrator only) provides full management:
### Subcommands
| Command | Description |
|---------|-------------|
| `/settings show` | Display current guild settings |
| `/settings set <key> [value]` | Update a setting |
| `/settings reset <key>` | Reset a setting to default |
| `/settings colors <action> [role]` | Manage color roles |
### Settable Keys
| Key | Type | Description |
|-----|------|-------------|
| `studentRole` | Role | Role for enrolled students |
| `visitorRole` | Role | Role for visitors |
| `welcomeChannel` | Channel | Channel for welcome messages |
| `welcomeMessage` | Text | Custom welcome message |
| `feedbackChannel` | Channel | Channel for feedback |
| `terminalChannel` | Channel | Terminal channel |
| `terminalMessage` | Text | Terminal message ID |
| `moderationLogChannel` | Channel | Moderation log channel |
| `moderationDmOnWarn` | Boolean | DM users on warn |
| `moderationAutoTimeoutThreshold` | Number | Auto timeout threshold |
## API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/guilds/:guildId/settings` | Get guild settings |
| PUT | `/api/guilds/:guildId/settings` | Create/replace settings |
| PATCH | `/api/guilds/:guildId/settings` | Partial update |
| DELETE | `/api/guilds/:guildId/settings` | Delete settings |
## Migration
To migrate existing config.json settings to the database:
```bash
bun run db:migrate-config
```
This will:
1. Read values from `config.json`
2. Create a database record for `DISCORD_GUILD_ID`
3. Store all guild-specific settings
## Migration Strategy for Code
Update code references incrementally:
```typescript
// Before
import { config } from "@shared/lib/config";
const role = config.studentRole;
// After
import { getGuildConfig } from "@shared/lib/config";
const guildConfig = await getGuildConfig(guildId);
const role = guildConfig.studentRole;
```
### Files to Update
Files using guild-specific config that should be updated:
- `bot/events/guildMemberAdd.ts`
- `bot/modules/user/enrollment.interaction.ts`
- `bot/modules/feedback/feedback.interaction.ts`
- `bot/commands/feedback/feedback.ts`
- `bot/commands/inventory/use.ts`
- `bot/commands/admin/create_color.ts`
- `shared/modules/moderation/moderation.service.ts`
- `shared/modules/terminal/terminal.service.ts`
## Files Updated to Use Database Config
All code has been migrated to use `getGuildConfig()`:
- `bot/events/guildMemberAdd.ts` - Role assignment on join
- `bot/modules/user/enrollment.interaction.ts` - Enrollment flow
- `bot/modules/feedback/feedback.interaction.ts` - Feedback submission
- `bot/commands/feedback/feedback.ts` - Feedback command
- `bot/commands/inventory/use.ts` - Color role handling
- `bot/commands/admin/create_color.ts` - Color role creation
- `bot/commands/admin/warn.ts` - Warning with DM and auto-timeout
- `shared/modules/moderation/moderation.service.ts` - Accepts config param
- `shared/modules/terminal/terminal.service.ts` - Terminal location persistence
- `shared/modules/economy/lootdrop.service.ts` - Terminal updates
## Implementation Files
| File | Purpose |
|------|---------|
| `shared/db/schema/guild-settings.ts` | Database schema |
| `shared/modules/guild-settings/guild-settings.service.ts` | Service layer |
| `shared/lib/config.ts` | Config loader with getGuildConfig() |
| `bot/commands/admin/settings.ts` | Admin command |
| `web/src/routes/guild-settings.routes.ts` | API routes |
| `shared/scripts/migrate-config-to-db.ts` | Migration script |