Voltar aos projetos
Logotipo de Pokemon

Pokemon

Plataforma com informações detalhadas de cada Pokémon, incluindo estatísticas, habilidades, movimentos, evoluções e características únicas.

AngularNestJSGraphQL

A seguir, apresento a análise técnica e arquitetural deste projeto de Pokédex, concebida para servir simultaneamente como documentação oficial do repositório e como estudo de caso. Meu foco principal é descrever o design do sistema, as decisões arquiteturais e os fluxos de dados de maneira analítica e objetiva.

1. Utilidade e Funcionamento Geral

A aplicação foi projetada para resolver o problema de indexação, busca e visualização de dados complexos de entidades “Pokémon”. Sua utilidade principal está em consolidar informações dispersas (estatísticas, linhas evolutivas, movimentos, descrições físicas) em uma interface de usuário visual coesa e de alta fidelidade.

O fluxo operacional principal ocorre da seguinte forma:

  1. Inicialização: Ao montar a aplicação web, o cliente solicita um estado base sincronizado com a URL atual. Se nenhum parâmetro estiver definido, o estado se sincroniza automaticamente com o identificador inicial (ID 1) e solicita o primeiro segmento paginado do diretório geral.
  2. Resolução de Dados: As consultas são enviadas por meio de operações GraphQL ao servidor backend. Esse serviço atua como intermediário para um banco de dados em memória pré-carregado com informações consolidadas, garantindo latência mínima.
  3. Processamento de Estado: As respostas da rede modificam um estado global imutável (NgRx Signals) no cliente.
  4. Atualização Reativa: Os componentes de apresentação, agnósticos à lógica de rede, recebem os novos dados (propriedades do Pokémon selecionado e a grade de paginação) e atualizam o DOM de acordo, refletindo elementos gráficos como modelos e estatísticas base.

2. Arquitetura Geral e Fluxos de Dados

Projetei o sistema com uma abordagem que combina os princípios de Clean Architecture e Domain-Driven Design (DDD) no backend, junto com um padrão Container/Presenter (Smart/Dumb Components) no frontend. A separação de responsabilidades garante alta manutenibilidade e escalabilidade.

Topologia do Sistema

O diagrama a seguir ilustra a interação entre os diferentes domínios do sistema:

graph TD
    subgraph Frontend [Cliente - Angular 19]
        UI_Layout[Layout/Componentes Smart]
        UI_Dumb[Componentes de Apresentação]
        Store[NgRx Signal Store]
        Service[Serviço GraphQL / Apollo]

        UI_Layout -->|Despacha Ações| Store
        Store -->|Fornece Estado Reativo| UI_Layout
        UI_Layout -->|Injeta Dados| UI_Dumb
        Store -->|Invoca Métodos| Service
    end

    subgraph Backend [Servidor - NestJS]
        Resolver[Resolver GraphQL]
        AppService[Serviço de Aplicação]
        Repository[Repositório em Memória]
        Entities[Entidades de Domínio]

        Service -->|Consultas GraphQL| Resolver
        Resolver -->|Injeção de Dependências| AppService
        AppService -->|Chamadas de Domínio| Repository
        Repository -.->|Mapeamento| Entities
    end

    subgraph Data [Camada de Persistência Inicial]
        Seed[Dados Seed JSON]
        PokeAPI[PokeAPI Externa]
        Repository -.->|Hidratação Inicial| Seed
        Seed -.->|Cache Prévio| PokeAPI
    end

Arquitetura do Backend

O servidor NestJS implementa uma abstração em camadas (Domain-Driven Design):

  • Camada de Apresentação (Resolvers): PokemonResolver define o contrato GraphQL (esquema gerado automaticamente) e gerencia os objetos de entrada (filtros, paginação).
  • Camada de Aplicação (Services): PokemonService orquestra os casos de uso, como a recuperação individual e a busca aproximada (fuzzy) de entidades.
  • Camada de Infraestrutura (Repositories): InMemoryPokemonRepository implementa os mecanismos reais de persistência. Nesta topologia, utiliza-se armazenamento em memória baseado em um conjunto de dados seed pré-gerado.
  • Camada de Domínio (Entities): Classes como Pokemon, PokemonStats e PokemonMove definem o núcleo do negócio.

