5. Modelo de Dados — Saída (Sucesso)
Este capítulo detalha as respostas de sucesso que você receberá de cada endpoint.
5.1 Estrutura Geral de Resposta
Campos Comuns a Todas as Respostas
| Campo | Tipo | Presença | Descrição |
|---|---|---|---|
| success | Boolean | Sempre | true para sucesso, false para erro |
| message | String | Sempre | Mensagem descritiva |
| id | Long | Operações create/update | ID do recurso criado ou atualizado |
| description | String | Variável | Dados resumidos do recurso |
5.2 HTTP 201 Created — Operação Individual (Criação)
Usado quando: POST (operação de criação individual)
Exemplo Requisição:
POST https://api.retailportal.com/erp-data/product HTTP/1.1
Content-Type: application/json
X-API-Key: ERP-RETAILPORTAL-2024-SECURE-KEY-ABC123
{
"erpId": 12345,
"ncmCode": "84733090",
"status": "Active",
"ean": "7896045000001",
"description": "Dipirona 500mg Cápsulas"
}
Exemplo Resposta (201 Created):
{
"success": true,
"id": 98765,
"message": "Produto criado com sucesso",
"description": "Dipirona 500mg Cápsulas"
}
Interpretação:
- success: true — Operação bem-sucedida
- id: 98765 — ID único do produto na plataforma Portal Retail
- message — Descrição de sucesso
- description — Resumo do recurso criado
5.3 HTTP 200 OK — Operação Individual (Atualização)
Usado quando: PUT (operação de atualização individual)
Exemplo Requisição:
PUT https://api.retailportal.com/erp-data/product HTTP/1.1
Content-Type: application/json
X-API-Key: ERP-RETAILPORTAL-2024-SECURE-KEY-ABC123
{
"erpId": 12345,
"description": "Dipirona 500mg - Atualizado"
}
Exemplo Resposta (200 OK):
{
"success": true,
"id": 98765,
"message": "Produto atualizado com sucesso",
"description": "Dipirona 500mg - Atualizado"
}
Interpretação:
- success: true — Atualização bem-sucedida
- id: 98765 — ID do produto atualizado
- message — Descrição de sucesso
5.4 HTTP 200 OK — Consulta (GET)
Usado quando: GET /get-latest-integration ou GET /batch-job-report
Exemplo: GET /product/get-latest-integration
Requisição:
GET https://api.retailportal.com/erp-data/product/get-latest-integration HTTP/1.1
X-API-Key: ERP-RETAILPORTAL-2024-SECURE-KEY-ABC123
Resposta (200 OK):
{
"classType": "ErpProduct",
"id": 1,
"erpId": 0,
"lastOperation": "Update",
"lastDateTime": "2024-12-06T15:45:23.456Z"
}
Campos:
- classType — Tipo de entidade (ErpProduct, ErpStock, etc.)
- id — ID interno do registro
- erpId — ID no seu ERP
- lastOperation — Última operação (Create ou Update)
- lastDateTime — Timestamp UTC da última sincronização bem-sucedida
Uso prático:
Você pode usar lastDateTime para sincronizações incrementais:
SELECT * FROM meu_erp.produtos
WHERE data_modificacao > '2024-12-06T15:45:23.456Z'
5.5 HTTP 202 Accepted — Operação em Lote
Usado quando: POST /batch ou PUT /batch (operações assíncronas)
Importante: HTTP 202 Accepted significa: - ✓ Sua requisição foi validada - ✓ Seu trabalho foi enfileirado - ✗ Mas ainda NÃO foi processado
Você deve consultar o status posteriormente.
Exemplo Requisição
POST https://api.retailportal.com/erp-data/product/batch HTTP/1.1
Content-Type: application/json
X-API-Key: ERP-RETAILPORTAL-2024-SECURE-KEY-ABC123
{
"products": [
{ "erpId": 12345, "ncmCode": "84733090", "status": "Active", "description": "Dipirona 500mg" },
{ "erpId": 12346, "ncmCode": "84733091", "status": "Active", "description": "Ibuprofeno 600mg" }
]
}
Exemplo Resposta (202 Accepted)
{
"message": "Batch received and will be processed asynchronously",
"jobId": "hangfire-job-1234567890",
"totalItems": 2
}
Campos:
- message — Confirma que o batch foi aceito
- jobId — Identificador único do trabalho (use para consultar progresso)
- totalItems — Total de itens na requisição
O que Fazer com HTTP 202
-
Armazene o jobId:
python job_id = response.json()['jobId'] storage.save_job_id(job_id) -
Consulte o status periodicamente:
GET /batch-job-report/{jobId} Intervalo: 10-30 segundos Timeout: 5 minutos máximo -
Implemente tratamento de estado:
Se state = "Enqueued" → Aguarde Se state = "Processing" → Continue aguardando Se state = "Finished" → Verifique successCount/failureCount Se state = "Failed" → Aguarde 5 minutos e reenvie
5.6 HTTP 200 OK — Consulta de Status de Batch
Endpoint: GET /batch-job-report/{jobId}
Exemplo Requisição
GET https://api.retailportal.com/erp-data/batch-job-report/hangfire-job-1234567890 HTTP/1.1
X-API-Key: ERP-RETAILPORTAL-2024-SECURE-KEY-ABC123
Resposta — Estado: Enqueued (Aguardando Processamento)
{
"jobId": "hangfire-job-1234567890",
"entityType": "ErpProduct",
"state": "Enqueued",
"isComplete": false,
"createdAt": "2024-12-06T10:30:00.000Z",
"startedAt": null,
"completedAt": null,
"duration": null,
"totalItems": 100,
"successCount": 0,
"failureCount": 0,
"retryAttempt": 0,
"hasPartialData": false,
"errorMessage": null,
"exceptionDetails": null
}
Interpretação:
- state: "Enqueued" — Job na fila, aguardando processamento
- successCount: 0 — Nenhum item processado ainda
- startedAt: null — Processamento ainda não começou
- Ação: Continue consultando a cada 10 segundos
Resposta — Estado: Processing (Processando)
{
"jobId": "hangfire-job-1234567890",
"entityType": "ErpProduct",
"state": "Processing",
"isComplete": false,
"createdAt": "2024-12-06T10:30:00.000Z",
"startedAt": "2024-12-06T10:30:02.000Z",
"completedAt": null,
"duration": null,
"totalItems": 100,
"successCount": 45,
"failureCount": 0,
"retryAttempt": 0,
"hasPartialData": false,
"errorMessage": null,
"exceptionDetails": null
}
Interpretação:
- state: "Processing" — Sistema está processando ativamente
- successCount: 45 — 45 itens já foram salvos
- startedAt — Processamento iniciou em 10:30:02
- Ação: Continue consultando até concluir
Resposta — Estado: Finished (Concluído com Sucesso Total)
{
"jobId": "hangfire-job-1234567890",
"entityType": "ErpProduct",
"state": "Finished",
"isComplete": true,
"createdAt": "2024-12-06T10:30:00.000Z",
"startedAt": "2024-12-06T10:30:02.000Z",
"completedAt": "2024-12-06T10:35:15.000Z",
"duration": "00:05:13",
"totalItems": 100,
"successCount": 100,
"failureCount": 0,
"retryAttempt": 0,
"hasPartialData": false,
"errorMessage": null,
"exceptionDetails": null
}
Interpretação:
- state: "Finished" — Processamento concluído
- isComplete: true — Trabalho finalizado
- successCount: 100 — Todos os 100 itens foram salvos
- failureCount: 0 — Nenhum erro
- duration: "00:05:13" — Tempo total: 5 minutos e 13 segundos
- hasPartialData: false — Todos os dados foram processados
- Resultado: ✓ SUCESSO TOTAL
Resposta — Estado: Finished (Sucesso Parcial com Erros)
{
"jobId": "hangfire-job-1234567891",
"entityType": "ErpProduct",
"state": "Finished",
"isComplete": true,
"createdAt": "2024-12-06T10:40:00.000Z",
"startedAt": "2024-12-06T10:40:02.000Z",
"completedAt": "2024-12-06T10:45:30.000Z",
"duration": "00:05:28",
"totalItems": 100,
"successCount": 95,
"failureCount": 5,
"retryAttempt": 0,
"hasPartialData": true,
"errorMessage": "5 items failed validation during processing",
"exceptionDetails": null
}
Interpretação:
- state: "Finished" — Processamento concluído
- successCount: 95 — 95 itens foram salvos com sucesso
- failureCount: 5 — 5 itens falharam
- hasPartialData: true — Dados parcialmente processados
- errorMessage — Resumo do problema
- Resultado: ⚠️ SUCESSO PARCIAL — Investigar os 5 erros
O que fazer: 1. Consulte o histórico de integração para identificar quais itens falharam 2. Verifique os dados desses 5 itens (validação, duplicidade, etc.) 3. Corrija os dados e reenvie apenas esses 5 itens
Resposta — Estado: Failed (Falha Total)
{
"jobId": "hangfire-job-1234567892",
"entityType": "ErpProduct",
"state": "Failed",
"isComplete": true,
"createdAt": "2024-12-06T11:00:00.000Z",
"startedAt": "2024-12-06T11:00:02.000Z",
"completedAt": "2024-12-06T11:00:45.000Z",
"duration": "00:00:43",
"totalItems": 100,
"successCount": 0,
"failureCount": 100,
"retryAttempt": 5,
"hasPartialData": false,
"errorMessage": "Database connection pool exhausted",
"exceptionDetails": "PostgreSQL connection timeout after 5 retry attempts"
}
Interpretação:
- state: "Failed" — Falha total do processamento
- successCount: 0 — Nenhum item foi salvo
- retryAttempt: 5 — Sistema tentou 5 vezes
- errorMessage — Razão da falha (problema do servidor, não dos dados)
- Resultado: ✗ FALHA DO SISTEMA
O que fazer: 1. Não é um erro de dados, mas do servidor 2. Aguarde 5 minutos 3. Reenvie exatamente a mesma requisição 4. Se persistir, contacte o suporte
5.7 Estrutura de Resposta para Batch Job Report
Campos Explicados
| Campo | Tipo | Descrição |
|---|---|---|
| jobId | String | Identificador único do trabalho |
| entityType | String | Tipo de dados (ErpProduct, ErpStock, etc.) |
| state | Enum | Estado atual (Enqueued, Processing, Finished, Failed) |
| isComplete | Boolean | true se estado é Finished ou Failed |
| createdAt | DateTime | Quando o job foi criado |
| startedAt | DateTime | Quando começou o processamento |
| completedAt | DateTime | Quando terminou |
| duration | TimeSpan | Tempo decorrido (HH:mm:ss) |
| totalItems | Integer | Total de itens enviados |
| successCount | Integer | Itens processados com sucesso |
| failureCount | Integer | Itens que falharam |
| retryAttempt | Integer | Número de tentativas do Hangfire |
| hasPartialData | Boolean | true se alguns itens falharam |
| errorMessage | String | Mensagem de erro geral |
| exceptionDetails | String | Stack trace completo (se houver) |
5.8 Exemplo de Fluxo Completo — Batch
TEMPO AÇÃO RESPOSTA
─────────────────────────────────────────────────────────────
00:00 POST /product/batch com 100 itens 202 Accepted
jobId: hangfire-1234567890
00:05 GET /batch-job-report/hangfire-... 200 OK
state: Enqueued
successCount: 0
00:10 GET /batch-job-report/hangfire-... 200 OK
state: Processing
successCount: 25
00:15 GET /batch-job-report/hangfire-... 200 OK
state: Processing
successCount: 75
00:20 GET /batch-job-report/hangfire-... 200 OK
state: Finished
successCount: 100
failureCount: 0
RESULTADO: ✓ Todos os 100 itens salvos com sucesso!
Checklist de Respostas de Sucesso
- [ ] HTTP 201 ou 202 recebido?
- [ ] Campo
success: true? - [ ] Campo
idcontém um número válido? - [ ] Campo
messagedescreve o resultado? - [ ] Se 202: jobId foi armazenado para consultas posteriores?
- [ ] Se batch: Estado progression (Enqueued → Processing → Finished)?
- [ ] Se Finished: successCount + failureCount = totalItems?
- [ ] Se Finished com falhas: errorMessage explica o problema?