```markdown
# @hed-hog/core

## 1. Visão geral do módulo

O módulo `@hed-hog/core` é o núcleo do monorepo HedHog, responsável por fornecer funcionalidades centrais essenciais para o sistema, incluindo autenticação, inteligência artificial, dashboard, sistema e gerenciamento de usuários, roles, permissões e componentes de interface. Ele integra diversos submódulos que tratam desde a segurança e autenticação até a gestão de dashboards customizáveis e agentes de IA.

## 2. Escopo e responsabilidades

- Gerenciamento de autenticação e autorização, incluindo MFA, WebAuthn, recuperação de senha e sessões.
- Serviços de inteligência artificial para chat e agentes AI com suporte a OpenAI e Gemini.
- Gestão de dashboards, componentes, roles e usuários associados.
- Informações do sistema operacional, hardware, banco de dados e módulos instalados.
- Validação e manipulação de dados via DTOs e integração com Prisma ORM.
- Suporte a internacionalização e paginação.

## 3. Endpoints

### Módulo AI (`/ai`)

| Método | Path                    | Autenticação | Descrição                                         | Parâmetros / Query / Body                                                                                   | Resposta                                                                                      | Erros Comuns                          |
|--------|-------------------------|--------------|--------------------------------------------------|-------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------|
| POST   | `/ai/chat`              | Autenticada  | Realiza chat com IA, podendo enviar arquivo.     | Body: `ChatDTO` (message: string, provider?: 'openai'|'gemini', model?: string, systemPrompt?: string, file_id?: number)<br>File: opcional | `{ provider: string, model: string, content: string }`                                       | 400: Chave API não configurada      |
| POST   | `/ai/agent`             | Autenticada  | Cria um agente AI.                                | Body: `CreateAgentDTO` (slug: string, provider?: 'openai'|'gemini', model?: string, instructions?: string)   | Objeto agente criado ou existente                                                           | 400: Slug já existe                 |
| GET    | `/ai/agent`             | Autenticada  | Lista agentes AI com paginação.                   | Query: paginação (page?: number, pageSize?: number, search?: string)                                         | Paginação com lista de agentes                                                              | -                                   |
| GET    | `/ai/agent/id/:agentId` | Autenticada  | Obtém agente AI por ID.                           | Path param: `agentId` (int)                                                                                  | Objeto agente                                                                              | 404: Agente não encontrado          |
| GET    | `/ai/agent/:slug`       | Autenticada  | Obtém agente AI por slug.                         | Path param: `slug` (string)                                                                                  | Objeto agente                                                                              | 404: Agente não encontrado          |
| PATCH  | `/ai/agent/:agentId`    | Autenticada  | Atualiza agente AI.                               | Path param: `agentId` (int)<br>Body: `UpdateAgentDTO` (slug?: string, provider?: 'openai'|'gemini', model?: string, instructions?: string) | Objeto agente atualizado                                                                   | 404: Agente não encontrado<br>400: Slug duplicado |
| DELETE | `/ai/agent`             | Autenticada  | Deleta agentes AI em lote.                        | Body: `DeleteDTO` (ids: number[])                                                                             | `{ count: number }`                                                                         | 404: Um ou mais agentes não encontrados |
| POST   | `/ai/agent/:slug/chat`  | Autenticada  | Chat com agente AI específico, com arquivo opcional. | Path param: `slug` (string)<br>Body: `ChatAgentDTO` (message: string, file_id?: number)<br>File: opcional      | `{ slug: string, provider: string, model: string, content: string }`                        | 404: Agente não encontrado          |

### Módulo Auth (`/auth`)

| Método | Path                                | Autenticação | Descrição                                         | Parâmetros / Body                                                                                  | Resposta                                                                                      | Erros Comuns                          |
|--------|-------------------------------------|--------------|--------------------------------------------------|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------|
| GET    | `/auth/verify`                      | Autenticada  | Verifica usuário autenticado.                     | -                                                                                                | Dados do usuário autenticado                                                                | -                                   |
| GET    | `/auth/roles`                      | Pública      | Retorna roles do usuário (se autenticado).       | -                                                                                                | `{ roles: string[] }`                                                                        | -                                   |
| POST   | `/auth/refresh`                    | Pública      | Atualiza token de acesso usando refresh token.   | Body: `{ refreshToken?: string }`<br>Cookies: `rt` opcional                                      | `{ accessToken: string, refreshToken?: string }`                                            | 400: Refresh token não fornecido    |
| POST   | `/auth/login`                      | Pública      | Login com email e senha.                           | Body: `LoginDTO` (email: string, password: string, refreshToken?: boolean)                       | Tokens de acesso e refresh ou MFA requerida                                                | 400: Acesso negado                   |
| POST   | `/auth/login-email-verification`  | Pública      | Login via verificação por email e código.         | Body: `LoginEmailVerificationDTO` (token: string, code: string)                                 | Tokens de acesso e refresh                                                                  | 400: Código inválido ou desafio não encontrado |
| POST   | `/auth/login-email-verification-resend` | Pública | Reenvia código de verificação por email.          | Body: `LoginEmailVerificationResendDTO` (token: string)                                         | Novo token para verificação                                                                 | 400: Token inválido ou expirado     |
| POST   | `/auth/signup`                    | Pública      | Cadastro com email e senha.                        | Body: `CreateWithEmailAndPasswordDTO`                                                           | Usuário criado                                                                             | -                                   |
| POST   | `/auth/login-code`                | Pública      | Login com código MFA.                              | Body: `LoginWithCodeDTO` (token: string, code: string, methodType?: 'totp'|'email'|'recovery')   | Tokens de acesso e refresh                                                                  | 400: Código MFA inválido            |
| POST   | `/auth/login-recovery-code`       | Pública      | Login com código de recuperação MFA.              | Body: `LoginWithRecoveryCodeDTO` (token: string, code: string)                                  | Tokens de acesso e refresh                                                                  | 400: Código de recuperação inválido|
| POST   | `/auth/resend-mfa-code`           | Pública      | Reenvia código MFA por email.                      | Body: `ResendMfaCodeDTO` (token: string)                                                        | `{ success: true, hasEmailMfa: true }`                                                     | 400: Nenhum método MFA por email    |
| POST   | `/auth/webauthn/generate`         | Pública      | Gera opções para autenticação WebAuthn.            | Body: `{ mfaToken: string }`                                                                     | Opções WebAuthn                                                                            | 400: WebAuthn não configurado       |
| POST   | `/auth/webauthn/verify`           | Pública      | Verifica autenticação WebAuthn.                     | Body: `{ mfaToken: string, assertionResponse: any }`                                            | Tokens de acesso e refresh                                                                  | 400: Verificação falhou             |
| POST   | `/auth/forgot`                    | Pública      | Solicita recuperação de senha via email.           | Body: `ForgetDTO` (email: string)                                                                | `{ success: true }`                                                                         | -                                   |
| POST   | `/auth/logout`                    | Pública      | Logout e invalida refresh token.                    | Body: `{ refreshToken?: string }`<br>Cookies: `rt` opcional                                      | `{ success: true }`                                                                         | 400: Refresh token não fornecido    |
| POST   | `/auth/forgot-reset`              | Pública      | Reseta senha via código de recuperação.             | Body: `ResetDTO` (password: string, code: string)                                               | Tokens de acesso e refresh                                                                  | 400: Código inválido ou expirado    |

### Módulo System (`/system`)

| Método | Path       | Autenticação | Descrição                         | Parâmetros / Body | Resposta                                                                                  | Erros Comuns |
|--------|------------|--------------|---------------------------------|-------------------|------------------------------------------------------------------------------------------|--------------|
| GET    | `/system`  | Autenticada  | Retorna informações do sistema. | -                 | Informações detalhadas do sistema operacional, hardware, banco de dados, módulos e usuários | -            |

### Módulo Dashboard Core (`/dashboard-core`)

| Método | Path                      | Autenticação | Descrição                                         | Parâmetros / Body                                                                                   | Resposta                                                                                      | Erros Comuns                          |
|--------|---------------------------|--------------|--------------------------------------------------|---------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------|
| GET    | `/dashboard-core/home`    | Autenticada  | Retorna dashboard home do usuário.                | -                                                                                                 | Objeto dashboard ou null                                                                     | 400: Usuário não encontrado          |
| GET    | `/dashboard-core/stats/overview/users` | Autenticada | Estatísticas de usuários.                         | -                                                                                                 | Estatísticas agregadas de usuários e sessões                                                | -                                   |
| GET    | `/dashboard-core/stats/overview/mails` | Autenticada | Estatísticas de emails enviados.                  | -                                                                                                 | Estatísticas agregadas de emails enviados                                                  | -                                   |
| GET    | `/dashboard-core/stats/overview/system` | Autenticada | Estatísticas do sistema (menus e rotas).          | -                                                                                                 | Estatísticas agregadas do sistema                                                          | -                                   |
| GET    | `/dashboard-core/config/overview` | Autenticada | Visão geral das configurações do sistema.         | -                                                                                                 | Objeto com configurações                                                                    | -                                   |
| GET    | `/dashboard-core/widgets/me` | Autenticada | Dados dos widgets para o usuário.                  | -                                                                                                 | Dados agregados para widgets do usuário                                                    | -                                   |
| GET    | `/dashboard-core/user-dashboards` | Autenticada | Lista dashboards do usuário.                       | -                                                                                                 | Lista de dashboards associados ao usuário                                                  | -                                   |
| GET    | `/dashboard-core/templates` | Autenticada | Lista templates disponíveis para dashboards.      | -                                                                                                 | Lista de templates                                                                          | -                                   |
| POST   | `/dashboard-core/dashboard` | Autenticada | Cria dashboard para usuário.                        | Body: `{ name?: string; slug?: string; icon?: string | null; templateSlug?: string }`               | Dashboard criado                                                                           | -                                   |
| PATCH  | `/dashboard-core/dashboard/order` | Autenticada | Reordena dashboards do usuário.                     | Body: `{ slugs?: string[] }`                                                                      | Dashboard reordenado                                                                       | -                                   |
| PATCH  | `/dashboard-core/dashboard/:slug` | Autenticada | Renomeia dashboard do usuário.                       | Path param: `slug` (string)<br>Body: `{ name?: string; icon?: string | null }`                    | Dashboard atualizado                                                                      | -                                   |
| POST   | `/dashboard-core/dashboard/:slug/home` | Autenticada | Define dashboard como home do usuário.              | Path param: `slug` (string)                                                                       | Sucesso                                                                                   | -                                   |
| GET    | `/dashboard-core/dashboard/:slug/shares` | Autenticada | Lista compartilhamentos do dashboard.               | Path param: `slug` (string)                                                                       | Lista de usuários com acesso                                                              | -                                   |
| GET    | `/dashboard-core/shareable-users/:slug` | Autenticada | Lista usuários para compartilhar dashboard.         | Path param: `slug` (string)<br>Query: search?: string, page?: string, pageSize?: string           | Paginação de usuários                                                                     | -                                   |
| POST   | `/dashboard-core/dashboard/:slug/share` | Autenticada | Compartilha dashboard com usuários.                  | Path param: `slug` (string)<br>Body: `{ userId?: number; userIds?: number[] }`                   | Sucesso                                                                                   | -                                   |
| DELETE | `/dashboard-core/dashboard/:slug/share/:sharedUserId` | Autenticada | Revoga compartilhamento de dashboard.                | Path params: `slug` (string), `sharedUserId` (int)                                               | Sucesso                                                                                   | -                                   |
| DELETE | `/dashboard-core/dashboard/:slug` | Autenticada | Remove dashboard do usuário.                          | Path param: `slug` (string)                                                                       | Sucesso                                                                                   | -                                   |
| GET    | `/dashboard-core/access/:slug` | Autenticada | Verifica acesso do usuário a dashboard.              | Path param: `slug` (string)                                                                       | `{ hasAccess: boolean, dashboard: object|null }`                                           | -                                   |
| GET    | `/dashboard-core/layout/:slug` | Autenticada | Obtém layout do usuário para dashboard.              | Path param: `slug` (string)                                                                       | Array de widgets com posições e dimensões                                                  | -                                   |
| POST   | `/dashboard-core/layout/:slug` | Autenticada | Salva layout do usuário para dashboard.               | Body: `{ layout: Array<{ i: string; x: number; y: number; w: number; h: number }> }`               | `{ success: true }`                                                                         | 403: Acesso negado                   |
| POST   | `/dashboard-core/widget/:slug` | Autenticada | Adiciona widget ao dashboard do usuário.              | Body: `{ componentSlug: string }`                                                                 | Dados do widget adicionado                                                                  | 403: Acesso negado                   |
| DELETE | `/dashboard-core/widget/:slug/:widgetId` | Autenticada | Remove widget do dashboard do usuário.                | Path params: `slug` (string), `widgetId` (string)                                                | Erro "Not implemented yet"                                                                  | -                                   |
| GET    | `/dashboard-core/:slug`   | Autenticada  | Obtém itens do dashboard por slug.                  | Path param: `slug` (string), Query param: `locale?: string`                                       | Lista de itens do dashboard                                                                | -                                   |

### Módulo Dashboard (`/dashboard`)

| Método | Path           | Autenticação | Descrição                      | Parâmetros / Body                                      | Resposta                      | Erros Comuns               |
|--------|----------------|--------------|-------------------------------|-------------------------------------------------------|------------------------------|----------------------------|
| GET    | `/dashboard`   | Autenticada  | Lista dashboards com paginação | Query: paginação (page?: number, pageSize?: number, search?: string) | Paginação com dashboards      | -                          |
| GET    | `/dashboard/:id` | Autenticada | Obtém dashboard por ID         | Path param: `id` (int)                                 | Objeto dashboard             | 404: Dashboard não encontrado |
| POST   | `/dashboard`   | Autenticada  | Cria dashboard                | Body: `CreateDashboardDTO` (slug: string, locale: Record<string, { name: string }>) | Dashboard criado             | -                          |
| PATCH  | `/dashboard/:id` | Autenticada | Atualiza dashboard            | Path param: `id` (int), Body: `UpdateDashboardDTO`    | Dashboard atualizado         | 404: Dashboard não encontrado |
| DELETE | `/dashboard/:id` | Autenticada | Deleta dashboard             | Path param: `id` (int)                                 | `{ success: true }`          | 404: Dashboard não encontrado |

### Módulo Dashboard Component (`/dashboard-component`)

| Método | Path                   | Autenticação | Descrição                      | Parâmetros / Body                                               | Resposta                      | Erros Comuns                   |
|--------|------------------------|--------------|-------------------------------|----------------------------------------------------------------|------------------------------|-------------------------------|
| GET    | `/dashboard-component` | Autenticada  | Lista componentes com paginação | Query: paginação (page?: number, pageSize?: number, search?: string) | Paginação com componentes     | -                             |
| GET    | `/dashboard-component/user` | Autenticada | Lista componentes por roles do usuário | Query: paginação (page?: number, pageSize?: number, search?: string), User ID via token | Paginação com componentes     | -                             |
| GET    | `/dashboard-component/:id` | Autenticada | Obtém componente por ID       | Path param: `id` (int)                                         | Objeto componente             | 404: Componente não encontrado |
| POST   | `/dashboard-component` | Autenticada  | Cria componente               | Body: `CreateDashboardComponentDTO`                            | Componente criado             | -                             |
| PATCH  | `/dashboard-component/:id` | Autenticada | Atualiza componente           | Path param: `id` (int), Body: `UpdateDashboardComponentDTO`   | Componente atualizado         | 404: Componente não encontrado |
| DELETE | `/dashboard-component/:id` | Autenticada | Deleta componente             | Path param: `id` (int)                                         | `{ success: true }`           | 404: Componente não encontrado |
| POST   | `/dashboard-component/:id/preview` | Autenticada | Salva preview de componente (imagem) | Path param: `id` (int), File: imagem (image/*)                 | `{ success: true, componentId: number, slug: string, library_slug: string, fileName: string, relativeUrl: string }` | 400: Arquivo inválido<br>403: Apenas em dev |

### Módulo Dashboard Component Role (`/dashboard-component-role`)

| Método | Path                          | Autenticação | Descrição                          | Parâmetros / Body                                               | Resposta                      | Erros Comuns                   |
|--------|-------------------------------|--------------|-----------------------------------|----------------------------------------------------------------|------------------------------|-------------------------------|
| GET    | `/dashboard-component-role`   | Autenticada  | Lista relações com paginação ou por componente | Query: paginação (page?: number, pageSize?: number), Query param: componentId?: number | Paginação ou lista de relações | -                             |
| POST   | `/dashboard-component-role`   | Autenticada  | Cria relação componente-role      | Body: `CreateDashboardComponentRoleDTO`                         | Relação criada                | Erro se relação já existe      |
| POST   | `/dashboard-component-role/batch` | Autenticada | Cria relações em lote             | Body: `CreateDashboardComponentRoleBatchDTO`                    | { success: boolean, created: number, skipped: number, message: string } | -                      |
| DELETE | `/dashboard-component-role/:id` | Autenticada | Deleta relação por ID             | Path param: `id` (int)                                          | `{ success: true }`           | 404: Relação não encontrada    |
| DELETE | `/dashboard-component-role/component/:componentId/role/:roleId` | Autenticada | Deleta relação por componente e role | Path params: `componentId` (int), `roleId` (int)                | `{ success: true }`           | 404: Relação não encontrada    |

### Módulo Dashboard Item (`/dashboard-item`)

| Método | Path               | Autenticação | Descrição                      | Parâmetros / Body                                               | Resposta                      | Erros Comuns                   |
|--------|--------------------|--------------|-------------------------------|----------------------------------------------------------------|------------------------------|-------------------------------|
| GET    | `/dashboard-item`  | Autenticada  | Lista itens com paginação e filtro por dashboard | Query: paginação (page?: number, pageSize?: number), Query param: dashboardId?: number | Paginação com itens           | -                             |
| POST   | `/dashboard-item`  | Autenticada  | Cria item                     | Body: `CreateDashboardItemDTO`                                 | Item criado                  | -                             |
| DELETE | `/dashboard-item/:id` | Autenticada | Deleta item por ID            | Path param: `id` (int)                                         | `{ success: true }`           | 404: Item não encontrado       |

### Módulo Dashboard Role (`/dashboard-role`)

| Método | Path               | Autenticação | Descrição                          | Parâmetros / Body                                               | Resposta                      | Erros Comuns                   |
|--------|--------------------|--------------|-----------------------------------|----------------------------------------------------------------|------------------------------|-------------------------------|
| GET    | `/dashboard-role`  | Autenticada  | Lista relações com paginação ou por dashboard | Query: paginação (page?: number, pageSize?: number), Query param: dashboardId?: number | Paginação ou lista de relações | -                             |
| POST   | `/dashboard-role`  | Autenticada  | Cria relação dashboard-role       | Body: `CreateDashboardRoleDTO`                                 | Relação criada                | Erro se relação já existe      |
| POST   | `/dashboard-role/batch` | Autenticada | Cria relações em lote             | Body: `CreateDashboardRoleBatchDTO`                            | { success: boolean, created: number, skipped: number, message: string } | -                      |
| DELETE | `/dashboard-role/:id` | Autenticada | Deleta relação por ID             | Path param: `id` (int)                                         | `{ success: true }`           | 404: Relação não encontrada    |
| DELETE | `/dashboard-role/dashboard/:dashboardId/role/:roleId` | Autenticada | Deleta relação por dashboard e role | Path params: `dashboardId` (int), `roleId` (int)               | `{ success: true }`           | 404: Relação não encontrada    |

### Módulo Dashboard User (`/dashboard-user`)

| Método | Path               | Autenticação | Descrição                      | Parâmetros / Body                                               | Resposta                      | Erros Comuns                   |
|--------|--------------------|--------------|-------------------------------|----------------------------------------------------------------|------------------------------|-------------------------------|
| GET    | `/dashboard-user`  | Autenticada  | Lista relações com paginação   | Query: paginação (page?: number, pageSize?: number)            | Paginação com relações        | -                             |
| GET    | `/dashboard-user/:id` | Autenticada | Obtém relação por ID           | Path param: `id` (int)                                         | Objeto relação                | -                             |
| POST   | `/dashboard-user`  | Autenticada  | Cria relação                  | Body: `CreateDTO` (dashboard_id: number, user_id: number)      | Relação criada                | -                             |
| PATCH  | `/dashboard-user/:id` | Autenticada | Atualiza relação              | Path param: `id` (int), Body: `UpdateDTO`                      | Relação atualizada            | -                             |
| DELETE | `/dashboard-user`  | Autenticada  | Deleta relações em lote       | Body: `DeleteDTO` (ids: number[])                              | `{ count: number }`           | 400: Nenhum id fornecido       |

## 4. Regras de autenticação e autorização

- A maioria dos endpoints requer autenticação via token JWT.
- Endpoints públicos são indicados explicitamente.
- Controle de acesso baseado em roles e permissões.
- MFA (Multi-Factor Authentication) suportado via TOTP, email e códigos de recuperação.
- WebAuthn suportado para autenticação forte.
- Refresh tokens são gerenciados via cookies HTTP-only ou no corpo da requisição.
- Operações sensíveis (criação, atualização, deleção) requerem autenticação e permissões adequadas.

## 5. Estruturas de request/response

### DTOs principais do módulo AI

- **ChatDTO**

```ts
{
  message: string; // obrigatório
  provider?: 'openai' | 'gemini'; // opcional, padrão 'openai'
  model?: string; // opcional
  systemPrompt?: string; // opcional
  file_id?: number; // opcional
}
```

- **ChatAgentDTO**

```ts
{
  message: string; // obrigatório
  file_id?: number; // opcional
}
```

- **CreateAgentDTO**

```ts
{
  slug: string; // obrigatório
  provider?: 'openai' | 'gemini'; // opcional, padrão 'openai'
  model?: string; // opcional
  instructions?: string; // opcional
}
```

- **UpdateAgentDTO**

```ts
{
  slug?: string;
  provider?: 'openai' | 'gemini';
  model?: string;
  instructions?: string;
}
```

- **DeleteDTO**

```ts
{
  ids: number[]; // array de IDs para deleção, mínimo 1 item
}
```

### DTOs principais do módulo Auth

- **LoginDTO**

```ts
{
  email: string; // obrigatório, email válido
  password: string; // obrigatório, senha forte mínima 6 caracteres
  refreshToken?: boolean; // opcional, padrão false
}
```

- **LoginEmailVerificationDTO**

```ts
{
  token: string; // obrigatório
  code: string; // obrigatório, código PIN
}
```

- **LoginEmailVerificationResendDTO**

```ts
{
  token: string; // obrigatório
}
```

- **LoginWithCodeDTO**

```ts
{
  code: string; // obrigatório
  token: string; // obrigatório, JWT
  methodType?: 'totp' | 'email' | 'recovery'; // opcional
}
```

- **LoginWithRecoveryCodeDTO**

```ts
{
  code: string; // obrigatório
  token: string; // obrigatório, JWT
}
```

- **ForgetDTO**

```ts
{
  email: string; // obrigatório, email válido
}
```

- **ResetDTO**

```ts
{
  password: string; // obrigatório, mínimo 8 caracteres
  code: string; // obrigatório
}
```

### DTOs principais do módulo Dashboard

- **CreateDashboardDTO**

```ts
{
  slug: string; // obrigatório
  locale: Record<string, { name: string }>; // obrigatório
}
```

- **UpdateDashboardDTO**

```ts
{
  slug?: string;
  locale?: Record<string, { name: string }>;
}
```

- **CreateDashboardComponentDTO**

```ts
{
  slug: string;
  library_slug?: string;
  min_width?: number;
  max_width?: number;
  min_height?: number;
  max_height?: number;
  width: number;
  height: number;
  is_resizable?: boolean;
  locale: Record<string, { name: string; description?: string }>;
}
```

- **UpdateDashboardComponentDTO**

```ts
{
  slug?: string;
  library_slug?: string;
  min_width?: number;
  max_width?: number;
  min_height?: number;
  max_height?: number;
  width?: number;
  height?: number;
  is_resizable?: boolean;
  locale?: Record<string, { name: string; description?: string }>;
}
```

- **CreateDashboardRoleDTO**

```ts
{
  dashboard_id: number;
  role_id: number;
}
```

- **CreateDashboardRoleBatchDTO**

```ts
{
  dashboard_id: number;
  role_ids: number[];
}
```

- **CreateDashboardComponentRoleDTO**

```ts
{
  component_id: number;
  role_id: number;
}
```

- **CreateDashboardComponentRoleBatchDTO**

```ts
{
  component_id: number;
  role_ids: number[];
}
```

- **CreateDashboardItemDTO**

```ts
{
  component_id: number;
  dashboard_id: number;
  width: number;
  height: number;
  x_axis: number;
  y_axis: number;
}
```

- **UpdateDashboardLayoutDTO**

```ts
{
  dashboard_id: number;
  items: Array<{
    id: number;
    width: number;
    height: number;
    x_axis: number;
    y_axis: number;
  }>;
}
```

- **UpdateDashboardItemDTO**

```ts
{
  component_id?: number;
  dashboard_id?: number;
  width?: number;
  height?: number;
  x_axis?: number;
  y_axis?: number;
}
```

- **CreateDTO (DashboardUser)**

```ts
{
  dashboard_id: number;
  user_id: number;
}
```

- **UpdateDTO (DashboardUser)**

```ts
{
  dashboard_id?: number;
  user_id?: number;
}
```

- **DeleteDTO**

```ts
{
  ids: number[];
}
```

## 6. Erros comuns

- **400 Bad Request**

  - Chave API não configurada para OpenAI ou Gemini.
  - Slug de agente AI já existente.
  - Código de verificação inválido ou expirado.
  - Refresh token não fornecido.
  - Acesso negado por credenciais inválidas.
  - MFA não configurado ou código inválido.
  - Tentativa de deletar itens inexistentes.
  - Requisição inválida para criação de relações duplicadas.
  - Arquivo inválido para preview de componente.
  - Operação de preview disponível somente em ambiente de desenvolvimento.

- **404 Not Found**

  - Agente AI não encontrado por ID ou slug.
  - Dashboard, componente ou relação não encontrada.
  - Desafio (challenge) para verificação não encontrado ou expirado.

- **403 Forbidden**

  - Acesso negado a dashboards ou recursos protegidos.
  - Tentativa de salvar preview fora do ambiente de desenvolvimento.

## 7. Banco de dados (tabelas YAML)

### ai_agent

```yaml
finalidade: Armazena agentes de inteligência artificial configurados no sistema.
colunas:
  - id: integer, PK, auto-increment
  - slug: string, único, não nulo
  - provider: enum('openai', 'gemini'), não nulo
  - model: string, nullable
  - instructions: string, nullable
  - external_agent_id: string, nullable
  - created_at: timestamp, não nulo, default NOW()
  - updated_at: timestamp, não nulo, default NOW()
