/projects/dietbox

← Todos os projetos

Dietbox Webapp

Nenhuma das APIs de hoje existia. Tudo começou aqui dentro.

Engenheiro de Software Sênior, depois Head de Tecnologia · 2020–2024

C#ASP.NET MVCEntity FrameworkSQL ServerAzure App ServiceKendo UIAzure DevOps
WebsitePrivado
Captura de tela de Dietbox Webapp

Visão geral

Quando cheguei, isto era o produto. A ferramenta da nutricionista, a do paciente, assinaturas, dados de alimentos, login — uma base de código, uma entrega, um horário. Nenhum dos serviços que rodam ao lado hoje existia ainda. Ao longo de quatro anos fui tirando a lógica de dentro dele uma peça por vez e levantando cada peça como uma API própria, deixando o monolito atendendo o que ainda não tinha saído. Ele segue sendo a maior base de código do produto.

O que eu fiz

Arquiteto principal por quatro anos. Conduzi a extração — o que saía do monolito, em que ordem, e que forma tomava do outro lado —, defini os padrões da plataforma e configurei o ambiente Azure, inclusive para serviços escritos por outras pessoas. Depois, toda a área de tecnologia passou a se reportar a mim.

  • O pipeline de build e release no Azure DevOps, entregando o projeto principal junto com seus satélites e seu front end construído em gulp com Kendo UI.
  • Disponibilidade em produção e resposta a incidentes.

A maior base de código do produto foi trabalho de time — cerca de um sexto dos commits daquele repositório são meus.

O problema

A nutricionista vive na ferramenta o dia inteiro; o paciente abre para ler um plano alimentar. Mesmo produto, expectativas opostas. Em 2020 um monolito .NET Framework carregava os dois no Windows App Service — e o login, as assinaturas e os dados de alimentos junto —, com deploy uma vez por dia, de madrugada, porque era a única janela que parecia segura. Qualquer coisa que o produto precisasse fazer diferente tinha que ser feita lá dentro.

Em números

Os números de commit vêm do repositório. O resto é meu próprio registro do período.

~600commits no monolitomeus, de ~3,9 mil no total
4 anosna mesma base de códigode 2020 a 2024

Arquitetura

O projeto principal, seus dados, o job agendado ao lado dele, e o app Azure onde é publicado.

  1. Web applicationO projeto principal e seus satélites — catálogos, enums, infraestrutura compartilhada, recursos e relatórios — atrás de um front end construído em gulp com Kendo UI.
  2. Data layerEntity Framework sobre SQL Server, a base que o monolito lê e grava.
  3. Background jobsUm projeto de webjob para trabalho agendado — um único job diário — que fica no repositório mas fora da solution que a release compila, e é publicado por fora.
  4. Azure App ServiceUm app Windows com um slot de staging: a release publica o artefato construído no slot e depois faz o swap do slot para produção.

O que faz

  • Montagem de plano alimentar para a profissional, e o mesmo plano no app do paciente.
  • Dois caminhos de cadastro sobre um único sistema de identidade — a profissional que assina e o paciente convidado por ela.
  • Atualizações em tempo real enviadas a clientes abertos, sem recarregar.
  • Assinaturas e cobrança recorrente.

Decisões de engenharia

  • Um núcleo, vários satélites

    O projeto principal não carrega catálogos, enums, infraestrutura compartilhada, recursos e relatórios sozinho — cada um vive em seu próprio projeto satélite. Uma mudança em dado de referência não toca o mesmo projeto que uma mudança no caminho de requisição.

  • A release compila um alvo, não a solution

    O pipeline de release restaura a solution mas compila um único alvo — o projeto do site — e arquiva apenas o que aquele alvo publica. O projeto de webjob que fica ao lado, no mesmo repositório, não está na solution: ainda tem 4.7.2 como alvo enquanto o site tem 4.8, carrega as próprias configurações de publicação com agendamento diário, e não é tocado desde 2021. Nomear um alvo em vez de uma solution é o que impede um projeto nesse estado de entrar de carona numa release em que ninguém pretendia incluí-lo.

  • Release por troca de slot, não por sobrescrita

    O pipeline compila uma vez e publica esse único artefato no slot de staging do app; produção muda pelo swap do slot, não por sobrescrever o site enquanto ele atende. O que vai ao ar é um build que já estava rodando antes de receber tráfego, e o caminho de volta é o mesmo swap na direção contrária. É isso que um deploy precisa ser antes de poder acontecer de dia em vez de de madrugada.

  • Um monolito que se estrangula, não se reescreve

    O monolito não foi portado nem reescrito. A lógica saiu dele uma peça por vez — login, pagamentos, dados de alimentos, o back office, notificações, tempo real — e cada peça virou uma API rodando ao lado, enquanto o monolito seguia atendendo o que ainda não tinha saído. Uma reescrita disputaria as mesmas horas com as funcionalidades entregues no resto da plataforma, e o produto não podia parar enquanto isso acontecia.