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