@hed-hog/ticket 0.0.285

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.
Files changed (134) hide show
  1. package/README.md +480 -0
  2. package/dist/dto/assign-ticket-owner.dto.d.ts +4 -0
  3. package/dist/dto/assign-ticket-owner.dto.d.ts.map +1 -0
  4. package/dist/dto/assign-ticket-owner.dto.js +7 -0
  5. package/dist/dto/assign-ticket-owner.dto.js.map +1 -0
  6. package/dist/dto/create-ticket-channel-account.dto.d.ts +10 -0
  7. package/dist/dto/create-ticket-channel-account.dto.d.ts.map +1 -0
  8. package/dist/dto/create-ticket-channel-account.dto.js +7 -0
  9. package/dist/dto/create-ticket-channel-account.dto.js.map +1 -0
  10. package/dist/dto/create-ticket-channel.dto.d.ts +7 -0
  11. package/dist/dto/create-ticket-channel.dto.d.ts.map +1 -0
  12. package/dist/dto/create-ticket-channel.dto.js +7 -0
  13. package/dist/dto/create-ticket-channel.dto.js.map +1 -0
  14. package/dist/dto/create-ticket-internal-note.dto.d.ts +4 -0
  15. package/dist/dto/create-ticket-internal-note.dto.d.ts.map +1 -0
  16. package/dist/dto/create-ticket-internal-note.dto.js +7 -0
  17. package/dist/dto/create-ticket-internal-note.dto.js.map +1 -0
  18. package/dist/dto/create-ticket-reply.dto.d.ts +5 -0
  19. package/dist/dto/create-ticket-reply.dto.d.ts.map +1 -0
  20. package/dist/dto/create-ticket-reply.dto.js +7 -0
  21. package/dist/dto/create-ticket-reply.dto.js.map +1 -0
  22. package/dist/dto/update-ticket-channel-account.dto.d.ts +8 -0
  23. package/dist/dto/update-ticket-channel-account.dto.d.ts.map +1 -0
  24. package/dist/dto/update-ticket-channel-account.dto.js +7 -0
  25. package/dist/dto/update-ticket-channel-account.dto.js.map +1 -0
  26. package/dist/dto/update-ticket-channel.dto.d.ts +5 -0
  27. package/dist/dto/update-ticket-channel.dto.d.ts.map +1 -0
  28. package/dist/dto/update-ticket-channel.dto.js +7 -0
  29. package/dist/dto/update-ticket-channel.dto.js.map +1 -0
  30. package/dist/dto/update-ticket-priority.dto.d.ts +4 -0
  31. package/dist/dto/update-ticket-priority.dto.d.ts.map +1 -0
  32. package/dist/dto/update-ticket-priority.dto.js +7 -0
  33. package/dist/dto/update-ticket-priority.dto.js.map +1 -0
  34. package/dist/dto/update-ticket-settings.dto.d.ts +13 -0
  35. package/dist/dto/update-ticket-settings.dto.d.ts.map +1 -0
  36. package/dist/dto/update-ticket-settings.dto.js +7 -0
  37. package/dist/dto/update-ticket-settings.dto.js.map +1 -0
  38. package/dist/dto/update-ticket-status.dto.d.ts +4 -0
  39. package/dist/dto/update-ticket-status.dto.d.ts.map +1 -0
  40. package/dist/dto/update-ticket-status.dto.js +7 -0
  41. package/dist/dto/update-ticket-status.dto.js.map +1 -0
  42. package/dist/index.d.ts +19 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +35 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/ticket-ai-review.controller.d.ts +9 -0
  47. package/dist/ticket-ai-review.controller.d.ts.map +1 -0
  48. package/dist/ticket-ai-review.controller.js +36 -0
  49. package/dist/ticket-ai-review.controller.js.map +1 -0
  50. package/dist/ticket-channel-accounts.controller.d.ts +24 -0
  51. package/dist/ticket-channel-accounts.controller.d.ts.map +1 -0
  52. package/dist/ticket-channel-accounts.controller.js +72 -0
  53. package/dist/ticket-channel-accounts.controller.js.map +1 -0
  54. package/dist/ticket-channels.controller.d.ts +21 -0
  55. package/dist/ticket-channels.controller.d.ts.map +1 -0
  56. package/dist/ticket-channels.controller.js +72 -0
  57. package/dist/ticket-channels.controller.js.map +1 -0
  58. package/dist/ticket-data.controller.d.ts +24 -0
  59. package/dist/ticket-data.controller.d.ts.map +1 -0
  60. package/dist/ticket-data.controller.js +81 -0
  61. package/dist/ticket-data.controller.js.map +1 -0
  62. package/dist/ticket-items.controller.d.ts +35 -0
  63. package/dist/ticket-items.controller.d.ts.map +1 -0
  64. package/dist/ticket-items.controller.js +100 -0
  65. package/dist/ticket-items.controller.js.map +1 -0
  66. package/dist/ticket-settings.controller.d.ts +11 -0
  67. package/dist/ticket-settings.controller.d.ts.map +1 -0
  68. package/dist/ticket-settings.controller.js +50 -0
  69. package/dist/ticket-settings.controller.js.map +1 -0
  70. package/dist/ticket.module.d.ts +3 -0
  71. package/dist/ticket.module.d.ts.map +1 -0
  72. package/dist/ticket.module.js +45 -0
  73. package/dist/ticket.module.js.map +1 -0
  74. package/dist/ticket.service.d.ts +88 -0
  75. package/dist/ticket.service.d.ts.map +1 -0
  76. package/dist/ticket.service.js +83 -0
  77. package/dist/ticket.service.js.map +1 -0
  78. package/hedhog/data/menu.yaml +164 -0
  79. package/hedhog/data/role.yaml +23 -0
  80. package/hedhog/data/route.yaml +225 -0
  81. package/hedhog/data/setting_group.yaml +574 -0
  82. package/hedhog/frontend/app/[id]/page.tsx.ejs +360 -0
  83. package/hedhog/frontend/app/_components/ai-draft-editor-dialog.tsx.ejs +67 -0
  84. package/hedhog/frontend/app/_components/ticket-badges.tsx.ejs +65 -0
  85. package/hedhog/frontend/app/_components/ticket-context-card.tsx.ejs +80 -0
  86. package/hedhog/frontend/app/_components/ticket-timeline.tsx.ejs +59 -0
  87. package/hedhog/frontend/app/_lib/mock-data.ts.ejs +474 -0
  88. package/hedhog/frontend/app/_lib/types.ts.ejs +134 -0
  89. package/hedhog/frontend/app/ai-review/page.tsx.ejs +205 -0
  90. package/hedhog/frontend/app/channel-accounts/page.tsx.ejs +476 -0
  91. package/hedhog/frontend/app/channels/page.tsx.ejs +406 -0
  92. package/hedhog/frontend/app/dashboard/page.tsx.ejs +178 -0
  93. package/hedhog/frontend/app/inbox/page.tsx.ejs +500 -0
  94. package/hedhog/frontend/app/page.tsx.ejs +5 -0
  95. package/hedhog/frontend/app/reports/page.tsx.ejs +151 -0
  96. package/hedhog/frontend/app/roles/page.tsx.ejs +110 -0
  97. package/hedhog/frontend/app/settings/page.tsx.ejs +484 -0
  98. package/hedhog/frontend/messages/en.json +412 -0
  99. package/hedhog/frontend/messages/pt.json +412 -0
  100. package/hedhog/table/channel.yaml +23 -0
  101. package/hedhog/table/channel_account.yaml +34 -0
  102. package/hedhog/table/ticket.yaml +73 -0
  103. package/hedhog/table/ticket_ai_draft.yaml +51 -0
  104. package/hedhog/table/ticket_attachment.yaml +40 -0
  105. package/hedhog/table/ticket_category.yaml +22 -0
  106. package/hedhog/table/ticket_context.yaml +64 -0
  107. package/hedhog/table/ticket_message.yaml +49 -0
  108. package/hedhog/table/ticket_message_source.yaml +50 -0
  109. package/hedhog/table/ticket_metadata.yaml +21 -0
  110. package/hedhog/table/ticket_participant.yaml +25 -0
  111. package/hedhog/table/ticket_source.yaml +43 -0
  112. package/hedhog/table/ticket_tag.yaml +22 -0
  113. package/package.json +40 -0
  114. package/src/dto/assign-ticket-owner.dto.ts +3 -0
  115. package/src/dto/create-ticket-channel-account.dto.ts +9 -0
  116. package/src/dto/create-ticket-channel.dto.ts +6 -0
  117. package/src/dto/create-ticket-internal-note.dto.ts +3 -0
  118. package/src/dto/create-ticket-reply.dto.ts +4 -0
  119. package/src/dto/update-ticket-channel-account.dto.ts +7 -0
  120. package/src/dto/update-ticket-channel.dto.ts +4 -0
  121. package/src/dto/update-ticket-priority.dto.ts +3 -0
  122. package/src/dto/update-ticket-settings.dto.ts +12 -0
  123. package/src/dto/update-ticket-status.dto.ts +3 -0
  124. package/src/index.ts +19 -0
  125. package/src/language/en.json +8 -0
  126. package/src/language/pt.json +8 -0
  127. package/src/ticket-ai-review.controller.ts +14 -0
  128. package/src/ticket-channel-accounts.controller.ts +34 -0
  129. package/src/ticket-channels.controller.ts +31 -0
  130. package/src/ticket-data.controller.ts +39 -0
  131. package/src/ticket-items.controller.ts +56 -0
  132. package/src/ticket-settings.controller.ts +20 -0
  133. package/src/ticket.module.ts +32 -0
  134. package/src/ticket.service.ts +102 -0
