@hed-hog/tag 0.0.270 → 0.0.273
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 +342 -0
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
# @hed-hog/tag
|
|
2
|
+
|
|
3
|
+
## 1. Visão geral do módulo
|
|
4
|
+
|
|
5
|
+
O módulo `@hed-hog/tag` é responsável pela gestão de tags dentro do ecossistema HedHog. Ele oferece funcionalidades para criação, leitura, atualização, exclusão e estatísticas de tags, que são identificadas por um slug único, possuem uma cor e um status (ativo ou inativo). O módulo é construído com NestJS e utiliza Prisma para acesso ao banco de dados.
|
|
6
|
+
|
|
7
|
+
## 2. Escopo e responsabilidades
|
|
8
|
+
|
|
9
|
+
- Gerenciar tags com atributos: slug, cor e status.
|
|
10
|
+
- Fornecer endpoints para CRUD (Create, Read, Update, Delete) de tags.
|
|
11
|
+
- Permitir paginação e busca simples por slug.
|
|
12
|
+
- Disponibilizar estatísticas básicas sobre as tags (total, ativas, inativas).
|
|
13
|
+
- Garantir validação e integridade dos dados.
|
|
14
|
+
- Controlar acesso via roles específicas.
|
|
15
|
+
|
|
16
|
+
## 3. Endpoints
|
|
17
|
+
|
|
18
|
+
### Listar tags
|
|
19
|
+
|
|
20
|
+
- **Método:** GET
|
|
21
|
+
- **Path:** `/tag`
|
|
22
|
+
- **Autenticação:** Requer role `admin` ou `admin-tag`
|
|
23
|
+
- **Descrição:** Retorna uma lista paginada de tags, com opção de busca por slug.
|
|
24
|
+
- **Query Parameters:**
|
|
25
|
+
- `skip` (number): quantidade de registros a pular (para paginação)
|
|
26
|
+
- `take` (number): quantidade de registros a retornar
|
|
27
|
+
- `search` (string, opcional): termo para busca parcial no slug
|
|
28
|
+
- **Resposta:**
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"data": [ { "id": number, "slug": string, "color": string, "status": "active"|"inactive", "created_at": string, "updated_at": string }, ... ],
|
|
32
|
+
"total": number,
|
|
33
|
+
"page": number,
|
|
34
|
+
"pageSize": number,
|
|
35
|
+
"prev": number|null,
|
|
36
|
+
"next": number|null,
|
|
37
|
+
"lastPage": number
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
- **Erros:**
|
|
41
|
+
- 401 Unauthorized (se não autenticado ou sem permissão)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### Obter estatísticas de tags
|
|
46
|
+
|
|
47
|
+
- **Método:** GET
|
|
48
|
+
- **Path:** `/tag/stats`
|
|
49
|
+
- **Autenticação:** Requer role `admin` ou `admin-tag`
|
|
50
|
+
- **Descrição:** Retorna contagem total de tags, tags ativas e inativas.
|
|
51
|
+
- **Resposta:**
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"total": number,
|
|
55
|
+
"active": number,
|
|
56
|
+
"inactive": number
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
- **Erros:**
|
|
60
|
+
- 401 Unauthorized
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
### Obter tag por ID
|
|
65
|
+
|
|
66
|
+
- **Método:** GET
|
|
67
|
+
- **Path:** `/tag/:id`
|
|
68
|
+
- **Autenticação:** Requer role `admin` ou `admin-tag`
|
|
69
|
+
- **Descrição:** Retorna os dados da tag identificada pelo ID.
|
|
70
|
+
- **Parâmetros:**
|
|
71
|
+
- `id` (number): ID da tag
|
|
72
|
+
- **Resposta:**
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"id": number,
|
|
76
|
+
"slug": string,
|
|
77
|
+
"color": string,
|
|
78
|
+
"status": "active"|"inactive",
|
|
79
|
+
"created_at": string,
|
|
80
|
+
"updated_at": string
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
- **Erros:**
|
|
84
|
+
- 400 Bad Request: Tag não encontrada
|
|
85
|
+
- 401 Unauthorized
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### Criar nova tag
|
|
90
|
+
|
|
91
|
+
- **Método:** POST
|
|
92
|
+
- **Path:** `/tag`
|
|
93
|
+
- **Autenticação:** Requer role `admin` ou `admin-tag`
|
|
94
|
+
- **Descrição:** Cria uma nova tag com os dados fornecidos.
|
|
95
|
+
- **Body:**
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"slug": "string",
|
|
99
|
+
"color": "#RRGGBB ou #RGB",
|
|
100
|
+
"status": "active"|"inactive" (opcional, padrão "active")
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
- **Resposta:**
|
|
104
|
+
Objeto da tag criada com todos os campos preenchidos.
|
|
105
|
+
- **Erros:**
|
|
106
|
+
- 400 Bad Request: Formato inválido de cor ou dados inválidos
|
|
107
|
+
- 401 Unauthorized
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### Atualizar tag existente
|
|
112
|
+
|
|
113
|
+
- **Método:** PATCH
|
|
114
|
+
- **Path:** `/tag/:id`
|
|
115
|
+
- **Autenticação:** Requer role `admin` ou `admin-tag`
|
|
116
|
+
- **Descrição:** Atualiza parcialmente os dados da tag identificada pelo ID.
|
|
117
|
+
- **Parâmetros:**
|
|
118
|
+
- `id` (number): ID da tag
|
|
119
|
+
- **Body:**
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"slug"?: "string",
|
|
123
|
+
"color"?: "#RRGGBB ou #RGB",
|
|
124
|
+
"status"?: "active"|"inactive"
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
- **Resposta:**
|
|
128
|
+
Objeto da tag atualizado.
|
|
129
|
+
- **Erros:**
|
|
130
|
+
- 400 Bad Request: Tag não encontrada ou dados inválidos
|
|
131
|
+
- 401 Unauthorized
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
### Deletar tag
|
|
136
|
+
|
|
137
|
+
- **Método:** DELETE
|
|
138
|
+
- **Path:** `/tag/:id`
|
|
139
|
+
- **Autenticação:** Requer role `admin` ou `admin-tag`
|
|
140
|
+
- **Descrição:** Remove a tag identificada pelo ID.
|
|
141
|
+
- **Parâmetros:**
|
|
142
|
+
- `id` (number): ID da tag
|
|
143
|
+
- **Resposta:**
|
|
144
|
+
Objeto da tag deletada.
|
|
145
|
+
- **Erros:**
|
|
146
|
+
- 400 Bad Request: Tag não encontrada
|
|
147
|
+
- 401 Unauthorized
|
|
148
|
+
|
|
149
|
+
## 4. Regras de autenticação e autorização
|
|
150
|
+
|
|
151
|
+
- Todos os endpoints requerem autenticação.
|
|
152
|
+
- Acesso restrito a usuários com roles `admin` ou `admin-tag`.
|
|
153
|
+
- Roles definidas no sistema HedHog:
|
|
154
|
+
- `admin-tag`: Administrador com acesso total à gestão de tags.
|
|
155
|
+
|
|
156
|
+
## 5. Estruturas de request/response
|
|
157
|
+
|
|
158
|
+
### TagDTO (Request Body para criação e atualização)
|
|
159
|
+
|
|
160
|
+
| Campo | Tipo | Obrigatório | Descrição |
|
|
161
|
+
|--------|----------------------|-------------|----------------------------------|
|
|
162
|
+
| slug | string | Sim | Identificador único da tag |
|
|
163
|
+
| color | string (hexadecimal) | Sim | Cor da tag no formato #RGB ou #RRGGBB |
|
|
164
|
+
| status | enum (`active`, `inactive`) | Não (default `active`) | Status da tag |
|
|
165
|
+
|
|
166
|
+
### Resposta de tag
|
|
167
|
+
|
|
168
|
+
| Campo | Tipo | Descrição |
|
|
169
|
+
|------------|----------------------|----------------------------------|
|
|
170
|
+
| id | number | Identificador único da tag |
|
|
171
|
+
| slug | string | Identificador único da tag |
|
|
172
|
+
| color | string | Cor da tag |
|
|
173
|
+
| status | enum (`active`, `inactive`) | Status da tag |
|
|
174
|
+
| created_at | string (timestamp) | Data de criação |
|
|
175
|
+
| updated_at | string (timestamp) | Data da última atualização |
|
|
176
|
+
|
|
177
|
+
## 6. Erros comuns
|
|
178
|
+
|
|
179
|
+
| Código | Mensagem | Causa provável |
|
|
180
|
+
|--------|---------------------------------|---------------------------------------------|
|
|
181
|
+
| 400 | Tag not found | ID informado não corresponde a nenhuma tag |
|
|
182
|
+
| 400 | Invalid color format | Cor informada não está no formato hexadecimal válido (#RGB ou #RRGGBB) |
|
|
183
|
+
| 401 | Unauthorized | Usuário não autenticado ou sem permissão |
|
|
184
|
+
| 422 | Validation errors (ex: slug must be string) | Dados enviados não passaram na validação do DTO |
|
|
185
|
+
|
|
186
|
+
## 7. Banco de dados (tabelas YAML)
|
|
187
|
+
|
|
188
|
+
### Tabela `tag`
|
|
189
|
+
|
|
190
|
+
- **Finalidade:** Armazenar tags com slug, cor e status para categorização e marcação de conteúdos.
|
|
191
|
+
- **Colunas:**
|
|
192
|
+
|
|
193
|
+
| Nome | Tipo | Nullable | Default | Descrição |
|
|
194
|
+
|------------|---------------|----------|----------|--------------------------------|
|
|
195
|
+
| id | Primary Key | Não | - | Identificador único da tag |
|
|
196
|
+
| slug | Slug (string) | Não | - | Identificador textual único |
|
|
197
|
+
| color | string | Não | - | Cor da tag em formato hexadecimal (#RGB ou #RRGGBB) |
|
|
198
|
+
| status | enum | Sim | active | Status da tag: `active` ou `inactive` |
|
|
199
|
+
| created_at | timestamp | Não | - | Data de criação |
|
|
200
|
+
| updated_at | timestamp | Não | - | Data da última atualização |
|
|
201
|
+
|
|
202
|
+
- **Integridade:**
|
|
203
|
+
- `slug` deve ser único (imposto pelo tipo slug).
|
|
204
|
+
- `status` é enum com valores permitidos `active` e `inactive`.
|
|
205
|
+
- **Índices:**
|
|
206
|
+
- Índice primário em `id`.
|
|
207
|
+
- **Enums:**
|
|
208
|
+
- `status`: `active`, `inactive`.
|
|
209
|
+
|
|
210
|
+
## 8. Regras de negócio relevantes
|
|
211
|
+
|
|
212
|
+
- O campo `color` deve estar no formato hexadecimal válido, aceitando tanto 3 dígitos (#RGB) quanto 6 dígitos (#RRGGBB). Caso contrário, retorna erro 400.
|
|
213
|
+
- O campo `status` é opcional na criação e atualização, assumindo `active` como padrão.
|
|
214
|
+
- A busca na listagem é feita por correspondência parcial e case-insensitive no campo `slug`.
|
|
215
|
+
- Exclusão, atualização e consulta por ID retornam erro 400 caso a tag não exista.
|
|
216
|
+
- Paginação é suportada via parâmetros `skip` e `take`, com informações de página atual, anterior, próxima e última página retornadas.
|
|
217
|
+
|
|
218
|
+
## 9. Guia rápido de uso (exemplos)
|
|
219
|
+
|
|
220
|
+
### Listar tags com paginação e busca
|
|
221
|
+
|
|
222
|
+
```http
|
|
223
|
+
GET /tag?skip=0&take=10&search=tech
|
|
224
|
+
Authorization: Bearer <token>
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Resposta:
|
|
228
|
+
|
|
229
|
+
```json
|
|
230
|
+
{
|
|
231
|
+
"data": [
|
|
232
|
+
{ "id": 1, "slug": "technology", "color": "#ff0000", "status": "active", "created_at": "...", "updated_at": "..." }
|
|
233
|
+
],
|
|
234
|
+
"total": 1,
|
|
235
|
+
"page": 1,
|
|
236
|
+
"pageSize": 10,
|
|
237
|
+
"prev": null,
|
|
238
|
+
"next": null,
|
|
239
|
+
"lastPage": 1
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
### Criar uma nova tag
|
|
246
|
+
|
|
247
|
+
```http
|
|
248
|
+
POST /tag
|
|
249
|
+
Authorization: Bearer <token>
|
|
250
|
+
Content-Type: application/json
|
|
251
|
+
|
|
252
|
+
{
|
|
253
|
+
"slug": "news",
|
|
254
|
+
"color": "#00ff00",
|
|
255
|
+
"status": "active"
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Resposta:
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"id": 2,
|
|
264
|
+
"slug": "news",
|
|
265
|
+
"color": "#00ff00",
|
|
266
|
+
"status": "active",
|
|
267
|
+
"created_at": "...",
|
|
268
|
+
"updated_at": "..."
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
### Atualizar uma tag
|
|
275
|
+
|
|
276
|
+
```http
|
|
277
|
+
PATCH /tag/2
|
|
278
|
+
Authorization: Bearer <token>
|
|
279
|
+
Content-Type: application/json
|
|
280
|
+
|
|
281
|
+
{
|
|
282
|
+
"color": "#0000ff"
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Resposta:
|
|
287
|
+
|
|
288
|
+
```json
|
|
289
|
+
{
|
|
290
|
+
"id": 2,
|
|
291
|
+
"slug": "news",
|
|
292
|
+
"color": "#0000ff",
|
|
293
|
+
"status": "active",
|
|
294
|
+
"created_at": "...",
|
|
295
|
+
"updated_at": "..."
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
### Deletar uma tag
|
|
302
|
+
|
|
303
|
+
```http
|
|
304
|
+
DELETE /tag/2
|
|
305
|
+
Authorization: Bearer <token>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Resposta:
|
|
309
|
+
|
|
310
|
+
```json
|
|
311
|
+
{
|
|
312
|
+
"id": 2,
|
|
313
|
+
"slug": "news",
|
|
314
|
+
"color": "#0000ff",
|
|
315
|
+
"status": "active",
|
|
316
|
+
"created_at": "...",
|
|
317
|
+
"updated_at": "..."
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
### Obter estatísticas de tags
|
|
324
|
+
|
|
325
|
+
```http
|
|
326
|
+
GET /tag/stats
|
|
327
|
+
Authorization: Bearer <token>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
Resposta:
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"total": 10,
|
|
335
|
+
"active": 8,
|
|
336
|
+
"inactive": 2
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
Este módulo é parte integrante do monorepo HedHog e deve ser utilizado conforme as regras de autenticação e autorização definidas.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/tag",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.273",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
12
|
"@hed-hog/api-prisma": "0.0.5",
|
|
13
13
|
"@hed-hog/api-pagination": "0.0.6",
|
|
14
|
-
"@hed-hog/core": "0.0.
|
|
15
|
-
"@hed-hog/api": "0.0.
|
|
16
|
-
"@hed-hog/api
|
|
14
|
+
"@hed-hog/core": "0.0.273",
|
|
15
|
+
"@hed-hog/api-locale": "0.0.13",
|
|
16
|
+
"@hed-hog/api": "0.0.4"
|
|
17
17
|
},
|
|
18
18
|
"exports": {
|
|
19
19
|
".": {
|