@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 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 | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
21
- |--------|-----------------------|--------------|------------------------------------------------|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------|
22
- | 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 |
23
- | POST | `/ai/agent` | Autenticada | Cria um agente AI. | Body: `CreateAgentDTO` (slug, provider?, model?, instructions?) | Objeto agente criado ou existente | 400: Slug já existe |
24
- | GET | `/ai/agent` | Autenticada | Lista agentes AI com paginação. | Query: paginação (page, pageSize, search) | Paginação com lista de agentes | - |
25
- | GET | `/ai/agent/id/:agentId` | Autenticada | Obtém agente AI por ID. | Path param: `agentId` (int) | Objeto agente | 404: Agente não encontrado |
26
- | GET | `/ai/agent/:slug` | Autenticada | Obtém agente AI por slug. | Path param: `slug` (string) | Objeto agente | 404: Agente não encontrado |
27
- | 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 |
28
- | DELETE | `/ai/agent` | Autenticada | Deleta agentes AI em lote. | Body: `DeleteDTO` (ids: number[]) | `{ count: number }` | 404: Um ou mais agentes não encontrados |
29
- | 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 |
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 | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
34
- |--------|-------------------------------|--------------|------------------------------------------------|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------|
35
- | GET | `/auth/verify` | Autenticada | Verifica usuário autenticado. | - | Dados do usuário autenticado | - |
36
- | GET | `/auth/roles` | Pública | Retorna roles do usuário (se autenticado). | - | `{ roles: string[] }` | - |
37
- | 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 |
38
- | 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 |
39
- | 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 |
40
- | 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 |
41
- | POST | `/auth/signup` | Pública | Cadastro com email e senha. | Body: `CreateWithEmailAndPasswordDTO` | Usuário criado | - |
42
- | 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 |
43
- | 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|
44
- | 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 |
45
- | POST | `/auth/webauthn/generate` | Pública | Gera opções para autenticação WebAuthn. | Body: `{ mfaToken: string }` | Opções WebAuthn | 400: WebAuthn não configurado |
46
- | POST | `/auth/webauthn/verify` | Pública | Verifica autenticação WebAuthn. | Body: `{ mfaToken: string, assertionResponse: any }` | Tokens de acesso e refresh | 400: Verificação falhou |
47
- | POST | `/auth/forgot` | Pública | Solicita recuperação de senha via email. | Body: `ForgetDTO` (email) | `{ success: true }` | - |
48
- | 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 |
49
- | 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 |
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, user_mfa, user_identifier, user_session, user_activity, role, role_user, dashboard, dashboard_component, dashboard_role, dashboard_user, dashboard_item, dashboard_component_role
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
- - Estruturas padrão para usuários, autenticação multifator, sessões, atividades, roles, dashboards e seus componentes, com relacionamentos muitos-para-muitos e suporte a internacionalização via tabelas de locale.
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
- - Campos comuns incluem IDs, slugs, timestamps de criação e atualização, e campos específicos para configurações de MFA, tokens, e layouts de dashboards.
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
- - Integridade referencial garantida via chaves estrangeiras.
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,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAapD,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"}
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"}
@@ -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
- ? client_1.Prisma.sql `WHERE LOWER(slug) LIKE LOWER(${`%${search}%`})`
103
- : client_1.Prisma.empty;
104
- const data = await this.prismaService.$queryRaw(client_1.Prisma.sql `
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(client_1.Prisma.sql `
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(client_1.Prisma.sql `
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 (${client_1.Prisma.join(ids)})
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 (${client_1.Prisma.join(ids)})
184
+ WHERE id IN (${api_prisma_1.Prisma.join(ids)})
186
185
  `;
187
186
  return {
188
187
  count: Number(deletedCount || 0),