specifica-br 1.2.2 → 1.5.0
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 +114 -44
- package/dist/boilerplate/commands/executar-task.md +133 -0
- package/dist/boilerplate/commands/gerar-contexto.md +1462 -0
- package/dist/boilerplate/commands/gerar-prd.md +289 -0
- package/dist/boilerplate/commands/gerar-tasks.md +168 -0
- package/dist/boilerplate/commands/gerar-techspec.md +1467 -0
- package/dist/boilerplate/commands/gerar-visao.md +731 -0
- package/dist/boilerplate/commands/realizar-codereview.md +288 -0
- package/dist/boilerplate/opencode-commands/executar-task.md +55 -48
- package/dist/boilerplate/opencode-commands/gerar-contexto.md +1462 -0
- package/dist/boilerplate/opencode-commands/gerar-prd.md +232 -40
- package/dist/boilerplate/opencode-commands/gerar-tasks.md +112 -31
- package/dist/boilerplate/opencode-commands/gerar-techspec.md +1464 -80
- package/dist/boilerplate/opencode-commands/gerar-visao.md +731 -0
- package/dist/boilerplate/opencode-commands/realizar-codereview.md +288 -0
- package/dist/boilerplate/skills/product-manager/SKILL.md +32 -0
- package/dist/boilerplate/skills/techspec-generator/SKILL.md +489 -0
- package/dist/boilerplate/skills/techspec-generator/references/api-contracts.md +421 -0
- package/dist/boilerplate/skills/techspec-generator/references/architecture-patterns.md +316 -0
- package/dist/boilerplate/skills/techspec-generator/references/database-modeling.md +436 -0
- package/dist/boilerplate/skills/techspec-generator/references/observability-testing.md +436 -0
- package/dist/boilerplate/skills/techspec-generator/references/security-hardening.md +238 -0
- package/dist/boilerplate/skills/techspec-generator/references/ux-ui-accessibility.md +511 -0
- package/dist/boilerplate/specs-templates/architecture-template.md +736 -0
- package/dist/boilerplate/specs-templates/codereview-template.md +95 -0
- package/dist/boilerplate/specs-templates/prd-template.md +101 -19
- package/dist/boilerplate/specs-templates/product_vision-template.md +284 -0
- package/dist/boilerplate/specs-templates/task-template.md +64 -18
- package/dist/boilerplate/specs-templates/tasks-template.md +12 -4
- package/dist/boilerplate/specs-templates/techspec-template.md +1227 -89
- package/dist/boilerplate/templates/architecture-template.md +736 -0
- package/dist/boilerplate/templates/codereview-template.md +95 -0
- package/dist/boilerplate/templates/prd-template.md +167 -0
- package/dist/boilerplate/templates/product_vision-template.md +284 -0
- package/dist/boilerplate/templates/task-template.md +169 -0
- package/dist/boilerplate/templates/tasks-template.md +15 -0
- package/dist/boilerplate/templates/techspec-template.md +1306 -0
- package/dist/commands/help.js +33 -11
- package/dist/commands/init.js +39 -43
- package/dist/tools-mapping.json +32 -0
- package/dist/types/init.d.ts +14 -17
- package/dist/utils/file-service.d.ts +5 -3
- package/dist/utils/file-service.js +168 -56
- package/dist/utils/message-formatter.d.ts +2 -1
- package/dist/utils/message-formatter.js +39 -22
- package/package.json +1 -1
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# Design de APIs e Contratos
|
|
2
|
+
|
|
3
|
+
Referência técnica para design de APIs ao gerar Tech Specs.
|
|
4
|
+
|
|
5
|
+
## Sumário
|
|
6
|
+
|
|
7
|
+
1. [Princípios de API Design](#1-principios-de-api-design)
|
|
8
|
+
2. [RESTful Design](#2-restful-design)
|
|
9
|
+
3. [Versionamento](#3-versionamento)
|
|
10
|
+
4. [Paginação, Filtros e Ordenação](#4-paginacao-filtros-e-ordenacao)
|
|
11
|
+
5. [Error Design](#5-error-design)
|
|
12
|
+
6. [Idempotência](#6-idempotencia)
|
|
13
|
+
7. [Rate Limiting](#7-rate-limiting)
|
|
14
|
+
8. [Contrato Completo](#8-contrato-completo)
|
|
15
|
+
9. [Webhooks](#9-webhooks)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. Princípios de API Design
|
|
20
|
+
|
|
21
|
+
### 1.1. Regras Fundamentais
|
|
22
|
+
|
|
23
|
+
- **Consistência:** Seguir padrão existente no projeto (verificar endpoints atuais)
|
|
24
|
+
- **Especificidade:** Cada endpoint faz UMA coisa bem definida
|
|
25
|
+
- **Expliciticidade:** Nomes de recursos no plural, ações claras
|
|
26
|
+
- **Versionamento:** Sempre versionar (pelo menos `/api/v1/`)
|
|
27
|
+
|
|
28
|
+
### 1.2. Nomenclatura de Recursos
|
|
29
|
+
|
|
30
|
+
| Padrão | Exemplo | Quando |
|
|
31
|
+
|:---|:---|:---|
|
|
32
|
+
| Substantivo plural | `/api/v1/orders` | Recursos |
|
|
33
|
+
| Nested resource | `/api/v1/orders/{id}/items` | Recursos filhos |
|
|
34
|
+
| Ação (verbo) | `/api/v1/orders/{id}/cancel` | Ações não-CRUD |
|
|
35
|
+
| Query param | `/api/v1/orders?status=pending` | Filtros |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 2. RESTful Design
|
|
40
|
+
|
|
41
|
+
### 2.1. Mapeamento CRUD
|
|
42
|
+
|
|
43
|
+
| Operação | Método | Rota | Status Code |
|
|
44
|
+
|:---|:---|:---|:---|
|
|
45
|
+
| Listar | GET | `/api/v1/orders` | 200 |
|
|
46
|
+
| Buscar por ID | GET | `/api/v1/orders/{id}` | 200 / 404 |
|
|
47
|
+
| Criar | POST | `/api/v1/orders` | 201 |
|
|
48
|
+
| Atualizar total | PUT | `/api/v1/orders/{id}` | 200 |
|
|
49
|
+
| Atualizar parcial | PATCH | `/api/v1/orders/{id}` | 200 |
|
|
50
|
+
| Deletar | DELETE | `/api/v1/orders/{id}` | 204 |
|
|
51
|
+
| Ação | POST | `/api/v1/orders/{id}/cancel` | 200 |
|
|
52
|
+
|
|
53
|
+
### 2.2. Status Codes Essenciais
|
|
54
|
+
|
|
55
|
+
| Code | Significado | Quando usar |
|
|
56
|
+
|:---|:---|:---|
|
|
57
|
+
| **200** | OK | GET, PUT, PATCH, DELETE sucesso |
|
|
58
|
+
| **201** | Created | POST com sucesso (recurso criado) |
|
|
59
|
+
| **204** | No Content | DELETE sucesso (sem body de resposta) |
|
|
60
|
+
| **400** | Bad Request | Validação de input falhou |
|
|
61
|
+
| **401** | Unauthorized | Token ausente ou inválido |
|
|
62
|
+
| **403** | Forbidden | Sem permissão para esta ação |
|
|
63
|
+
| **404** | Not Found | Recurso não encontrado |
|
|
64
|
+
| **409** | Conflict | Conflito de estado (ex: já processado) |
|
|
65
|
+
| **422** | Unprocessable Entity | Regra de negócio violada |
|
|
66
|
+
| **429** | Too Many Requests | Rate limit excedido |
|
|
67
|
+
| **500** | Internal Server Error | Erro inesperado no servidor |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 3. Versionamento
|
|
72
|
+
|
|
73
|
+
### 3.1. Estratégias
|
|
74
|
+
|
|
75
|
+
| Estratégia | Exemplo | Recomendação |
|
|
76
|
+
|:---|:---|:---|
|
|
77
|
+
| **URI Path** | `/api/v1/orders` | Mais comum, explícito |
|
|
78
|
+
| **Header** | `Accept: application/vnd.api.v1+json` | Para APIs avançadas |
|
|
79
|
+
| **Query Param** | `/api/orders?version=1` | Evitar (cache issues) |
|
|
80
|
+
|
|
81
|
+
**Na TechSpec, sempre especificar:** `GET /api/v1/orders` (URI Path é o padrão)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 4. Paginação, Filtros e Ordenação
|
|
86
|
+
|
|
87
|
+
### 4.1. Paginação
|
|
88
|
+
|
|
89
|
+
**Offset-based (padrão):**
|
|
90
|
+
```
|
|
91
|
+
GET /api/v1/orders?page=1&page_size=20
|
|
92
|
+
|
|
93
|
+
Response:
|
|
94
|
+
{
|
|
95
|
+
"data": [...],
|
|
96
|
+
"pagination": {
|
|
97
|
+
"page": 1,
|
|
98
|
+
"page_size": 20,
|
|
99
|
+
"total_items": 150,
|
|
100
|
+
"total_pages": 8
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Cursor-based (para datasets grandes):**
|
|
106
|
+
```
|
|
107
|
+
GET /api/v1/orders?cursor=eyJpZCI6MTAwfQ&limit=20
|
|
108
|
+
|
|
109
|
+
Response:
|
|
110
|
+
{
|
|
111
|
+
"data": [...],
|
|
112
|
+
"pagination": {
|
|
113
|
+
"next_cursor": "eyJpZCI6MTIwfQ",
|
|
114
|
+
"prev_cursor": "eyJpZCI6ODB9",
|
|
115
|
+
"has_more": true
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 4.2. Filtros
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
GET /api/v1/orders?status=pending&created_after=2024-01-01&customer_id=uuid
|
|
124
|
+
|
|
125
|
+
Convenção:
|
|
126
|
+
- Igualdade direta: ?status=pending
|
|
127
|
+
- Range: ?created_after=2024-01-01&created_before=2024-12-31
|
|
128
|
+
- Múltiplos valores: ?status=pending,processing
|
|
129
|
+
- Busca: ?search=joão
|
|
130
|
+
- Existência: ?has_items=true
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 4.3. Ordenação
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
GET /api/v1/orders?sort=created_at&order=desc
|
|
137
|
+
|
|
138
|
+
Ou multi-sort:
|
|
139
|
+
GET /api/v1/orders?sort=status:asc,created_at:desc
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## 5. Error Design
|
|
145
|
+
|
|
146
|
+
### 5.1. Formato de Erro (RFC 7807)
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"type": "https://errors.example.com/insufficient-stock",
|
|
151
|
+
"title": "Insufficient Stock",
|
|
152
|
+
"status": 422,
|
|
153
|
+
"detail": "Product 'Widget X' has only 2 units available, but 5 were requested.",
|
|
154
|
+
"instance": "/api/v1/orders",
|
|
155
|
+
"traceId": "uuid-correlation-id",
|
|
156
|
+
"errors": [
|
|
157
|
+
{
|
|
158
|
+
"field": "items[0].quantity",
|
|
159
|
+
"code": "INSUFFICIENT_STOCK",
|
|
160
|
+
"message": "Requested 5 but only 2 available",
|
|
161
|
+
"productId": "uuid"
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 5.2. Códigos de Erro por Domínio
|
|
168
|
+
|
|
169
|
+
**Padrão de nomenclatura:** `SCREAMING_SNAKE_CASE`
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
Validation Errors:
|
|
173
|
+
- VALIDATION_ERROR (400) - Genérico de validação
|
|
174
|
+
- REQUIRED_FIELD_MISSING (400) - Campo obrigatório ausente
|
|
175
|
+
- INVALID_FORMAT (400) - Formato inválido (email, CPF)
|
|
176
|
+
- FIELD_TOO_LONG (400) - Campo excede tamanho máximo
|
|
177
|
+
|
|
178
|
+
Business Errors:
|
|
179
|
+
- INSUFFICIENT_STOCK (422) - Estoque insuficiente
|
|
180
|
+
- ORDER_ALREADY_CANCELLED (409) - Pedido já cancelado
|
|
181
|
+
- PAYMENT_FAILED (422) - Pagamento rejeitado
|
|
182
|
+
- DUPLICATE_ENTRY (409) - Entrada duplicada
|
|
183
|
+
|
|
184
|
+
Auth Errors:
|
|
185
|
+
- UNAUTHORIZED (401) - Token inválido/ausente
|
|
186
|
+
- FORBIDDEN (403) - Sem permissão
|
|
187
|
+
- TOKEN_EXPIRED (401) - Token expirado
|
|
188
|
+
|
|
189
|
+
System Errors:
|
|
190
|
+
- INTERNAL_ERROR (500) - Erro inesperado
|
|
191
|
+
- SERVICE_UNAVAILABLE (503) - Serviço terceiro indisponível
|
|
192
|
+
- TIMEOUT (504) - Timeout de serviço terceiro
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 5.3. Erros de Validação em Batch
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"type": "https://errors.example.com/validation-error",
|
|
200
|
+
"title": "Validation Failed",
|
|
201
|
+
"status": 400,
|
|
202
|
+
"errors": [
|
|
203
|
+
{ "field": "email", "code": "REQUIRED", "message": "Email é obrigatório" },
|
|
204
|
+
{ "field": "quantity", "code": "MIN_VALUE", "message": "Quantidade mínima é 1", "min": 1 },
|
|
205
|
+
{ "field": "items", "code": "MIN_LENGTH", "message": "Pedido deve ter pelo menos 1 item", "min": 1 }
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 6. Idempotência
|
|
213
|
+
|
|
214
|
+
### 6.1. Quando Especificar
|
|
215
|
+
|
|
216
|
+
**SEMPRE para:**
|
|
217
|
+
- Criação de recursos financeiros (pagamentos, transferências)
|
|
218
|
+
- Operações que causam efeitos colaterais (envio de email, reserva)
|
|
219
|
+
- Operações que podem ser retentadas automaticamente
|
|
220
|
+
|
|
221
|
+
### 6.2. Implementação
|
|
222
|
+
|
|
223
|
+
**Header de idempotência:**
|
|
224
|
+
```
|
|
225
|
+
POST /api/v1/orders
|
|
226
|
+
Idempotency-Key: client-generated-uuid
|
|
227
|
+
|
|
228
|
+
- Se key já existe: retornar resposta cacheada (200/201)
|
|
229
|
+
- Se key nova: processar e cache resultado por 24h
|
|
230
|
+
- TTL: 24 horas
|
|
231
|
+
- Storage: Redis ou tabela no banco
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**Na TechSpec:**
|
|
235
|
+
```
|
|
236
|
+
Endpoints idempotentes:
|
|
237
|
+
- POST /api/v1/payments: Idempotency-Key header obrigatório
|
|
238
|
+
- POST /api/v1/orders: Idempotency-Key header opcional (recomendado)
|
|
239
|
+
|
|
240
|
+
Storage: Redis com TTL 24h (key: idempotency:{hash})
|
|
241
|
+
Conflict: Se key já existe, retornar 200 + resposta cacheada
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 7. Rate Limiting
|
|
247
|
+
|
|
248
|
+
### 7.1. Headers de Rate Limit
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
HTTP/1.1 200 OK
|
|
252
|
+
X-RateLimit-Limit: 100
|
|
253
|
+
X-RateLimit-Remaining: 95
|
|
254
|
+
X-RateLimit-Reset: 1709318400
|
|
255
|
+
|
|
256
|
+
HTTP/1.1 429 Too Many Requests
|
|
257
|
+
Retry-After: 60
|
|
258
|
+
X-RateLimit-Limit: 100
|
|
259
|
+
X-RateLimit-Remaining: 0
|
|
260
|
+
X-RateLimit-Reset: 1709318400
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### 7.2. Limites por Tipo de Endpoint
|
|
264
|
+
|
|
265
|
+
| Tipo | Limite | Janela |
|
|
266
|
+
|:---|:---|:---|
|
|
267
|
+
| **Autenticação** | 5 req | Por minuto por IP |
|
|
268
|
+
| **Criação de recursos** | 10 req | Por minuto por usuário |
|
|
269
|
+
| **Listagem/Busca** | 100 req | Por minuto por usuário |
|
|
270
|
+
| **Operações pesadas** | 2 req | Por minuto por usuário |
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## 8. Contrato Completo
|
|
275
|
+
|
|
276
|
+
### Template de Endpoint na TechSpec
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
[METHOD] /api/v1/[resource]
|
|
280
|
+
Content-Type: application/json
|
|
281
|
+
Authorization: Bearer {token}
|
|
282
|
+
|
|
283
|
+
Request:
|
|
284
|
+
{
|
|
285
|
+
"field1": "type - description",
|
|
286
|
+
"field2": 0
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
Response [STATUS_CODE] [STATUS_TEXT]:
|
|
290
|
+
{
|
|
291
|
+
"field1": "type"
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
Response [ERROR_STATUS] [ERROR_TEXT]:
|
|
295
|
+
{
|
|
296
|
+
"code": "ERROR_CODE",
|
|
297
|
+
"message": "Human readable message",
|
|
298
|
+
"details": { ... }
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
Headers:
|
|
302
|
+
- X-Request-Id: Correlation ID para tracing
|
|
303
|
+
|
|
304
|
+
Rules:
|
|
305
|
+
- [Regra de validação/negócio específica]
|
|
306
|
+
- [Regra de autorização específica]
|
|
307
|
+
|
|
308
|
+
Rate Limit: [N] req/min por [user/ip]
|
|
309
|
+
Idempotent: [Yes/No] [como]
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Exemplo Completo
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
POST /api/v1/orders
|
|
316
|
+
Content-Type: application/json
|
|
317
|
+
Authorization: Bearer {token}
|
|
318
|
+
|
|
319
|
+
Request:
|
|
320
|
+
{
|
|
321
|
+
"customer_id": "uuid-v4",
|
|
322
|
+
"items": [
|
|
323
|
+
{
|
|
324
|
+
"product_id": "uuid-v4",
|
|
325
|
+
"quantity": 1
|
|
326
|
+
}
|
|
327
|
+
],
|
|
328
|
+
"shipping_address": {
|
|
329
|
+
"street": "string (max 255)",
|
|
330
|
+
"city": "string (max 100)",
|
|
331
|
+
"state": "string (2 chars)",
|
|
332
|
+
"zip_code": "string (8 chars)",
|
|
333
|
+
"country": "string (2 chars, default: BR)"
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
Response 201 Created:
|
|
338
|
+
{
|
|
339
|
+
"order_id": "uuid-v4",
|
|
340
|
+
"status": "PENDING",
|
|
341
|
+
"total_amount": 99.99,
|
|
342
|
+
"items": [
|
|
343
|
+
{
|
|
344
|
+
"product_id": "uuid-v4",
|
|
345
|
+
"name": "Product Name",
|
|
346
|
+
"quantity": 1,
|
|
347
|
+
"unit_price": 99.99
|
|
348
|
+
}
|
|
349
|
+
],
|
|
350
|
+
"created_at": "2024-03-01T10:00:00Z"
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
Response 400 Bad Request:
|
|
354
|
+
{
|
|
355
|
+
"code": "VALIDATION_ERROR",
|
|
356
|
+
"message": "Invalid request data",
|
|
357
|
+
"errors": [
|
|
358
|
+
{ "field": "items[0].quantity", "code": "MIN_VALUE", "message": "Quantity must be >= 1" }
|
|
359
|
+
]
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
Response 422 Unprocessable Entity:
|
|
363
|
+
{
|
|
364
|
+
"code": "INSUFFICIENT_STOCK",
|
|
365
|
+
"message": "Product 'Widget' has insufficient stock",
|
|
366
|
+
"details": { "product_id": "uuid", "requested": 5, "available": 2 }
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
Response 404 Not Found:
|
|
370
|
+
{
|
|
371
|
+
"code": "PRODUCT_NOT_FOUND",
|
|
372
|
+
"message": "Product with id 'uuid' not found"
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
Response 500 Internal Server Error:
|
|
376
|
+
{
|
|
377
|
+
"code": "INTERNAL_ERROR",
|
|
378
|
+
"message": "An unexpected error occurred",
|
|
379
|
+
"request_id": "correlation-uuid"
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
Authorization: customer (próprio pedido) ou admin (qualquer pedido)
|
|
383
|
+
Rate Limit: 10 req/min por user
|
|
384
|
+
Idempotent: Sim, via Idempotency-Key header
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 9. Webhooks
|
|
390
|
+
|
|
391
|
+
### 9.1. Formato de Webhook
|
|
392
|
+
|
|
393
|
+
```
|
|
394
|
+
POST [webhook_url]
|
|
395
|
+
Content-Type: application/json
|
|
396
|
+
X-Webhook-Signature: sha256=hmac_signature
|
|
397
|
+
X-Webhook-Event: order.created
|
|
398
|
+
X-Webhook-Delivery-Id: uuid
|
|
399
|
+
|
|
400
|
+
Payload:
|
|
401
|
+
{
|
|
402
|
+
"event": "order.created",
|
|
403
|
+
"timestamp": "2024-03-01T10:00:00Z",
|
|
404
|
+
"delivery_id": "uuid",
|
|
405
|
+
"data": {
|
|
406
|
+
"order_id": "uuid",
|
|
407
|
+
"status": "PENDING",
|
|
408
|
+
"total_amount": 99.99
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### 9.2. Retry Policy
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
Retry: 5 tentativas com backoff exponencial (1s, 2s, 4s, 8s, 16s)
|
|
417
|
+
Timeout: 10s por tentativa
|
|
418
|
+
Success: HTTP 2xx
|
|
419
|
+
Failure: Após 5 tentativas, mover para dead letter queue
|
|
420
|
+
Signature: HMAC-SHA256 com webhook secret
|
|
421
|
+
```
|