defaults:
  - created_at: NOW()
  - updated_at: NOW()
nulabilidade:
  - model: nullable
  - instructions: nullable
  - external_agent_id: nullable
integridade:
  - slug único
indices:
  - id (PK)
  - slug (único)
enums:
  - provider: ['openai', 'gemini']
```

### user

```yaml
finalidade: Armazena usuários do sistema.
colunas:
  - id: integer, PK, auto-increment
  - name: string, não nulo
  - photo_id: integer, nullable
  - last_login_at: timestamp, nullable
  - created_at: timestamp, não nulo, default NOW()
  - updated_at: timestamp, não nulo, default NOW()
integridade:
  - PK em id
indices:
  - id (PK)
```

### user_mfa

```yaml
finalidade: Armazena métodos de autenticação multifator dos usuários.
colunas:
  - id: integer, PK, auto-increment
  - user_id: integer, FK para user.id, não nulo
  - name: string, não nulo
  - type: enum('totp', 'email', 'webauthn'), não nulo
  - verified_at: timestamp, nullable
  - suspended_until: timestamp, nullable
  - created_at: timestamp, não nulo, default NOW()
  - updated_at: timestamp, não nulo, default NOW()
integridade:
  - FK user_id referencia user.id
indices:
  - id (PK)
enums:
  - type: ['totp', 'email', 'webauthn']
