A proposta desse estudo é visualizar uma maneira em que a retaguarda envie arquivos de dados ao Sync Server, que serão processados pelo Sync Client no PDV. Isso não substitui a API, mas complementa o fluxo para situações em que seja mais eficiente carregar os dados dessa maneira.
Desafios gerados para esse estudo foram:
Na solução proposta foi desenhado o seguinte escopo:

Para esse fluxo, foi considerado o envio do arquivo pelo Bucked Cloud. No teste realizado, foi utilizado o bucket do GCP (biblioteca Google.Cloud.Storage).
Para o uso do bucket de arquivos do GCP, deve ser considerado as seguintes observações:
PRINCIPAIS RECURSOS:
✅Armazenamento escalável para grandes volumes de dados
✅ Alto desempenho para leitura e escrita de arquivos
✅ Suporte a múltiplos tipos de armazenamento (Standard, Nearline, Coldline e Archive)
✅ Integração com serviços Google (BigQuery, AI, Kubernetes, etc.)
✅ Segurança com criptografia automática e permissões IAM
✅ Versionamento e backup de arquivos
TIPOS DE STORAGE E CASOS DE USO:
| Tipo de Armazenamento | Custo ($/GB/mês) | Recuperação | Uso Ideal |
|---|---|---|---|
| Standard | $$$ (Alto) | Rápido | Dados acessados frequentemente |
| Nearline | $$ (Médio) | Leve atraso | Backups, arquivamento de médio prazo |
| Coldline | $ (Baixo) | Demorado | Dados raramente acessados (1x por ano) |
| Archive | $ (Muito Baixo) | Muito lento | Arquivamento de longo prazo |
Exemplo de Preços (EUA, Março/2024):
Standard: $0.023/GB
Nearline: $0.01/GB
Coldline: $0.004/GB
Archive: $0.0012/GB
Os preços variam conforme a região e volume de armazenamento.
Para o nosso caso, o tipo de armazenamento standard é o mais recomendado, visto que precisamos de um processo que a subida de arquivo seja feita de forma rápida e que o mesmo seja acessado frequentemente (subindo o arquivo uma vez e baixando o arquivo apenas uma vez na máquina local para o recebimento dos dados via arquivo).
✔ Escalabilidade → Suporta petabytes de dados sem limitação de tamanho.
✔ Segurança Avançada → Dados criptografados e integração com IAM.
✔ Baixa Latência → Alta performance para leitura e escrita de arquivos.
✔ Multi-Regional → Armazene dados em várias regiões para redundância.
✔ Integração com BigQuery, AI e Kubernetes.
❌ Custo pode ser alto para grandes volumes de dados em classes Standard.
❌ Cobrança por requisições e downloads → Cada leitura/escrita pode gerar custos extras.
❌ Necessidade de autenticação → Exige configuração de chaves e permissões via IAM.
❌ Recuperação lenta em Coldline/Archive → Pode levar horas para acessar arquivos arquivados.
No teste foi criado duas APIs simulando a subida e download de um arquivo via bucket cloud do GCP.
No GCP foi criado um bucket onde fosse possível armazenar os arquivos subidos através da API.

Para a criação do bucket foi necessário colocar permissão de envio/baixa de arquivo para o usuário utilizado no micro serviço de Controle que faz o acesso ao diretório através da aplicação.
Após a criação do bucket, foi criado as APIs POST para envio do arquivo e a API GET para a baixa do arquivo.
API POST - Carga Loja - Envio:


API GET - Baixa do Arquivo:

Para a solução proposta, é necessário que o arquivo enviado esteja criptografado. Para isso, iremos utilizar o modelo AES, já utilizado dentro do PDV SYNC, na criptografia de senhas do banco de dados dos serviços do client.
Para isso, podemos utilizar o modelo abaixo para criptografia do arquivo, uma vez que o arquivo enviado já tem que estar devidamente criptografado.
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
class AESFileEncryption
{
static void Main()
{
string filePath = "C:\\Temp\\arquivo.txt"; // Arquivo original
string encryptedFilePath = "C:\\Temp\\arquivo_encrypted.aes"; // Arquivo criptografado
string decryptedFilePath = "C:\\Temp\\arquivo_decrypted.txt"; // Arquivo descriptografado
// Gerar chave e IV AES-256
byte[] key = GenerateRandomKey(32); // 256 bits
byte[] iv = GenerateRandomKey(16); // 128 bits
Console.WriteLine($"🔑 Chave AES-256: {Convert.ToBase64String(key)}");
Console.WriteLine($"🌀 IV: {Convert.ToBase64String(iv)}");
// Criptografar arquivo
EncryptFile(filePath, encryptedFilePath, key, iv);
Console.WriteLine("✅ Arquivo criptografado com sucesso!");
// Descriptografar arquivo
DecryptFile(encryptedFilePath, decryptedFilePath, key, iv);
Console.WriteLine("✅ Arquivo descriptografado com sucesso!");
}
// Método para gerar chave e IV aleatórios
static byte[] GenerateRandomKey(int size)
{
using (var rng = new RNGCryptoServiceProvider())
{
byte[] key = new byte[size];
rng.GetBytes(key);
return key;
}
}
// Método para descriptografar um arquivo
public static void DecryptFile(string inputFile, string outputFile, byte[] key, byte[] iv)
{
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using (FileStream fsInput = new FileStream(inputFile, FileMode.Open))
using (CryptoStream cryptoStream = new CryptoStream(fsInput, aes.CreateDecryptor(), CryptoStreamMode.Read))
using (FileStream fsOutput = new FileStream(outputFile, FileMode.Create))
{
cryptoStream.CopyTo(fsOutput);
}
}
}
} |
Para a baixa de arquivo de carga, o modelo ideal para a proposta seria a seguinte:
O solução proposta unindo todos esses pontos é eficiente, rápido e eficaz, uma vez que o processo de leitura/gravação de dados por arquivo já está implementado no client, com a baixa de dados via Function, e com o modelo de dados proposto para o envio do arquivo para o server, vai gerar mais fluidez para o processo de carga inicial de uma loja. Dito isso, as issues de história que devemos considerar para que esse modelo acima seja seguido são: