{"id":32724998,"url":"https://github.com/ricarthlima/flutter_gastro_go","last_synced_at":"2026-04-10T22:38:10.643Z","repository":{"id":321656921,"uuid":"1085474858","full_name":"ricarthlima/flutter_gastro_go","owner":"ricarthlima","description":"Este projeto é uma solução para o Desafio Mobile Flutter, com foco em arquitetura limpa, gerenciamento de estado reativo, testes e boas práticas de desenvolvimento. Trata-se das telas iniciais de um aplicativo agregador de restaurantes, como iFood.","archived":false,"fork":false,"pushed_at":"2025-10-30T19:22:29.000Z","size":82834,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-10T22:37:40.747Z","etag":null,"topics":["actions","cached-network-images","flutter","getit","mobx","objectbox","shimmer"],"latest_commit_sha":null,"homepage":"","language":"Dart","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/ricarthlima.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-29T04:58:35.000Z","updated_at":"2025-12-04T09:59:15.000Z","dependencies_parsed_at":"2025-10-30T21:24:14.101Z","dependency_job_id":null,"html_url":"https://github.com/ricarthlima/flutter_gastro_go","commit_stats":null,"previous_names":["ricarthlima/flutter_gastro_go"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ricarthlima/flutter_gastro_go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ricarthlima%2Fflutter_gastro_go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ricarthlima%2Fflutter_gastro_go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ricarthlima%2Fflutter_gastro_go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ricarthlima%2Fflutter_gastro_go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ricarthlima","download_url":"https://codeload.github.com/ricarthlima/flutter_gastro_go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ricarthlima%2Fflutter_gastro_go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31662169,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-10T17:19:37.612Z","status":"ssl_error","status_checked_at":"2026-04-10T17:19:13.364Z","response_time":98,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["actions","cached-network-images","flutter","getit","mobx","objectbox","shimmer"],"created_at":"2025-11-03T01:01:27.494Z","updated_at":"2026-04-10T22:38:10.634Z","avatar_url":"https://github.com/ricarthlima.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GastroGo - Mini-app de Restaurantes\n\n\u003e Este projeto é uma solução para o **Desafio Mobile Flutter**, com foco em **arquitetura limpa**, **gerenciamento de estado reativo**, **testes** e **boas práticas** de desenvolvimento. Trata-se das telas iniciais de um aplicativo agregador de restaurantes, como iFood.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/gif.gif\" alt=\"Tela inicial\" height=\"500\"/\u003e\n\u003c/p\u003e\n\n## ✨ Funcionalidades Implementadas\n\nA lista de funcionalidades foi baseada no escopo do desafio.\n\n### Arquitetura\n- [x] Camadas separadas (`data/`, `domain/`, `presentation/`)\n- [x] Gerenciamento de estado reativo (**MobX**)\n- [x] Repository Pattern para isolar as fontes de dados\n\n### Must-Have\n- [x] UI Responsiva, Dark/Light Mode e Acessibilidade (Tooltips)\n- [x] **Lista de Restaurantes**\n  - [x] Exibição de Nome, Categoria, Rating e Distância\n  - [x] Busca por texto (nome) e Filtro por categoria (exata)\n  - [x] Ordenação por Rating ou Distância\n- [x] **Tela de Detalhes**\n  - [x] Informações do Restaurante + Lista de Pratos (nome, preço, vegano)\n  - [x] Botão de favoritar (Restaurante e Prato)\n- [x] **Favoritos**\n  - [x] Tela com abas para Restaurantes e Pratos favoritos\n  - [x] Persistência local (**ObjectBox**)\n- [x] **Fonte de Dados**\n  - [x] JSON local (`assets/restaurants.json`, `assets/dishes.json`)\n- [x] **Estados Explícitos**\n  - [x] Loading, Sucesso, Vazio e Erro (com botão de *Retry*)\n- [x] **Testes**\n  - [x] +5 Testes Unitários (Repositórios e UseCases)\n  - [x] 2 Testes de Widget (Lista e Detalhes)\n\n### Nice-to-Have\n- [ ] Scroll Infinito (Despriorizado para focar na robustez da arquitetura core)\n- [x] Animação Hero na imagem do card (da Lista para os Detalhes)\n- [x] i18n (Internacionalização `pt-BR` e `en`)\n- [x] Cache de Imagens (`cached_network_image`)\n- [x] Simular API com `Future.delayed` e chance de erro (1 chance em 20 por motivos de RPG)\n- [x] Pull-to-Refresh (`RefreshIndicator`) nas telas\n- [x] Navegação robusta com `GoRouter`\n- [x] Filtro \"Apenas Vegano\"\n\n### Extras\n- [x] Animação com Lottie para carregamento\n- [x] Shimmer para placeholder do carregamento de imagens\n- [x] Lógica de carrossel para banners\n- [x] Bloqueada rotação\n- [x] Tela de splash para inicialização\n- [x] Ícone de lançamento para Android\n\n## 🏛️ Arquitetura e Decisões\n\nEsta seção detalha as decisões de arquitetura tomadas, conforme solicitado na avaliação.\n\n### 1. Arquitetura Limpa em Camadas\nO projeto segue uma arquitetura limpa rigorosa, separando responsabilidades nas camadas `data/`, `domain/` e `presentation/`.\n- **`presentation/`**: Contém a UI (Widgets) e o Gerenciamento de Estado (MobX Stores).\n- **`domain/`**: Contém as regras de negócio puras (UseCases) e os contratos (Interfaces de Repositório).\n- **`data/`**: Contém as implementações concretas dos repositórios e a lógica de acesso às fontes de dados (ObjectBox, JSON).\n\n### 2. Gerenciamento de Estado (MobX)\nEmbora `Provider`, `Riverpod` ou `Bloc` fossem sugeridos, escolhi **MobX**.\n- **Por quê:** MobX oferece um gerenciamento de estado reativo poderoso com o mínimo de *boilerplate*. Sua integração com `Observer` permite que os *widgets* se reconstruam de forma granular, e o sistema de `Actions` e `Computeds` se encaixa perfeitamente na arquitetura com `UseCases`.\n- **Ciclo de Vida das Stores:**\n  - `RestaurantListStore`, `ThemeStore` e `FavoritesStore` são registrados como **`LazySingleton`** no GetIt.\n  - `DishListStore` (detalhes do restaurante) é registrada como **`Factory`**, garantindo instâncias isoladas.\n\n### 3. Persistência Local (ObjectBox)\nOptamos por **ObjectBox** em vez de `shared_preferences` ou `hive`.\n- **Por quê:** ObjectBox é um banco de dados de objetos **fortemente tipado**, exigindo `Entities` (`FavoriteRestaurantEntity`, `FavoriteDishEntity`) e um `IFavoritesRepository` robusto, que encapsula toda a lógica de query (`.query()`, `.build()`, `.put()`, `.remove()`), reforçando princípios **SOLID**.\n- Além disso, possui atualizações frequentes, enquanto o `hive` ou o `isar`parecem estar descontinuados não oficialmente.\n- O `shared_preferences` foi usado para registrar a preferência de tema.\n\n### 4. O Padrão \"Backend Burro\" (UseCases Híbridos)\n- **Problema:** A fonte de dados é um JSON local, um \"backend burro\" que não sabe filtrar ou ordenar.\n- **Decisão:** `UseCases` de filtro e ordenação aceitam uma lista opcional (`List\u003cRestaurantDto\u003e? restaurants`) para reutilizar os dados em memória.\n- **Resultado:** A `Store` se torna um orquestrador eficiente, aplicando filtros e ordenações sem reconsultar o repositório, preservando o isolamento do domínio e a performance do app.\n\n### 5. DTOs como Entidades de Domínio\n- **Decisão:** Utilizar `DTOs` diretamente nas camadas `domain/` e `presentation/`. (Achatamento)\n- **Motivo:** Como o app é *read-only*, criar `Entities` seria redundante. Essa escolha reduz *boilerplate* sem comprometer a clareza. E tempo, né.\n\n### 6. Navegação (GoRouter)\n- **Decisão:** Uso do `GoRouter`.\n- **Motivo:** Permite rotas nomeadas e parâmetros (`/restaurants/dishes/:rid`) e suporte a transições suaves (`Hero`), além de aceitar objetos (`extra`) para inicialização otimizada.\n- No futuro, e principalmente para esse tipo de app, **Deeplinks** podem ser configurados com o `GoRouter`.\n\n## 🚀 Como Rodar o Projeto\n\n### Pré-requisitos\n- Flutter SDK (3.22.0 ou superior)\n- Emulador ou dispositivo físico Android ou iOS\n- IDE como VSCode, IntelliJ ou XCode\n\n### 1. Instalação\n```bash\n# Clone o repositório\ngit clone \u003curl-do-seu-repositorio\u003e\ncd gastro-go\n\n# Instale as dependências\nflutter pub get\n```\n\n### 2. Geração de Código (Obrigatória)\nEste projeto usa **build_runner** para MobX, ObjectBox e i18n. Rode:\n```bash\nflutter pub run build_runner build --delete-conflicting-outputs\n```\n\n### 3. Executar o App\n```bash\nflutter run\n```\n\n## ✅ Qualidade e Automação\n\n### 1. Linting (Análise Estática)\nConfigurado com **flutter_lints** e um `analysis_options.yaml` rigoroso, com regras como:\n- `prefer_final_fields`\n- `avoid_print`\n- `curly_braces_in_flow_control_structures`\n- `prefer_relative_imports`\n\nVerificar o código:\n```bash\nflutter analyze\n```\n\nCorrigir automaticamente:\n```bash\ndart fix --apply\n```\n\n### 2. Testes\nO projeto inclui testes unitários e de widget.\n\n- **Unitários:** Cobrem todos os `UseCases` e Repositórios (`ObjectBoxFavoritesRepository`).\n- **Widget:** Testam as telas `RestaurantsScreen` e `DishScreen`, com `Stores` mockadas via GetIt.\n\nExecutar todos os testes:\n```bash\nflutter test\n```\n\n### 3. CI (GitHub Actions)\nWorkflow em `.github/workflows/main.yml`, executado a cada `push` ou `pull_request` para `main`, rodando automaticamente:\n\n```bash\nflutter analyze\nflutter test\nflutter build apk --debug\n```\n\n---\n\nComo sempre,\nfeito com 🩵 e Flutter por Ricarth Lima\n\n*(Eu botava emojis nos meus READMEs muito antes de IAs viu)*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fricarthlima%2Fflutter_gastro_go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fricarthlima%2Fflutter_gastro_go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fricarthlima%2Fflutter_gastro_go/lists"}