```

### user_identifier

```yaml
finalidade: Identificadores do usuário, como emails.
colunas:
  - id: integer, PK, auto-increment
  - user_id: integer, FK para user.id, não nulo
  - type: string, não nulo (ex: 'email')
  - value: string, não nulo
  - verified_at: timestamp, nullable
  - enabled: boolean, não nulo, default true
  - created_at: timestamp, não nulo, default NOW()
  - updated_at: timestamp, não nulo, default NOW()
integridade:
  - FK user_id referencia user.id
indices:
  - id (PK)
```

### user_session

```yaml
finalidade: Sessões de usuários autenticados.
colunas:
  - id: integer, PK, auto-increment
  - user_id: integer, FK para user.id, não nulo
  - token: string, não nulo
  - ip_address: string, nullable
  - user_agent: string, nullable
  - created_at: timestamp, não nulo, default NOW()
  - expires_at: timestamp, não nulo
  - revoked_at: timestamp, nullable
integridade:
  - FK user_id referencia user.id
indices:
  - id (PK)
```

### user_activity

```yaml
finalidade: Registro de atividades dos usuários.
colunas:
  - id: integer, PK, auto-increment
  - user_id: integer, FK para user.id, não nulo
  - action: string, não nulo
  - created_at: timestamp, não nulo, default NOW()
