# Configuration Guide

This document outlines the structure and available options for the `config/config.json` file. The configuration is validated using Zod schemas at runtime (see `src/lib/config.ts`).

## Core Structure

### Leveling
Configuration for the XP and leveling system.

| Field | Type | Description |
|-------|------|-------------|
| `base` | `number` | The base XP required for the first level. |
| `exponent` | `number` | The exponent used to calculate XP curves. |
| `chat.cooldownMs` | `number` | Time in milliseconds between XP gains from chat. |
| `chat.minXp` | `number` | Minimum XP awarded per message. |
| `chat.maxXp` | `number` | Maximum XP awarded per message. |

### Economy
Settings for currency, rewards, and transfers.

#### Daily
| Field | Type | Description |
|-------|------|-------------|
| `amount` | `integer` | Base amount granted by `/daily`. |
| `streakBonus` | `integer` | Bonus amount per streak day. |
| `weeklyBonus` | `integer` | Bonus amount for a 7-day streak. |
| `cooldownMs` | `number` | Cooldown period for the command (usually 24h). |

#### Transfers
| Field | Type | Description |
|-------|------|-------------|
| `allowSelfTransfer` | `boolean` | Whether users can transfer money to themselves. |
| `minAmount` | `integer` | Minimum amount required for a transfer. |

#### Exam
| Field | Type | Description |
|-------|------|-------------|
| `multMin` | `number` | Minimum multiplier for exam rewards. |
| `multMax` | `number` | Maximum multiplier for exam rewards. |

### Inventory
| Field | Type | Description |
|-------|------|-------------|
| `maxStackSize` | `integer` | Maximum count of a single item in one slot. |
| `maxSlots` | `number` | Total number of inventory slots available. |

### Lootdrop
Settings for the random chat loot drop events.

| Field | Type | Description |
|-------|------|-------------|
| `activityWindowMs` | `number` | Time window to track activity for spawning drops. |
| `minMessages` | `number` | Minimum messages required in window to trigger drop. |
| `spawnChance` | `number` | Probability (0-1) of a drop spawning when conditions met. |
| `cooldownMs` | `number` | Minimum time between loot drops. |
| `reward.min` | `number` | Minimum currency reward. |
| `reward.max` | `number` | Maximum currency reward. |
| `reward.currency` | `string` | The currency ID/Symbol used for rewards. |

### Roles
| Field | Type | Description |
|-------|------|-------------|
| `studentRole` | `string` | Discord Role ID for students. |
| `visitorRole` | `string` | Discord Role ID for visitors. |
| `colorRoles` | `string[]` | List of Discord Role IDs available as color roles. |

### Moderation
Automated moderation settings.

#### Prune
| Field | Type | Description |
|-------|------|-------------|
| `maxAmount` | `number` | Maximum messages to delete in one go. |
| `confirmThreshold` | `number` | Amount above which confirmation is required. |
| `batchSize` | `number` | Size of delete batches. |
| `batchDelayMs` | `number` | Delay between batches. |

#### Cases
| Field | Type | Description |
|-------|------|-------------|
| `dmOnWarn` | `boolean` | Whether to DM users when they are warned. |
| `logChannelId` | `string` | (Optional) Channel ID for moderation logs. |
| `autoTimeoutThreshold` | `number` | (Optional) Warn count to trigger auto-timeout. |

### System & Misc
| Field | Type | Description |
|-------|------|-------------|
| `commands` | `Object` | Map of command names (keys) to boolean (values) to enable/disable them. |
| `welcomeChannelId` | `string` | (Optional) Channel ID for welcome messages. |
| `welcomeMessage` | `string` | (Optional) Custom welcome message text. |
| `feedbackChannelId` | `string` | (Optional) Channel ID where feedback is posted. |
| `terminal.channelId` | `string` | (Optional) Channel ID for terminal display. |
| `terminal.messageId` | `string` | (Optional) Message ID for terminal display. |

## Example Config

```json
{
    "leveling": {
        "base": 100,
        "exponent": 1.5,
        "chat": {
            "cooldownMs": 60000,
            "minXp": 15,
            "maxXp": 25
        }
    },
    "economy": {
        "daily": {
            "amount": "100",
            "streakBonus": "10",
            "weeklyBonus": "500",
            "cooldownMs": 86400000
        },
        "transfers": {
            "allowSelfTransfer": false,
            "minAmount": "10"
        },
        "exam": {
            "multMin": 1.0,
            "multMax": 2.0
        }
    },
    "inventory": {
        "maxStackSize": "99",
        "maxSlots": 20
    },
    "lootdrop": {
        "activityWindowMs": 300000,
        "minMessages": 10,
        "spawnChance": 0.05,
        "cooldownMs": 3600000,
        "reward": {
            "min": 50,
            "max": 150,
            "currency": "CREDITS"
        }
    },
    "commands": {
        "example": true
    },
    "studentRole": "123456789012345678",
    "visitorRole": "123456789012345678",
    "colorRoles": [],
    "moderation": {
        "prune": {
            "maxAmount": 100,
            "confirmThreshold": 50,
            "batchSize": 100,
            "batchDelayMs": 1000
        },
        "cases": {
            "dmOnWarn": true
        }
    }
}
```

> [!NOTE]
> Fields marked as `integer` or `bigint` in the types can often be provided as strings in the JSON to ensure precision, but the system handles parsing them.
