entregas_app/docs/ENDPOINTS_APIS.md

497 lines
9.7 KiB
Markdown

# Endpoints e APIs - Documentação Técnica
## Visão Geral
O aplicativo utiliza uma API REST para comunicação com o servidor, implementando autenticação JWT e endpoints específicos para gerenciamento de entregas, roteirização e sincronização de dados.
## Configuração Base
### URL Base
```typescript
const API_BASE_URL = process.env.API_BASE_URL || 'https://api.example.com'
```
### Timeout
```typescript
const API_TIMEOUT = 10000; // 10 segundos
```
### Headers Padrão
```typescript
const defaultHeaders = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
}
```
## Endpoints de Autenticação
### 1. Login
**Endpoint**: `POST /auth/login`
**Request Body**:
```json
{
"username": "string",
"password": "string"
}
```
**Response**:
```json
{
"success": true,
"message": "Login realizado com sucesso",
"data": {
"access_token": "jwt_token_here",
"user": {
"id": 1,
"username": "string",
"sellerId": 1,
"name": "string",
"storeId": "string",
"email": "string"
}
},
"timestamp": "2024-01-01T00:00:00.000Z",
"statusCode": 200
}
```
**Implementação**:
```typescript
async login(username: string, password: string): Promise<User> {
const response = await fetch(`${API_BASE_URL}/auth/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username, password })
});
const data = await response.json();
if (!data.success) throw new Error(data.message);
await this.setToken(data.data.access_token);
await this.saveUserData(data.data.user);
return data.data.user;
}
```
### 2. Logout
**Endpoint**: `POST /auth/logout`
**Headers**:
```typescript
{
'Authorization': `Bearer ${token}`
}
```
**Response**:
```json
{
"success": true,
"message": "Logout realizado com sucesso",
"data": null,
"timestamp": "2024-01-01T00:00:00.000Z",
"statusCode": 200
}
```
## Endpoints de Entregas
### 1. Listar Entregas
**Endpoint**: `GET /v1/driver/deliveries`
**Headers**:
```typescript
{
'Authorization': `Bearer ${token}`
}
```
**Response**:
```json
{
"success": true,
"message": "Entregas carregadas com sucesso",
"data": [
{
"outId": 12345,
"customerId": 67890,
"customerName": "João Silva",
"street": "Rua das Flores",
"streetNumber": "123",
"neighborhood": "Centro",
"city": "São Paulo",
"state": "SP",
"zipCode": "01234-567",
"customerPhone": "(11) 99999-9999",
"lat": -23.5505,
"lng": -46.6333,
"latFrom": "-23.5505",
"lngFrom": "-46.6333",
"deliverySeq": 1,
"routing": 1,
"status": "pending",
"outDate": "2024-01-01T10:00:00.000Z",
"notes": "Observações da entrega"
}
],
"timestamp": "2024-01-01T00:00:00.000Z",
"statusCode": 200
}
```
### 2. Obter Entrega Específica
**Endpoint**: `GET /v1/driver/deliveries/{outId}`
**Parâmetros**:
- `outId`: ID da entrega
**Response**: Mesmo formato do item individual da lista de entregas
### 3. Notas Fiscais do Cliente
**Endpoint**: `GET /v1/driver/deliveries/{outId}/customer/{customerId}`
**Parâmetros**:
- `outId`: ID da entrega
- `customerId`: ID do cliente
**Response**:
```json
{
"success": true,
"message": "Notas fiscais carregadas",
"data": [
{
"invoiceId": "NF001",
"transactionId": 12345,
"customerName": "João Silva",
"invoiceValue": 150.00,
"status": "pending",
"itens": [
{
"productName": "Produto A",
"quantity": 2,
"unitValue": 75.00
}
]
}
]
}
```
### 4. Criar/Concluir Entrega
**Endpoint**: `POST /v1/delivery/create`
**Request Body**:
```json
{
"outId": 12345,
"transactionId": 67890,
"receiverDoc": "12345678901",
"receiverName": "João Silva",
"lat": -23.5505,
"lng": -46.6333,
"broken": false,
"devolution": false,
"reasonDevolution": null,
"deliveryImages": ["url1", "url2"],
"userId": 1
}
```
**Response**:
```json
{
"success": true,
"message": "Entrega criada com sucesso",
"data": {
"deliveryId": "del_12345",
"status": "delivered",
"timestamp": "2024-01-01T10:00:00.000Z"
}
}
```
### 5. Atualizar Status da Entrega
**Endpoint**: `POST /v1/driver/delivery/status`
**Request Body**:
```json
{
"outId": 12345,
"customerId": 67890,
"status": "in_progress",
"lat": -23.5505,
"lng": -46.6333,
"notes": "Observações opcionais"
}
```
## Endpoints de Roteirização
### 1. Enviar Ordem de Roteamento
**Endpoint**: `POST /v1/driver/routing`
**Request Body**:
```json
[
{
"outId": 12345,
"customerId": 67890,
"deliverySeq": 1,
"lat": -23.5505,
"lng": -46.6333
},
{
"outId": 12346,
"customerId": 67891,
"deliverySeq": 2,
"lat": -23.5506,
"lng": -46.6334
}
]
```
**Response**:
```json
{
"success": true,
"message": "Roteamento enviado com sucesso",
"data": {
"routingId": "route_12345",
"totalDeliveries": 2,
"estimatedTime": "2h30m",
"totalDistance": "45.2km"
}
}
```
## Endpoints de Geolocalização
### 1. Obter Coordenadas por Endereço
**Endpoint**: `GET /v1/geolocation/google`
**Query Parameters**:
- `address`: Endereço
- `addressNumber`: Número
- `neighborhood`: Bairro
- `city`: Cidade
- `state`: Estado
**Response**:
```json
{
"success": true,
"message": "Coordenadas obtidas",
"data": [
{
"latitude": -23.5505,
"longitude": -46.6333,
"formatted_address": "Rua das Flores, 123 - Centro, São Paulo - SP",
"accuracy": "high"
}
]
}
```
## Endpoints de Upload
### 1. Upload de Imagens
**Endpoint**: `POST /api/v1/base/send-image`
**Content-Type**: `multipart/form-data`
**Form Data**:
- `files`: Arquivos de imagem
- `transactionId`: ID da transação
**Response**:
```json
{
"success": true,
"message": "Imagens enviadas com sucesso",
"data": [
{
"url": "https://api.example.com/images/image1.jpg",
"transactionId": 12345
}
]
}
```
## Tratamento de Erros
### Códigos de Status HTTP
- **200**: Sucesso
- **400**: Erro de validação
- **401**: Não autorizado (token expirado)
- **403**: Acesso negado
- **404**: Recurso não encontrado
- **500**: Erro interno do servidor
### Formato de Erro
```json
{
"success": false,
"message": "Descrição do erro",
"data": null,
"timestamp": "2024-01-01T00:00:00.000Z",
"statusCode": 400
}
```
### Tratamento de Erros no Cliente
```typescript
try {
const response = await fetch(endpoint, options);
if (response.status === 401) {
// Token expirado - redirecionar para login
if (onUnauthorized) onUnauthorized();
throw new Error('Sessão expirada. Faça login novamente.');
}
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.message || 'Erro na requisição');
}
const data = await response.json();
return data.data;
} catch (error) {
console.error('Erro na requisição:', error);
throw error;
}
```
## Implementação de Retry e Timeout
### Timeout de Requisições
```typescript
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), API_TIMEOUT);
try {
const response = await fetch(endpoint, {
...options,
signal: controller.signal
});
clearTimeout(timeoutId);
return response;
} catch (error) {
if (error.name === 'AbortError') {
throw new Error('Tempo limite excedido');
}
throw error;
}
```
### Retry Automático
```typescript
async function requestWithRetry<T>(
requestFn: () => Promise<T>,
maxRetries: number = 3
): Promise<T> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await requestFn();
} catch (error) {
if (attempt === maxRetries) throw error;
// Aguardar antes da próxima tentativa
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, attempt) * 1000)
);
}
}
}
```
## Cache e Otimização
### Cache de Requisições
```typescript
class ApiCache {
private cache = new Map<string, { data: any; timestamp: number }>();
private TTL = 5 * 60 * 1000; // 5 minutos
get(key: string): any | null {
const cached = this.cache.get(key);
if (!cached) return null;
if (Date.now() - cached.timestamp > this.TTL) {
this.cache.delete(key);
return null;
}
return cached.data;
}
set(key: string, data: any): void {
this.cache.set(key, {
data,
timestamp: Date.now()
});
}
}
```
### Compressão de Dados
```typescript
// Para dados grandes, implementar compressão
const compressedData = await compress(JSON.stringify(data));
```
## Monitoramento e Logs
### Log de Requisições
```typescript
function logRequest(endpoint: string, method: string, duration: number) {
console.log(`API Request: ${method} ${endpoint} - ${duration}ms`);
}
```
### Métricas de Performance
```typescript
interface ApiMetrics {
totalRequests: number;
successRate: number;
averageResponseTime: number;
errorCount: number;
}
```
## Considerações para Sincronização Offline
### 1. Endpoints para Sincronização
```typescript
// Endpoint para sincronização completa
POST /v1/sync/full
// Endpoint para sincronização incremental
POST /v1/sync/incremental
// Endpoint para sincronização seletiva
POST /v1/sync/selective
```
### 2. Controle de Versão
```typescript
// Headers para controle de versão
{
'If-Modified-Since': '2024-01-01T00:00:00.000Z',
'If-None-Match': 'etag_value'
}
```
### 3. Sincronização em Lotes
```typescript
// Enviar múltiplas entregas de uma vez
POST /v1/delivery/create-batch
```
Esta documentação fornece uma visão completa dos endpoints utilizados pelo aplicativo, servindo como base para implementar melhorias na sincronização offline e otimizações de performance.