integridade:
  - FK user_id referencia user.id
indices:
  - id (PK)
```

### role

```yaml
finalidade: Papéis (roles) do sistema para controle de acesso.
colunas:
  - id: integer, PK, auto-increment
  - slug: string, único, não nulo
  - created_at: timestamp, não nulo, default NOW()
  - updated_at: timestamp, não nulo, default NOW()
integridade:
  - slug único
indices:
  - id (PK)
  - slug (único)
```

### role_user

```yaml
finalidade: Relação muitos-para-muitos entre usuários e roles.
colunas:
  - id: integer, PK, auto-increment
  - user_id: integer, FK para user.id, não nulo
  - role_id: integer, FK para role.id, não nulo
integridade:
  - FK user_id referencia user.id
  - FK role_id referencia role.id
indices:
  - id (PK)
```

### dashboard

```yaml
finalidade: Dashboards configuráveis do sistema.
colunas:
  - id: integer, PK, auto-increment
  - slug: string, único, não nulo
  - created_at: timestamp, não nulo, default NOW()
  - updated_at: timestamp, não nulo, default NOW()
integridade:
  - slug único
indices:
  - id (PK)
  - slug (único)
```

### dashboard_component

```yaml
finalidade: Componentes que podem ser usados em dashboards.
colunas:
  - id: integer, PK, auto-increment
  - slug: string, único, não nulo
  - library_slug: string, nullable
  - min_width: integer, nullable
  - max_width: integer, nullable
  - min_height: integer, nullable
  - max_height: integer, nullable
  - width: integer, não nulo
  - height: integer, não nulo
  - is_resizable: boolean, não nulo, default true
  - created_at: timestamp, não nulo, default NOW()
  - updated_at: timestamp, não nulo, default NOW()
