Create simplified address
POST/company/address/simple
Cria um novo endereço de forma simplificada usando apenas coordenadas e dados básicos.
Este endpoint está otimizado para casos em que as coordenadas exatas são conhecidas e é necessário
criar um endereço rapidamente, sem a complexidade dos dados do Google Maps.
Fluxo de operação:
- Autenticação via JWT válido
- Validação dos campos mínimos obrigatórios (lat, lng, name, company_name)
- Geocodificação reversa automática a partir das coordenadas
- Criação automática do endereço completo
- Associação à empresa do usuário
- Retorno do endereço criado
Vantagens deste endpoint:
- Requer apenas 4 campos obrigatórios vs ~15 do endpoint padrão
- Geocodificação automática a partir de coordenadas
- Reutiliza a lógica testada do sistema de importação em massa
- Mantém a mesma qualidade de dados que a criação normal
Casos de uso típicos:
- Aplicativos móveis com GPS
- Integração a partir de sistemas de terceiros com coordenadas
- Criação rápida a partir de mapas interativos
- Criação em massa simplificada
Exemplo de solicitação:
POST /company/address/simple
Authorization: Bearer {token}
Content-Type: application/json
{
lat: 40.416775,
lng: -3.703790,
name: Escritório Central,
company_name: CargoOffer SL,
phone: +34912345678,
isDefault: false
}
Exemplo de resposta bem-sucedida:
\{
_id: 507f1f77bcf86cd799439011,
name: Escritório Central,
company_name: CargoOffer SL,
phone: +34912345678,
street: Calle de Alcalá, 42,
city: madrid,
zipcode: 28014,
country: es,
location: \{
type: Point,
coordinates: [-3
<Heading
id={"request"}
as={"h2"}
className={"openapi-tabs__heading"}
children={"Request"}
>
</Heading>
<ParamsDetails
parameters={[]}
>
</ParamsDetails>
<RequestSchema
title={"Body"}
body={{"content":{"application/json":{"schema":{"type":"object","properties":{"lat":{"type":"number","description":"Latitude em graus decimais (WGS84)","minimum":-90,"maximum":90,"example":40.416775},"lng":{"type":"number","description":"Comprimento em graus decimais (WGS84)","minimum":-180,"maximum":180,"example":-3.70379},"name":{"type":"string","description":"Nome descritivo do endereço","minLength":3,"maxLength":100,"example":"Oficina Central"},"company_name":{"type":"string","description":"Razão social da empresa neste endereço","minLength":2,"maxLength":100,"example":"CargoOffer SL"},"phone":{"type":"string","description":"Telefone de contato (opcional, formato internacional recomendado)","maxLength":20,"example":"+34912345678"},"isDefault":{"type":"boolean","description":"Indique se este será o endereço principal da empresa","default":false,"example":false}},"required":["lat","lng","name","company_name"],"example":{"lat":40.416775,"lng":-3.70379,"name":"Oficina Central","company_name":"CargoOffer SL","phone":"+34912345678","isDefault":false}},"example":{"lat":40.416775,"lng":-3.70379,"name":"Oficina Central","company_name":"CargoOffer SL","phone":"+34912345678","isDefault":false}}},"required":true}}
>
</RequestSchema>
<StatusCodes
id={undefined}
label={undefined}
responses={{"200":{"description":"Direção criada com sucesso","content":{"application/json":{"schema":{"type":"object","description":"Representa um endereço físico associado a uma empresa para operações de carga/descarga.\n**Funcionalidade**: - Ponto de origem (ETL - Tempo Esperado de Carregamento) ou destino (ETD - Tempo Esperado de Entrega) em leilões de transporte - Armazenado por empresa e reutilizável em múltiplas operações - Geocodificado automaticamente via Google Maps API ao criar - Validado contra uso em leilões/entregas ativas antes de excluir\n**Modelo**: `src/features/models/address.model.js`\n**Controlador**: `src/features/company/address/controller.js`","properties":{"_id":{"type":"string","description":"Identificador único MongoDB do endereço (24 caracteres hexadecimais). Gerado automaticamente pelo sistema ao criar o endereço. Utilizado como referência nos modelos de leilões (auction.etl_address, auction.etd_address) e entregas (delivery.etl_address, delivery.etd_address).","pattern":"^[a-f0-9]{24}$","example":"507f1f77bcf86cd799439011"},"name":{"type":"string","description":"Nome descritivo ou apelido personalizado da localização atribuído pelo usuário. Usado para identificação rápida em listas e seleção de endereços. **Obrigatório** - Mínimo de 3 caracteres, máximo de 100. Exemplos: Armazém Norte, Escritório Central, Cliente ABC - Fábrica Madrid","minLength":3,"maxLength":100,"example":"Oficina Central"},"company_name":{"type":"string","description":"Razão social ou nome comercial da empresa nesta localização. **Obrigatório** - Aparece em documentos oficiais (CMR, contratos). Pode diferir do nome da empresa principal se for um endereço de cliente/fornecedor. Mínimo de 2 caracteres, máximo de 100.","minLength":2,"maxLength":100,"example":"CargoOffer SL"},"phone":{"type":"string","description":"Número de telefone de contato para coordenação logística neste endereço. **Opcional** - Formato internacional recomendado (E.164 com +código do país). Usado por transportadoras para confirmar a chegada e resolver incidentes. Validado com padrão: 9-15 dígitos.","pattern":"^\\+?[0-9]{9,15}$","maxLength":20,"example":"+34912345678"},"street":{"type":"string","description":"Rua completa com número, gerada automaticamente a partir de addressGoogleMaps. Formato: 'Nome da Rua, Número'. Usado em visualização e exportações CSV. Campo legado combinado (ver street_address + street_number para separados).","example":"Calle Ejemplo 123"},"street_address":{"type":"string","description":"Nome da rua sem número (campo separado). Parseado da resposta da API do Google Maps (componente de rota).","example":"Calle de Alcalá"},"street_number":{"type":"string","description":"Número da rua como campo independente. Extraído da resposta da API do Google Maps (componente street_number).","example":"42"},"city":{"type":"string","description":"Cidade normalizada em minúsculas, extraída automaticamente de coordenadas via Google Maps Geocoding API. Usada em filtros de busca e agrupamento de endereços por zona. Tipo: locality ou administrative_area_level_2 do Google Maps.","example":"madrid"},"state":{"type":"string","description":"Estado, comunidade autónoma ou região administrativa (normalizado em minúsculas). Extraído de administrative_area_level_1 do Google Maps. Opcional - Pode estar vazio em países sem divisão regional.","example":"comunidad de madrid"},"zipcode":{"type":"string","description":"Código postal conforme ao formato do país correspondente. Extraído do componente postal_code da API do Google Maps. Utilizado em validações de zona e cálculos de tarifas.","example":"28045"},"country":{"type":"string","description":"Código do país ISO 3166-1 alpha-2 em MAIÚSCULAS (2 letras). **Crítico** para: validação de TaxID, formato de matrícula, cálculo de tarifas, restrições ADR. Extraído do componente de país (short_name) da API do Google Maps. Deve corresponder aos países ativos na collection 'countries'.","pattern":"^[A-Z]{2}$","example":"ES"},"neighborhood":{"type":"string","description":"Bairro ou zona dentro da cidade (opcional). Extraído de neighborhood ou sublocality do Google Maps. Usado para precisão em grandes zonas urbanas.","example":"centro"},"province":{"type":"string","description":"Província ou divisão administrativa provincial. Extraído de administrative_area_level_2 do Google Maps (em países com províncias). Opcional - Relevante principalmente na Espanha, Itália, etc.","example":"madrid"},"location":{"type":"object","description":"Coordenadas geográficas no formato GeoJSON Point conforme ao padrão RFC 7946. Sistema de referência: WGS84 (EPSG:4326). **OBRIGATÓRIO** - Usado pelo MongoDB para consultas geoespaciais ($near, $geoWithin). **CRÍTICO**: A ordem no array coordinates é [longitude, latitude] (X, Y) - NÃO inverter. Usado em: cálculo de distâncias, rotas ótimas, validação de zonas de serviço.","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point"],"description":"Tipo de geometria GeoJSON. Deve ser sempre Point para endereços. Outros tipos (LineString, Polygon) não são válidos neste contexto.","example":"Point"},"coordinates":{"type":"array","description":"Array de dois números: [longitude, latitude] em graus decimais. **ORDEM CRÍTICA**: longitude primeiro (eixo X, -180 a 180), latitude segundo (eixo Y, -90 a 90). Exemplo válido: [-3.70379, 40.416775] = 3.70° Oeste, 40.41° Norte (Madrid). **ERRO COMUM**: Inverter a ordem causa cálculos incorretos. Usado em: model.find({location: {$near: {$geometry: {type: 'Point', coordinates: [lng, lat]}}}})","items":{"type":"number"},"minItems":2,"maxItems":2,"example":[-3.70379,40.416775]}}},"placeId":{"type":"string","description":"Identificador único e imutável do Google Place para esta localização. Usado para: geocodificação reversa, validação de alterações, obtenção de detalhes atualizados. Formato: String alfanumérica que geralmente começa com ChIJ. Persistido para evitar geocodificações repetidas (economia de custos de API).","example":"ChIJi-AoYTIoQg0RnHvWosEVABQ"},"name_address":{"type":"string","description":"Endereço completo formatado gerado pelo Google Maps (formatted_address). Inclui: rua, número, código postal, cidade, país no formato local. Usado em: exibição para usuários, exportações, documentos oficiais. Não editável manualmente - regenerado automaticamente ao atualizar coordenadas.","example":"Calle de Alcalá, 42, 28014 Madrid, España"},"isDefault":{"type":"boolean","description":"Indica se este é o endereço principal/padrão da empresa. **Restrição**: Só pode haver um endereço com isDefault=true por empresa. Ao definir isDefault=true em um endereço, o anterior com este flag é automaticamente alterado para false. Usado em: preenchimento automático de formulários, endereço padrão em novos leilões. Também armazenado em: company.address_default (referência ao _id deste endereço).","default":false,"example":true},"can_be_deleted":{"type":"boolean","description":"Flag calculado dinamicamente no momento da consulta (não armazenado no banco de dados). **false**: O endereço está referenciado em leilões ou entregas ativas (status != canceled/delivered). **true**: O endereço não tem dependências e pode ser excluído com segurança. Calculado em: controller.get() verificando a contagem de auction/delivery onde etl_address ou etd_address == this._id Previne: exclusão acidental de endereços em uso que causaria dados órfãos.","example":false},"destinations":{"type":"array","description":"Array de destinos frequentes com rotas pré-calculadas a partir deste endereço. **Otimização**: Evita recálculo de rotas repetitivas, melhora desempenho na busca de leilões. Populado em: cron noturno ou sob demanda para pares de endereços frequentes. Usado em: endpoint /company/minimal para cálculos de custo/distância sem chamar API externa. Estrutura: [{address: ObjectId, minimalRoute: {distance: Number(km), timeCost: Number(min)}}]","items":{"type":"object","properties":{"address":{"type":"string","description":"ObjectId do endereço de destino","example":"507f1f77bcf86cd799439012"},"minimalRoute":{"type":"object","properties":{"distance":{"type":"number","description":"Distância calculada em quilômetros (via API de rotas)","example":523.7},"timeCost":{"type":"number","description":"Tempo estimado de viagem em minutos (considerando velocidade média)","example":360}}}}}}},"required":["_id","name","location","isDefault","can_be_deleted"],"title":"Address"}}},"headers":{}},"400":{"description":"Erro de validação - Campos obrigatórios ausentes ou formato inválido","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["MISSING_FIELD_LAT","MISSING_FIELD_LNG","MISSING_FIELD_NAME","MISSING_FIELD_COMPANY_NAME","INVALID_COORDINATES"],"example":"MISSING_FIELD_LAT"}}}}},"headers":{}},"401":{"description":"Erro de autenticação - Token inválido ou empresa não encontrada","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["USER_NOT_FOUND","CIA_NOT_FOUND"],"example":"CIA_NOT_FOUND"}}}}},"headers":{}},"404":{"description":"Usuário não encontrado","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"USER_NOT_FOUND"}}}}},"headers":{}},"500":{"description":"Erro interno do servidor","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["CANNOT_SAVE_ADDRESS","INTERNAL_ERROR"],"example":"CANNOT_SAVE_ADDRESS"}}}}},"headers":{}}}}
>
</StatusCodes>