Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ For developers, contributors, and project governance, the following documentatio

- **[docs/system-design.md](docs/system-design.md)** - System architecture and design with:
- All system actors (Discord users, servers, bot, API, database)
- All system actions (9 slash commands, message scanning, backfill, API interactions)
- All system actions (15 slash commands, message scanning, backfill, API interactions)
- Complete data flow diagrams for each major operation
- Component interactions and subsystems
- Database schema and data models
Expand All @@ -146,7 +146,7 @@ For developers, contributors, and project governance, the following documentatio
- [OSPS-SA-01.01]

- **[docs/api-reference.md](docs/api-reference.md)** - External software interfaces and API documentation with:
- Discord Bot API: 9 slash commands with full parameter and response documentation
- Discord Bot API: 15 slash commands with full parameter and response documentation
- Discord Message Event API: Automatic code detection patterns and behavior
- Request/response schemas with data types and examples
- Error codes, causes, and resolution procedures
Expand Down
59 changes: 59 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,65 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

### Added

- **`/stats` command** - Server-wide statistics and aggregate loot totals
- Shows total unique codes seen, total redemption events, registered user count
- Displays server-wide aggregate chest and item loot counts from `loot_totals` table
- Available to all users — no special permissions required

- **`/logs` command** - Real-time log viewing for administrators
- Shows last N lines (1–100, default 20) of `logs/combined.log`
- Restricted to users with Discord `Administrator` permission
- Returns ephemeral response

- **`/notifications` command** - Configurable per-user DM notification preferences
- `dm_on_code` (default: false) — DM user when a new code is detected in the channel
- `dm_on_success` (default: true) — DM user when auto-redeem succeeds
- `dm_on_failure` (default: false) — DM user when auto-redeem fails
- With no parameters, shows current preferences
- Settings persisted in `users` table

- **`/deleteaccount` command** - GDPR-compliant self-service account deletion
- Requires explicit confirmation via Yes / Cancel button prompt (30-second timeout)
- Deletes: credentials, all redeemed code records, audit log entries, backfill operation history
- Refuses deletion while a user-initiated backfill is in progress
- Returns per-category deletion summary

- **AES-256-GCM credential encryption** - Credentials now encrypted at rest
- `users.user_id` and `users.user_hash` stored as AES-256-GCM ciphertext (`enc1:<iv>:<authTag>:<ct>`)
- 12-byte random IV and 16-byte auth tag per ciphertext
- Key loaded from `ENCRYPTION_KEY` env var (64-char hex = 32 bytes)
- `isEncrypted()` / `encrypt()` / `decrypt()` helpers in `src/bot/utils/crypto.ts`
- `migratePlaintextCredentials()` in UserManager migrates existing plaintext rows on startup

- **`loot_totals` table** - Aggregate loot cache
- Pre-computed per-user and server-wide loot totals updated on every redemption
- Composite primary key: `(loot_key, scope)` where scope is `discordId` or `__server__`
- `backfillLootTotals()` rebuilds the cache from existing `redeemed_codes` rows
- Powers the `/stats` aggregate loot display

- **Winston structured logging** (`src/bot/utils/logger.ts`)
- Logs to `logs/combined.log` (all levels, 20 rotated files, 5 MB each)
- Logs errors to `logs/error.log` (10 rotated files)
- Console output colour-coded with timestamps
- Default level `info`; override with `LOG_LEVEL=debug` in `.env`
- `/logs` command reads `combined.log` for in-Discord admin access

- **`/backfill` command** - Recover missed codes from channel history (admin only)
- Fetches message history in batches of 100 via Discord API
- Global concurrency lock: only one backfill runs at a time
- Per-user rate limit: 1 backfill per hour
- Startup backfill: runs automatically on bot start if last run was > 6 hours ago
- Progress reported via interaction follow-ups
- Returns `{ codesFound, codesRedeemed, pendingCodes, errors }` summary

- **DM notification fan-out in `bot.ts`** - On code detection
- `getAllUsersWithDmOnCode()` fetches users with `dm_on_code = true`
- Sends a DM to each matching user when a new code is detected in the monitored channel

- **`/codes` pagination** - `/codes` now paginates results (5 per page) with Prev/Next buttons
- `buildCodesPage()` helper generates paginated embeds
- Each entry shows code, status, loot detail, and timestamp

- **`/catchup` command** - Redeem all known valid codes in one step
- Collects every code the bot has seen (successful redeems from any user + pending codes)
- Skips codes already redeemed by the requesting user and codes marked as expired
Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,19 @@ See [docker-compose.example.yml](docker-compose.example.yml) for all available c

## ✨ Features

