Skip to content

Orbit API ⚡ ​

O backend do Orbit é uma infraestrutura Edge-first distribuída globalmente, rodando sobre a rede da Cloudflare. É responsável por toda lógica de negócio, autenticação, comunicação em tempo real e integrações externas.

Ambiente de produção: https://api.redeorbit.com


🛠️ Stack Tecnológica ​

TecnologiaUso
Cloudflare Workers (TypeScript)Runtime serverless edge, zero cold start
Cloudflare D1Banco de dados SQL distribuído
Cloudflare R2Object Storage (imagens, vídeos, áudios)
Durable ObjectsWebSockets stateful e estado em tempo real
Cloudflare KVCache distribuído e rate limiting
LiveKitInfraestrutura de chamadas de vídeo/áudio em grupo
ResendEnvio de e-mails transacionais
Firebase AdminVerificação de tokens Firebase Auth e envio de FCM
Last.fm APIIntegração de música (perfil e status)
Steam APIIntegração de jogos (conquistas, biblioteca)
Cloudflare TurnstileAnti-bot e proteção de formulários
ZodValidação de schemas na camada de roteamento
joseJWT (geração e verificação de tokens internos)

📂 Estrutura de Pastas ​

api/
├── src/
│   ├── index.ts            # Entry point do Worker (rotas + Durable Objects)
│   ├── routers.ts          # Definição central de todas as rotas REST
│   ├── cron-jobs.ts        # Jobs agendados (crons)
│   │
│   ├── core/               # Contexto de requisição, DI e interfaces base
│   │
│   ├── durable-objects/    # Objetos stateful do Cloudflare
│   │   ├── WebSocketHandler     # Hub de WebSockets (presença, eventos)
│   │   ├── CinemaRoomDO         # Sala de cinema sincronizada
│   │   └── DimensionChatRoom    # Chat em tempo real de dimensões
│   │
│   ├── features/           # Módulos por domínio (Vertical Slice Architecture)
│   │   ├── admin/          # Painel administrativo
│   │   ├── auth/           # Login, registro, refresh de JWT
│   │   ├── chat/           # Mensagens, grupos, criptografia
│   │   ├── cinema/         # Salas de cinema colaborativas
│   │   ├── communities/    # Grupos temáticos e canais
│   │   ├── emails/         # Templates e envio de e-mails
│   │   ├── events/         # Sistema de eventos (Kraken boss battles)
│   │   ├── interactions/   # Amizades, match, bloqueios
│   │   ├── misc/           # Endpoints utilitários
│   │   ├── pets/           # Pets digitais, batalhas, itens
│   │   ├── posts/          # Feed, comentários, reações, agendamento
│   │   ├── shorts/         # Vídeos curtos (VAP)
│   │   ├── users/          # Perfil, visitas, badges, configurações
│   │   └── webhooks/       # Webhooks externos
│   │
│   ├── infrastructure/     # Adaptadores para serviços externos
│   │   ├── d1/             # Queries 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 helpers, validações, formatadores
│
├── migrations/             # Arquivos .sql de migrations do D1
├── wrangler.toml           # Configuração de infra (D1, R2, DO, vars)
└── package.json            # Scripts e dependências

🚀 Setup e Desenvolvimento ​

1. Requisitos ​

  • Node.js LTS
  • Wrangler CLI: npm install -g wrangler
  • Acesso ao Cloudflare (autenticado com wrangler login)

2. Rodar Localmente ​

O Wrangler emula o ambiente da Cloudflare localmente com D1 e R2 simulados:

bash
npm install
npm run dev    # → http://localhost:8787

3. Verificar Erros de Tipo ​

bash
npm run typecheck

TIP

O Wrangler usa esbuild internamente — não há passo de build separado. npm run dev e npm run deploy:test compilam TypeScript automaticamente.


🗄️ Banco de Dados (D1) ​

O Orbit utiliza um banco relacional SQLite distribuído na Edge (Cloudflare D1). A arquitetura é moldada para alta performance em leitura, com forte uso de relacionamentos e índices.

📚 Dicionário de Dados Automático ​

(Gerado automaticamente a partir das migrations do Cloudflare D1)

Atualmente, o banco de dados possui 43 tabelas principais:

