- Replace setTimeout race in use-item flow with explicit Back button
- Fix collector end handler to re-render current view instead of blanking
- Add appendUseBackButton helper to attach navigation to use results
- Remove unused isInventoryInteraction import
- Fix rarity test type assertions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Viewing another user's inventory is read-only — Use and Discard
buttons only render when viewer is the inventory owner, with a
server-side guard in the interaction handler.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds a limit check to assignQuest that reads maxActiveQuests from game
settings and throws a UserError when the user has reached their active
quest limit. Completed quests are excluded from the count.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
These domain events were only connected to dashboard recording but never
called questService.handleEvent(), so quests with triggers TRANSFER_OUT,
DAILY_REWARD, TRIVIA_WIN, and EXAM_REWARD never tracked progress. Added
userId and tx to event payloads and switched from emit to emitAsync for
transaction atomicity.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Discord counts all nested components (buttons inside action rows)
toward the message-level 40 component cap. 7 per page exceeded this
when pagination buttons were included.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The available quests view was exceeding Discord's 40-component container
limit when many quests existed, causing an API error. Paginate both
active and available quest views at 7 quests per page with prev/next
navigation buttons.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve ITEM-type pool entry names from the API when loading an
existing lootbox for editing, so the ItemSearchPicker displays
the selected item instead of showing an empty default.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The trivia service now emits domain events via systemEvents instead
of directly calling dashboardService.recordEvent. Updated the test
mock and assertions to match.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
oven-sh/setup-bun@v2 now requires node24 runtime, which Gitea Act
runner v0.2.11 does not support. Using direct curl install instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests the full transfer cycle against a real database: debit/credit,
transaction records, insufficient funds rejection, self-transfer
rejection, non-positive amounts, and sequential transfers.
Uses *.integration.test.ts convention — excluded from default test
runs, included with --integration flag in CI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Covers the critical financial transfer path against a real database,
catching schema mismatches, constraint violations, and transaction
atomicity bugs that mocked unit tests cannot detect.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move terminal.service.ts and prune.service.ts entirely to bot/modules/
since they are Discord-specific. Split lootdrop.service.ts: pure logic
(activity tracking, DB ops, claim) stays in shared/, Discord operations
(message sending, channel interactions) move to bot/modules/economy/
lootdrop.handler.ts. Move effect registry/handlers/types from bot/ to
shared/modules/inventory/ since they contain no Discord.js imports and
are needed by inventory.service.ts in shared.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add DomainEventPayloads interface to events.ts for typed event payloads
- Wrap dashboard listeners with fireAndForget() to prevent unhandled promise rejections
- Type all listener parameters explicitly using DomainEventPayloads
- Add idempotency guard to registerDomainEventListeners to prevent double registration on hot-reload
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace raw `Error` with `UserError` for user-facing conditions (invalid trade state, user not found, permission/channel type checks) and `SystemError` for internal failures (DB insert failures, external API errors, missing config). Improves Discord UX by ensuring user-facing errors are surfaced cleanly via withCommandErrorHandling.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>