integridade:
  - slug único
indices:
  - id (PK)
  - slug (único)
```

### dashboard_role

```yaml
finalidade: Relação entre dashboards e roles para controle de acesso.
colunas:
  - id: integer, PK, auto-increment
  - dashboard_id: integer, FK para dashboard.id, não nulo
  - role_id: integer, FK para role.id, não nulo
integridade:
  - FK dashboard_id referencia dashboard.id
  - FK role_id referencia role.id
indices:
  - id (PK)
```

### dashboard_user

```yaml
finalidade: Relação entre dashboards e usuários.
colunas:
  - id: integer, PK, auto-increment
  - dashboard_id: integer, FK para dashboard.id, não nulo
  - user_id: integer, FK para user.id, não nulo
  - is_home: boolean, não nulo, default false
integridade:
  - FK dashboard_id referencia dashboard.id
  - FK user_id referencia user.id
indices:
  - id (PK)
```

### dashboard_item

```yaml
finalidade: Itens (widgets) dentro de dashboards.
colunas:
  - id: integer, PK, auto-increment
  - dashboard_id: integer, FK para dashboard.id, não nulo
  - component_id: integer, FK para dashboard_component.id, não nulo
  - width: integer, não nulo
  - height: integer, não nulo
  - x_axis: integer, não nulo
  - y_axis: integer, não nulo
