{"id":30569152,"url":"https://github.com/erikbernard/exchange-rate","last_synced_at":"2026-04-20T10:33:02.318Z","repository":{"id":312072598,"uuid":"1045908721","full_name":"erikbernard/exchange-rate","owner":"erikbernard","description":"O projeto consiste em uma Single Page Application (SPA) que permite ao usuário pesquisar por uma sigla de moeda (ex: USD) e visualizar a cotação atual em relação a uma moeda base (ex: BRL), bem como uma lista com o histórico de cotações dos últimos dias","archived":false,"fork":false,"pushed_at":"2025-08-28T11:28:51.000Z","size":177,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-28T17:37:39.335Z","etag":null,"topics":["angular","bem-methodology","observables","rxjs","scss"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erikbernard.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-27T22:35:47.000Z","updated_at":"2025-08-28T11:28:54.000Z","dependencies_parsed_at":"2025-08-28T17:38:01.255Z","dependency_job_id":"160e4a81-6191-4733-ba48-fe942d756998","html_url":"https://github.com/erikbernard/exchange-rate","commit_stats":null,"previous_names":["erikbernard/exchange-rate"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/erikbernard/exchange-rate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikbernard%2Fexchange-rate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikbernard%2Fexchange-rate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikbernard%2Fexchange-rate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikbernard%2Fexchange-rate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erikbernard","download_url":"https://codeload.github.com/erikbernard/exchange-rate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erikbernard%2Fexchange-rate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32043052,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","bem-methodology","observables","rxjs","scss"],"created_at":"2025-08-28T20:01:25.159Z","updated_at":"2026-04-20T10:33:02.305Z","avatar_url":"https://github.com/erikbernard.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Aplicação de Consulta de Taxa de Câmbio\n\nEsta é uma aplicação front-end desenvolvida em Angular para consultar taxas de câmbio de moedas em tempo real e visualizar o histórico diário.\n\n## 📜 Descrição\n\nO projeto consiste em uma Single Page Application (SPA) que permite ao usuário pesquisar por uma sigla de moeda (ex: USD) e visualizar a cotação atual em relação a uma moeda base (ex: BRL), bem como uma lista com o histórico de cotações dos últimos dias. A aplicação é reativa, responsiva e consome uma API externa para obter os dados de câmbio.\n\n## 📜 Minhas impressões sobre o desafio\n\nSobre o projeto, foi bem tranquilo eu que adicionei mais complexidade no teste, pontos positivos e o fato de não precisar criar o layout no Figma nem elaborar um CRUD completo, já que recebi tudo pronto. Fiquei até surpreso com isso. Nesse sentido, foquei em aplicar recursos do Angular. A versão utilizada foi a 17, que já estava instalada. Pensei em adotar `Signals`, mas optei por seguir com `Observables`. Dos recursos novos, explorei o control flow introduzido no Angular 17 e utilizei componentização, pipes, serviços e o uso do RxJS, para demonstrar domínio dos principais recursos do framework. Também utilizei o padrão BEM (Block, Element, Modifier) na estilização com SCSS, o que, além de organizar melhor o código, contribui para a criação de testes unitários.\n\n## ✨ Tecnologias Utilizadas\n\nAs seguintes tecnologias e ferramentas foram utilizadas na construção do projeto:\n\n-   **[Angular V17](https://angular.io/):** Framework principal para a construção da interface de usuário.\n-   **[TypeScript](https://www.typescriptlang.org/):** Superset do JavaScript que adiciona tipagem estática ao código.\n-   **[SCSS](https://sass-lang.com/):** Pré-processador CSS que adiciona recursos como variáveis, aninhamento e mixins.\n-   **[RxJS](https://rxjs.dev/):** Biblioteca para programação reativa usando Observables, utilizada extensivamente no Angular para lidar com eventos assíncronos.\n-   **[Karma](https://karma-runner.github.io/):** Ferramenta para execução de testes de unidade.\n-   **[Jasmine](https://jasmine.github.io/):** Framework de testes BDD (Behavior-Driven Development) para JavaScript.\n\n## 🏗️ Conceitos do Angular Aplicados\n\n### Gerenciamento de Estado\n\nPara o gerenciamento de estado da aplicação, foi adotada uma abordagem reativa utilizando `BehaviorSubject` do RxJS dentro dos serviços.\n\n-   **`ExchangeRateService`**: Este serviço centraliza a lógica de negócio e a comunicação com a API. Ele utiliza um `BehaviorSubject` para manter o estado atual dos dados de câmbio (`exchangeRateData$`).\n-   **Fluxo de Dados**: Quando um componente solicita os dados (por exemplo, através de uma busca), o serviço faz a chamada à API, atualiza o `BehaviorSubject` com os novos dados e notifica todos os componentes que estão inscritos (`subscribed`) neste `Observable`. Isso garante que a UI seja atualizada de forma reativa e consistente em toda a aplicação.\n\nEssa é uma abordagem simples para aplicações de pequeno porte. Seria possível implementá-la de forma ainda mais enxuta? Sim. Porém, optei por explorar melhor os recursos do `RxJS`, mantendo os componentes mais limpos ao utilizar o `async pipe`, que já realiza o unsubscribe dos observables automaticamente.\n\n### Componentização\n\nNa aplicação apliquei estrutura em componentes focando no conceito de Dumb e Smart components, para facilitar os testes de unidade.\n\n-   **Componentes de Apresentação (Dumb Components):** Componentes como `HeaderComponent`, `FooterComponent`, `DailyExchangeItemComponent` e `CurrentExchangeComponent` são responsáveis apenas por exibir dados recebidos via `@Input()` e emitir eventos via `@Output()`. Eles não possuem lógica de negócio.\n-   **Componentes de Container (Smart Components):** A `HomePage` atua como um componente container, orquestrando a interação entre os serviços e os componentes de apresentação. Ela é responsável por buscar os dados e repassá-los para os componentes filhos.\n\n### Pipes\n\nA criação de pipes customizados para manipular e formatar dados diretamente nos templates HTML, nesse caso foi aplicado justamente para isolar a logica dos componentes mantendo os mais limpos.\n\n-   **`CalculateDiffPipe`**: Recebe o valor de fechamento atual e o anterior para calcular e retornar a diferença percentual, formatando o resultado para exibição.\n-   **`PreviousClosePipe`**: Recebe o histórico de cotações e um índice para encontrar e retornar o valor de fechamento do dia anterior.\n\n### Metodologia BEM e Testes\nA utilização da metodologia BEM (Block, Element, Modifier) para a nomeação de classes CSS no projeto não apenas organiza o estilo, mas também facilita significativamente os testes de unidade e combina perfeitamente o scss do Angular.\n\n- Seletores Previsíveis e Únicos: BEM cria nomes de classes específicos e previsíveis (ex: `.search__input, .list__item--active`). Isso torna a seleção de elementos do DOM nos testes de unidade extremamente confiável e direta, usando `By.css('.search__input')`.\n\n- Testes Menos Frágeis: Ao atrelar os seletores de teste a classes BEM, os testes se tornam mais resilientes a mudanças na estrutura do HTML. Alterar uma div para um article não quebra o teste, desde que a classe BEM funcional (`.daily-list__item`) seja mantida. Isso desacopla a lógica do teste da estrutura exata do DOM.\n\n- Clareza e Legibilidade: Os nomes das classes BEM descrevem a função de cada elemento. Um seletor como `.button--disabled `em um teste deixa claro para qualquer desenvolvedor qual estado do componente está sendo verificado, melhorando a manutenibilidade dos testes.\n\n\n## 📂 Organização do Repositório\n\nA estrutura de diretórios do projeto, optei por essa forma por conter apenas uma pagina, no caso a de home, normalmente e colocado dentro de uma diretório 'features':\n\n```\n/src\n|-- /app\n|   |-- /components     # Componentes reutilizáveis\n|   |-- /models         # Modelos de dados (interfaces)\n|   |-- /pages          # Componentes de página (containers)\n|   |-- /pipes          # Pipes customizados\n|   |-- /services       # Serviços (lógica de negócio, API)\n|   |-- app.config.ts   # Configurações globais da aplicação\n|   |-- app.routes.ts   # Definição de rotas\n|-- /assets             # Arquivos estáticos (imagens, etc.)\n|-- /environments       # Arquivos de configuração de ambiente\n```\n\n## 🚀 Instruções de Execução\n\nSiga os passos abaixo para executar o projeto em seu ambiente local.\n\n### Pré-requisitos\n\n-   [Node.js](https://nodejs.org/) (versão 18.x ou superior)\n-   [Angular CLI](https://angular.io/cli) (versão 18.x ou superior)\n\n### Instalação\n\n1.  Clone o repositório:\n    ```bash\n    git clone https://github.com/erikbernard/exchange-rate.git\n    ```\n\n2.  Navegue até o diretório do projeto:\n    ```bash\n    cd exchange-rate\n    ```\n\n3.  Instale as dependências:\n    ```bash\n    npm install\n    ```\n\n### Configurando Variáveis de Ambiente\n\nAntes de executar, você precisa configurar as variáveis de ambiente. No `src/environments/environment.ts` e preencha as informações da API.\n\n**`src/environments/environment.ts`**\n```typescript\nexport const environment = {\n  production: false,\n  apiUrl: 'URL_DA_SUA_API', // Ex: https://api.exchangerate-api.com/v4/latest\n  apiKey: 'SUA_CHAVE_DE_API' // Se a API exigir uma chave\n};\n```\nFaça o mesmo para o arquivo `src/environments/environment.prod.ts` para o ambiente de produção.\n\n### Executando a Aplicação\n\n1.  Inicie o servidor de desenvolvimento:\n    ```bash\n    ng serve\n    ```\n\n2.  Abra seu navegador e acesse `http://localhost:4200/`. A aplicação será recarregada automaticamente se você alterar qualquer um dos arquivos de origem.\n\n## 🧪 Testes Unitários\n\nPara garantir a qualidade e o funcionamento correto dos componentes, serviços e pipes, foram criados testes unitários com Karma e Jasmine.\n\nPara executar os testes, utilize o seguinte comando:\n\n```bash\nng test\n```\n\nIsso iniciará o executor de testes Karma, que abrirá um navegador para exibir os resultados.\n\n## 📦 Deploy\n\nPara gerar uma versão de produção da aplicação, execute o comando abaixo:\n\n```bash\nng build\n```\n\nOs artefatos da compilação serão armazenados no diretório `dist/`. Você pode então implantar o conteúdo deste diretório em qualquer servidor web estático.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikbernard%2Fexchange-rate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferikbernard%2Fexchange-rate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferikbernard%2Fexchange-rate/lists"}