Files
AuroraBot-discord/shared/docs/MODULE_STRUCTURE.md
2026-01-08 16:15:55 +01:00

3.1 KiB

Aurora Module Structure Guide

This guide documents the standard module organization patterns used in the Aurora codebase. Following these patterns ensures consistency, maintainability, and clear separation of concerns.

Module Anatomy

A typical module in @modules/ is organized into several files, each with a specific responsibility.

Example: trade module

  • trade.service.ts: Business logic and data access.
  • trade.view.ts: Discord UI components (embeds, modals, select menus).
  • trade.interaction.ts: Handler for interaction events (buttons, modals, etc.).
  • trade.types.ts: TypeScript interfaces and types.
  • trade.service.test.ts: Unit tests for the service logic.

File Responsibilities

1. Service (*.service.ts)

The core of the module. It contains the business logic, database interactions (using Drizzle), and state management.

  • Rules:
    • Export a singleton instance: export const tradeService = new TradeService();
    • Should not contain Discord-specific rendering logic (return data, not embeds).
    • Throw UserError for validation issues that should be shown to the user.

2. View (*.view.ts)

Handles the creation of Discord-specific UI elements like EmbedBuilder, ActionRowBuilder, and ModalBuilder.

  • Rules:
    • Focus on formatting and presentation.
    • Takes raw data (from services) and returns Discord components.

3. Interaction Handler (*.interaction.ts)

The entry point for Discord component interactions (buttons, select menus, modals).

  • Rules:
    • Export a single handler function: export async function handleTradeInteraction(interaction: Interaction) { ... }
    • Routes internal customId patterns to specific logic.
    • Relies on ComponentInteractionHandler for centralized error handling.
    • No local try-catch for standard validation errors; let them bubble up as UserError.

4. Types (*.types.ts)

Central location for module-specific TypeScript types and constants.

  • Rules:
    • Define interfaces for complex data structures.
    • Use enums or literal types for states and custom IDs.

Interaction Routing

All interaction handlers must be registered in src/lib/interaction.routes.ts.

{
    predicate: (i) => i.customId.startsWith("module_"),
    handler: () => import("@/modules/module/module.interaction"),
    method: 'handleModuleInteraction'
}

Error Handling Standards

Aurora uses a centralized error handling pattern in ComponentInteractionHandler.

  1. UserError: Use this for validation errors or issues the user can fix (e.g., "Insufficient funds").
    • throw new UserError("You need more coins!");
  2. SystemError / Generic Error: Use this for unexpected system failures.
    • These are logged to the console/logger and show a generic "Unexpected error" message to the user.

Naming Conventions

  • Directory Name: Lowercase, singular (e.g., trade, inventory).
  • File Names: moduleName.type.ts (e.g., trade.service.ts).
  • Class Names: PascalCase (e.g., TradeService).
  • Service Instances: camelCase (e.g., tradeService).
  • Interaction Method: handle[ModuleName]Interaction.