Desafio Kanban - Envio do desafio valinor - Pedro Paulo Cividanes#492
Open
Pedro-Paulo-Mendes wants to merge 1 commit intoFieldControl:masterfrom
Open
Desafio Kanban - Envio do desafio valinor - Pedro Paulo Cividanes#492Pedro-Paulo-Mendes wants to merge 1 commit intoFieldControl:masterfrom
Pedro-Paulo-Mendes wants to merge 1 commit intoFieldControl:masterfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Respostas
Envio de solução
Framework, linguagem e ferramentas
Back-end —
kanban-apiFront-end —
kanban-webTécnologias X e Y
NestJS em vez de Express puro
Quando comecei a pensar na arquitetura da API, o Express seria a opção mais simples e rápida. Porém, sem uma estrutura opinada, o código cresce desorganizado — principalmente em projetos separados por módulos como este. O NestJS me deu uma arquitetura consistente desde o início, com injeção de dependência nativa, decorators, separação em módulos (
ColumnsModule,CardsModule) e um ciclo de vida claro. Para um desafio onde organização e boas práticas são critérios de avaliação, fazia muito mais sentido.Angular em vez de React ou Vue
O desafio pedia explicitamente o uso do Angular, então não havia dúvida aqui. Mas mesmo como escolha própria, o Angular se encaixa bem: ele já vem com tudo que preciso (HttpClient, FormsModule, CDK, roteamento), sem precisar montar um ecossistema na mão. O sistema de tipagem forte com TypeScript e a organização por componentes também me ajudam a manter o código legível.
Angular CDK em vez de uma biblioteca de drag-and-drop externa
Optei pelo
@angular/cdkem vez de bibliotecas comoSortableJSoung-drag-dropporque ele é o módulo oficial do ecossistema Angular, mantido pela própria equipe do framework. Isso evita conflitos de versão, atualização quebrada de dependências e edge cases bizarros. OtransferArrayItemdo CDK resolveu o movimento de cards entre colunas de forma limpa e confiável.JSON como persistência em vez de um banco de dados
Para o escopo deste desafio, não quis adicionar a complexidade de configurar um banco relacional ou NoSQL. A persistência via arquivo
cards.jsoné suficiente para demonstrar a lógica de CRUD e mantém a API autossuficiente. Já sei que isso tem limitações (discuto isso na seção de melhorias).Vitest em vez de Karma/Jasmine
O Karma era o test runner padrão do Angular por anos, mas está sendo descontinuado. O Vitest é significativamente mais rápido, tem suporte nativo a ESM e integração direta com o Angular moderno. Faz mais sentido adotar o que está chegando do que manter o que está saindo.
Princípios de software
ColumnsServicerecebe oCardsServicevia construtor, sem criar instâncias manualmente. No Angular, oKanbanServiceé injetado no componente pelo próprio framework.CreateCardDto,UpdateCardDto, etc.), garantindo que payloads inválidos ou maliciosos sejam rejeitados antes de chegar na lógica da aplicação.loadColumns,submitCard,requestDeleteColumneconfirmDeletedescrevem exatamente o que cada função faz, sem precisar de comentários para explicar.KanbanService.ChangeDetectionStrategy.OnPushpara que o Angular só re-renderize os componentes quando os dados realmente mudam, evitando re-renders desnecessários.ValidationPipeglobal comwhitelist: trueeforbidNonWhitelisted: truegarante que nenhum campo não declarado no DTO chegue a ser processado.Desafios e problemas
CORS entre Vercel e Render
O maior desafio foi a configuração de CORS. Em ambiente de desenvolvimento tudo funcionava perfeitamente, mas ao publicar o front na Vercel e a API no Render os requests começavam a ser bloqueados. Resolvi habilitando o
app.enableCors()nomain.tsda API e configurando overcel.jsonno front-end com os rewrites corretos para o domínio do Render.Sincronização de estado com o drag-and-drop
Mover um card entre colunas parecia simples visualmente, mas garantir que o
columnIddo card fosse atualizado corretamente na API (e não apenas na tela) exigiu atenção. A solução foi chamar okanbanService.updateCard(card)assim que otransferArrayItemdo CDK era executado, atualizando ocolumnIddo card antes de passar para o array de destino.ChangeDetection com OnPush e chamadas assíncronas
Ao usar
ChangeDetectionStrategy.OnPush, percebi que as respostas das chamadas HTTP não estavam refletindo na interface automaticamente, já que saem fora do ciclo de detecção do Angular. Resolvi usandoNgZone.run()para garantir que as atualizações de estado acontecessem dentro da zona do Angular, forçando o re-render corretamente.Persistência no Render com sistema de arquivos efêmero
O Render tem um sistema de arquivos efêmero — ou seja, os dados do
cards.jsonsão perdidos sempre que o servidor reinicia. Isso é uma limitação conhecida e documentada. Para o escopo do desafio é aceitável, mas já tenho em mente como resolver (veja a próxima seção).Melhorias e próximas implementações
cards.jsonpor um banco como PostgreSQL (via TypeORM ou Prisma), resolvendo o problema de persistência efêmera no Render e abrindo caminho pra queries mais complexas.ordere persistir a posição após cada drag-and-drop.Vídeo de apresentação
🎬 Assista à gravação do projeto rodando
Sobre você
Oi, sou o Pedro Paulo Mendes Cividanes, tenho 19 anos e sou nativo de São José do Rio Preto.
Estudei no Colégio Anglo Rio Preto e, paralelamente, fiz alguns cursos no SENAI, como Power BI e Java Foundations, que me ajudaram a entrar mais fundo no mundo da tecnologia. Hoje estou no terceiro semestre de Ciências da Computação na UNIP.
Comecei a me interessar por desenvolvimento porque quero ter qualidade de vida com minha família em uma área que me permita trabalhar de casa, sendo próximo das pessoas que amo — e ao mesmo tempo continuar aprendendo sobre como o mundo (e a web) funcionam por baixo dos panos. Automatizar processos e entender o funcionamento real das coisas são as partes que mais me motivam.
Trabalho na prefeitura de Rio Preto na Secretaria Municipal da Educação, onde desenvolvo jogos educativos usados em escolas da cidade. Já fiz projetos para a minha igreja e estou desenvolvendo com alguns amigos um sistema de gerenciamento de estoque. Tudo isso enquanto ainda estou na faculdade, o que tem sido uma escola e tanto.
Meu GitHub é Pedro-Paulo-Mendes.
Outros detalhes
Este foi meu primeiro contato com NestJS de forma mais aprofundada. Já tinha visto o framework em tutoriais, mas construí esta API do zero durante o desafio e aproveitei para entender de verdade o que acontece em cada camada. Foi desafiador e muito enriquecedor ao mesmo tempo.
A aplicação está publicada e funcionando em produção:
📧 pedropmc07@gmail.com
📱 (17) 98227-4524