Como entregamos um novo serviço em meio a um reshuffle sem deixar a bola cair
Com o advento do banco na SumUp, surgiu a necessidade das operações como transferências, pagamentos de contas e recarga de celular possuírem um registro com o qual o usuário pudesse consultar, compartilhar e comprovar suas transações. Essa nova funcionalidade foi idealizada para possuir uma infraestrutura que fosse independente do resto dos serviços já existentes, a fim de que esse nova aplicação de geração de recibos pudesse ser utilizada por outras equipes.
Porém nesse ínterim, devido a uma alteração estratégica – a mudança sempre é certa na SumUp — as equipes passaram por um reshuffle e foi nessa hora que cheguei na minha nova equipe.
Somos em três colegas de trabalho que cuidam do backend, porém nos conhecíamos apenas de vista e começamos a trabalhar juntos em meio a uma pandemia. Os outros colegas de equipe que cuidam do design e produto estavam preocupados, pois era esperado que a entrega do novo serviço atrasasse pelo menos um sprint (rodamos scrum com uma sprint de duas semanas), devido às mudanças na equipe e à falta de contexto dos novos integrantes.
Começamos com o primeiro passo que sempre tomamos na hora de desenvolver uma nova funcionalidade: definir a arquitetura bem como sua documentação, que para nós é extremamente viva e colaborativa. Fazer isso, facilitou a passagem do conhecimento e também tivemos oportunidade de questionar a solução proposta para entregar uma feature mais robusta.
A feature em questão possuía alguns requisitos atrelados a resiliência e consistência eventual. Não poderíamos falhar uma operação caso o comprovante não fosse gerado, tampouco esperar a geração para dar o feedback de sucesso para o nosso usuário. Além disso, inicialmente não planejamos permitir a geração de comprovantes para todas as operações e sim ter um lançamento faseado e controlado, a estratégia adotada junto com o time de produto para manter a consistência na experiência do usuário foi ter um fallback para os comprovantes que ainda não estavam habilitados.
Voltando ao ponto de como gerar os comprovantes atendendo nossos requisitos, dentre as diversas abordagens possíveis, optamos por extrair o máximo do elixir e utilizar GenServers juntamente com o Registry, independentes e assíncronos para isso. Sabemos que quanto mais resiliente uma solução, mais devemos nos preocupar com os fluxos de exceção, e um deles era a possibilidade de um usuário acessar um comprovante durante a geração, nesse caso dado a facilidade de lidar com processos dentro do elixir, então realizamos uma busca dos processos que estavam sendo executados e, caso o nosso estivesse lá, esperaríamos o resultado do processamento .
Então, logo na primeira semana, fizemos uma reunião para que nosso colega que estava há mais tempo na equipe, nos desse um compilado de como funcionavam as aplicações e qual era a parte da jornada do usuário a qual ficaríamos responsáveis.
Para que todos ficássemos alinhados e para nos conhecermos melhor (uma vez que a única coisa que tínhamos em comum era o uso da mesma linguagem de programação, o elixir), combinamos de fazer algumas tarefas em conjunto no novo projeto para irmos pegando o contexto. Passados alguns dias, adotamos a estratégia de pair programming, a fim de agilizarmos as entregas e não deixar nenhum colega travado.
Nos reuníamos sempre ao final do dia, para alinhar o progresso de cada um e tirar alguma dúvida remanescente para facilitar a comunicação e, para conseguirmos tocar o trabalho de forma assíncrona, criamos um canal no slack exclusivo para os backenders de forma que nenhuma informação fosse perdida ou esquecida.
Para fins de velocidade de entrega, escolhemos adicionar a aplicação de recibos dentro do que em elixir chamamos de umbrella app, um guarda chuva de aplicações que com isso, podemos reaproveitar a pipeline de deploy já existente, assim não gastamos tempo construindo a infraestrutura de um serviço novo. Já está planejado futuramente removê-la desse guarda chuva e tratá-la como um serviço totalmente separado, uma vez que não criando dependências com outras aplicações, o trabalho de removê-la do guarda chuva se torna mais simples.
No final do ciclo de sprint, fizemos com toda a equipe uma retrospectiva para apontar os pontos fortes e os pontos que precisaríamos melhorar.
Ao analisar o que poderíamos ter feito de melhor, percebemos que o mecanismo de re-tentativa de geração dos recibos poderia ter sido feito de maneira diferente. Tivemos um problema no qual, ao rodar uma migração para criar dados retroativos, cerca de 3% das transações não tiveram seus recibos criados. Isso nos forçou a recriar os dados retroativos mais uma vez. Uma alternativa para melhorarmos o fluxo é adicionarmos um mecanismo de worker, como o Oban.
Nas palavras do nosso gerente de produto, “o reshuffle foi superado sem problemas”. Terminamos com uma versão 100% funcional, com todos os templates de recibos necessários para colocar no aplicativo e de quebra, fizemos novos amigos.
Escrito coletivamente por Stevan Olegário, Felipe Piacsek e Felipe Araújo.