# Shipping Cost:
## Handler:
1. inclui o shipment no log (X-Shipment-Id);
2. recebe o payload via body (POST);
3. executa o **método de cálculo**;
4. Se o shipment for inválido, retorna 404;
5. Com o resultado dos cálculos em mão, varre as rotas (json resposta), e seta o custo para cada uma juntamente com o valor dos steps;
## Route Service (método de cálculo):
1. Gera os requests (entra em cada rota);
2. Para cada rota, [identifica](https://github.com/mercadolibre/fury_shipping-cost-api/blob/53e5d7d28675dd158115c5cb9f3cd33f48292f09/cost/route_service.go#L112) se a mesma é um cross_docking, fulfillment, first_mile ou drop_off;
3. Dentro de cada rota, e com o picking type calculado, filtra tudo que é `transitional`;
4. [Valida](https://github.com/mercadolibre/fury_shipping-cost-api/blob/53e5d7d28675dd158115c5cb9f3cd33f48292f09/cost/route_service.go#L121-L123) que a rota é válida sabendo que o step filtrado não é o primeiro, ou o último;
5. Gera o request com as informações:
1. Mile;
2. Price
3. Dimensions (Length, Weight, Width, Height);
4. ServiceID
5. Operation (picking_type calculado anteriormente);
6. Se houver país de origem e destino setados no request no passo anterior, marca o step como `cbt`;
7. De volta no método de gerar requests, após todas as rotas calculadas uma métrica de `destination_info` é incrementada;
8. É retornado uma lista com todas as requests;
9. Chama o método de realizar o request de acordo com o tipo de configuração da calculadora;
9.1 Se houver logistic center (`payload.Origin.LogisticCenterID != ""`), busca o logistic center na API de logist centers, e seta a informação de zipcode e city_id (tanto para origem como para destino);
9.2 para cada serviceID/payload dentro do request, busca a config no DB da calculadora adequada;
9.3 Se a calculadora for `fixed`, um novo valor calculado é retornado com o serviceID e o custo configurado na calculadora;
9.4 preenche um mapa com a informação de quais os service IDs são utilizados para que tipo de calculadora;
9.5 se qualquer erro for identificado na busca das calculadoras, o cálculo não é realizado;
9.6 Para cada calculadora preenchida no passo 9.4, se for commercial-carriers:
9.7 É buscado o momento do cálculo baseado no país de origem, convertendo a data atual para UTC, e adicionando horas e minutos de acordo com o timezone do país;
9.8 é feita uma request para a cc-cost-calculator:
9.8.1 se a API estiver fora ou um erro for retornado, retornamos um erro;
9.8.2 se o status code for 422, retornamos um resultado de cálculo "vazio";
9.8.2 se tudo der certo, adicionamos o valor retornado na cc-cost dentro da lista de cálculos realizados;
9.9 se nenhum cálculo foi realizado (ver o ponto 9.8.2) e não houver erros, utilizamos o fallback para retornar (para MLM é 999999);
10. Salva a resposta do cálculo em uma lista;
11. Itera sobre a lista retornada, setando o valor do custo em cada step transitional existente, e também calculando o valor total da rota para setar posteriormente;
## CC-Cost-Calculator
```
scopeMLMStep, weightStep, rateStep, baseCostStep, extraCostStep, finalCostStep
```
1. Obtem o service config com base no serviceID;
2. É escolhido a "pipeline" com base no service config/scope calculation type (no caso de MLM, se o Scope calculation type do service config for MLM, esse será considerado);
3. A pipeline é executada (steps);
5. O retorno com o custo calculado dentro da pipeline é preenchido;
6. O valor é retornado para a shipping-cost-api;
### Steps
#### 1. Scopes MLM
É enviado um request para a freight-rate-api com:
- carrierID;
- cep de origem;
- cep de destino;
- hora do cálculo;
- carrier service (service config)
A freight-rate faz a seleção do âmbito correto, e retorna para a cc-cost.
#### 2. Weight Step
.....
# Shipping Costs | Pré-compra
## Contexto e problema
Existe uma necessidade de incluir custos em pré-compra para o site de méxico (MLM). De acordo com os testes realizados, a arquitetura de custos suporta em torno de 20K requisições respondendo em um tempo "aceitável" para pós-compra, porém, não para o que se espera do pré-compra (p99 < 70ms). Além disso, a arquitetura atual possui três pontos de chamadas (shipping-cost-api, cc-cost-calculator e freight-rate-api), escalar esta mesma arquitetura para pré-compra levaria a um custo de infraestrutura bem mais alto do que conseguiríamos remodelando a mesma.
### Modelo de arquitetura
https://drive.google.com/file/d/1yGmnX5BS2VniZ9UaloVqFkdoCLv0IZTD/view?usp=sharing
### O que está incluso neste MVP?
- Regras específicas para o modelo de MLM;
- Será específica para identificar rotas de commercial carriers last-mile;
- API que unifica o que atualmente faz a shipping-cost-api e a cc-cost-calculator;
- Possíveis desenvolvimentos na API de tarifários (freight-rate-api);
### Qual a previsão de entrega?
Primeiro quinzena de novembro.
### Objetivos
- Incluir custos na pré-compra;
- Conseguir responder no mínimo 200K de requisições em um tempo inferior a (p99 < 70ms);
- Resolver o problema de saltos de rede que ocorrem na arquitetura de pós-compra;
- Disponibilizar uma infraestrutura "mais em conta", específica para o processo de pré-compra na primeira quinzena de novembro;
### Stakeholders
- Thiago Marques - PL Costs (thiago.tmarques@mercadolivre.com);
- Cleisson - Manager Costs (Cleisson Da Silva Barboza)
- Equipe de Tarifários (freight-rate): Jairo, Joel, Shara;
- Equipe de route-options: ????;
- Fernando Gomez (fernando.gomez@mercadolibre.com);
- Manuel Mendez (manuel.mendez@mercadolibre.com);
## Perguntas que precisam de resposta:
=
- [ ] Qual o troughput (rate limit) da nova API?
- [ ] Quantas instâncias vamos ter ativas?
- [ ] O que fazer em caso de falha no object storage?
- [ ] O que fazer em falha de consumir um dado na freight-rate-api?
- [ ] O que acontece quando um dado é atualizado na freight-rate (service-config, âmbitos e tarifários)?
- [ ] Vamos ter um endpoint único na freight-rate que retorna todos os dados, ou vários endpoints para cada recurso?
- [ ] Vamos continuar retornando fallback não definido na freight-rate? (um fallback definido na freight-rate significa que foi carregado um arquivo com N/A em sua chave);
- [ ] O que acontece se há uma mudança de contrato na freight-rate e quebrar a montagem do snapshot?
- [ ] Como atrelar uma versão (se houver) do snapshot para a versão da API em produção?
- [ ] Podemos receber e retornar um payload na mesma estrutura, mas sem os campos preenchidos?
- [ ] Vamos ter um circuit-breaker em route-options para quando falharmos?
## Perguntas para
- [ ] No fluxo de pós-compra, existe uma propriedade `price (goods_value)`, a qual é utilizada para calcular um custo-extra com base no valor do produto (PRODUCT_TYPE), já no fluxo de pré-compra esse valor vem zero (0). No momento em que recebermos a requisição, esse valor será preenchido? Detalhe importante: não temos nenhum custo extra em MLM com essa configuração ativa, são todos de MLB.