README.md

# VtexWs

## Arquitetura do Sistema
 ![Fluxo do Sistema](./public/images/readme/flux.png)

## Fluxo do Sistema

- Vtex faz um post para a rota vtex/:app_slug/notification (ex: app_slug = "rihappy"")
```json
{
  "IdSku": "37800",
  "ProductId": 37800, 
  "An": "rihappy",
  "IdAffiliate": "TDC",
  "Version": "00000000000000000000000000000000",
  "DateModified": "2020-04-03T00:01:04.5673672Z", 
  "IsActive": false, 
  "StockModified": false, 
  "PriceModified": false, 
  "HasStockKeepingUnitModified": true, 
  "HasStockKeepingUnitRemovedFromAffiliate": false
}
```
- A controller **NotificationController** action **notification** enfileira um job no **Redis**.
- O Worker **NotificationWorker** é responsável por consolidar o produto em 3 etapas (fazendo requisições para a **Vtex**):
    1. Pegar o preço
    2. Pegar o estoque
    3. Pegar os metadados do produto
- Uma vez consolidado o produto há duas opções:
    1. O produto foi consolidado sem erros, nesse caso ele é enviado para o **Amazon SQS**.
    2. Houve algum erro nas requisições. Nesse caso o job é enfileirado novamente incrementando o parâmetro **retry**. Caso o **retry** seja 10 então é disparado um **Bugsnag**.
- O App Manager possui um listener que escuta os produtos enviados para o **Amazon SQS**: ProductConsolidationService.
- Quando o **Service** resgata esses produtos do **SQS**, eles são enviados para um Worker responsável por salvá-los no Banco de Dados: **ProductConsolidationWorker**.    

####Observações:
Existe um processo paralelo que ocorre no Notification Worker que é a consolidação de **Categorias**.
As categorias são consolidadas no seguinte fluxo:
- Ao pegar os metadados do produto, um deles são os **category ids**.
- A partir dos **category ids** fazemos requisições pra **Vtex** para pegar as informações de cada categoria.
- Uma vez consolidadas é chamado o método **Categories.consolidate_all_by_app!** que atualiza cada uma no **App Manager**. Observação: Existe uma estratégia de **cache** em **VtexWs.Categories** que atualiza as categorias só uma vez por semana.
- No **App Manager** existe um endpoint que faz o **create/update** de categorias.

Sobre a estratégia de cache:
Como muitos produtos compartilham categorias entre si não é necessário atualizar as categorias toda vez, pra isso foi desenvolvida uma estratégia de cache usando o Redis que guarda os ids das categorias por app num key value que expira a cada semana. Antes de atualizar cada categoria é verificado se ela existe no redis, se ela não existir(por que nunca foi consolidada ou expirou) então ela é atualizada/criada no **App Manager**.

## Documentação
[https://hexdocs.pm/vtexws/0.1.0](https://hexdocs.pm/vtexws/0.1.0)

## Referência VTEX
[https://help.vtex.com/tutorial/integration-guide-consuming-catalog-information-for-use-in-an-external-service](https://help.vtex.com/tutorial/integration-guide-consuming-catalog-information-for-use-in-an-external-service--3j15zRDuismM42Y8SoGMO2)