integridade:
  - FK dashboard_id referencia dashboard.id
  - FK component_id referencia dashboard_component.id
indices:
  - id (PK)
```

### dashboard_component_role

```yaml
finalidade: Relação entre componentes de dashboard e roles.
colunas:
  - id: integer, PK, auto-increment
  - component_id: integer, FK para dashboard_component.id, não nulo
  - role_id: integer, FK para role.id, não nulo
integridade:
  - FK component_id referencia dashboard_component.id
  - FK role_id referencia role.id
indices:
  - id (PK)
```

## 8. Regras de negócio relevantes

- Agentes AI podem ser criados, atualizados e deletados, com integração direta com APIs OpenAI e Gemini.
- Chat com IA suporta anexos de arquivos, com extração de texto para PDFs e arquivos de texto.
- MFA obrigatório pode ser configurado, com suporte a email, TOTP e WebAuthn.
- Tokens de acesso e refresh são gerenciados com segurança, incluindo cookies HTTP-only.
- Dashboards são personalizados por usuário, com controle de acesso baseado em roles.
- Layouts de dashboards e widgets podem ser salvos e recuperados por usuário.
- Sistema coleta estatísticas de uso, sessões, emails enviados e segurança da conta.
- Validações rigorosas são aplicadas via DTOs e classes de validação.
- Operações de criação em batch evitam duplicações e retornam contagem de criados e ignorados.
- A remoção de widgets do dashboard do usuário ainda não está implementada.
- Preview de componentes de dashboard é permitido somente em ambiente de desenvolvimento e aceita apenas imagens.
- MFA via email envia códigos para múltiplos emails associados ao usuário.
- WebAuthn é suportado para autenticação forte com geração e verificação de desafios.

## 9. Guia rápido de uso (exemplos)

### Criar agente AI

```http
POST /ai/agent
Authorization: Bearer <token>
Content-Type: application/json

