From ac54562996487adda93f880997b975c3b7aa6bc3 Mon Sep 17 00:00:00 2001 From: Vladimir Eremin Date: Wed, 28 Jan 2026 21:23:42 +0300 Subject: [PATCH] docs: Write quetza docs --- .gemini/skills/write-docs/SKILL.md | 26 ++--- services/docs/content/en/_index.md | 1 + services/docs/content/en/quetza/_index.md | 30 ++++++ .../docs/content/en/quetza/concepts/_index.md | 14 +++ .../en/quetza/concepts/architecture.md | 38 ++++++++ .../en/quetza/concepts/module-system.md | 54 +++++++++++ .../docs/content/en/quetza/getting-started.md | 58 +++++++++++ .../docs/content/en/quetza/guides/_index.md | 22 +++++ .../content/en/quetza/guides/deployment.md | 72 ++++++++++++++ .../en/quetza/guides/module-development.md | 97 +++++++++++++++++++ .../docs/content/en/quetza/recipes/_index.md | 14 +++ .../en/quetza/recipes/conversational-ai.md | 50 ++++++++++ .../en/quetza/recipes/voice-features.md | 58 +++++++++++ .../en/quetza/troubleshooting/_index.md | 13 +++ .../en/quetza/troubleshooting/diagnostics.md | 65 +++++++++++++ 15 files changed, 600 insertions(+), 12 deletions(-) create mode 100644 services/docs/content/en/quetza/_index.md create mode 100644 services/docs/content/en/quetza/concepts/_index.md create mode 100644 services/docs/content/en/quetza/concepts/architecture.md create mode 100644 services/docs/content/en/quetza/concepts/module-system.md create mode 100644 services/docs/content/en/quetza/getting-started.md create mode 100644 services/docs/content/en/quetza/guides/_index.md create mode 100644 services/docs/content/en/quetza/guides/deployment.md create mode 100644 services/docs/content/en/quetza/guides/module-development.md create mode 100644 services/docs/content/en/quetza/recipes/_index.md create mode 100644 services/docs/content/en/quetza/recipes/conversational-ai.md create mode 100644 services/docs/content/en/quetza/recipes/voice-features.md create mode 100644 services/docs/content/en/quetza/troubleshooting/_index.md create mode 100644 services/docs/content/en/quetza/troubleshooting/diagnostics.md diff --git a/.gemini/skills/write-docs/SKILL.md b/.gemini/skills/write-docs/SKILL.md index 8ba6935..7feb7b1 100644 --- a/.gemini/skills/write-docs/SKILL.md +++ b/.gemini/skills/write-docs/SKILL.md @@ -45,7 +45,9 @@ You must adhere to the following strict stylistic rules. There are no exceptions * *Good:* "Module A Configuration Settings" -* **MUST** ensure the H1 title corresponds exactly to the content's scope. +* **MUST NOT** write a top-level H1 header (e.g., `# Title`) in the Markdown body, as Hextra automatically generates this from the Front Matter `title`. + + * **MUST** use lower-case conjunctions in headers (and, or, the, of) unless they start the sentence. ### 1.4 Tone & Audience @@ -189,7 +191,7 @@ The glossary is the "Source of Truth" for terminology. It resides in `(en/ru)/{p Every document MUST end with a "See Also" block containing external references and last update metadata. * **Location:** Always at the very bottom of the file. -* **Format:** Use a generic Markdown Blockquote or GitHub Alert (`> [!NOTE]`). +* **Format:** Use a horizontal rule (`---`) followed by bold text. * **Content:** * **MUST** contain only a bulleted list of Markdown links. * **MUST NOT** contain paths to files as inline code. @@ -198,10 +200,11 @@ Every document MUST end with a "See Also" block containing external references a * **Template:** ```markdown -> [!NOTE] -> **See Also:** -> - [Doc: Related Component A](https://docs.example.com/comp-a) -> - [Wiki: Legacy Architecture](https://wiki.example.com/arch) +--- + +**See also:** +- [Doc: Related Component A](https://docs.example.com/comp-a) +- [Wiki: Legacy Architecture](https://wiki.example.com/arch) ``` @@ -349,16 +352,15 @@ Use GitHub-flavored alerts for emphasis. ## 6. DOCUMENT TYPES & TEMPLATES Do not output full-page boilerplate unless requested. Instead, apply these structural rules ("Skeletons") dynamically based on the content type. -This is also serves as the fixed categories which should populate every project's doc: Getting Started, Guides, Recipes, Concepts, Troubleshooting. +This is also serves as the fixed categories which should populate every project's docs: Getting Started, Guides, Recipes, Concepts, Troubleshooting. ### 6.1 General Skeleton (All Docs) 1. **Front Matter:** `title`, `weight`, `date` (optional). -2. **H1 Title:** Descriptive. -3. **Brief:** 1-2 sentences summarizing the "What" and "Why". -4. **Body Sections:** (See specific types below). -5. **Glossary Tooltips:** Use `[Term](/glossary#term)` for first mentions. -6. **Footer:** The `> [!NOTE]` "See Also" block. +2. **Brief:** 1-2 sentences summarizing the "What" and "Why". +3. **Body Sections:** (See specific types below). +4. **Glossary Tooltips:** Use `[Term](/glossary#term)` for first mentions. +5. **Footer:** The `> [!NOTE]` "See Also" block. ### 6.2 Quick Start (Beginner) diff --git a/services/docs/content/en/_index.md b/services/docs/content/en/_index.md index dacc290..7f6d931 100644 --- a/services/docs/content/en/_index.md +++ b/services/docs/content/en/_index.md @@ -8,4 +8,5 @@ Welcome to the unified documentation for my own projects {{< cards >}} {{< card link="root" title="root.ermnvldmr.com" icon="server" subtitle="Documentation for root.ermnvldmr.com infrastructure" >}} + {{< card link="quetza" title="Quetza Bot" icon="terminal" subtitle="Modular Discord bot framework documentation" >}} {{< /cards >}} diff --git a/services/docs/content/en/quetza/_index.md b/services/docs/content/en/quetza/_index.md new file mode 100644 index 0000000..e44aa84 --- /dev/null +++ b/services/docs/content/en/quetza/_index.md @@ -0,0 +1,30 @@ +--- +title: Quetza Bot +weight: 1 +type: docs +cascade: + type: docs +--- + +**Quetza** is a modular Discord bot framework built with TypeScript and Discord.js. It transforms feature development from core modification into independent module addition. + +## Project Vision + +The framework addresses the fundamental challenge of extensible bot design: providing a scalable architecture where functionality can be added without increasing system complexity or coupling. + +## Documentation Sections + +{{% cards %}} + {{< card link="getting-started" title="Getting Started" icon="lightning-bolt" subtitle="Understand the core philosophy and architecture of Quetza." >}} + {{< card link="guides" title="Guides" icon="book-open" subtitle="Step-by-step instructions for development and deployment." >}} + {{< card link="recipes" title="Recipes" icon="beaker" subtitle="Strategic patterns for common bot features." >}} + {{< card link="concepts" title="Concepts" icon="light-bulb" subtitle="Deep dive into the philosophy and design principles." >}} + {{< card link="troubleshooting" title="Troubleshooting" icon="shield-exclamation" subtitle="Diagnose and fix common issues." >}} +{{% /cards %}} + +## Key Features + +* **Modular Architecture:** Features are plugins, not core modifications. +* **TypeScript First:** Built for type safety and developer experience. +* **Zero-Config Discovery:** Filesystem-based module registration. +* **State Management:** Built-in patterns for guild-scoped services. diff --git a/services/docs/content/en/quetza/concepts/_index.md b/services/docs/content/en/quetza/concepts/_index.md new file mode 100644 index 0000000..f150270 --- /dev/null +++ b/services/docs/content/en/quetza/concepts/_index.md @@ -0,0 +1,14 @@ +--- +title: Concepts +weight: 4 +--- + + +**Quetza** concepts explain the *Why* and *How* behind the framework's design. These documents cover the underlying philosophy and architectural decisions. + +## Key Topics + +{{% cards %}} + {{< card link="architecture" title="Architecture & Philosophy" icon="scale" subtitle="Design principles: Convention over Configuration, Composition, and Isolation." >}} + {{< card link="module-system" title="The Module System" icon="template" subtitle="Understanding Clients, Modules, Controllers, and Events." >}} +{{% /cards %}} diff --git a/services/docs/content/en/quetza/concepts/architecture.md b/services/docs/content/en/quetza/concepts/architecture.md new file mode 100644 index 0000000..c26c833 --- /dev/null +++ b/services/docs/content/en/quetza/concepts/architecture.md @@ -0,0 +1,38 @@ +--- +title: Architecture & Philosophy +weight: 1 +--- + + +**Goal:** Understand the core design principles that drive Quetza's modularity. + +## Design Philosophies + +### Convention Over Configuration +Quetza minimizes boilerplate by relying on strict folder structures. +* **No central registry:** The filesystem *is* the registry. +* **Result:** You don't update a config file to add a module; you just create the folder. + +### Composition Over Inheritance +Modules are composed of capabilities, not inherited from a base class. +* **Flexibility:** Modules can use any internal architecture (Functional, OOP) as long as they export the required interfaces. + +### Isolation Over Integration +Modules cannot directly invoke each other. +* **Why:** Prevents tight coupling. +* **Benefit:** You can delete any module without breaking the rest of the bot. + +## Core Entities + +| Entity | Role | Lifecycle | +| :--- | :--- | :--- | +| **Client** | Service Locator & Orchestrator | Singleton. Runs the show. | +| **Module** | Namespace for features | Loaded at startup. | +| **Command** | User Interaction Endpoint | Stateless. Request/Response. | +| **Event** | Reactive Observer | Subscribed at startup. | +| **Controller** | State Manager | Persists across interactions. | + +--- +**See also:** +- [Service Locator Pattern](https://en.wikipedia.org/wiki/Service_locator_pattern) +- [Observer Pattern](https://en.wikipedia.org/wiki/Observer_pattern) diff --git a/services/docs/content/en/quetza/concepts/module-system.md b/services/docs/content/en/quetza/concepts/module-system.md new file mode 100644 index 0000000..dee4677 --- /dev/null +++ b/services/docs/content/en/quetza/concepts/module-system.md @@ -0,0 +1,54 @@ +--- +title: The Module System +weight: 2 +--- + + +**Goal:** Define the vocabulary and mechanics of Quetza's primary abstraction unit. + +## System Vocabulary + +### Module Declaration +The `module.ts` file acts as the manifest. It is the entry point for discovery. +```typescript +export const name = 'my-module'; // ID +export const description = '...'; // Doc +``` + +### Command Registration +Occurs during the `ready` event. +1. Quetza scans all `commands/` folders. +2. Compiles `ApplicationCommandData`. +3. PUTs the payload to Discord's API. + +### Controller Injection +State is injected, not imported. +```typescript +// The framework calls this: +execute(client, interaction, controller) +``` +* **Why?** Allows the framework to manage the controller's lifecycle (singleton per module). + +## State Management Philosophy + +### Ephemeral by Default +Quetza provides **no built-in database**. +* **Memory:** Controllers store state in JS `Map` or `Set` objects. +* **Restart:** All state is lost when the process exits. +* **Persistence:** Must be implemented manually (e.g., SQLite, Redis) inside the Controller. + +### Scope as Key +State must be keyed by its boundary. +* `Map` - Server specific (Most common). +* `Map` - User specific (DM bots). + +## Error Handling Model + +**Fail Fast & Friendly.** +* **Validation:** Check permissions/inputs immediately. +* **User-Facing:** "You don't have permission" (Not "Error: 403"). +* **Isolation:** A crash in `/ping` catches itself and doesn't kill the bot. + +--- +**See also:** +- [Discord Interaction Lifecycle](https://discord.com/developers/docs/interactions/receiving-and-responding) diff --git a/services/docs/content/en/quetza/getting-started.md b/services/docs/content/en/quetza/getting-started.md new file mode 100644 index 0000000..47a349a --- /dev/null +++ b/services/docs/content/en/quetza/getting-started.md @@ -0,0 +1,58 @@ +--- +title: Getting Started +weight: 1 +--- + +**Quetza** is a modular Discord bot framework built with TypeScript that enables developers to build feature-rich Discord applications through self-contained, composable modules. + +## What is Quetza? + +Quetza provides an architectural foundation that transforms feature development from core modification into module addition. It solves the problem of rigid bot design by inverting dependency structures—the core knows nothing about modules, yet modules have full access to capabilities through defined contracts. + +## The Core Philosophy + +### The Problem +Traditional monolithic bots suffer from brittleness. Adding features requires modifying core logic, intertwining dependencies, and managing growing codebases that are difficult to test or change. + +### The Solution +Quetza treats modules as plugins. +- **Zero-Touch Extension:** Add features by creating a folder. No core code modification required. +- **Isolation:** Modules operate independently. +- **Composition:** Enable/disable features by simply adding or removing module folders. + +## High-Level Architecture + +Quetza consists of three primary layers: + +1. **Foundation Layer**: The `Discord.js` client extended with module-aware registries (Commands, Events, Modules). It acts as a service locator. +2. **Module Layer**: Self-contained feature packages. Each module exposes its own commands and events via a standardized file structure. +3. **Service Layer**: Optional **Controllers** that manage stateful business logic (e.g., audio players, conversation context) across guilds. + +## Key Concepts + +### Mental Model +To work effectively with Quetza, adopt this framework: + +* **Modules are Plugins:** Independent folders discovered at runtime. +* **Commands are Endpoints:** Stateless handlers acting like REST API endpoints. +* **Events are Observers:** Reactive logic subscribing to Discord lifecycle events. +* **Controllers are Services:** Stateful managers bridging the gap between stateless commands and persistent behavior. + +### System Boundaries +Understanding constraints is critical for design: +* **No Persistence:** In-memory state is lost on restart. External storage is required for persistence. +* **No Inter-Module Communication:** Modules cannot directly invoke each other, ensuring loose coupling. +* **No Dynamic Loading:** Modules are loaded only at startup. + +## Architectural Invariants + +Quetza trades flexibility for predictability through strict conventions: + +* **Convention-Based Discovery:** Modules *must* follow the directory structure (`module.ts`, `commands/`, `events/`) to be loaded. +* **Single-Phase Initialization:** All loading happens before the Discord connection is established. +* **Interface Compliance:** All commands and events must export specific interfaces to be registered. + +--- +**See also:** +- [Discord.js Documentation](https://discord.js.org/) +- [TypeScript Documentation](https://www.typescriptlang.org/) diff --git a/services/docs/content/en/quetza/guides/_index.md b/services/docs/content/en/quetza/guides/_index.md new file mode 100644 index 0000000..11a51a4 --- /dev/null +++ b/services/docs/content/en/quetza/guides/_index.md @@ -0,0 +1,22 @@ +--- +title: Guides +weight: 2 +--- + + +**Quetza** guides provide step-by-step instructions for common tasks and workflows. These documents focus on practical application of the framework's concepts. + +## Core Workflows + +The development and operation of Quetza bots revolve around three primary workflows: + +1. **Module Development:** Creating new features by adding self-contained modules. +2. **Deployment & Operations:** Running the bot in various environments (Docker, Source). +3. **Lifecycle Management:** Maintaining modules from creation to deprecation. + +## Available Guides + +{{% cards %}} + {{< card link="module-development" title="Module Development" icon="code" subtitle="Step-by-step guide to creating your first module." >}} + {{< card link="deployment" title="Deployment & Operations" icon="server" subtitle="Deploying Quetza with Docker or from source." >}} +{{% /cards %}} diff --git a/services/docs/content/en/quetza/guides/deployment.md b/services/docs/content/en/quetza/guides/deployment.md new file mode 100644 index 0000000..68aeffa --- /dev/null +++ b/services/docs/content/en/quetza/guides/deployment.md @@ -0,0 +1,72 @@ +--- +title: Deployment & Operations +weight: 2 +--- + + +**Goal:** Configure, deploy, and monitor a Quetza bot instance. + +## 1. Environment Preparation +Quetza relies on environment variables for configuration. **Never** commit these to version control. + +| Variable | Description | Required | +| :--- | :--- | :--- | +| `DISCORD_TOKEN` | Bot token from Discord Developer Portal | **Yes** | +| `CLIENT_ID` | Application ID for slash command registration | **Yes** | +| `LLAMA_API_KEY` | Required if using the AI module | No | + +## 2. Deployment Strategies + +{{< tabs items="Docker (Recommended),Source" >}} + {{< tab >}} +**Docker** ensures a consistent runtime environment. + +1. **Build** the image: + ```bash + docker build -t quetza-bot . + ``` + +2. **Run** the container: + ```bash + docker run -d \ + --env-file .env \ + --name quetza \ + quetza-bot + ``` + {{< /tab >}} + {{< tab >}} +**Source** deployment is useful for development. + +1. **Install** dependencies: + ```bash + pnpm install + ``` + +2. **Build** the project: + ```bash + pnpm build + ``` + +3. **Start** the bot: + ```bash + pnpm start + ``` + {{< /tab >}} +{{< /tabs >}} + +## 3. Operational Monitoring + +Once running, use these mechanisms to check health: + +* **Logs:** Check standard output (Docker logs) for initialization errors. +* **`/ping` Command:** Verifies network latency and API responsiveness. +* **`/modules` Command:** Lists all loaded modules to confirm feature availability. + +> [!WARNING] +> **Scaling Constraint:** +> Quetza follows a single-instance-per-token model. Do not run multiple instances with the same token, as this will cause WebSocket conflicts. + +--- +**See also:** +- [Docker Documentation](https://docs.docker.com/) +- [Discord Developer Portal](https://discord.com/developers/applications) diff --git a/services/docs/content/en/quetza/guides/module-development.md b/services/docs/content/en/quetza/guides/module-development.md new file mode 100644 index 0000000..bcb9103 --- /dev/null +++ b/services/docs/content/en/quetza/guides/module-development.md @@ -0,0 +1,97 @@ +--- +title: Module Development Workflow +weight: 1 +--- + + +**Goal:** Create a new feature for the Quetza bot by implementing a self-contained module. + +## 1. Conceptualization Phase +Before writing code, determine the module's architecture: +* **Simple Command:** Needs only a `commands/` folder (e.g., utility commands). +* **Reactive Logic:** Needs `events/` to listen to Discord lifecycles (e.g., welcome messages). +* **Stateful Feature:** Needs a **Controller** to manage state across guilds (e.g., music player). + +## 2. Structure Establishment +Create the module directory structure. The presence of these files triggers automatic discovery. + +{{< filetree/container >}} + {{< filetree/folder name="src" state="open" >}} + {{< filetree/folder name="modules" state="open" >}} + {{< filetree/folder name="my-feature" state="open" >}} + {{< filetree/file name="module.ts" >}} + {{< filetree/folder name="commands" >}} {{< /filetree/folder >}} + {{< filetree/folder name="events" >}} {{< /filetree/folder >}} + {{< filetree/folder name="lib" >}} {{< /filetree/folder >}} + {{< /filetree/folder >}} + {{< /filetree/folder >}} + {{< /filetree/folder >}} +{{< /filetree/container >}} + +## 3. Implementation Steps + +{{% steps %}} + +### Step 1: Create the Manifest +Create `module.ts` to declare the module. + +```typescript +// src/modules/my-feature/module.ts +export const name = 'my-feature'; +export const description = 'Adds cool feature capabilities'; +// Optional: export const controller = new MyFeatureController(); +``` + +### Step 2: Implement Commands +Create command files in `commands/`. Each file exports data and an executor. + +```typescript +// src/modules/my-feature/commands/ping.ts +import { SlashCommandBuilder } from 'discord.js'; + +export const data = new SlashCommandBuilder() + .setName('ping') + .setDescription('Replies with Pong!'); + +export async function execute(interaction) { + await interaction.reply('Pong!'); +} +``` + +### Step 3: Implement Events (Optional) +Create event handlers in `events/` to observe Discord state. + +```typescript +// src/modules/my-feature/events/ready.ts +import { Events } from 'discord.js'; + +export const name = Events.ClientReady; +export const once = true; + +export function execute(client) { + console.log(`Ready! Logged in as ${client.user.tag}`); +} +``` + +### Step 4: Define Controller (Optional) +For stateful logic, implement a controller in `lib/` and export it in `module.ts`. + +### Step 5: Validate +Restart the bot. +1. Check logs for "Loaded module: my-feature". +2. Verify the command `/ping` appears in Discord. + +{{% /steps %}} + +## Integration Patterns + +| Pattern | Use Case | Components | +| :--- | :--- | :--- | +| **Simple Command** | Stateless utilities (Ping, Dice Roll) | `commands/` only | +| **Stateful Service** | Music, RPGs, Economy | `commands/` + `lib/Controller` | +| **Event-Driven** | Auto-moderation, Logging | `events/` only | +| **Hybrid** | Complex features (AI Chat) | All components | + +--- +**See also:** +- [Discord.js Guide: Slash Commands](https://discordjs.guide/creating-your-bot/slash-commands.html) diff --git a/services/docs/content/en/quetza/recipes/_index.md b/services/docs/content/en/quetza/recipes/_index.md new file mode 100644 index 0000000..21a5cee --- /dev/null +++ b/services/docs/content/en/quetza/recipes/_index.md @@ -0,0 +1,14 @@ +--- +title: Recipes +weight: 3 +--- + + +**Quetza** recipes are strategic architectural patterns for common functional requirements. They focus on *how* to compose framework features to solve business problems. + +## Recipe Categories + +{{% cards %}} + {{< card link="voice-features" title="Interactive Voice Features" icon="users" subtitle="Managing audio players and guild-scoped state." >}} + {{< card link="conversational-ai" title="Conversational AI" icon="chip" subtitle="Handling LLM context and long-running responses." >}} +{{% /cards %}} diff --git a/services/docs/content/en/quetza/recipes/conversational-ai.md b/services/docs/content/en/quetza/recipes/conversational-ai.md new file mode 100644 index 0000000..3643714 --- /dev/null +++ b/services/docs/content/en/quetza/recipes/conversational-ai.md @@ -0,0 +1,50 @@ +--- +title: Conversational AI Integration +weight: 2 +--- + + +**Goal:** Integrate Large Language Models (LLMs) while managing context and Discord's timeout constraints. + +## 1. Context Management Strategy +Conversations require history to be coherent. +* **Scoping:** `Map>` + * **Guild Key:** Prevents cross-server leaks. + * **User Key:** Prevents cross-user confusion in public channels. +* **Lifecycle:** Implement a rolling window (e.g., last 50 messages) to prevent context bloat. + +## 2. Response Streaming +LLMs are slow; Discord is fast (3s timeout). + +{{% steps %}} +### Step 1: Defer Interaction +Immediately call `interaction.deferReply()`. This buys you 15 minutes. + +### Step 2: Invoke LLM +Call your AI service asynchronously. + +### Step 3: Edit Response +When data arrives, use `interaction.editReply(content)`. +{{% /steps %}} + +## 3. Implementation Sketch + +```typescript +// commands/chat.ts +export async function execute(interaction, controller) { + // 1. Defer + await interaction.deferReply(); + + // 2. Process + const history = controller.getHistory(interaction.guildId, interaction.user.id); + const response = await aiService.generate(interaction.options.getString('prompt'), history); + + // 3. Respond + await interaction.editReply(response); + controller.updateHistory(interaction.guildId, interaction.user.id, response); +} +``` + +> [!WARNING] +> **API Costs:** +> AI APIs are often billed by token. Implement strict user-based rate limits in your Controller to prevent abuse. diff --git a/services/docs/content/en/quetza/recipes/voice-features.md b/services/docs/content/en/quetza/recipes/voice-features.md new file mode 100644 index 0000000..96b744d --- /dev/null +++ b/services/docs/content/en/quetza/recipes/voice-features.md @@ -0,0 +1,58 @@ +--- +title: Interactive Voice Features +weight: 1 +--- + + +**Goal:** Implement sophisticated voice interactions that respect guild boundaries and manage ephemeral resources. + +## 1. Resource Scoping Strategy +Voice features **MUST** be scoped to the Guild. +* **Pattern:** The Controller maintains a `Map`. +* **Behavior:** + * **Join:** Create a Player for `Guild A` if none exists. + * **Leave:** Destroy the Player and release connections. + * **Isolation:** Commands in `Guild B` never affect `Guild A`. + +## 2. Command Orchestration +Voice features require a suite of commands coordinated via the Controller. + +| Command | Action | Controller Logic | +| :--- | :--- | :--- | +| `/join` | Connect to channel | `createPlayer(guildId, channelId)` | +| `/play` | Add track to queue | `getPlayer(guildId).enqueue(track)` | +| `/stop` | Disconnect | `destroyPlayer(guildId)` | + +## 3. State Persistence +Audio sessions are ephemeral. +* **Transient State:** Active audio stream (Lost on disconnect). +* **Durable State:** Queue/Playlist (Persisted in Controller until restart). + +> [!TIP] +> **Resilience:** Separate the *Queue* logic from the *Voice Connection* logic. This allows the bot to reconnect without losing the user's playlist. + +## 4. Implementation Sketch + +```typescript +// lib/MusicController.ts +class MusicController { + private players = new Map(); + + getPlayer(guildId: string): AudioPlayer { + if (!this.players.has(guildId)) { + this.players.set(guildId, new AudioPlayer()); + } + return this.players.get(guildId); + } + + destroyPlayer(guildId: string) { + this.players.get(guildId)?.disconnect(); + this.players.delete(guildId); + } +} +``` + +--- + +**See also:** +- [Discord.js Voice Guide](https://discordjs.guide/voice/) diff --git a/services/docs/content/en/quetza/troubleshooting/_index.md b/services/docs/content/en/quetza/troubleshooting/_index.md new file mode 100644 index 0000000..247bd1d --- /dev/null +++ b/services/docs/content/en/quetza/troubleshooting/_index.md @@ -0,0 +1,13 @@ +--- +title: Troubleshooting +weight: 5 +--- + + +**Quetza** troubleshooting focuses on diagnosing structural and conceptual issues. Because of its convention-based nature, most errors are silent (missing files) rather than noisy (stack traces). + +## Common Issue Categories + +{{% cards %}} + {{< card link="diagnostics" title="Diagnostics Guide" icon="exclamation" subtitle="Solutions for module discovery, command registration, and state leaks." >}} +{{% /cards %}} diff --git a/services/docs/content/en/quetza/troubleshooting/diagnostics.md b/services/docs/content/en/quetza/troubleshooting/diagnostics.md new file mode 100644 index 0000000..8676fe9 --- /dev/null +++ b/services/docs/content/en/quetza/troubleshooting/diagnostics.md @@ -0,0 +1,65 @@ +--- +title: Diagnostics Guide +weight: 1 +--- + + +**Goal:** Identify and fix common pitfalls in Quetza development. + +## 1. Module Discovery Failures +**Symptom:** The bot starts, but my module is ignored. +**Cause:** Violation of filesystem conventions. + +{{% details title="Checklist: Directory Structure" closed="false" %}} +* [ ] Does `src/modules//` exist? +* [ ] Does `module.ts` export `name`? +* [ ] Are commands in `commands/` (not `cmds/`)? +* [ ] Did you run `pnpm build`? (Quetza runs from `dist/`). +{{% /details %}} + +## 2. Command Registration Issues +**Symptom:** `/command` does not appear in Discord. + +### Global vs. Guild Registration +* **Global:** Takes up to 1 hour to propagate. +* **Guild:** Instant update. + * **Fix:** Set `DEV_GUILD_ID` in your `.env` for development. + +### Data Malformation +Discord rejects invalid command structures silently or with generic errors. +* **Name:** Must be lowercase, alphanumeric, `-` only. +* **Description:** Required, max 100 chars. + +## 3. Interaction Failures +**Symptom:** "The application did not respond". +**Cause:** Command took > 3 seconds without deferral. + +**Solution:** +```typescript +// BAD +await longRunningTask(); +await interaction.reply('Done'); // Too late! + +// GOOD +await interaction.deferReply(); +await longRunningTask(); +await interaction.editReply('Done'); +``` + +## 4. State Management Leaks +**Symptom:** Bot memory usage grows; cross-server weirdness. +**Cause:** Storing state globally instead of per-guild. + +**Diagnostic:** +Check your Controller. +* ❌ `private player: AudioPlayer;` (Shared by everyone!) +* ✅ `private players = new Map();` (Scoped by ID). + +## 5. Event Handling +**Symptom:** Events fire multiple times or not at all. +* **Multiple:** Events are additive. Did you register the same handler in two modules? +* **None:** Did you export `name` and `execute` correctly? + +> [!TIP] +> **Debug Mode:** +> Enable verbose logging to see exactly which modules and commands are loaded at startup.