Arquitetura do Orbit 🪐
Este documento é o guia definitivo para desenvolvedores e novos membros da equipe entenderem como o projeto Orbit está estruturado. O ecossistema é dividido em três frentes principais que trabalham juntas de forma modular e escalável.
Visão Geral do Sistema
┌─────────────────────────────────────────────────────────────┐
│ ORBIT ECOSYSTEM │
│ │
│ ┌──────────────┐ REST/WS ┌──────────────────────┐ │
│ │ Flutter App │ ──────────► │ Cloudflare Workers │ │
│ │ (iOS/Android)│ │ (API) │ │
│ └──────────────┘ │ D1 · R2 · DO · KV │ │
│ └──────────────────────┘ │
│ │ │
│ ┌──────────────┐ WebView │ FCM / LiveKit │
│ │ React Games │ ─────────────┐ │ │
│ │ (Micro-fronts)│ │ Firebase / LiveKit │
│ └──────────────┘ └─────────────────────────── │
└─────────────────────────────────────────────────────────────┘1. Aplicativo Mobile + Web (Flutter) — /app
Filosofia Arquitetural
O aplicativo não segue o "Clean Architecture" purista. O projeto adota uma Arquitetura Orientada a Serviços (Service-Based Architecture) — pragmática, ágil e muito comum na comunidade Flutter. A separação é feita por responsabilidade funcional, não por camadas rígidas.
- Gerenciamento de estado:
flutter_bloc(Cubit/BLoC) para lógica de negócio,Providerpara estado leve de UI. - Navegação:
GoRoutercom roteamento declarativo, deep links e redirecionamento condicional (autenticado/não-autenticado). - Banco local:
ObjectBoxcomo cache offline de alta performance (conversas, perfil, drafts).
Estrutura de Pastas — /app/lib
lib/
├── main.dart # Entry point, inicialização, router raiz
├── firebase_options.dart # Configuração gerada do Firebase
│
├── core/ # Infraestrutura central do app
│ ├── config/ # AppInitializer, AppConfigService (config remota)
│ ├── database/ # ObjectBoxService (banco local)
│ ├── di/ # AppProviders (injeção de dependências via MultiBlocProvider)
│ ├── routes/ # AppRoutes (GoRouter centralizado)
│ ├── cache/ # Utilitários de cache
│ └── update/ # UpdateCubit (verificação de versão)
│
├── blocs/ # BLoCs/Cubits de lógica de negócio pesada
│ ├── auth/ # AuthBloc (login, logout, sessão)
│ └── devices/ # Gerenciamento de sessões de dispositivos
│
├── provider/ # Cubits de estado de UI (mais leves)
│ ├── profile_provider.dart # ProfileCubit — dados do usuário logado
│ ├── chat_provider.dart # ChatCubit — conversas e mensagens
│ ├── friends_provider.dart # FriendsCubit — lista de amigos
│ ├── settings_provider.dart # SettingsCubit — preferências locais
│ ├── locale_provider.dart # LocaleCubit — idioma do app
│ ├── badge_provider.dart # BadgeCubit — contadores de notificações
│ ├── upload_provider.dart # UploadCubit — estado de uploads em progresso
│ ├── live_provider.dart # LiveCubit — estado de lives
│ ├── wallpaper_provider.dart # WallpaperCubit — papel de parede
│ └── offline_provider.dart # OfflineCubit — estado de conectividade
│
├── models/ # Data classes (tipagem de dados da API)
│ ├── user_model.dart # Usuário completo (~28KB — modelo rico)
│ ├── message_model.dart # Mensagem de chat (E2E, tipos, reações)
│ ├── post_model.dart # Post do feed (mídia, enquetes, reações)
│ ├── chat_model.dart # Conversa/grupo
│ ├── short_model.dart # Vídeo curto (VAP)
│ ├── community_model.dart # Comunidade e canais
│ ├── pet_model.dart # Pet digital com status vital
│ ├── event_model.dart # Eventos (Kraken boss battles)
│ └── ... # +25 outros modelos
│
├── services/ # Regras de negócio, chamadas de API, lógicas pesadas
│ ├── api/ # ApiService + ApiConfig (cliente HTTP base com Dio)
│ ├── auth/ # AuthService (Firebase Auth + JWT backend)
│ ├── chat/ # ChatService (E2E encryption, WebSocket, grupos)
│ ├── websocket/ # WebSocketService (singleton, eventos em tempo real)
│ ├── notifications/ # NotificationService + NotificationHandler (FCM + local)
│ ├── sync/ # BackgroundSyncManager (sincronização em background)
│ ├── encryption/ # EncryptionService (criptografia E2E das mensagens)
│ ├── call/ # CallService (LiveKit — vídeo/áudio em grupo)
│ ├── cine/ # CineService (salas de cinema colaborativas)
│ ├── post/ # PostService (feed, comentários, reações)
│ ├── shorts/ # ShortsService (upload e streaming de VAPs)
│ ├── friends/ # FriendsService (amigos, match, bloqueios)
│ ├── user/ # UserService (perfil, visitas, badges)
│ ├── community/ # CommunityService
│ ├── event/ # EventService (Kraken, boss battles)
│ ├── games/ # GamesService (pontuações, rankings)
│ ├── pet/ # PetService (ciclo de vida, acessórios, batalhas)
│ ├── store/ # StoreService (loja de itens digitais)
│ ├── billing/ # BillingService (In-App Purchase)
│ ├── status/ # StatusService (stories)
│ ├── search/ # SearchService
│ ├── news/ # NewsService
│ ├── review/ # ReviewService (in-app review)
│ ├── update/ # UpdateService (verificação de versão)
│ ├── offline/ # OfflineService (modo offline)
│ ├── draft/ # DraftService (rascunhos de posts)
│ ├── dimension/ # DimensionService (espaços temáticos)
│ ├── storage/ # StorageService (upload de mídia)
│ ├── transcription/ # TranscriptionService (transcrição de áudio)
│ ├── ads/ # AdsService (Google Mobile Ads)
│ ├── session/ # SessionService (gestão de sessões)
│ ├── testimonals/ # TestimonialsService
│ ├── visits/ # VisitsService (rastreamento de visitas ao perfil)
│ └── websocket/ # WebSocketService (singleton global)
│
├── screens/ # Telas (Views) do aplicativo
│ ├── home/ # Feed principal de posts
│ ├── login/ # Autenticação (login, registro, recuperação)
│ ├── profile/ # Perfil de usuário
│ ├── search/ # Busca global
│ ├── shorts/ # Feed de vídeos curtos (VAP)
│ ├── notifications/ # Central de notificações
│ ├── settings/ # Configurações do app
│ │ ├── account/ # Conta e privacidade
│ │ ├── theme/ # Personalização visual
│ │ ├── notification/ # Preferências de notificação
│ │ ├── wallet/ # Carteira, missões e loja
│ │ ├── devices/ # Sessões ativas
│ │ ├── integrations/ # Integrações externas (OBS, Steam, Last.fm)
│ │ ├── scheduled_posts/ # Agendamento de posts
│ │ └── ...
│ ├── more/ # Hub de funcionalidades extras
│ │ ├── chat/ # Chat privado e grupos (E2E)
│ │ │ ├── user/ # Conversa 1-para-1
│ │ │ ├── group/ # Grupos de chat
│ │ │ ├── ia/ # Chat com IA
│ │ │ ├── archived/ # Conversas arquivadas
│ │ │ └── forward/ # Encaminhamento de mensagens
│ │ ├── cine/ # Cinema colaborativo
│ │ ├── community/ # Comunidades e canais
│ │ ├── match/ # Sistema de match (Amigar)
│ │ ├── dimensions/ # Espaços temáticos
│ │ ├── events/ # Eventos e boss battles
│ │ ├── games/ # Aba de jogos (WebView → Godot/Web)
│ │ ├── pet/ # Pets digitais
│ │ ├── status/ # Stories
│ │ └── testimonial/ # Depoimentos
│ ├── stickers/ # Gerenciador de stickers
│ ├── rules/ # Regras da plataforma
│ ├── splash/ # Splash screen
│ └── maintenance/ # Tela de manutenção
│
├── widgets/ # Componentes reutilizáveis
│ ├── nav/ # BottomNavigation, GamesShelfOverlay
│ ├── chat_widget/ # Bubble de mensagem, input de chat
│ ├── post/ # Card de post, composer de post
│ ├── call/ # CallHandler (overlay de chamada)
│ ├── events/ # EventManager, BossEventBanner (Kraken)
│ ├── flame_pet/ # Pet com Flame engine
│ ├── interactive_pet_avatar.dart # Pet interativo animado
│ ├── avatar.dart # Avatar com moldura, status online
│ ├── poll.dart # Widget de enquete
│ ├── live_pip_overlay.dart # Picture-in-picture de lives
│ ├── theme_transition.dart # Transição animada de tema
│ └── ... # +40 outros widgets
│
├── theme/ # Sistema de temas e configurações visuais
│ ├── theme.dart # ThemeCubit + temas claro/escuro/exile
│ ├── christmas.dart # Tema de Natal
│ ├── halloween.dart # Tema de Halloween
│ ├── new_year.dart # Tema de Ano Novo
│ ├── valentines.dart # Tema de Dia dos Namorados
│ ├── world_cup.dart # Tema de Copa do Mundo
│ └── birthday.dart # Tema de Aniversário
│
├── l10n/ # Internacionalização
│ └── *.arb # Strings em pt, en, es
│
└── utils/ # Utilitários e helpersFluxo de Inicialização
main()
└─ AppInitializer.init() ← Firebase, ObjectBox, ApiConfig
└─ runApp(AppState)
└─ AppProviders.buildProviders() ← MultiBlocProvider
└─ CallHandler
└─ MyApp
└─ AppRoutes.createRouter() ← GoRouter
└─ MainScreenWrapper
└─ BottomNavSistema de Roteamento (GoRouter)
O roteamento é centralizado em core/routes/app_routes.dart. Há redirecionamento automático para /login quando o AuthBloc está em estado AuthUnauthenticated, e para /home quando AuthSuccess.
Gerenciamento de Estado — Decisão de uso
| Cubit/BLoC | Tecnologia | Razão |
|---|---|---|
AuthBloc | BLoC | Lógica complexa com múltiplos eventos e estados |
ChatCubit | Cubit | Estado de conversas com operações assíncronas |
ProfileCubit | Cubit | Dados do perfil com sincronização via WS |
ThemeCubit | Cubit | Estado simples de UI, sem side effects pesados |
SettingsCubit | Cubit | Preferências locais (SharedPreferences) |
UploadCubit | Cubit | Estado de uploads em progresso |
2. Backend API — /api
Construída em TypeScript e hospedada como Cloudflare Workers. A API segue rigorosamente o padrão Vertical Slice Architecture: o código é organizado por domínio/funcionalidade, não por tipo de arquivo.
Estrutura — /api/src
src/
├── index.ts # Entry point do Worker (binding de rotas e DO)
├── routers.ts # Definição central de todas as rotas REST
├── cron-jobs.ts # Jobs agendados (limpeza, manutenção, eventos)
│
├── core/ # Coração da aplicação
│ └── ... # Contexto de requisição, DI, interfaces base
│
├── durable-objects/ # Objetos stateful do Cloudflare
│ ├── WebSocketHandler # Hub de WebSockets (presença, eventos em tempo real)
│ ├── CinemaRoomDO # Estado sincronizado de salas de cinema
│ └── DimensionChatRoom # Chat em tempo real de dimensões
│
├── features/ # Módulos por domínio (Vertical Slice)
│ ├── auth/ # Login, registro, refresh de token
│ ├── users/ # Perfil, visitas, badges, configurações
│ ├── posts/ # Feed, comentários, reações, agendamento
│ ├── shorts/ # Upload e streaming de vídeos curtos
│ ├── chat/ # Mensagens, grupos, criptografia
│ ├── communities/ # Grupos temáticos e canais
│ ├── cinema/ # Salas de cinema colaborativas
│ ├── events/ # Sistema de eventos (Kraken, boss battles)
│ ├── pets/ # Pets digitais, batalhas, itens
│ ├── interactions/ # Amizades, match, bloqueios
│ ├── admin/ # Painel administrativo
│ ├── emails/ # Templates e envio de e-mails (Resend)
│ ├── webhooks/ # Webhooks externos
│ └── misc/ # Endpoints utilitários
│
├── infrastructure/ # Adaptadores para serviços externos
│ ├── d1/ # Queries SQL no Cloudflare D1
│ ├── r2/ # Upload/download no Cloudflare R2
│ ├── ai/ # Cloudflare AI Bindings
│ └── livekit/ # Geração de tokens LiveKit
│
├── types/ # Tipagens TypeScript unificadas
└── utils/ # JWT, validações, helpersCron Jobs
A API executa tarefas agendadas via Cloudflare Cron Triggers:
| Schedule | Tarefa |
|---|---|
* * * * * | Monitoramento de saúde dos pets, expiração de itens |
*/30 * * * * | Limpeza de sessões expiradas |
0 2 * * * | Limpeza de stories expirados |
0 */12 * * * | Atualização de rankings e pontuações |
Autenticação
A autenticação usa dupla validação:
- Firebase Auth Token → verificado via Firebase Admin SDK para login inicial.
- JWT interno (
jose) → emitido após validação, usado em todas as requisições subsequentes.
3. Jogos Web / Site — /site
Os jogos integrados ao Flutter são projetos Godot 4 (pasta /games na raiz) exportados para Web e servidos via WebView (flutter_inappwebview). O fluxo é: Godot → Exportar Projeto (preset "Web (Orbit WebView)", saída build/web/) → copiar para /site/games/<nome>/ → deploy publica em redeorbit.com/games/<nome>. Esta arquitetura permite atualizar jogos sem publicar novas versões nas lojas.
Jogos Disponíveis (/site/games/)
| Jogo | Pasta | Descrição |
|---|---|---|
| Sudoku | sudoku/ | Puzzle clássico de números |
| Campo Minado | minesweeper/ | Clássico jogo de desviar de minas |
| Memória | memory/ | Jogo de pares de cartas |
| TicTacToe | tictactoe/ | Jogo da velha |
| Space | space/ | Jogo espacial |
| Runner | runner/ | Endless runner |
| Combat | combat/ | Combate entre personagens |
| Master | master/ | Mini-game master |
Comunicação Flutter ↔ Godot
Os jogos se comunicam bidirecionalmente com o Flutter através de JavaScript Handlers (via JavaScriptBridge no GDScript):
# Jogo → Flutter (ex: enviar pontuação)
JavaScriptBridge.eval("window.flutter_inappwebview.callHandler('onScoreSubmit', %d)" % score)
// Flutter → Jogo (ex: mudar idioma)
// Via URL params: ?lang=pt&theme=darkStack Tecnológica
- Core: Godot 4.4 + GDScript (renderer GL Compatibility,
thread_support=false) - Export: preset "Web (Orbit WebView)" →
index.html+.js/.wasm/.pckem/site/games/<nome>/ - i18n: Parâmetro de URL
?lang=pt|en|es(lido pelo jogo; legado React usavaengine.ts)
4. Padrões de Desenvolvimento
Regra de Ouro: Service Layer
Nunca chame a API diretamente de um Widget ou Cubit. O fluxo obrigatório é:
Widget → Cubit/BLoC → Service → APIConvenções de Nomenclatura
| Tipo | Padrão | Exemplo |
|---|---|---|
| Cubits | XxxCubit | ChatCubit, ProfileCubit |
| BLoCs | XxxBloc | AuthBloc |
| Services | XxxService | ChatService, PostService |
| Models | XxxModel | PostModel, UserModel |
| Screens | XxxScreen | HomeScreen, ChatScreen |
| Widgets | Descritivos | OrbBackdropFilter, OrbitLoadingIndicator |
Performance — ScrollBlur Optimization
O app implementa uma otimização crítica: durante o scroll, os BackdropFilter (blur) são desativados temporariamente para evitar jank. Controlado via SettingsCubit.setScrollingFast() com debounce de 300ms. Todos os widgets que usam blur devem checar este estado.
5. Por Que Essa Arquitetura?
| Decisão | Razão |
|---|---|
| Service-Based no Flutter (não Clean Arch) | Evita boilerplate excessivo (5-6 arquivos por feature). Desenvolvimento mais ágido sem sacrificar organização. |
| Vertical Slice na API | Cada feature é isolada e auto-contida. Facilita trabalho paralelo e evita acoplamento entre domínios. |
| Jogos Godot exportados p/ Web | Jogos podem ser atualizados em produção sem passar por revisão da App Store/Google Play. |
| ObjectBox como cache local | Performance superior ao SQLite para queries de coleções. Suporta offline-first de mensagens e perfil. |
| Cloudflare Workers (edge) | Latência mínima global. Sem cold starts. Durable Objects permitem WebSockets stateful sem servidor dedicado. |
| Shorebird Code Push | Patches críticos chegam ao usuário em minutos, sem ciclo de revisão da store. |