Files
aurorabot/docs/superpowers/specs/2026-03-28-inventory-display-redesign.md
syntaxbullet 289044e26f docs: add inventory display redesign spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:56:45 +01:00

6.0 KiB
Raw Blame History

Inventory Display Redesign

Overview

Redesign the /inventory command from a basic embed listing to a polished Components V2 experience with rarity indicators, paginated list view, item detail view with artwork, and inline item management actions.

Rarity Emoji Mapping

Add a squareEmoji field to RARITY_CONFIG in shared/lib/rarity.ts:

Rarity squareEmoji Existing emoji Color hex
C 🟤 📦 0x95A5A6
R 🔵 📦 0x3498DB
SR 🟣 0x9B59B6
SSR 🟡 🌟 0xF1C40F

Non-item rarities (CURRENCY, XP, NOTHING) do not get square emojis. The existing emoji field remains unchanged (used by lootbox results).

List View

The /inventory [user] command renders a Components V2 message:

  1. HeaderTextDisplayBuilder: # 📦 {username}'s Inventory with subtitle showing total item count.
  2. Separator
  3. Item rows (5 per page) — Each item is a TextDisplayBuilder line: {squareEmoji} **{Item Name}** — {Rarity Label} · {Type} · ×{quantity}
  4. Separator
  5. Select menuStringSelectMenuBuilder populated with the 5 items on the current page. Placeholder: "Select an item for details". Each option shows item name and rarity label.
  6. Navigation rowActionRowBuilder: ◀ Previous (disabled on page 1), disabled Page X/Y indicator button, Next ▶ (disabled on last page).

Container: ContainerBuilder with accent color from the highest-rarity item on the current page.

Sorting: Items sorted by rarity descending (SSR → SR → R → C), then alphabetically within the same rarity.

Empty state: If inventory is empty, show: "No items yet. Visit the shop or complete quests to earn items!"

Collector: createMessageComponentCollector with 2-minute idle timeout. On timeout, disable all interactive components.

Detail View

Shown when a user selects an item from the dropdown or uses /inventory view <item>:

  1. Header sectionSectionBuilder:
    • TextDisplayBuilder: {squareEmoji} **{Item Name}** with subtitle -# {Rarity Label} · {Type}
    • ThumbnailBuilder with the item's iconUrl
  2. ArtworkMediaGalleryBuilder displaying the item's imageUrl
  3. DescriptionTextDisplayBuilder with the item's description
  4. Separator
  5. Stats rowTextDisplayBuilder: Owned: **×{quantity}** and Value: **{price} 🪙** (or "Not tradeable" if price is null)
  6. Action buttonsActionRowBuilder:
    • ◀ Back (primary) — returns to list view at the same page
    • 🧪 Use (success) — only shown if item type is CONSUMABLE with effects defined
    • 🗑 Discard (danger) — drops one unit of the item

Container: ContainerBuilder with accent color matching the item's rarity color.

Use Button Flow

Calls inventoryService.useItem() and shows the result inline. Then returns to the detail view with updated quantity. If quantity reaches 0, returns to the list view.

Discard Flow

  1. Clicking 🗑 Discard replaces the action row with a confirmation: "Discard 1× {Item Name}?" with Confirm (danger) and Cancel (secondary) buttons.
  2. On confirm: calls inventoryService.removeItem(userId, itemId, 1), returns to detail view with updated quantity. If quantity reaches 0, returns to list view.
  3. On cancel: returns to the normal detail view action buttons.

/inventory view <item> Subcommand

Adds a view subcommand with a required item string option that has autocomplete. Autocomplete queries the user's inventory items (reusing the pattern from getAutocompleteItems). Goes directly to the detail view. The Back button returns to the full paginated list at page 1.

Item Selection Entry Points

Two ways to reach the detail view:

  • Select menu dropdown on the inventory list — for browsing
  • /inventory view <item> subcommand — for direct access when the user knows the item name

Both render the same detail view.

Interaction Custom IDs

All custom IDs include the invoking user's ID to prevent other users from interacting:

Custom ID Purpose
inv_select_{userId} Item select menu
inv_prev_{userId} Previous page button
inv_next_{userId} Next page button
inv_back_{userId} Back to list from detail
inv_use_{userId} Use item button
inv_discard_{userId} Discard item button
inv_discard_confirm_{userId} Confirm discard
inv_discard_cancel_{userId} Cancel discard

File Changes

Modified

  • shared/lib/rarity.ts — Add squareEmoji field to RARITY_CONFIG entries for C, R, SR, SSR.
  • bot/commands/inventory/inventory.ts — Rewrite to CV2 with pagination collector. Add view subcommand with autocomplete. Command setup and collector logic live here.
  • bot/modules/inventory/inventory.view.ts — Replace getInventoryEmbed with getInventoryListMessage (builds the paginated CV2 list) and add getItemDetailMessage (builds the detail CV2 view). getLootboxResultMessage is untouched.

New

  • bot/modules/inventory/inventory.interaction.ts — Handles all inventory interaction routing: select menu item selection, pagination buttons, back navigation, use item, discard + confirmation flow.

Unchanged

  • shared/modules/inventory/inventory.service.ts — Already provides getInventory, useItem, removeItem, getAutocompleteItems.
  • Database schema — All required fields (iconUrl, imageUrl, description, rarity, type, price) already exist on the items table.

Pagination Details

  • Items per page: 5
  • Page calculation: totalPages = Math.ceil(items.length / 5)
  • Page clamping: safePage = Math.min(page, totalPages - 1) to handle items being consumed while browsing
  • Collector timeout: 2 minutes idle, matching the quest system pattern
  • On timeout: Edit message to disable all buttons and the select menu