updates
This commit is contained in:
@@ -167,6 +167,106 @@ Used when interacting with a specific store (Catalog, Checkout).
|
||||
- Se a distância entre `lat_long` enviado e o ponto do CEP for maior que `1.5 km`, a API substitui `lat_long` pelo ponto do CEP cacheado.
|
||||
- Objetivo: evitar discrepâncias grandes entre endereço e coordenada salva no perfil.
|
||||
|
||||
### 5. List Favorite Stores
|
||||
**GET** `/api/customer/favorites`
|
||||
|
||||
**Headers:**
|
||||
|
||||
- `Authorization: Bearer <JWT_Token>`
|
||||
- `Atomenta-Token: 550e8400-e29b-41d4-a716-44665544000a`
|
||||
|
||||
**Notes:**
|
||||
|
||||
- Retorna as lojas favoritas do customer autenticado.
|
||||
- Apenas lojas públicas/visíveis são retornadas.
|
||||
- A ordem segue a ordem salva em `favorites`.
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": false,
|
||||
"code": "CUSTOMER_FAVORITES_RETRIEVED",
|
||||
"result": [
|
||||
{
|
||||
"id": "store_1775510226293_yn5ys",
|
||||
"name": "CPS Drinks",
|
||||
"logo": null,
|
||||
"cover": null,
|
||||
"category": "Doces & Bolos",
|
||||
"rating": 4.8,
|
||||
"totalReviews": 12,
|
||||
"isOpen": true,
|
||||
"statusLabel": "Aberto",
|
||||
"nextOpenLabel": null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Add Store to Favorites
|
||||
**POST** `/api/customer/favorites/:storeId`
|
||||
|
||||
**Headers:**
|
||||
|
||||
- `Authorization: Bearer <JWT_Token>`
|
||||
- `Atomenta-Token: 550e8400-e29b-41d4-a716-44665544000a`
|
||||
|
||||
**Notes:**
|
||||
|
||||
- Salva a loja nos favoritos do customer autenticado.
|
||||
- Se a loja já estiver favoritada, a operação continua idempotente.
|
||||
- A loja precisa existir e estar publicamente visível.
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": false,
|
||||
"code": "CUSTOMER_FAVORITE_SAVED",
|
||||
"result": {
|
||||
"favorites": ["store_1775510226293_yn5ys"],
|
||||
"store": {
|
||||
"id": "store_1775510226293_yn5ys",
|
||||
"name": "CPS Drinks",
|
||||
"logo": null,
|
||||
"cover": null,
|
||||
"category": "Doces & Bolos",
|
||||
"rating": 4.8,
|
||||
"totalReviews": 12,
|
||||
"isOpen": true,
|
||||
"statusLabel": "Aberto",
|
||||
"nextOpenLabel": null
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Remove Store from Favorites
|
||||
**DELETE** `/api/customer/favorites/:storeId`
|
||||
|
||||
**Headers:**
|
||||
|
||||
- `Authorization: Bearer <JWT_Token>`
|
||||
- `Atomenta-Token: 550e8400-e29b-41d4-a716-44665544000a`
|
||||
|
||||
**Notes:**
|
||||
|
||||
- Remove a loja dos favoritos do customer autenticado.
|
||||
- A operação é idempotente: se a loja não estiver favoritada, o array volta sem ela.
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": false,
|
||||
"code": "CUSTOMER_FAVORITE_REMOVED",
|
||||
"result": {
|
||||
"favorites": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏠 App Home Screen
|
||||
@@ -538,19 +638,29 @@ Use este canal para acompanhar mudança de status do pedido em tempo real (sem d
|
||||
```
|
||||
|
||||
**Eventos recebidos pelo app:**
|
||||
- `order_update`: enviado quando o pedido muda (pagamento aprovado, aceito pela loja, saiu para entrega, concluído, cancelado).
|
||||
- `order_update`: alteração geral de status do pedido.
|
||||
- `order_cancelled`: cancelamento confirmado, com motivo e metadados de estorno.
|
||||
- `delivery_order_cancelled`: evento dedicado para telas de OTP/entrega interromperem o fluxo imediatamente.
|
||||
|
||||
**Payload típico de `order_update`:**
|
||||
**Payload típico de `order_cancelled`:**
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "ord_987...",
|
||||
"shortId": "1234",
|
||||
"storeId": "store_123...",
|
||||
"userId": "cust_uuid...",
|
||||
"status": "CONFIRMED",
|
||||
"paymentStatus": "CONFIRMED",
|
||||
"updatedAt": "2026-02-15T20:10:00.000Z"
|
||||
"event": "order_cancelled",
|
||||
"emittedAt": "2026-03-05T18:00:00.000Z",
|
||||
"orderId": "ffdc47b4-6a55-4713-aea9-45169e4cf0d7",
|
||||
"shortId": "3778",
|
||||
"storeId": "store_1772117366848_wmqw4",
|
||||
"userId": "cust_uuid_001",
|
||||
"status": "CANCELED",
|
||||
"cancelledBy": "store",
|
||||
"cancelledAt": "2026-03-05T18:00:00.000Z",
|
||||
"cancelReasonCode": "STORE_UNAVAILABLE",
|
||||
"cancelReasonDetail": "Falta de insumo crítico para finalizar o pedido",
|
||||
"refundStatus": "failed",
|
||||
"refundIdempotencyKey": "refund:ffdc47b4-...",
|
||||
"refundProviderRef": null,
|
||||
"refundError": "Falha ao solicitar estorno automático"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -566,9 +676,45 @@ Se o socket cair, o app deve continuar consultando o status até estado final.
|
||||
- depois: a cada `10s`
|
||||
- parar em status final (`COMPLETED`, `CANCELED`, `REFUNDED`) ou ao sair da tela.
|
||||
|
||||
### 8. Catálogo Oficial de Tags de Review
|
||||
### 8. Cancelamento de Pedido (Loja/Customer)
|
||||
|
||||
### 8.1 Matriz Completa de Endpoints (Reviews + Tags)
|
||||
**Cancelamento pela loja (Store API):**
|
||||
- `POST /api/store/:storeId/orders/:orderId/cancel`
|
||||
|
||||
**Cancelamento pelo customer:**
|
||||
- `POST /api/customer/orders/:orderId/cancel`
|
||||
|
||||
**Request body (ambos):**
|
||||
```json
|
||||
{
|
||||
"reasonCode": "CUSTOMER_REQUEST",
|
||||
"reasonDetail": "Cliente solicitou cancelamento antes da entrega"
|
||||
}
|
||||
```
|
||||
|
||||
**Motivos aceitos (`reasonCode`):**
|
||||
- `STORE_UNAVAILABLE`
|
||||
- `CUSTOMER_REQUEST`
|
||||
- `DELIVERY_ISSUE`
|
||||
|
||||
**Regras atuais de cancelamento:**
|
||||
- Permitido em: `PAYMENT_PENDING`, `PENDING`, `ACCEPTED`, `PREPARING`, `READY`, `DELIVERING`.
|
||||
- Bloqueado em: `COMPLETED` e `CANCELED`.
|
||||
- Motoboy não cancela pedido.
|
||||
- Ao cancelar, o backend invalida `otp`, `confirmOtp` e `customerOtp`.
|
||||
|
||||
**Concorrência e idempotência (ponta a ponta):**
|
||||
- Cancelamento é serializado por `orderId` (lock por pedido).
|
||||
- Estorno automático usa lock + chave idempotente de estorno para evitar duplicidade.
|
||||
- Em segunda tentativa após cancelamento efetivado, a API retorna `409 ORDER_ALREADY_CANCELED`.
|
||||
|
||||
**Campos relevantes no retorno:**
|
||||
- `cancelledBy`, `cancelledAt`, `cancelReasonCode`, `cancelReasonDetail`
|
||||
- `refundStatus`, `refundIdempotencyKey`, `refundProviderRef`
|
||||
|
||||
### 9. Catálogo Oficial de Tags de Review
|
||||
|
||||
### 9.1 Matriz Completa de Endpoints (Reviews + Tags)
|
||||
|
||||
**Público/App (Customer):**
|
||||
- `GET /api/public/reviews/tags` → catálogo oficial de tags e regras de validação.
|
||||
@@ -630,7 +776,7 @@ O app deve buscar este endpoint para renderizar as tags válidas e enviar soment
|
||||
- Não hardcodear tags no app; usar o catálogo do backend.
|
||||
- Enviar no POST de review apenas os `id` retornados em cada bloco.
|
||||
|
||||
### 9. Enviar Avaliação do Pedido
|
||||
### 10. Enviar Avaliação do Pedido
|
||||
Permite o customer enviar review da loja a partir de um pedido finalizado.
|
||||
|
||||
**Endpoint:**
|
||||
@@ -749,7 +895,7 @@ Exemplo inválido (entrega positiva com tags negativas):
|
||||
|
||||
Retorno esperado: `400 INVALID_DELIVERY_SENTIMENT_TAGS`.
|
||||
|
||||
### 10. Analytics de Reviews (Store/API)
|
||||
### 11. Analytics de Reviews (Store/API)
|
||||
Para dashboard da loja e análise de produto, usar:
|
||||
|
||||
- `GET /api/store/:storeId/reviews`
|
||||
|
||||
Reference in New Issue
Block a user