Arquitetura do Frontend

O cliente Angular 19 utiliza o modelo NgRx Signals para um gerenciamento de estado altamente previsível e eficiente:

  • PokemonStore centraliza o estado global. Utiliza internamente fluxos reativos (RxJS) para a desfragmentação de eventos assíncronos (como o debounce da busca) antes de aplicar as alterações ao estado baseado em Signals.
  • Os componentes são estritamente divididos entre os que gerenciam layout/estado e os que se encarregam da renderização pura (UI Glassmorphism).

3. Modelagem de Dados e Lógica de Negócio

A entidade principal, Pokemon, encapsula a complexidade dos dados associados.

classDiagram
    class Pokemon {
        +String id
        +Number number
        +String name
        +String[] types
        +String description
        +PokemonPhysic physic
        +PokemonStats stats
        +PokemonEvolution evolution
        +PokemonMove[] moves
    }
    class PokemonStats {
        +Number health
        +Number attack
        +Number defense
        +Number resistance
        +Number speed
    }
    class PokemonMove {
        +String name
        +String type
        +Number damage
    }
    class PokemonPhysic {
        +Number weight
        +Number height
    }
    class PokemonEvolution {
        +String[] pre
        +String[] pos
    }

    Pokemon *-- PokemonStats
    Pokemon *-- PokemonMove
    Pokemon *-- PokemonPhysic
    Pokemon *-- PokemonEvolution

A lógica de busca do repositório é resolvida aplicando operações de filtragem encadeadas no nível do servidor: primeiro avalia-se se a consulta de entrada corresponde ao nome ou ao índice numérico e, em seguida, os resultados são restringidos de acordo com um filtro opcional de tipo, antes de resolver o subarray correspondente à paginação da visualização atual.

4. Stack Tecnológico

O stack tecnológico foi selecionado com base em tipagem forte e em arquiteturas orientadas a eventos e fluxos de dados.

TecnologiaCategoriaPapel Técnico na Arquitetura
Angular 19Framework FrontendMotor de renderização reativo; ciclo de vida dos componentes e roteamento sincronizados com o estado.
NgRx SignalsGerenciamento de EstadoGerenciador de estado global que modifica signals atômicos reativos; reduz a complexidade do ciclo padrão de detecção de mudanças.
Apollo ClientObtenção de DadosCliente GraphQL com estratégia de políticas de cache otimizada (por exemplo, cache-and-network).
Tailwind CSS v4Estilos de UIMotor de CSS utilitário sob arquitetura PostCSS, que estrutura a camada Glassmorphism sem bibliotecas de componentes rígidas.
NestJSFramework BackendEstruturação modular por meio de Inversão de Controle (IoC), com suporte a padrões de design corporativos.
GraphQLCamada de APIInterface de consulta fortemente tipada, que mitiga o over-fetching de dados em modelos complexos.
BiomeToolchainFerramenta unificada de formatação e linting de código, garantindo consistência sintática transversal.

5. Fechamento Arquitetural

A consolidação do padrão Container/Presenter no frontend, junto com um backend GraphQL-para-DDD, elimina a ambiguidade nos contratos de dados e isola efetivamente as mutações de estado dos efeitos colaterais da UI. A incorporação de abstrações assíncronas para o mapeamento em memória permite que o sistema responda com dados pré-calculados e alta disponibilidade, simplificando a orquestração do servidor e concentrando o processamento na manipulação reativa de Signals no nível do cliente.

Arraste para mover o diagrama. Use + e − para dar zoom, as setas para movê-lo e 0 para redefinir a visualização.

Vamos trabalhar juntos

Engenheiro de Software e desenvolvedor Senior Full-Stack, trabalho remotamente a partir de Santa Cruz, Bolívia. Aberto a novas oportunidades.