- 🤖 **Slash Commands** - `/setup`, `/redeem`, `/catchup`, `/autoredeem`, `/inventory`, `/open`, `/blacksmith`, `/codes`, `/makepublic`, `/backfill`, `/deleteaccount`, `/help`
- 🤖 **Slash Commands** - `/setup`, `/redeem`, `/catchup`, `/autoredeem`, `/inventory`, `/open`, `/blacksmith`, `/codes`, `/makepublic`, `/backfill`, `/notifications`, `/stats`, `/logs`, `/deleteaccount`, `/help`
- 🔄 **Auto Code Detection** - Scans Discord messages for codes automatically
- ⏮️ **Message History Backfill** - Recover missed codes from message history with built-in rate limiting
- 🔁 **Catch Up** - Redeem all known valid codes in one command (great for new members)
- 🤖 **Auto-Redeem Toggle** - Enable or disable automatic code redemption per user (`/autoredeem`)
- 🔔 **DM Notifications** - Configurable per-user DM alerts for new codes, successes, and failures (`/notifications`)
- 📊 **Server Stats** - Aggregate loot totals and redemption statistics (`/stats`)
- 🎁 **Code Redemption** - Submit codes and get rewards
- 📦 **Chest Management** - Open chests and view loot
- ⚒️ **Blacksmith** - Upgrade heroes with contracts
- 📊 **Inventory** - View gold, rubies, equipment, and progress
- 📋 **Inventory** - View gold, rubies, equipment, and progress
- 🗑️ **Account Deletion** - GDPR-friendly self-service data removal (`/deleteaccount`)
- 🔐 **Encrypted Credentials** - AES-256-GCM encryption for stored user credentials
- 💾 **Secure Storage** - SQLite database keeps credentials safe and local
- 👥 **Multi-User** - Each user manages their own account
- ⚡ **Fast** - Built on Bun for 3-4x performance vs Node.js
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ For complete dependency management details, see [docs/dependency-management.md](
The project includes comprehensive design documentation describing all actors and actions within the system. See [docs/system-design.md](docs/system-design.md) for:

- **Actors**: Discord users, Discord servers, Discord bot, Idle Champions API, SQLite database
- **Actions**: 9 slash commands, message scanning, backfill operations, API interactions, database operations
- **Actions**: 15 slash commands, message scanning, backfill operations, API interactions, database operations
- **Data Flows**: Complete flow diagrams for each major operation
- **Architecture**: Component interactions, subsystems, deployment
- **Data Models**: User credentials, code history, backfill state, API logs
Expand All @@ -532,7 +532,7 @@ The project includes comprehensive design documentation describing all actors an

The project includes complete API documentation for all external software interfaces. See [docs/api-reference.md](docs/api-reference.md) for:

- **Discord Bot API**: 9 slash commands with parameters, responses, and error handling
- **Discord Bot API**: 15 slash commands with parameters, responses, and error handling
- **Command Parameters**: Detailed description of each parameter and valid values
- **Response Formats**: Discord embeds, ephemeral responses, data structures
- **Error Responses**: Error codes, causes, and resolution steps
Expand Down
147 changes: 133 additions & 14 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The Discord bot responds to slash commands in Discord channels. All commands ret

**Response Format**: Discord Embeds (rich message format) or Ephemeral Text

**Total commands**: 12 (`/setup`, `/redeem`, `/catchup`, `/autoredeem`, `/inventory`, `/open`, `/blacksmith`, `/codes`, `/makepublic`, `/backfill`, `/deleteaccount`, `/help`)
**Total commands**: 15 (`/setup`, `/redeem`, `/catchup`, `/autoredeem`, `/inventory`, `/open`, `/blacksmith`, `/codes`, `/makepublic`, `/notifications`, `/stats`, `/logs`, `/backfill`, `/deleteaccount`, `/help`)

---

Expand Down Expand Up @@ -754,7 +754,119 @@ Bot (ephemeral): ✅ Account Deleted

---

### 12. `/help`
### 13. `/notifications`

View and update DM notification preferences.

**Invocation**:
```
/notifications [dm_on_code:<true|false>] [dm_on_success:<true|false>] [dm_on_failure:<true|false>]
```

**Parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `dm_on_code` | boolean | No | DM when a new code is detected in the channel (default: false) |
| `dm_on_success` | boolean | No | DM when auto-redeem succeeds (default: true) |
| `dm_on_failure` | boolean | No | DM when auto-redeem fails (default: false) |

**Behaviour**: With no parameters, shows current preferences. With parameters, updates specified preferences.

**Response Format** (Ephemeral):
```
┌─────────────────────────────────────────┐
│ 🔔 Notification Preferences │
│ │
│ DM on code detected: ❌ Off │
│ DM on redeem success: ✅ On │
│ DM on redeem failure: ❌ Off │
└─────────────────────────────────────────┘
```

**Error Responses**:

| Error | Cause | Resolution |
|-------|-------|-----------|
| `NO_CREDENTIALS` | User hasn't run `/setup` | Run `/setup` first |

---

### 14. `/stats`

Show server-wide code redemption statistics and aggregate loot totals.

**Invocation**:
```
/stats
```

**Parameters**: None

**Response Format** (Public Embed):
```
┌───────────────────────────────────────┐
│ 📊 Server Statistics │
│ │
│ Unique codes tracked: 142 │
│ Total redemptions: 1,087 │
│ Registered users: 12 │
│ │
│ **Aggregate Loot (all users)** │
│ Sapphire Chest: 2,340 │
│ Gold Chest: 810 │
│ Modron Chest: 156 │
│ ... │
└───────────────────────────────────────┘
```

**Data Returned**:
- Total unique codes seen by the bot
- Total successful redemption events
- Number of registered users
- Server-wide aggregate chest and item loot counts

---

### 15. `/logs`

Show the last N lines of the bot's combined log file. Admin only.

**Invocation**:
```
/logs [lines:<number>]
```

**Parameters**:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `lines` | integer | No | Number of log lines to show (1-100, default: 20) |

**Permissions**: Requires the `Manage Messages` permission on the Discord server.

**Response Format** (Ephemeral):
```
┌─────────────────────────────────────────────┐
│ 📋 Last 20 log lines │
│ │
│ [2026-05-24 10:15:01] [info] Bot ready │
│ [2026-05-24 10:15:42] [info] Code detected │
│ [2026-05-24 10:15:43] [info] Redeemed OK │
│ ... │
└─────────────────────────────────────────────┘
```

**Error Responses**:

| Error | Cause | Resolution |
|-------|-------|-----------|
| `PERMISSION_DENIED` | User lacks Manage Messages permission | Requires Manage Messages permission |
| `LOG_NOT_FOUND` | Log file does not exist | Bot has not run long enough to create logs |

---

### 16. `/help`

Display command reference and usage instructions.

Expand Down Expand Up @@ -796,7 +908,13 @@ Display command reference and usage instructions.
│ **Utilities** │
│ /autoredeem enabled:<on|off> │
│ Toggle automatic code redemption │
│ /backfill [channel:<channel>] │
│ /notifications │
│ View/update DM notification preferences │
│ /stats │
│ Server-wide stats and aggregate loot │
│ /logs [lines:<num>] (admin) │
│ Show last N lines of the bot log │
│ /backfill [channel:<channel>] (admin) │
│ Recover codes from message history │
│ /deleteaccount │
│ Permanently delete all your stored data │
Expand All @@ -823,35 +941,36 @@ The bot automatically scans all messages in the monitored channel for promo code

**Trigger**: Message posted in monitored Discord channel

**Pattern Matching**: Regular expression matching 4-20 alphanumeric character sequences
**Pattern Matching**: Regular expression matching 12- or 16-character sequences of uppercase alphanumeric and symbol characters (optionally hyphen-separated)

**Detection Pattern**:
```regex
\b([A-Z0-9]{4,20})\b
(?:[A-Z0-9*!@#$%^&*]-?){12}(?:(?:[A-Z0-9*!@#$%^&*]-?){4})?
```

Applied after stripping Discord emoji tags (`<:name:id>`, `<a:name:id>`) and URLs from message content.

Matches:
- `IDLE2024` ✅
- `CHAMPIONS500` ✅
- `PROMO100` ✅
- 12-character or 16-character sequences of uppercase alphanumeric and symbol characters
- Characters may be separated by single hyphens (e.g., `ABCD-EFGH-IJKL`)

Does NOT match:
- `ABC` (too short, <4 chars) ❌
- `ABC-123` (contains hyphen) ❌
- `abc123` (all lowercase, needs validation per API) ⚠️
- Shorter sequences (< 12 characters)
- Discord emoji markup (stripped before matching)
- URLs (stripped before matching)

**Detection Behavior**:

Comment thread
BigMichi1 marked this conversation as resolved.
```
Message Posted: "Free code: IDLE2024"
Message Posted: "Free code: ABCD1234EFGH"
Bot scans message content
Pattern matches: IDLE2024
Pattern matches: ABCD1234EFGH
Retrieves message author credentials
Calls API: redeemCoupon(IDLE2024)
Calls API: redeemCoupon(ABCD1234EFGH)
Records result in database
Expand Down
Loading
Loading