entregas_app/docs/ENDPOINTS_APIS.md

9.7 KiB

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

const API_BASE_URL = process.env.API_BASE_URL || 'https://api.example.com'

Timeout

const API_TIMEOUT = 10000; // 10 segundos

Headers Padrão

const defaultHeaders = {
  'Content-Type': 'application/json',
  'Authorization': `Bearer ${token}`
}

Endpoints de Autenticação

1. Login

Endpoint: POST /auth/login

Request Body:

{
  "username": "string",
  "password": "string"
}

Response:

{
  "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:

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:

{
  'Authorization': `Bearer ${token}`
}

Response:

{
  "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:

{
  'Authorization': `Bearer ${token}`
}

Response:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

{
  "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:

[
  {
    "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:

{
  "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:

{
  "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:

{
  "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

{
  "success": false,
  "message": "Descrição do erro",
  "data": null,
  "timestamp": "2024-01-01T00:00:00.000Z",
  "statusCode": 400
}

Tratamento de Erros no Cliente

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

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

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

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

// Para dados grandes, implementar compressão
const compressedData = await compress(JSON.stringify(data));

Monitoramento e Logs

Log de Requisições

function logRequest(endpoint: string, method: string, duration: number) {
  console.log(`API Request: ${method} ${endpoint} - ${duration}ms`);
}

Métricas de Performance

interface ApiMetrics {
  totalRequests: number;
  successRate: number;
  averageResponseTime: number;
  errorCount: number;
}

Considerações para Sincronização Offline

1. Endpoints para Sincronização

// 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

// 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

// 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.