{
  "slug": "meu-agente",
  "provider": "openai",
  "model": "gpt-4o-mini",
  "instructions": "Seja um assistente amigável."
}
```

Resposta:

```json
{
  "id": 1,
  "slug": "meu-agente",
  "provider": "openai",
  "model": "gpt-4o-mini",
  "instructions": "Seja um assistente amigável.",
  "external_agent_id": "abc123",
  "created_at": "2024-06-01T12:00:00Z",
  "updated_at": "2024-06-01T12:00:00Z"
}
```

### Chat com agente AI

```http
POST /ai/agent/meu-agente/chat
Authorization: Bearer <token>
Content-Type: multipart/form-data

Form-data:
- message: "Olá, como você está?"
- file: (arquivo opcional)
```

Resposta:

```json
{
  "slug": "meu-agente",
  "provider": "openai",
  "model": "gpt-4o-mini",
  "content": "Olá! Estou bem, obrigado por perguntar."
}
```

### Login com email e senha

```http
POST /auth/login
Content-Type: application/json

{
  "email": "usuario@exemplo.com",
  "password": "senhaSegura123"
}
```

Resposta:

```json
{
  "accessToken": "<jwt_access_token>",
  "refreshToken": "<jwt_refresh_token>"
}
```

### Obter informações do sistema

```http
GET /system
Authorization: Bearer <token>
```

Resposta (exemplo resumido):

```json
{
  "os": {
    "name": "Linux",
    "platform": "linux",
    "version": "5.15.0",
    "architecture": "x64",
    "uptime": 123456,
    "cpu": {
      "model": "Intel(R) Xeon(R)",
      "speed": 2400,
      "physicalCores": 4,
      "virtualCores": 8
    },
    "memory": {
      "total": 17179869184,
      "free": 8589934592
    },
    "disk": [
      {
        "filesystem": "/dev/sda1",
        "size": 500107862016,
        "free": 250053931008,
        "mountpoint": "/"
      }
    ]
  },
  "modules": [
    {
      "name": "@hedhog/core",
      "version": "^1.0.0",
      "latestVersion": "1.0.1",
      "upToDate": false
    }
  ],
  "users": {
    "total": 100,
    "admin": 5,
    "active": 80,
    "activities": []
  },
  "database": {
    "connections": 10,
    "size": 104857600,
    "queriesPerSecond": 50
  }
}
```

---

Este README documenta o módulo `@hed-hog/core` com base no código-fonte e definições atuais, fornecendo uma visão técnica detalhada para desenvolvedores e integradores do sistema.

```