text
- access_logs
- active_group_calls
- active_lives
- ad_campaigns
- ad_metrics
- ad_rewards_history
- advertisers
- banned_device_ids
- cashout_requests
- community_channel_messages
- community_channel_poll_options
- community_channel_poll_votes
- community_channel_polls
- community_channel_reactions
- community_channels
- device_checks
- dimension_wiki
- game_scores
- global_events
- highlight_items
- highlights
- marketplace_transactions
- match_signals
- orbit_emails
- pet_caregivers
- pet_interactions
- pet_items
- post_collaborators
- processed_payments
- redeem_codes
- redeem_history
- shorts_favorites
- shorts_shares
- space_capsule_interactions
- space_capsules
- user_event_contributions
- user_key_history
- user_push_tokens
- user_sticker_packs
- user_stickers
- user_stream_keys
- view_once_views
- virtual_pets

🗺️ Principais Entidades (ER Diagram) ​

Abaixo está o modelo simplificado das entidades essenciais do núcleo da plataforma:

mermaid
erDiagram
    USERS {
        string id PK
        string username
        string email
        int orbit_coins
    }
    COMMUNITIES {
        string id PK
        string owner_id FK
        string name
        string category
    }
    DIGITAL_ITEMS {
        string id PK
        string category "avatar_frame, chat_bubble, profile_bg"
        int price
        boolean is_iap "True if bought with real money"
    }
    USER_ITEMS {
        string id PK
        string user_id FK
        string item_id FK
        datetime acquired_at
    }
    POSTS {
        string id PK
        string author_id FK
        string content
        datetime created_at
    }
    
    USERS ||--o{ POSTS : "cria"
    USERS ||--o{ COMMUNITIES : "administra"
    USERS ||--o{ USER_ITEMS : "possui"
    DIGITAL_ITEMS ||--o{ USER_ITEMS : "é adquirido como"

📖 Nota de Arquitetura (Digital Items): O ecossistema de cosméticos separa a definição global (DIGITAL_ITEMS) da posse pelo usuário (USER_ITEMS). Itens marcados como is_iap não podem ser comprados com moedas virtuais (orbit_coins).

Criar nova migration ​

bash
npm run db:new nome_da_migration
# Edite o arquivo .sql gerado em migrations/

Aplicar em produção ​

bash
npm run db:push

CAUTION

Nunca altere o banco diretamente pelo painel da Cloudflare. Use sempre migrations para garantir rastreabilidade.


⏰ Cron Jobs ​

A API executa jobs agendados automaticamente via Cloudflare Cron Triggers:

ScheduleFrequênciaTarefa
* * * * *A cada minutoSaúde de pets, expiração de itens temporários
*/30 * * * *A cada 30 minLimpeza de sessões expiradas, eventos
0 2 * * *Diário (02:00)Limpeza de stories expirados, manutenção
0 */8 * * *3x por diaAtualização de rankings e estatísticas

🌍 Deploy ​

Ambiente de Teste ​

bash
npm run deploy:test    # → orbit-server-test (environment: test)

Produção ​

bash
# 1. Aplicar migrations pendentes
npm run db:push

# 2. Deploy do Worker
npm run deploy:prod    # → orbit-server (environment: production)

NOTE

O deploy de produção é automatizado via GitHub Actions em push na branch stable. Use o deploy manual apenas como último recurso.


📊 Observabilidade ​

bash
# Logs em tempo real — ambiente de teste
npm run tail:dev

# Logs em tempo real — produção
npm run tail:prod

🔐 Autenticação ​

A API usa dupla validação:

  1. Firebase Auth Token — o app envia o idToken do Firebase. A API o verifica via Firebase Admin SDK.
  2. JWT Interno (jose) — após validação, a API emite um JWT próprio usado em todas as requisições subsequentes.

Segredos sensíveis são armazenados como Wrangler Secrets (não no wrangler.toml):

bash
wrangler secret put NOME_DA_SECRET --env production

🧱 Boas Práticas ​

  • Use Zod para todas as validações de entrada na camada de routers.ts. O core nunca deve receber dados malformados.
  • Nunca altere o banco direto — sempre use migrations.
  • Vertical Slice: cada feature em features/ é auto-contida. Evite importações cruzadas entre features.
  • Durable Objects são caros — use apenas para estado realmente stateful (WebSockets, salas). Não use para queries simples.

TIP

Regra de Ouro: Código altera → migration → teste local → push → CI compila e sobe.