# Configuração
> Leia variáveis, canais e cargos globais ou específicos de cada guild sem espalhar IDs pelo código.

- Área: Operação
- URL humana: https://ninenity.vercel.app/doc/configuracao
- URL Markdown: https://ninenity.vercel.app/doc/markdown/configuracao
- Pacotes e conceitos: appConfig, Channels, Roles, HUB

## De onde vem a configuração

O Client começa com defaults locais e pode ser hidratado pela API quando as credenciais estão presentes.

1. **Defaults locais** — O objeto `config` passado ao `LibsClient` garante valores básicos mesmo sem API.
2. **Hidratação** — Com `API_KEY` e `API_SECRET`, o Core solicita a configuração persistida do bot.
3. **Resolução por guild** — `appConfig(guildId?)` mescla a base global com a entrada em `guilds[guildId]`.
4. **Contexto automático** — Em comandos, eventos, callbacks e tasks por guild, o ID atual é resolvido pelo runtime.

> **Sem guild, retorno seguro e vazio:** Fora de um contexto de servidor, chame `Client.appConfig(guildId)`. Sem contexto e sem ID explícito, o Core não escolhe uma guild arbitrária.

## Estrutura persistida

A configuração base e as sobrescritas de cada guild seguem o mesmo formato.

### exemplo conceitual de AppConfig

```json

{
  "channels": {
    "support": "123456789012345678"
  },
  "roles": {
    "staff": "223456789012345678"
  },
  "variables": {
    "general": {
      "prefix": { "type": "string", "value": "!" },
      "maxTickets": { "type": "number", "value": 3 },
      "features": { "type": "list", "value": ["tickets", "logs"] }
    }
  },
  "guilds": {
    "323456789012345678": {
      "channels": { "support": "423456789012345678" },
      "variables": {
        "general": {
          "prefix": { "type": "string", "value": "?" }
        }
      }
    }
  }
}
```


| Tipo | Valor resolvido |
| --- | --- |
| `string` | Texto |
| `number` | Número, sem conversão para string |
| `object` | Objeto JSON de chave e valor |
| `list` | Array JSON ordenado |

## Ler variáveis no contexto atual

O runtime remove os wrappers `type/value`; sua lógica recebe os valores puros.

### configuração dentro de comando

```text

Client.slash({
  data: new SlashCommandBuilder()
    .setName('settings')
    .setDescription('Mostra as configurações atuais.'),
  execute: async interaction => {
    const config = Client.appConfig()
    const general = config.variables?.general ?? {}

    await interaction.reply({
      content: [
        'Prefixo: ' + (general.prefix ?? '!'),
        'Máximo de tickets: ' + (general.maxTickets ?? 1),
        'Recursos: ' + (general.features ?? []).join(', ')
      ].join('
'),
      flags: 64
    })
  }
})
```


### fora de uma interação

```text

async function refreshGuild(guildId: string) {
  const config = Client.appConfig(guildId)
  const enabled = config.variables?.automation?.enabled ?? false

  if (!enabled) return
  await synchronizeGuild(guildId, config)
}
```


## Aliases de canais e cargos

Aliases tornam o código legível e permitem trocar IDs no HUB sem editar o bot.

### uso de aliases

```text

const channels = Client.getAppChannels()
const roles = Client.getAppRoles()

const supportChannel = channels.support
const staffRole = roles.staff

if (supportChannel) {
  console.log(
    '[Config] support=' + supportChannel.Name +
    ' id=' + supportChannel.Id
  )
}

await interaction.reply({
  content: [
    'Suporte: ' + (supportChannel?.Mention ?? 'não configurado'),
    'Equipe: ' + (staffRole?.Mention ?? 'não configurado')
  ].join('
'),
  flags: 64
})
```


| Campo | Canal | Cargo |
| --- | --- | --- |
| ID | `Id` | `Id` |
| Nome | `Name` | `Name` |
| Menção | `Mention` / `toString()` | `Mention` / `toString()` |
| Metadado | `Type` | `Color` e `Position` |

## Defaults locais

Defaults permitem desenvolver sem depender da API e documentam o formato esperado.

### Shared/Settings/Client.ts

```text

const Client = new LibsClient<AppConfig>({
  intents: [GatewayIntentBits.Guilds],
  token: process.env.BOT_TOKEN,
  config: {
    channels: {},
    roles: {},
    variables: {
      general: {
        prefix: { type: 'string', value: '!' },
        maxTickets: { type: 'number', value: 1 },
        features: { type: 'list', value: [] }
      }
    }
  }
})
```


> **Defaults não são secrets:** Tokens, senhas e chaves de API pertencem ao `.env` ou a um cofre de secrets. A configuração do bot é adequada para comportamento, aliases e valores operacionais.