package/README.md ADDED
@@ -0,0 +1,480 @@
1
+ # Módulo Ticket (@hed-hog/ticket)
2
+
3
+ ## 1. Visão Geral do Módulo
4
+
5
+ O módulo Ticket centraliza as interações de suporte omnichannel para a plataforma Hcode. Ele oferece modelagem completa do banco de dados, interfaces administrativas estáticas e governança de acessos, canais e configurações. Atualmente, o backend possui apenas scaffolding e mocks, sem integrações reais ou lógica de negócio implementada.
6
+
7
+ ## 2. Escopo e Responsabilidades
8
+
9
+ - Gerenciamento de tickets de atendimento (criação, atualização, respostas, notas internas).
10
+ - Administração de canais e contas de canais de comunicação.
11
+ - Configuração de parâmetros globais e específicos para canais.
12
+ - Controle de acesso baseado em papéis (roles).
13
+ - Visualização de dashboards, filas de revisão AI, relatórios e matrizes de permissão.
14
+ - Suporte a metadados, tags, categorias e contexto dos tickets.
15
+
16
+ ## 3. Endpoints
17
+
18
+ ### Ticket Data Controller
19
+
20
+ | Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
21
+ |--------|----------------|--------------|----------------------------------|-------------------|---------------------------|-----------------------|
22
+ | GET | /ticket/dashboard | Sim (admin, admin-ticket, analyst-ticket) | Retorna dados do dashboard | - | `{ items: [] }` | 401 Unauthorized |
23
+ | GET | /ticket/inbox | Sim (admin, admin-ticket, operator-ticket, analyst-ticket) | Retorna a caixa de entrada | - | `{ items: [] }` | 401 Unauthorized |
24
+ | GET | /ticket/ai-review | Sim (admin, admin-ticket, operator-ticket) | Retorna fila de revisão AI | - | `{ items: [] }` | 401 Unauthorized |
25
+ | GET | /ticket/reports | Sim (admin, admin-ticket, analyst-ticket) | Retorna relatórios | - | `{ items: [] }` | 401 Unauthorized |
26
+ | GET | /ticket/roles | Sim (admin, admin-ticket) | Retorna matriz de papéis | - | `{ items: [] }` | 401 Unauthorized |
27
+ | GET | /ticket | Sim (admin, admin-ticket, operator-ticket, analyst-ticket) | Lista tickets | - | `{ items: [] }` | 401 Unauthorized |
28
+
29
+ ---
30
+
31
+ ### Ticket Items Controller
32
+
33
+ | Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
34
+ |--------|--------------------|--------------|----------------------------------|------------------------------------------------|---------------------------------|-----------------------|
35
+ | GET | /ticket/:id | Sim (admin, admin-ticket, operator-ticket, analyst-ticket) | Obtém ticket por ID | `id` (path) | `{ id: number }` | 401 Unauthorized, 404 Not Found |
36
+ | POST | /ticket/:id/reply | Sim (admin, admin-ticket, operator-ticket) | Cria resposta pública para ticket | `{ subject?: string, body?: string }` | `{ id, subject?, body? }` | 401 Unauthorized, 400 Bad Request |
37
+ | POST | /ticket/:id/internal-note | Sim (admin, admin-ticket, operator-ticket) | Cria nota interna para ticket | `{ body?: string }` | `{ id, body? }` | 401 Unauthorized, 400 Bad Request |
38
+ | PATCH | /ticket/:id/assign | Sim (admin, admin-ticket, operator-ticket) | Atribui proprietário ao ticket | `{ owner_person_id?: number }` | `{ id, owner_person_id? }` | 401 Unauthorized, 400 Bad Request |
39
+ | PATCH | /ticket/:id/status | Sim (admin, admin-ticket, operator-ticket) | Atualiza status do ticket | `{ status?: string }` | `{ id, status? }` | 401 Unauthorized, 400 Bad Request |
40
+ | PATCH | /ticket/:id/priority| Sim (admin, admin-ticket, operator-ticket) | Atualiza prioridade do ticket | `{ priority?: string }` | `{ id, priority? }` | 401 Unauthorized, 400 Bad Request |
41
+
42
+ ---
43
+
44
+ ### Ticket Channels Controller
45
+
46
+ | Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
47
+ |--------|--------------------|--------------|----------------------------------|------------------------------------------------|---------------------------------|-----------------------|
48
+ | GET | /ticket/channels | Sim (admin, admin-ticket) | Lista canais | - | `{ items: [] }` | 401 Unauthorized |
49
+ | POST | /ticket/channels | Sim (admin, admin-ticket) | Cria novo canal | `{ code?: string, name?: string, kind?: string, status?: string }` | Dados do canal criado | 401 Unauthorized, 400 Bad Request |
50
+ | PATCH | /ticket/channels/:id| Sim (admin, admin-ticket) | Atualiza canal existente | `id` (path), `{ name?: string, status?: string }` | Dados atualizados | 401 Unauthorized, 400 Bad Request, 404 Not Found |
51
+ | DELETE | /ticket/channels/:id| Sim (admin, admin-ticket) | Remove canal | `id` (path) | `{ id, deleted: true }` | 401 Unauthorized, 404 Not Found |
52
+
53
+ ---
54
+
55
+ ### Ticket Channel Accounts Controller
56
+
57
+ | Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
58
+ |--------|---------------------------|--------------|----------------------------------|----------------------------------------------------------------------------------|---------------------------------|-----------------------|
59
+ | GET | /ticket/channel-accounts | Sim (admin, admin-ticket) | Lista contas de canais | - | `{ items: [] }` | 401 Unauthorized |
60
+ | POST | /ticket/channel-accounts | Sim (admin, admin-ticket) | Cria conta de canal | `{ channel_id?: number, code?: string, name?: string, external_identifier?: string, status?: string, ai_enabled?: boolean, ai_model?: string }` | Dados da conta criada | 401 Unauthorized, 400 Bad Request |
61
+ | PATCH | /ticket/channel-accounts/:id | Sim (admin, admin-ticket) | Atualiza conta de canal | `id` (path), `{ name?: string, external_identifier?: string, status?: string, ai_enabled?: boolean, ai_model?: string }` | Dados atualizados | 401 Unauthorized, 400 Bad Request, 404 Not Found |
62
+ | DELETE | /ticket/channel-accounts/:id | Sim (admin, admin-ticket) | Remove conta de canal | `id` (path) | `{ id, deleted: true }` | 401 Unauthorized, 404 Not Found |
63
+
64
+ ---
65
+
66
+ ### Ticket Settings Controller
67
+
68
+ | Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
69
+ |--------|------------------|--------------|----------------------------------|----------------------------------------------------------------------------------|---------------------------------|-----------------------|
70
+ | GET | /ticket/settings | Sim (admin, admin-ticket) | Obtém configurações gerais | - | `{ items: [] }` | 401 Unauthorized |
71
+ | PATCH | /ticket/settings | Sim (admin, admin-ticket) | Atualiza configurações gerais | `{ enabled?: boolean, code_prefix?: string, default_ai_review_mode?: string, default_visibility?: string, auto_assign_enabled?: boolean, default_owner_person_id?: number, allow_public_reply?: boolean, allow_internal_notes?: boolean, default_reopen_on_customer_reply?: boolean, default_close_after_days_without_reply?: number }` | Dados atualizados | 401 Unauthorized, 400 Bad Request |
72
+
73
+ ---
74
+
75
+ ### Ticket AI Review Controller
76
+
77
+ | Método | Path | Autenticação | Descrição | Parâmetros / Body | Resposta | Erros Comuns |
78
+ |--------|----------------|--------------|----------------------------------|-------------------|---------------------------|-----------------------|
79
+ | GET | /ticket/ai-review | Sim (admin, admin-ticket, operator-ticket) | Retorna fila de revisão AI | - | `{ items: [] }` | 401 Unauthorized |
80
+
81
+ ---
82
+
83
+ ## 4. Regras de Autenticação e Autorização
84
+
85
+ - Todos os endpoints requerem autenticação.
86
+ - Papéis (roles) definidos para controle de acesso:
87
+ - **admin-ticket**: Administração completa, acesso a canais, configurações e governança.
88
+ - **operator-ticket**: Operação em tickets, respostas, notas internas, status e atribuições.
89
+ - **analyst-ticket**: Acesso somente leitura para visualização e relatórios.
90
+ - A matriz de permissões está disponível via endpoint `/ticket/roles` e na interface administrativa.
91
+
92
+ ## 5. Estruturas de Request/Response
93
+
94
+ ### DTOs principais
95
+
96
+ - **AssignTicketOwnerDto**
97
+ ```ts
98
+ {
99
+ owner_person_id?: number;
100
+ }
101
+ ```
102
+
103
+ - **CreateTicketChannelAccountDto**
104
+ ```ts
105
+ {
106
+ channel_id?: number;
107
+ code?: string;
108
+ name?: string;
109
+ external_identifier?: string;
110
+ status?: string;
111
+ ai_enabled?: boolean;
112
+ ai_model?: string;
113
+ }
114
+ ```
115
+
116
+ - **CreateTicketChannelDto**
117
+ ```ts
118
+ {
119
+ code?: string;
120
+ name?: string;
121
+ kind?: string;
122
+ status?: string;
123
+ }
124
+ ```
125
+
126
+ - **CreateTicketInternalNoteDto**
127
+ ```ts
128
+ {
129
+ body?: string;
130
+ }
131
+ ```
132
+
133
+ - **CreateTicketReplyDto**
134
+ ```ts
135
+ {
136
+ subject?: string;
137
+ body?: string;
138
+ }
139
+ ```
140
+
141
+ - **UpdateTicketChannelAccountDto**
142
+ ```ts
143
+ {
144
+ name?: string;
145
+ external_identifier?: string;
146
+ status?: string;
147
+ ai_enabled?: boolean;
148
+ ai_model?: string;
149
+ }
150
+ ```
151
+
152
+ - **UpdateTicketChannelDto**
153
+ ```ts
154
+ {
155
+ name?: string;
156
+ status?: string;
157
+ }
158
+ ```
159
+
160
+ - **UpdateTicketPriorityDto**
161
+ ```ts
162
+ {
163
+ priority?: string;
164
+ }
165
+ ```
166
+
167
+ - **UpdateTicketSettingsDto**
168
+ ```ts
169
+ {
170
+ enabled?: boolean;
171
+ code_prefix?: string;
172
+ default_ai_review_mode?: string;
173
+ default_visibility?: string;
174
+ auto_assign_enabled?: boolean;
175
+ default_owner_person_id?: number;
176
+ allow_public_reply?: boolean;
177
+ allow_internal_notes?: boolean;
178
+ default_reopen_on_customer_reply?: boolean;
179
+ default_close_after_days_without_reply?: number;
180
+ }
181
+ ```
182
+
183
+ - **UpdateTicketStatusDto**
184
+ ```ts
185
+ {
186
+ status?: string;
187
+ }
188
+ ```
189
+
190
+ ## 6. Erros Comuns
191
+
192
+ - **401 Unauthorized**: Usuário não autenticado ou sem permissão para o recurso.
193
+ - **400 Bad Request**: Dados inválidos ou incompletos no corpo da requisição.
194
+ - **404 Not Found**: Recurso (ticket, canal, conta) não encontrado para o ID informado.
195
+
196
+ ## 7. Banco de Dados (Tabelas YAML)
197
+
198
+ ### channel
199
+
200
+ - **Finalidade**: Define canais de comunicação (ex: portal, email, whatsapp).
201
+ - **Colunas**:
202
+ - `id` (PK)
203
+ - `code` (varchar 64, único)
204
+ - `name` (varchar 160)
205
+ - `kind` (enum: portal, marketplace, social, form, email, whatsapp, api, other)
206
+ - `status` (enum: active, inactive, default active)
207
+ - `created_at`, `updated_at`
208
+ - **Índices**: `code` (único), `kind`, `status`
209
+
210
+ ---
211
+
212
+ ### channel_account
213
+
214
+ - **Finalidade**: Contas específicas vinculadas a canais.
215
+ - **Colunas**:
216
+ - `id` (PK)
217
+ - `channel_id` (FK para channel.id, RESTRICT)
218
+ - `code` (varchar 80, único)
219
+ - `name` (varchar 180)
220
+ - `external_identifier` (varchar 255, nullable)
221
+ - `status` (enum: active, inactive, default active)
222
+ - `settings_json` (json, nullable)
223
+ - `created_at`, `updated_at`
224
+ - **Índices**: `code` (único), `channel_id`, `status`, `external_identifier`
225
+
226
+ ---
227
+
228
+ ### ticket
229
+
230
+ - **Finalidade**: Registro principal dos tickets de atendimento.
231
+ - **Colunas**:
232
+ - `id` (PK)
233
+ - `code` (varchar 40, único)
234
+ - `subject` (varchar 255)
235
+ - `status` (enum: open, pending, waiting_customer, resolved, closed, spam; default open)
236
+ - `priority` (enum: low, normal, high, urgent; default normal)
237
+ - `visibility` (enum: private, public; default private)
238
+ - `ai_review_mode` (enum: disabled, optional, required; default optional)
239
+ - `requester_person_id` (FK para person.id, nullable, SET NULL)
240
+ - `owner_person_id` (FK para person.id, nullable, SET NULL)
241
+ - Datas de mensagens e status (`first_message_at`, `last_message_at`, etc.)
242
+ - `created_at`, `updated_at`
243
+ - **Índices**: `code` (único), `status`, `priority`, `visibility`, `ai_review_mode`, `requester_person_id`, `owner_person_id`, combinações para performance
244
+
245
+ ---
246
+
247
+ ### ticket_ai_draft
248
+
249
+ - **Finalidade**: Rascunhos e revisões AI para respostas.
250
+ - **Colunas**:
251
+ - `id` (PK)
252
+ - `ticket_id` (FK para ticket.id, CASCADE)
253
+ - `ticket_message_id` (FK para ticket_message.id, nullable, SET NULL)
254
+ - `model_name` (varchar 120)
255
+ - `status` (enum: draft, pending_review, approved, rejected, sent; default draft)
256
+ - `suggestion_html`, `suggestion_text`, `feedback` (text, nullable)
257
+ - `reviewed_by_person_id` (FK para person.id, nullable, SET NULL)
258
+ - `reviewed_at` (datetime, nullable)
259
+ - `created_at`, `updated_at`
260
+ - **Índices**: `ticket_id`, `ticket_message_id`, `status`, `reviewed_by_person_id`, `created_at`
261
+
262
+ ---
263
+
264
+ ### ticket_attachment
265
+
266
+ - **Finalidade**: Anexos vinculados a mensagens de tickets.
267
+ - **Colunas**:
268
+ - `id` (PK)
269
+ - `ticket_message_id` (FK para ticket_message.id, CASCADE)
270
+ - `kind` (enum: image, file, link)
271
+ - `storage` (enum: upload, external_url)
272
+ - `file_name`, `mime_type`, `url` (varchar, nullable)
273
+ - `size_bytes` (int, nullable)
274
+ - `content` (text, nullable)
275
+ - `created_at`, `updated_at`
276
+ - **Índices**: `ticket_message_id`, `kind`, `storage`, `created_at`
277
+
278
+ ---
279
+
280
+ ### ticket_category
281
+
282
+ - **Finalidade**: Associação de tickets a categorias.
283
+ - **Colunas**:
284
+ - `id` (PK)
285
+ - `ticket_id` (FK para ticket.id, CASCADE)
286
+ - `category_id` (FK para category.id, CASCADE)
287
+ - `created_at`, `updated_at`
288
+ - **Índices**: combinação única `ticket_id, category_id`, índices individuais
289
+
290
+ ---
291
+
292
+ ### ticket_context
293
+
294
+ - **Finalidade**: Contexto externo relacionado ao ticket (curso, vídeo, página etc).
295
+ - **Colunas**:
296
+ - `id` (PK)
297
+ - `ticket_id` (FK para ticket.id, CASCADE, único)
298
+ - `channel_account_id` (FK para channel_account.id, nullable, SET NULL)
299
+ - `context_type` (enum: course_lesson, course, video, page, email_thread, whatsapp_chat, contact_form, other)
300
+ - Campos opcionais para nomes e URLs contextuais
301
+ - `created_at`, `updated_at`
302
+ - **Índices**: `ticket_id` (único), `channel_account_id`, `context_type`, campos de nome e label
303
+
304
+ ---
305
+
306
+ ### ticket_message
307
+
308
+ - **Finalidade**: Mensagens trocadas em tickets.
309
+ - **Colunas**:
310
+ - `id` (PK)
311
+ - `ticket_id` (FK para ticket.id, CASCADE)
312
+ - `author_person_id` (FK para person.id, nullable, SET NULL)
313
+ - `parent_message_id` (FK para ticket_message.id, nullable, SET NULL)
314
+ - `direction` (enum: inbound, outbound, internal, system)
315
+ - `audience` (enum: public, internal; default public)
316
+ - `body_html`, `body_text` (text, nullable)
317
+ - `source_created_at` (datetime, nullable)
318
+ - `created_at`, `updated_at`
319
+ - **Índices**: `ticket_id`, `author_person_id`, `parent_message_id`, `direction`, `audience`, `created_at`
320
+
321
+ ---
322
+
323
+ ### ticket_message_source
324
+
325
+ - **Finalidade**: Origem e status de entrega das mensagens.
326
+ - **Colunas**:
327
+ - `id` (PK)
328
+ - `ticket_message_id` (FK para ticket_message.id, CASCADE)
329
+ - `channel_account_id` (FK para channel_account.id, nullable, SET NULL)
330
+ - `provider_message_id`, `provider_thread_id` (varchar, nullable)
331
+ - `direction` (enum: inbound, outbound)
332
+ - `delivery_status` (enum: pending, sent, delivered, failed, received, read; default pending)
333
+ - `payload_json` (json, nullable)
334
+ - `sent_at`, `received_at` (datetime, nullable)
335
+ - `created_at`, `updated_at`
336
+ - **Índices**: `ticket_message_id`, `channel_account_id`, `provider_message_id`, `provider_thread_id`, `direction`, `delivery_status`, `created_at`
337
+
338
+ ---
339
+
340
+ ### ticket_metadata
341
+
342
+ - **Finalidade**: Metadados customizados para tickets.
343
+ - **Colunas**:
344
+ - `id` (PK)
345
+ - `ticket_id` (FK para ticket.id, CASCADE)
346
+ - `key` (varchar 120)
347
+ - `value` (text, nullable)
348
+ - `created_at`, `updated_at`
349
+ - **Índices**: `ticket_id`, `key`, combinação `ticket_id, key`
350
+
351
+ ---
352
+
353
+ ### ticket_participant
354
+
355
+ - **Finalidade**: Participantes associados a tickets com papéis.
356
+ - **Colunas**:
357
+ - `id` (PK)
358
+ - `ticket_id` (FK para ticket.id, CASCADE)
359
+ - `person_id` (FK para person.id, CASCADE)
360
+ - `role` (enum: requester, agent, collaborator, watcher)
361
+ - `created_at`, `updated_at`
362
+ - **Índices**: combinação única `ticket_id, person_id`, índices por `ticket_id, role` e `person_id, role`
363
+
364
+ ---
365
+
366
+ ### ticket_source
367
+
368
+ - **Finalidade**: Origem externa do ticket em contas de canal.
369
+ - **Colunas**:
370
+ - `id` (PK)
371
+ - `ticket_id` (FK para ticket.id, CASCADE)
372
+ - `channel_account_id` (FK para channel_account.id, nullable, SET NULL)
373
+ - `external_thread_id`, `external_message_id` (varchar, nullable)
374
+ - `external_url` (varchar 500, nullable)
375
+ - `status` (enum: active, archived, sync_error; default active)
376
+ - `metadata_json` (json, nullable)
377
+ - `created_at`, `updated_at`
378
+ - **Índices**: `ticket_id`, `channel_account_id`, `status`, `external_thread_id`, `external_message_id`
379
+
380
+ ---
381
+
382
+ ### ticket_tag
383
+
384
+ - **Finalidade**: Associação de tags a tickets.
385
+ - **Colunas**:
386
+ - `id` (PK)
387
+ - `ticket_id` (FK para ticket.id, CASCADE)
388
+ - `tag_id` (FK para tag.id, CASCADE)
389
+ - `created_at`, `updated_at`
390
+ - **Índices**: combinação única `ticket_id, tag_id`, índices individuais
391
+
392
+ ## 8. Regras de Negócio Relevantes
393
+
394
+ - Tickets possuem status, prioridade e visibilidade configuráveis.
395
+ - Tickets podem ser atribuídos a um proprietário (owner_person_id).
396
+ - Mensagens podem ser públicas ou internas, com direções inbound/outbound.
397
+ - Canais e contas de canais possuem status ativo/inativo para controle.
398
+ - Revisões AI são gerenciadas via rascunhos com status e feedback.
399
+ - Configurações globais e específicas por canal são armazenadas e gerenciadas.
400
+ - Papéis definem níveis de acesso e permissões para operações no módulo.
401
+
402
+ ## 9. Guia Rápido de Uso (Exemplos)
403
+
404
+ ### Listar tickets (GET /ticket)
405
+
406
+ ```bash
407
+ curl -H "Authorization: Bearer <token>" https://api.seudominio.com/ticket
408
+ ```
409
+
410
+ Resposta:
411
+
412
+ ```json
413
+ {
414
+ "items": []
415
+ }
416
+ ```
417
+
418
+ ---
419
+
420
+ ### Criar canal (POST /ticket/channels)
421
+
422
+ ```bash
423
+ curl -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
424
+ -d '{"code":"email","name":"Email","kind":"email","status":"active"}' \
425
+ https://api.seudominio.com/ticket/channels
426
+ ```
427
+
428
+ Resposta:
429
+
430
+ ```json
431
+ {
432
+ "code": "email",
433
+ "name": "Email",
434
+ "kind": "email",
435
+ "status": "active"
436
+ }
437
+ ```
438
+
439
+ ---
440
+
441
+ ### Atualizar status do ticket (PATCH /ticket/:id/status)
442
+
443
+ ```bash
444
+ curl -X PATCH -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
445
+ -d '{"status":"resolved"}' \
446
+ https://api.seudominio.com/ticket/123/status
447
+ ```
448
+
449
+ Resposta:
450
+
451
+ ```json
452
+ {
453
+ "id": 123,
454
+ "status": "resolved"
455
+ }
456
+ ```
457
+
458
+ ---
459
+
460
+ ### Criar resposta pública (POST /ticket/:id/reply)
461
+
462
+ ```bash
463
+ curl -X POST -H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
464
+ -d '{"subject":"Re: Dúvida","body":"Olá, sua dúvida foi resolvida."}' \
465
+ https://api.seudominio.com/ticket/123/reply
466
+ ```
467
+
468
+ Resposta:
469
+
470
+ ```json
471
+ {
472
+ "id": 123,
473
+ "subject": "Re: Dúvida",
474
+ "body": "Olá, sua dúvida foi resolvida."
475
+ }
476
+ ```
477
+
478
+ ---
479
+
480
+ Este módulo é parte integrante do monorepo HedHog e segue as políticas de governança, roles e configurações definidas para o ecossistema.
@@ -0,0 +1,4 @@
1
+ export declare class AssignTicketOwnerDto {
2
+ owner_person_id?: number;
3
+ }
4
+ //# sourceMappingURL=assign-ticket-owner.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assign-ticket-owner.dto.d.ts","sourceRoot":"","sources":["../../src/dto/assign-ticket-owner.dto.ts"],"names":[],"mappings":"AAAA,qBAAa,oBAAoB;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AssignTicketOwnerDto = void 0;
4
+ class AssignTicketOwnerDto {
5
+ }
6
+ exports.AssignTicketOwnerDto = AssignTicketOwnerDto;
7
+ //# sourceMappingURL=assign-ticket-owner.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assign-ticket-owner.dto.js","sourceRoot":"","sources":["../../src/dto/assign-ticket-owner.dto.ts"],"names":[],"mappings":";;;AAAA,MAAa,oBAAoB;CAEhC;AAFD,oDAEC"}
@@ -0,0 +1,10 @@
1
+ export declare class CreateTicketChannelAccountDto {
2
+ channel_id?: number;
3
+ code?: string;
4
+ name?: string;
5
+ external_identifier?: string;
6
+ status?: string;
7
+ ai_enabled?: boolean;
8
+ ai_model?: string;
9
+ }
10
+ //# sourceMappingURL=create-ticket-channel-account.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ticket-channel-account.dto.d.ts","sourceRoot":"","sources":["../../src/dto/create-ticket-channel-account.dto.ts"],"names":[],"mappings":"AAAA,qBAAa,6BAA6B;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreateTicketChannelAccountDto = void 0;
4
+ class CreateTicketChannelAccountDto {
5
+ }
6
+ exports.CreateTicketChannelAccountDto = CreateTicketChannelAccountDto;
7
+ //# sourceMappingURL=create-ticket-channel-account.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ticket-channel-account.dto.js","sourceRoot":"","sources":["../../src/dto/create-ticket-channel-account.dto.ts"],"names":[],"mappings":";;;AAAA,MAAa,6BAA6B;CAQzC;AARD,sEAQC"}
@@ -0,0 +1,7 @@
1
+ export declare class CreateTicketChannelDto {
2
+ code?: string;
3
+ name?: string;
4
+ kind?: string;
5
+ status?: string;
6
+ }
7
+ //# sourceMappingURL=create-ticket-channel.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ticket-channel.dto.d.ts","sourceRoot":"","sources":["../../src/dto/create-ticket-channel.dto.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAsB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreateTicketChannelDto = void 0;
4
+ class CreateTicketChannelDto {
5
+ }
6
+ exports.CreateTicketChannelDto = CreateTicketChannelDto;
7
+ //# sourceMappingURL=create-ticket-channel.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ticket-channel.dto.js","sourceRoot":"","sources":["../../src/dto/create-ticket-channel.dto.ts"],"names":[],"mappings":";;;AAAA,MAAa,sBAAsB;CAKlC;AALD,wDAKC"}
@@ -0,0 +1,4 @@
1
+ export declare class CreateTicketInternalNoteDto {
2
+ body?: string;
3
+ }
4
+ //# sourceMappingURL=create-ticket-internal-note.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ticket-internal-note.dto.d.ts","sourceRoot":"","sources":["../../src/dto/create-ticket-internal-note.dto.ts"],"names":[],"mappings":"AAAA,qBAAa,2BAA2B;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreateTicketInternalNoteDto = void 0;
4
+ class CreateTicketInternalNoteDto {
5
+ }
6
+ exports.CreateTicketInternalNoteDto = CreateTicketInternalNoteDto;
7
+ //# sourceMappingURL=create-ticket-internal-note.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ticket-internal-note.dto.js","sourceRoot":"","sources":["../../src/dto/create-ticket-internal-note.dto.ts"],"names":[],"mappings":";;;AAAA,MAAa,2BAA2B;CAEvC;AAFD,kEAEC"}
@@ -0,0 +1,5 @@
1
+ export declare class CreateTicketReplyDto {
2
+ subject?: string;
3
+ body?: string;
4
+ }
5
+ //# sourceMappingURL=create-ticket-reply.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ticket-reply.dto.d.ts","sourceRoot":"","sources":["../../src/dto/create-ticket-reply.dto.ts"],"names":[],"mappings":"AAAA,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CreateTicketReplyDto = void 0;
4
+ class CreateTicketReplyDto {
5
+ }
6
+ exports.CreateTicketReplyDto = CreateTicketReplyDto;
7
+ //# sourceMappingURL=create-ticket-reply.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-ticket-reply.dto.js","sourceRoot":"","sources":["../../src/dto/create-ticket-reply.dto.ts"],"names":[],"mappings":";;;AAAA,MAAa,oBAAoB;CAGhC;AAHD,oDAGC"}
@@ -0,0 +1,8 @@
1
+ export declare class UpdateTicketChannelAccountDto {
2
+ name?: string;
3
+ external_identifier?: string;
4
+ status?: string;
5
+ ai_enabled?: boolean;
6
+ ai_model?: string;
7
+ }
8
+ //# sourceMappingURL=update-ticket-channel-account.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-ticket-channel-account.dto.d.ts","sourceRoot":"","sources":["../../src/dto/update-ticket-channel-account.dto.ts"],"names":[],"mappings":"AAAA,qBAAa,6BAA6B;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UpdateTicketChannelAccountDto = void 0;
4
+ class UpdateTicketChannelAccountDto {
5
+ }
6
+ exports.UpdateTicketChannelAccountDto = UpdateTicketChannelAccountDto;
7
+ //# sourceMappingURL=update-ticket-channel-account.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-ticket-channel-account.dto.js","sourceRoot":"","sources":["../../src/dto/update-ticket-channel-account.dto.ts"],"names":[],"mappings":";;;AAAA,MAAa,6BAA6B;CAMzC;AAND,sEAMC"}
@@ -0,0 +1,5 @@
1
+ export declare class UpdateTicketChannelDto {
2
+ name?: string;
3
+ status?: string;
4
+ }
5
+ //# sourceMappingURL=update-ticket-channel.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-ticket-channel.dto.d.ts","sourceRoot":"","sources":["../../src/dto/update-ticket-channel.dto.ts"],"names":[],"mappings":"AAAA,qBAAa,sBAAsB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UpdateTicketChannelDto = void 0;
4
+ class UpdateTicketChannelDto {
5
+ }
6
+ exports.UpdateTicketChannelDto = UpdateTicketChannelDto;
7
+ //# sourceMappingURL=update-ticket-channel.dto.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-ticket-channel.dto.js","sourceRoot":"","sources":["../../src/dto/update-ticket-channel.dto.ts"],"names":[],"mappings":";;;AAAA,MAAa,sBAAsB;CAGlC;AAHD,wDAGC"}
@@ -0,0 +1,4 @@
1
+ export declare class UpdateTicketPriorityDto {
2
+ priority?: string;
3
+ }
4
+ //# sourceMappingURL=update-ticket-priority.dto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-ticket-priority.dto.d.ts","sourceRoot":"","sources":["../../src/dto/update-ticket-priority.dto.ts"],"names":[],"mappings":"AAAA,qBAAa,uBAAuB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}