@hed-hog/core 0.0.274 → 0.0.276
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +399 -38
- package/dist/ai/ai.service.d.ts.map +1 -1
- package/dist/ai/ai.service.js +7 -8
- package/dist/ai/ai.service.js.map +1 -1
- package/dist/task/task.service.d.ts.map +1 -1
- package/dist/task/task.service.js +1 -2
- package/dist/task/task.service.js.map +1 -1
- package/hedhog/data/dashboard_component.yaml +11 -11
- package/hedhog/data/dashboard_item.yaml +32 -32
- package/hedhog/frontend/app/dashboard/[slug]/dashboard-content.tsx.ejs +10 -10
- package/hedhog/frontend/app/dashboard/components/draggable-grid.tsx.ejs +20 -20
- package/hedhog/frontend/app/dashboard/components/widget-wrapper.tsx.ejs +6 -6
- package/hedhog/frontend/app/dashboard/dashboard.css.ejs +92 -92
- package/hedhog/table/mail.yaml +15 -15
- package/hedhog/table/mail_sent.yaml +21 -21
- package/hedhog/table/mail_var.yaml +12 -12
- package/package.json +3 -3
- package/src/ai/ai.service.ts +3 -4
- package/src/setting/setting.service.ts +5 -5
- package/src/task/task.service.ts +5 -6
package/README.md
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
```markdown
|
|
1
2
|
# @hed-hog/core
|
|
2
3
|
|
|
3
4
|
## 1. Visão geral do módulo
|
|
@@ -17,36 +18,36 @@ O módulo `@hed-hog/core` é o núcleo do monorepo HedHog, responsável por forn
|
|
|
17
18
|
|
|
18
19
|
### Módulo AI (`/ai`)
|
|
19
20
|
|
|
20
|
-
| Método | Path
|
|
21
|
-
|
|
22
|
-
| POST | `/ai/chat`
|
|
23
|
-
| POST | `/ai/agent`
|
|
24
|
-
| GET | `/ai/agent`
|
|
25
|
-
| GET | `/ai/agent/id/:agentId` | Autenticada
|
|
26
|
-
| GET | `/ai/agent/:slug`
|
|
27
|
-
| PATCH | `/ai/agent/:agentId`
|
|
28
|
-
| DELETE | `/ai/agent`
|
|
29
|
-
| POST | `/ai/agent/:slug/chat
|
|
21
|
+
| Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
|
|
22
|
+
|--------|-------------------------|--------------|--------------------------------------------------|---------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------|
|
|
23
|
+
| POST | `/ai/chat` | Autenticada | Realiza chat com IA, podendo enviar arquivo. | Body: `ChatDTO` (message, provider?, model?, systemPrompt?, file_id?)<br>File: opcional | `{ provider, model, content }` | 400: Chave API não configurada |
|
|
24
|
+
| POST | `/ai/agent` | Autenticada | Cria um agente AI. | Body: `CreateAgentDTO` (slug, provider?, model?, instructions?) | Objeto agente criado ou existente | 400: Slug já existe |
|
|
25
|
+
| GET | `/ai/agent` | Autenticada | Lista agentes AI com paginação. | Query: paginação (page, pageSize, search) | Paginação com lista de agentes | - |
|
|
26
|
+
| GET | `/ai/agent/id/:agentId` | Autenticada | Obtém agente AI por ID. | Path param: `agentId` (int) | Objeto agente | 404: Agente não encontrado |
|
|
27
|
+
| GET | `/ai/agent/:slug` | Autenticada | Obtém agente AI por slug. | Path param: `slug` (string) | Objeto agente | 404: Agente não encontrado |
|
|
28
|
+
| PATCH | `/ai/agent/:agentId` | Autenticada | Atualiza agente AI. | Path param: `agentId` (int)<br>Body: `UpdateAgentDTO` (slug?, provider?, model?, instructions?) | Objeto agente atualizado | 404: Agente não encontrado<br>400: Slug duplicado |
|
|
29
|
+
| DELETE | `/ai/agent` | Autenticada | Deleta agentes AI em lote. | Body: `DeleteDTO` (ids: number[]) | `{ count: number }` | 404: Um ou mais agentes não encontrados |
|
|
30
|
+
| POST | `/ai/agent/:slug/chat` | Autenticada | Chat com agente AI específico, com arquivo opcional. | Path param: `slug` (string)<br>Body: `ChatAgentDTO` (message, file_id?)<br>File: opcional | `{ slug, provider, model, content }` | 404: Agente não encontrado |
|
|
30
31
|
|
|
31
32
|
### Módulo Auth (`/auth`)
|
|
32
33
|
|
|
33
|
-
| Método | Path
|
|
34
|
-
|
|
35
|
-
| GET | `/auth/verify`
|
|
36
|
-
| GET | `/auth/roles`
|
|
37
|
-
| POST | `/auth/refresh`
|
|
38
|
-
| POST | `/auth/login`
|
|
39
|
-
| POST | `/auth/login-email-verification`
|
|
40
|
-
| POST | `/auth/login-email-verification-resend` | Pública | Reenvia código de verificação por email.
|
|
41
|
-
| POST | `/auth/signup`
|
|
42
|
-
| POST | `/auth/login-code`
|
|
43
|
-
| POST | `/auth/login-recovery-code`
|
|
44
|
-
| POST | `/auth/resend-mfa-code`
|
|
45
|
-
| POST | `/auth/webauthn/generate`
|
|
46
|
-
| POST | `/auth/webauthn/verify`
|
|
47
|
-
| POST | `/auth/forgot`
|
|
48
|
-
| POST | `/auth/logout`
|
|
49
|
-
| POST | `/auth/forgot-reset`
|
|
34
|
+
| Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
|
|
35
|
+
|--------|-------------------------------------|--------------|--------------------------------------------------|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------|
|
|
36
|
+
| GET | `/auth/verify` | Autenticada | Verifica usuário autenticado. | - | Dados do usuário autenticado | - |
|
|
37
|
+
| GET | `/auth/roles` | Pública | Retorna roles do usuário (se autenticado). | - | `{ roles: string[] }` | - |
|
|
38
|
+
| POST | `/auth/refresh` | Pública | Atualiza token de acesso usando refresh token. | Body: `{ refreshToken?: string }`<br>Cookies: `rt` opcional | `{ accessToken, refreshToken? }` | 400: Refresh token não fornecido |
|
|
39
|
+
| POST | `/auth/login` | Pública | Login com email e senha. | Body: `LoginDTO` (email, password, refreshToken?) | Tokens de acesso e refresh ou MFA requerida | 400: Acesso negado |
|
|
40
|
+
| POST | `/auth/login-email-verification` | Pública | Login via verificação por email e código. | Body: `LoginEmailVerificationDTO` (token, code) | Tokens de acesso e refresh | 400: Código inválido ou desafio não encontrado |
|
|
41
|
+
| POST | `/auth/login-email-verification-resend` | Pública | Reenvia código de verificação por email. | Body: `LoginEmailVerificationResendDTO` (token) | Novo token para verificação | 400: Token inválido ou expirado |
|
|
42
|
+
| POST | `/auth/signup` | Pública | Cadastro com email e senha. | Body: `CreateWithEmailAndPasswordDTO` | Usuário criado | - |
|
|
43
|
+
| POST | `/auth/login-code` | Pública | Login com código MFA. | Body: `LoginWithCodeDTO` (token, code, methodType?) | Tokens de acesso e refresh | 400: Código MFA inválido |
|
|
44
|
+
| POST | `/auth/login-recovery-code` | Pública | Login com código de recuperação MFA. | Body: `LoginWithRecoveryCodeDTO` (token, code) | Tokens de acesso e refresh | 400: Código de recuperação inválido|
|
|
45
|
+
| POST | `/auth/resend-mfa-code` | Pública | Reenvia código MFA por email. | Body: `ResendMfaCodeDTO` (token) | `{ success: true, hasEmailMfa: true }` | 400: Nenhum método MFA por email |
|
|
46
|
+
| POST | `/auth/webauthn/generate` | Pública | Gera opções para autenticação WebAuthn. | Body: `{ mfaToken: string }` | Opções WebAuthn | 400: WebAuthn não configurado |
|
|
47
|
+
| POST | `/auth/webauthn/verify` | Pública | Verifica autenticação WebAuthn. | Body: `{ mfaToken: string, assertionResponse: any }` | Tokens de acesso e refresh | 400: Verificação falhou |
|
|
48
|
+
| POST | `/auth/forgot` | Pública | Solicita recuperação de senha via email. | Body: `ForgetDTO` (email) | `{ success: true }` | - |
|
|
49
|
+
| 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 |
|
|
50
|
+
| POST | `/auth/forgot-reset` | Pública | Reseta senha via código de recuperação. | Body: `ResetDTO` (password, code) | Tokens de acesso e refresh | 400: Código inválido ou expirado |
|
|
50
51
|
|
|
51
52
|
### Módulo System (`/system`)
|
|
52
53
|
|
|
@@ -54,6 +55,22 @@ O módulo `@hed-hog/core` é o núcleo do monorepo HedHog, responsável por forn
|
|
|
54
55
|
|--------|------------|--------------|---------------------------------|-------------------|------------------------------------------------------------------------------------------|--------------|
|
|
55
56
|
| GET | `/system` | Autenticada | Retorna informações do sistema. | - | Informações detalhadas do sistema operacional, hardware, banco de dados, módulos e usuários | - |
|
|
56
57
|
|
|
58
|
+
### Módulo Dashboard Core (`/dashboard-core`)
|
|
59
|
+
|
|
60
|
+
| Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
|
|
61
|
+
|--------|---------------------------|--------------|--------------------------------------------------|---------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------|
|
|
62
|
+
| GET | `/dashboard-core/home` | Autenticada | Retorna dashboard home do usuário. | - | Objeto dashboard ou null | 400: Usuário não encontrado |
|
|
63
|
+
| GET | `/dashboard-core/stats/overview/users` | Autenticada | Estatísticas de usuários. | - | Estatísticas agregadas de usuários e sessões | - |
|
|
64
|
+
| GET | `/dashboard-core/stats/overview/mails` | Autenticada | Estatísticas de emails enviados. | - | Estatísticas agregadas de emails enviados | - |
|
|
65
|
+
| GET | `/dashboard-core/widgets/me` | Autenticada | Dados dos widgets para o usuário. | - | Dados agregados para widgets do usuário | - |
|
|
66
|
+
| GET | `/dashboard-core/user-dashboards` | Autenticada | Lista dashboards do usuário. | - | Lista de dashboards associados ao usuário | - |
|
|
67
|
+
| GET | `/dashboard-core/access/:slug` | Autenticada | Verifica acesso do usuário a dashboard. | Path param: `slug` (string) | `{ hasAccess: boolean, dashboard: object|null }` | - |
|
|
68
|
+
| 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 | - |
|
|
69
|
+
| 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 |
|
|
70
|
+
| POST | `/dashboard-core/widget/:slug` | Autenticada | Adiciona widget ao dashboard do usuário. | Body: `{ componentSlug: string }` | Dados do widget adicionado | 403: Acesso negado |
|
|
71
|
+
| DELETE | `/dashboard-core/widget/:slug/:widgetId` | Autenticada | Remove widget do dashboard do usuário. | Path param: `slug` (string), `widgetId` (string) | Erro "Not implemented yet" | - |
|
|
72
|
+
| 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 | - |
|
|
73
|
+
|
|
57
74
|
## 4. Regras de autenticação e autorização
|
|
58
75
|
|
|
59
76
|
- A maioria dos endpoints requer autenticação via token JWT.
|
|
@@ -184,6 +201,135 @@ O módulo `@hed-hog/core` é o núcleo do monorepo HedHog, responsável por forn
|
|
|
184
201
|
}
|
|
185
202
|
```
|
|
186
203
|
|
|
204
|
+
### DTOs principais do módulo Dashboard
|
|
205
|
+
|
|
206
|
+
- **CreateDashboardDTO**
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
{
|
|
210
|
+
slug: string; // obrigatório
|
|
211
|
+
locale: Record<string, { name: string }>; // obrigatório
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
- **UpdateDashboardDTO**
|
|
216
|
+
|
|
217
|
+
```ts
|
|
218
|
+
{
|
|
219
|
+
slug?: string;
|
|
220
|
+
locale?: Record<string, { name: string }>;
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
- **CreateDashboardComponentDTO**
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
{
|
|
228
|
+
slug: string;
|
|
229
|
+
min_width?: number;
|
|
230
|
+
max_width?: number;
|
|
231
|
+
min_height?: number;
|
|
232
|
+
max_height?: number;
|
|
233
|
+
width: number;
|
|
234
|
+
height: number;
|
|
235
|
+
is_resizable?: boolean;
|
|
236
|
+
locale: Record<string, { name: string; description?: string }>;
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
- **UpdateDashboardComponentDTO**
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
{
|
|
244
|
+
slug?: string;
|
|
245
|
+
min_width?: number;
|
|
246
|
+
max_width?: number;
|
|
247
|
+
min_height?: number;
|
|
248
|
+
max_height?: number;
|
|
249
|
+
width?: number;
|
|
250
|
+
height?: number;
|
|
251
|
+
is_resizable?: boolean;
|
|
252
|
+
locale?: Record<string, { name: string; description?: string }>;
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
- **CreateDashboardRoleDTO**
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
{
|
|
260
|
+
dashboard_id: number;
|
|
261
|
+
role_id: number;
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
- **CreateDashboardRoleBatchDTO**
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
{
|
|
269
|
+
dashboard_id: number;
|
|
270
|
+
role_ids: number[];
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
- **CreateDashboardComponentRoleDTO**
|
|
275
|
+
|
|
276
|
+
```ts
|
|
277
|
+
{
|
|
278
|
+
component_id: number;
|
|
279
|
+
role_id: number;
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
- **CreateDashboardComponentRoleBatchDTO**
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
{
|
|
287
|
+
component_id: number;
|
|
288
|
+
role_ids: number[];
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
- **CreateDashboardItemDTO**
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
{
|
|
296
|
+
component_id: number;
|
|
297
|
+
dashboard_id: number;
|
|
298
|
+
width: number;
|
|
299
|
+
height: number;
|
|
300
|
+
x_axis: number;
|
|
301
|
+
y_axis: number;
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
- **UpdateDashboardLayoutDTO**
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
{
|
|
309
|
+
dashboard_id: number;
|
|
310
|
+
items: Array<{
|
|
311
|
+
id: number;
|
|
312
|
+
width: number;
|
|
313
|
+
height: number;
|
|
314
|
+
x_axis: number;
|
|
315
|
+
y_axis: number;
|
|
316
|
+
}>;
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
- **UpdateDashboardItemDTO**
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
{
|
|
324
|
+
component_id?: number;
|
|
325
|
+
dashboard_id?: number;
|
|
326
|
+
width?: number;
|
|
327
|
+
height?: number;
|
|
328
|
+
x_axis?: number;
|
|
329
|
+
y_axis?: number;
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
187
333
|
## 6. Erros comuns
|
|
188
334
|
|
|
189
335
|
- **400 Bad Request**
|
|
@@ -195,6 +341,7 @@ O módulo `@hed-hog/core` é o núcleo do monorepo HedHog, responsável por forn
|
|
|
195
341
|
- Acesso negado por credenciais inválidas.
|
|
196
342
|
- MFA não configurado ou código inválido.
|
|
197
343
|
- Tentativa de deletar itens inexistentes.
|
|
344
|
+
- Requisição inválida para criação de relações duplicadas.
|
|
198
345
|
|
|
199
346
|
- **404 Not Found**
|
|
200
347
|
|
|
@@ -237,31 +384,244 @@ enums:
|
|
|
237
384
|
- provider: ['openai', 'gemini']
|
|
238
385
|
```
|
|
239
386
|
|
|
240
|
-
### user
|
|
387
|
+
### user
|
|
388
|
+
|
|
389
|
+
```yaml
|
|
390
|
+
finalidade: Armazena usuários do sistema.
|
|
391
|
+
colunas:
|
|
392
|
+
- id: integer, PK, auto-increment
|
|
393
|
+
- name: string, não nulo
|
|
394
|
+
- photo_id: integer, nullable
|
|
395
|
+
- last_login_at: timestamp, nullable
|
|
396
|
+
- created_at: timestamp, não nulo, default NOW()
|
|
397
|
+
- updated_at: timestamp, não nulo, default NOW()
|
|
398
|
+
integridade:
|
|
399
|
+
- PK em id
|
|
400
|
+
indices:
|
|
401
|
+
- id (PK)
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### user_mfa
|
|
405
|
+
|
|
406
|
+
```yaml
|
|
407
|
+
finalidade: Armazena métodos de autenticação multifator dos usuários.
|
|
408
|
+
colunas:
|
|
409
|
+
- id: integer, PK, auto-increment
|
|
410
|
+
- user_id: integer, FK para user.id, não nulo
|
|
411
|
+
- name: string, não nulo
|
|
412
|
+
- type: enum('totp', 'email', 'webauthn'), não nulo
|
|
413
|
+
- verified_at: timestamp, nullable
|
|
414
|
+
- suspended_until: timestamp, nullable
|
|
415
|
+
- created_at: timestamp, não nulo, default NOW()
|
|
416
|
+
- updated_at: timestamp, não nulo, default NOW()
|
|
417
|
+
integridade:
|
|
418
|
+
- FK user_id referencia user.id
|
|
419
|
+
indices:
|
|
420
|
+
- id (PK)
|
|
421
|
+
enums:
|
|
422
|
+
- type: ['totp', 'email', 'webauthn']
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### user_identifier
|
|
426
|
+
|
|
427
|
+
```yaml
|
|
428
|
+
finalidade: Identificadores do usuário, como emails.
|
|
429
|
+
colunas:
|
|
430
|
+
- id: integer, PK, auto-increment
|
|
431
|
+
- user_id: integer, FK para user.id, não nulo
|
|
432
|
+
- type: string, não nulo (ex: 'email')
|
|
433
|
+
- value: string, não nulo
|
|
434
|
+
- verified_at: timestamp, nullable
|
|
435
|
+
- enabled: boolean, não nulo, default true
|
|
436
|
+
- created_at: timestamp, não nulo, default NOW()
|
|
437
|
+
- updated_at: timestamp, não nulo, default NOW()
|
|
438
|
+
integridade:
|
|
439
|
+
- FK user_id referencia user.id
|
|
440
|
+
indices:
|
|
441
|
+
- id (PK)
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### user_session
|
|
445
|
+
|
|
446
|
+
```yaml
|
|
447
|
+
finalidade: Sessões de usuários autenticados.
|
|
448
|
+
colunas:
|
|
449
|
+
- id: integer, PK, auto-increment
|
|
450
|
+
- user_id: integer, FK para user.id, não nulo
|
|
451
|
+
- token: string, não nulo
|
|
452
|
+
- ip_address: string, nullable
|
|
453
|
+
- user_agent: string, nullable
|
|
454
|
+
- created_at: timestamp, não nulo, default NOW()
|
|
455
|
+
- expires_at: timestamp, não nulo
|
|
456
|
+
- revoked_at: timestamp, nullable
|
|
457
|
+
integridade:
|
|
458
|
+
- FK user_id referencia user.id
|
|
459
|
+
indices:
|
|
460
|
+
- id (PK)
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### user_activity
|
|
464
|
+
|
|
465
|
+
```yaml
|
|
466
|
+
finalidade: Registro de atividades dos usuários.
|
|
467
|
+
colunas:
|
|
468
|
+
- id: integer, PK, auto-increment
|
|
469
|
+
- user_id: integer, FK para user.id, não nulo
|
|
470
|
+
- action: string, não nulo
|
|
471
|
+
- created_at: timestamp, não nulo, default NOW()
|
|
472
|
+
integridade:
|
|
473
|
+
- FK user_id referencia user.id
|
|
474
|
+
indices:
|
|
475
|
+
- id (PK)
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### role
|
|
479
|
+
|
|
480
|
+
```yaml
|
|
481
|
+
finalidade: Papéis (roles) do sistema para controle de acesso.
|
|
482
|
+
colunas:
|
|
483
|
+
- id: integer, PK, auto-increment
|
|
484
|
+
- slug: string, único, não nulo
|
|
485
|
+
- created_at: timestamp, não nulo, default NOW()
|
|
486
|
+
- updated_at: timestamp, não nulo, default NOW()
|
|
487
|
+
integridade:
|
|
488
|
+
- slug único
|
|
489
|
+
indices:
|
|
490
|
+
- id (PK)
|
|
491
|
+
- slug (único)
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
### role_user
|
|
495
|
+
|
|
496
|
+
```yaml
|
|
497
|
+
finalidade: Relação muitos-para-muitos entre usuários e roles.
|
|
498
|
+
colunas:
|
|
499
|
+
- id: integer, PK, auto-increment
|
|
500
|
+
- user_id: integer, FK para user.id, não nulo
|
|
501
|
+
- role_id: integer, FK para role.id, não nulo
|
|
502
|
+
integridade:
|
|
503
|
+
- FK user_id referencia user.id
|
|
504
|
+
- FK role_id referencia role.id
|
|
505
|
+
indices:
|
|
506
|
+
- id (PK)
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### dashboard
|
|
510
|
+
|
|
511
|
+
```yaml
|
|
512
|
+
finalidade: Dashboards configuráveis do sistema.
|
|
513
|
+
colunas:
|
|
514
|
+
- id: integer, PK, auto-increment
|
|
515
|
+
- slug: string, único, não nulo
|
|
516
|
+
- created_at: timestamp, não nulo, default NOW()
|
|
517
|
+
- updated_at: timestamp, não nulo, default NOW()
|
|
518
|
+
integridade:
|
|
519
|
+
- slug único
|
|
520
|
+
indices:
|
|
521
|
+
- id (PK)
|
|
522
|
+
- slug (único)
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### dashboard_component
|
|
241
526
|
|
|
242
|
-
|
|
527
|
+
```yaml
|
|
528
|
+
finalidade: Componentes que podem ser usados em dashboards.
|
|
529
|
+
colunas:
|
|
530
|
+
- id: integer, PK, auto-increment
|
|
531
|
+
- slug: string, único, não nulo
|
|
532
|
+
- min_width: integer, nullable
|
|
533
|
+
- max_width: integer, nullable
|
|
534
|
+
- min_height: integer, nullable
|
|
535
|
+
- max_height: integer, nullable
|
|
536
|
+
- width: integer, não nulo
|
|
537
|
+
- height: integer, não nulo
|
|
538
|
+
- is_resizable: boolean, não nulo, default true
|
|
539
|
+
- created_at: timestamp, não nulo, default NOW()
|
|
540
|
+
- updated_at: timestamp, não nulo, default NOW()
|
|
541
|
+
integridade:
|
|
542
|
+
- slug único
|
|
543
|
+
indices:
|
|
544
|
+
- id (PK)
|
|
545
|
+
- slug (único)
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### dashboard_role
|
|
549
|
+
|
|
550
|
+
```yaml
|
|
551
|
+
finalidade: Relação entre dashboards e roles para controle de acesso.
|
|
552
|
+
colunas:
|
|
553
|
+
- id: integer, PK, auto-increment
|
|
554
|
+
- dashboard_id: integer, FK para dashboard.id, não nulo
|
|
555
|
+
- role_id: integer, FK para role.id, não nulo
|
|
556
|
+
integridade:
|
|
557
|
+
- FK dashboard_id referencia dashboard.id
|
|
558
|
+
- FK role_id referencia role.id
|
|
559
|
+
indices:
|
|
560
|
+
- id (PK)
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### dashboard_user
|
|
564
|
+
|
|
565
|
+
```yaml
|
|
566
|
+
finalidade: Relação entre dashboards e usuários.
|
|
567
|
+
colunas:
|
|
568
|
+
- id: integer, PK, auto-increment
|
|
569
|
+
- dashboard_id: integer, FK para dashboard.id, não nulo
|
|
570
|
+
- user_id: integer, FK para user.id, não nulo
|
|
571
|
+
- is_home: boolean, não nulo, default false
|
|
572
|
+
integridade:
|
|
573
|
+
- FK dashboard_id referencia dashboard.id
|
|
574
|
+
- FK user_id referencia user.id
|
|
575
|
+
indices:
|
|
576
|
+
- id (PK)
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
### dashboard_item
|
|
243
580
|
|
|
244
|
-
|
|
581
|
+
```yaml
|
|
582
|
+
finalidade: Itens (widgets) dentro de dashboards.
|
|
583
|
+
colunas:
|
|
584
|
+
- id: integer, PK, auto-increment
|
|
585
|
+
- dashboard_id: integer, FK para dashboard.id, não nulo
|
|
586
|
+
- component_id: integer, FK para dashboard_component.id, não nulo
|
|
587
|
+
- width: integer, não nulo
|
|
588
|
+
- height: integer, não nulo
|
|
589
|
+
- x_axis: integer, não nulo
|
|
590
|
+
- y_axis: integer, não nulo
|
|
591
|
+
integridade:
|
|
592
|
+
- FK dashboard_id referencia dashboard.id
|
|
593
|
+
- FK component_id referencia dashboard_component.id
|
|
594
|
+
indices:
|
|
595
|
+
- id (PK)
|
|
596
|
+
```
|
|
245
597
|
|
|
246
|
-
|
|
598
|
+
### dashboard_component_role
|
|
599
|
+
|
|
600
|
+
```yaml
|
|
601
|
+
finalidade: Relação entre componentes de dashboard e roles.
|
|
602
|
+
colunas:
|
|
603
|
+
- id: integer, PK, auto-increment
|
|
604
|
+
- component_id: integer, FK para dashboard_component.id, não nulo
|
|
605
|
+
- role_id: integer, FK para role.id, não nulo
|
|
606
|
+
integridade:
|
|
607
|
+
- FK component_id referencia dashboard_component.id
|
|
608
|
+
- FK role_id referencia role.id
|
|
609
|
+
indices:
|
|
610
|
+
- id (PK)
|
|
611
|
+
```
|
|
247
612
|
|
|
248
613
|
## 8. Regras de negócio relevantes
|
|
249
614
|
|
|
250
615
|
- Agentes AI podem ser criados, atualizados e deletados, com integração direta com APIs OpenAI e Gemini.
|
|
251
|
-
|
|
252
616
|
- Chat com IA suporta anexos de arquivos, com extração de texto para PDFs e arquivos de texto.
|
|
253
|
-
|
|
254
617
|
- MFA obrigatório pode ser configurado, com suporte a email, TOTP e WebAuthn.
|
|
255
|
-
|
|
256
618
|
- Tokens de acesso e refresh são gerenciados com segurança, incluindo cookies HTTP-only.
|
|
257
|
-
|
|
258
619
|
- Dashboards são personalizados por usuário, com controle de acesso baseado em roles.
|
|
259
|
-
|
|
260
620
|
- Layouts de dashboards e widgets podem ser salvos e recuperados por usuário.
|
|
261
|
-
|
|
262
621
|
- Sistema coleta estatísticas de uso, sessões, emails enviados e segurança da conta.
|
|
263
|
-
|
|
264
622
|
- Validações rigorosas são aplicadas via DTOs e classes de validação.
|
|
623
|
+
- Operações de criação em batch evitam duplicações e retornam contagem de criados e ignorados.
|
|
624
|
+
- A remoção de widgets do dashboard do usuário ainda não está implementada.
|
|
265
625
|
|
|
266
626
|
## 9. Guia rápido de uso (exemplos)
|
|
267
627
|
|
|
@@ -400,3 +760,4 @@ Resposta (exemplo resumido):
|
|
|
400
760
|
---
|
|
401
761
|
|
|
402
762
|
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.
|
|
763
|
+
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai.service.d.ts","sourceRoot":"","sources":["../../src/ai/ai.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,
|
|
1
|
+
{"version":3,"file":"ai.service.d.ts","sourceRoot":"","sources":["../../src/ai/ai.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAU,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAY5D,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,KAAK,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEtC,KAAK,aAAa,GAAG;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;CAClB,CAAC;AAQF,qBACa,SAAS;IAKlB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAR9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;gBAIlC,aAAa,EAAE,aAAa,EAE5B,cAAc,EAAE,cAAc,EAE9B,WAAW,EAAE,WAAW;IAGrC,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,UAAU;;;;;;;;;IAmCrC,WAAW,CAAC,IAAI,EAAE,cAAc;IAmChC,UAAU,CAAC,gBAAgB,EAAE,aAAa;;;;;;;IAuC1C,YAAY,CAAC,OAAO,EAAE,MAAM;IAU5B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc;IA6CjD,YAAY,CAAC,EAAE,GAAG,EAAE,EAAE,SAAS;;;IAyB/B,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,UAAU;;;;;;;;;;;IAqDjE,cAAc,CAAC,IAAI,EAAE,MAAM;IAU3B,qBAAqB,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkB1E,qBAAqB,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,MAAM;;;;;;;;;;YA+ChD,eAAe;YAWf,aAAa;IAW3B,OAAO,CAAC,eAAe;YAQT,UAAU;YAYV,cAAc;YA6Cd,qBAAqB;YA0CrB,uBAAuB;YAiGvB,cAAc;YAwEd,KAAK;YAIL,iBAAiB;YAgCjB,sBAAsB;IA+BpC,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,2BAA2B;YAmBrB,cAAc;IAkB5B,OAAO,CAAC,UAAU;CAGnB"}
|
package/dist/ai/ai.service.js
CHANGED
|
@@ -19,7 +19,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
19
19
|
exports.AiService = void 0;
|
|
20
20
|
const api_prisma_1 = require("@hed-hog/api-prisma");
|
|
21
21
|
const common_1 = require("@nestjs/common");
|
|
22
|
-
const client_1 = require("@prisma/client");
|
|
23
22
|
const axios_1 = __importDefault(require("axios"));
|
|
24
23
|
const crypto_1 = require("crypto");
|
|
25
24
|
const pdf_parse_1 = __importDefault(require("pdf-parse"));
|
|
@@ -99,9 +98,9 @@ let AiService = AiService_1 = class AiService {
|
|
|
99
98
|
const offset = (page - 1) * pageSize;
|
|
100
99
|
const search = String((paginationParams === null || paginationParams === void 0 ? void 0 : paginationParams.search) || '').trim();
|
|
101
100
|
const whereClause = search
|
|
102
|
-
?
|
|
103
|
-
:
|
|
104
|
-
const data = await this.prismaService.$queryRaw(
|
|
101
|
+
? api_prisma_1.Prisma.sql `WHERE LOWER(slug) LIKE LOWER(${`%${search}%`})`
|
|
102
|
+
: api_prisma_1.Prisma.empty;
|
|
103
|
+
const data = await this.prismaService.$queryRaw(api_prisma_1.Prisma.sql `
|
|
105
104
|
SELECT id, slug, provider, model, instructions, external_agent_id, created_at, updated_at
|
|
106
105
|
FROM ai_agent
|
|
107
106
|
${whereClause}
|
|
@@ -109,7 +108,7 @@ let AiService = AiService_1 = class AiService {
|
|
|
109
108
|
LIMIT ${pageSize}
|
|
110
109
|
OFFSET ${offset}
|
|
111
110
|
`);
|
|
112
|
-
const totalResult = await this.prismaService.$queryRaw(
|
|
111
|
+
const totalResult = await this.prismaService.$queryRaw(api_prisma_1.Prisma.sql `
|
|
113
112
|
SELECT COUNT(*) AS total
|
|
114
113
|
FROM ai_agent
|
|
115
114
|
${whereClause}
|
|
@@ -170,10 +169,10 @@ let AiService = AiService_1 = class AiService {
|
|
|
170
169
|
return this.getAgentById(agentId);
|
|
171
170
|
}
|
|
172
171
|
async deleteAgents({ ids }) {
|
|
173
|
-
const existing = await this.prismaService.$queryRaw(
|
|
172
|
+
const existing = await this.prismaService.$queryRaw(api_prisma_1.Prisma.sql `
|
|
174
173
|
SELECT id
|
|
175
174
|
FROM ai_agent
|
|
176
|
-
WHERE id IN (${
|
|
175
|
+
WHERE id IN (${api_prisma_1.Prisma.join(ids)})
|
|
177
176
|
`);
|
|
178
177
|
if (existing.length !== ids.length) {
|
|
179
178
|
const existingIds = existing.map((item) => item.id);
|
|
@@ -182,7 +181,7 @@ let AiService = AiService_1 = class AiService {
|
|
|
182
181
|
}
|
|
183
182
|
const deletedCount = await this.prismaService.$executeRaw `
|
|
184
183
|
DELETE FROM ai_agent
|
|
185
|
-
WHERE id IN (${
|
|
184
|
+
WHERE id IN (${api_prisma_1.Prisma.join(ids)})
|
|
186
185
|
`;
|
|
187
186
|
return {
|
|
188
187
|
count: Number(deletedCount || 0),
|