As decisões por trás de um projeto back-end real
Sobre o Evento
No primeiro evento ao vivo da comunidade Aguiar Dev, Tiago Aguiar recebeu Thais Cavalcante, desenvolvedora júnior, para olhar por dentro de um projeto que foge do "CRUD básico": um motor de liquidação financeira em C# e .NET. A conversa não tratou de certo ou errado, e sim de por que cada decisão foi tomada e o que muda quando o projeto cresce.
O que foi discutido
- O projeto: um motor que calcula a data de liquidação de operações com ações (D+2), pulando finais de semana e feriados, com um front-end simples em React que simula a tela de um banco
- A organização em camadas: controllers que só recebem, delegam e devolvem; services com as regras do sistema; repositórios para o acesso a dados
- O padrão Repository: quando faz sentido, quando é exagero e por que usar interfaces facilita a injeção de dependência e os testes
- A regra dos dias úteis: um cálculo que avança um dia por vez e só conta quando o dia não é fim de semana nem feriado, usando o
DayOfWeekdo .NET em vez de números soltos - Os DTOs: devolver só o que o front-end precisa, e a conversa sobre
class,recordestruct - O
DataSeedere as migrations: carga de dados iniciais sem duplicar a cada execução e versionamento do banco gerado pelo Entity Framework - O
ExceptionMiddleware: um ponto único no pipeline do ASP.NET para capturar erros e devolver um JSON padronizado - Dicas de mercado: empresas do setor financeiro que usam .NET, como BTG, XP, PicPay e Itaú
Sobre Thais Cavalcante
Thais é desenvolvedora júnior e cursa Análise e Desenvolvimento de Sistemas. Sempre teve interesse pelo universo financeiro e quis entender como uma instituição calcula, por exemplo, em que dia o dinheiro de uma ação cai na conta. Montou o motor de liquidação como projeto de estudo para evoluir em C# e .NET, e apresentou o trabalho de forma transparente: ainda em andamento, com partes mais avançadas por fazer, mas com o essencial funcionando.
Principais pontos
Um projeto de estudo com problema de verdade
Em vez de mais uma Pokédex ou cadastro de locadora, Thais partiu de uma dúvida concreta do mercado financeiro: como um sistema sabe pular fins de semana e feriados ao contar prazos de liquidação. Um erro nesse cálculo pode gerar prejuízo, o que dá ao projeto um problema com regras reais. Tiago destacou que esse tipo de escolha tira o iniciante da zona de conforto e funciona bem como portfólio, porque mostra maturidade mesmo em quem está começando.
"como que o sistema sabe pular um feriado, pular um final de semana, porque a partir do momento que esse cálculo é feito errado, ele pode quebrar, pode trazer muito prejuízo, então, a partir dessa curiosidade, eu decidi criar um motor para entender como funciona." por Thais Cavalcante
Controller só recebe, delega e devolve
O projeto separa controllers, services, domínio, dados e testes. Na controller há apenas a comunicação HTTP; a regra mora no service, que valida o cliente, busca o ativo e calcula a liquidação. Thais evitou o erro comum de empilhar lógica na controller porque soube antes que isso viraria bagunça. Na conversa sobre o Repository, Tiago explicou que o padrão é uma forma de organizar o acesso a dados, que cresce em valor em projetos robustos e pode ser dispensado em escopos pequenos e fechados. Ele também recomendou injetar interfaces, e não classes concretas, para viabilizar testes unitários.
"eu só não fiz isso porque eu tive a informação antes de que poderia virar uma bagunça" por Thais Cavalcante
DTO: devolver só o que o front-end precisa
Thais aprendeu sobre DTOs no meio do desenvolvimento, quando percebeu que precisava: a entidade tem mais campos do que a tela deve ver, então ela converte a entidade para um objeto de resposta com apenas os dados necessários. Tiago acrescentou o argumento do tráfego: quanto menos dados trafegam, menor a latência e o consumo do plano de dados de quem usa o aplicativo no celular. A conversa passou ainda por record e struct como alternativas à class, com a observação de que o record, imutável e de sintaxe mais enxuta, tende a valer mais o estudo.
"ele tem muito mais informação do que o front-end precisa ver" por Thais Cavalcante
DataSeeder e migrations: o projeto sobe do zero
O DataSeeder verifica o que já existe antes de inserir, então a aplicação pode reiniciar quantas vezes for preciso sem duplicar dados. Tiago complementou que o seeder serve para cadastros essenciais do sistema, não para dados que vêm do usuário, e que em produção ele costuma ser controlado por uma configuração no appsettings. As migrations, geradas pelo Entity Framework, versionam o banco e são aplicadas em ordem quando a API sobe no Docker. Tiago ainda sugeriu dividir mudanças em várias migrations menores, para poder reverter só a parte que deu problema.
"ao invés de eu estar rodando aqui um SQL na mão em cada máquina o entity framework que foi o que gerou esse arquivo aqui ele gera automaticamente tudo isso aqui com base nas minhas classes" por Thais Cavalcante
Um middleware para todos os erros
O ExceptionMiddleware fica no início do pipeline do ASP.NET e captura qualquer exceção não tratada, devolvendo ao cliente um JSON com status e mensagem. Tiago explicou o conceito de pipeline e de RequestDelegate, e defendeu que ter um ponto central de padronização é quase sempre bom, mesmo com try/catch em pontos específicos onde se quer agregar informação. O erro a evitar é deixar uma exceção inesperada chegar ao cliente em formato feio.
"em vez de colocar um try cat no método completo esse midwere ele fica meio que no início aqui do pipeline então qualquer erro que acontecer em qualquer lugar aqui da aplicação ele consegue interceptar esse erro e devolver um JSON padronizado" por Thais Cavalcante
Frase de destaque
"mas ao trocar a ideia com você eu percebi que eu aprendi mais eu apliquei mais na prática, consegui pensar além então é muito legal essa troca" por Thais Cavalcante
Lições do evento
- Projetos de estudo ficam melhores quando partem de um problema real e com regras que dão trabalho, como o cálculo de dias úteis do mercado financeiro.
- Controller recebe, delega e devolve; a regra de negócio vive em services, o que evita bagunça e facilita os testes.
- Padrões como Repository dependem do contexto: valem em projetos que vão crescer e podem ser exagero em escopos pequenos e fechados.
- DTOs entregam só o necessário ao cliente, o que protege a entidade e reduz o tráfego de dados.
- Seeder idempotente e migrations geradas pelo framework permitem que qualquer pessoa suba o projeto do zero sem passos manuais.
- Discutir o código com alguém mais experiente revela perguntas que o iniciante nem sabia que existiam.