Fluxo Típico de Uso
1. Onboarding & Cadastro
O usuário baixa o app ou abre o site. Ele precisa criar uma
conta para salvar seus alertas.
POST /register
{ "name": "Leandro", "email": "leo@sky.com", "pass": "*****" }
{ "name": "Leandro", "email": "leo@sky.com", "pass": "*****" }
2. Descoberta & Feed
Ao logar, ele vê o "Feed de Oportunidades". Voos que caíram
de preço nas últimas horas aparecem no topo com destaque
verde.
3. Intenção de Compra (Alerta)
O usuário quer ir para Lisboa, mas só se for barato. Ele
cadastra uma intenção de monitoramento.
POST /alerts
{ "origin": "REC", "dest": "LIS", "target_price": 3000.00 }
{ "origin": "REC", "dest": "LIS", "target_price": 3000.00 }
4. O "Motor" Trabalha (Invisible)
O backend (Márcio) roda 24/7. De repente, o algoritmo baixa
o preço de REC-LIS para R$ 2.950,00. O sistema detecta que
bateu com o alvo do usuário.
5. Notificação & Conversão
O App do Leandro vibra e o Site do Jefferson mostra um
Toast: "Seu voo baixou!". O usuário clica e vê os detalhes
da oferta.
Visual Targets (A Meta Visual)
Dashboard Web
ANÁLISE: REC-LIS
R$ 2.450
▼ Caindo rápido nas últimas 2h
App Mobile
Olá, Leandro 👋
OFERTAS QUENTES
REC ✈️ GRU▲ +5%
LatamR$ 1.200
GRU ✈️ MIA▼ -12%
AmericanR$ 3.100
REC ✈️ LIS▼ -2%
TAPR$ 4.800
Organização e Git Flow
Regras da Casa
-
Git Flow Simplificado:
-
main: Ninguém toca. É o código que funciona. -
develop: Onde juntamos o código de todo mundo. -
feat/nome-da-feature: Onde você trabalha. Ex:feat/login-leandro.
-
-
Commits Semânticos:
feat:Nova funcionalidade.fix:Correção de bug.docs:Mudança em documentação.
- Rituais: Daily Assíncrona no WhatsApp ("O que fiz ontem, o que farei hoje").
Strato Design System
Copiem estes hexadecimais. Se usarem cores diferentes, o projeto vai parecer uma colcha de retalhos.
BG Body
#0f172a
#0f172a
BG Card
#1e293b
#1e293b
Primary
#6366f1
#6366f1
Green/Down
#10b981
#10b981
Red/Up
#ef4444
#ef4444
Backend: Márcio GoLang
O cérebro da operação. Você não cria telas, você cria a inteligência.
🚀 Features Detalhadas para Desenvolver
1. Simulador Estocástico (Worker)
Criar uma Goroutine que roda infinitamente. A cada ciclo (ex:
5s), ela deve iterar sobre todos os voos no banco. Use a função
rand para aplicar volatilidade (+/- 5%), mas
implemente uma lógica de "Mean Reversion" para que o preço não
suba para sempre, ele deve tender a voltar para o
base_price.
2. API RESTful Padronizada
Não devolva apenas arrays soltos. Padronize as respostas JSON.
Se der erro, devolva
{"error": "message", "code": 400}. Se der sucesso,
devolva {"data": [...], "meta": { "total": 10 }}.
Implemente CORS para que o React e o Native consigam acessar.
3. Autenticação JWT (Middleware)
Crie um middleware no Gin. Antes de deixar acessar
/alerts, verifique se o Header tem
Authorization: Bearer xyz. Valide a assinatura do
token. Se for inválido, retorne 401 Unauthorized imediatamente.
4. Sistema de Logs Estruturados
Em vez de usar
println, use uma lib de log (ex:
Zerolog ou Zap). O log deve sair em JSON:
{"level": "info", "msg": "Price updated", "route":
"REC-LIS"}. Isso é vital para debugging em produção.
Esquema do Banco de Dados (DER)
routes (As Rotas)
id UUID
origin CHAR(3)
destination CHAR(3)
current_price FLOAT
price_history (O Gráfico)
id INT (AI)
route_id UUID
price FLOAT
timestamp DATETIME
Arquitetura & Código Core
sky-backend/
cmd/
main.go
internal/
models/
flight.go
simulator/
worker.go
Code Snippet: O Simulador (worker.go)
package simulator
import (
"math/rand"
"time"
"gorm.io/gorm"
"sky-backend/internal/models"
)
// StartMarket roda em uma Goroutine separada (Background)
func StartMarket(db *gorm.DB) {
go func() {
for {
time.Sleep(5 * time.Second) // O pulso do mercado
var routes []models.Route
db.Find(&routes)
for _, r := range routes {
// Variação percentual (-5% a +5%)
variation := (rand.Float64() * 0.10) - 0.05
newPrice := r.CurrentPrice * (1 + variation)
// Trava de segurança (preço mínimo)
if newPrice < 50 { newPrice = 50 }
// Atualiza e Salva Histórico
r.CurrentPrice = newPrice
db.Save(&r)
db.Create(&models.PriceHistory{
RouteID: r.ID,
Price: newPrice,
Timestamp: time.Now(),
})
}
println("♻️ Market Updated")
}
}()
}
Web: Jefferson React
O Analista. Foco em Dashboards densos e performance de renderização.
🚀 Features Detalhadas para Desenvolver
1. Polling Inteligente (SWR/React Query)
Não use
setInterval puro. Use bibliotecas como SWR.
Configure-a para parar de fazer requisições se o usuário trocar
de aba (foco perdido) e retomar quando voltar. Isso economiza
bateria e dados. O intervalo deve ser de ~5 segundos.
2. Gráficos de Alta Performance
Use Recharts. O desafio aqui é pegar o array de
histórico (que pode ter 1000 itens) e formatar a data no Eixo X
para ficar legível (ex: apenas Hora:Minuto). Implemente Tooltips
customizados que mostram o preço exato ao passar o mouse.
3. Protected Routes (Auth Wrapper)
Crie um componente
RequireAuth que envolve as rotas
do Dashboard. Se o usuário não tiver o token no LocalStorage,
ele deve ser "kickado" automaticamente para a tela de Login.
4. Feedback Visual (Toasts)
Implemente uma biblioteca de Toasts (ex: React Hot Toast).
Quando o usuário salvar uma configuração ou fizer login, mostre
um feedback visual no canto superior direito. Não use
alert() nativo do navegador.
Arquitetura & Código Core
sky-web/
src/
hooks/
useFlightData.js
components/
FlightChart.jsx
App.jsx
Code Snippet: Custom Hook (useFlightData.js)
import { useState, useEffect } from 'react';
export function useFlightData() {
const [data, setData] = useState([]);
const update = async () => {
try {
const res = await fetch('http://localhost:8080/flights');
const json = await res.json();
setData(json);
} catch (err) {
console.error("API Error", err);
}
};
useEffect(() => {
update();
// Polling a cada 3s
const interval = setInterval(update, 3000);
return () => clearInterval(interval);
}, []);
return data;
}
Mobile: Leandro React Native
O Viajante. Foco em UX fluida, animações e funcionamento offline.
🚀 Features Detalhadas para Desenvolver
1. Lista Virtualizada (FlatList Optimization)
Como a lista de voos pode crescer, nunca use
ScrollView com map. Use
FlatList. Implemente as propriedades
initialNumToRender e windowSize para
garantir que o scroll fique em 60fps mesmo com muitos dados.
2. Animações de Preço (Reanimated)
Quando o preço mudar, não mude o texto "seco". Faça a cor piscar
ou o número deslizar. Use
useEffect dentro do Card
para detectar mudança na prop price e disparar uma
animação de cor (Verde para queda, Vermelho para subida).
3. Cache Offline (AsyncStorage)
Implemente a estratégia "Stale-While-Revalidate". Ao abrir o
app, carregue imediatamente o JSON salvo no
AsyncStorage para a tela não ficar branca. Só
depois tente buscar na API e atualizar a tela. O usuário deve
ver dados em 100ms.
4. Pull to Refresh & Haptics
Adicione a propriedade
onRefresh na FlatList.
Quando o usuário puxar e soltar, dispare o fetch novamente. Ao
concluir, use Haptics.notificationAsync para dar um
"tique" de vibração na mão do usuário, confirmando a
atualização.
Arquitetura & Código Core
sky-mobile/
src/
components/
FlightCard.js
screens/
Home.js
App.js
Code Snippet: Lógica de Cor (FlightCard.js)
import { View, Text, StyleSheet } from 'react-native';
export default function FlightCard({ item }) {
// Lógica visual simples
const isCheap = item.trend === 'down';
const color = isCheap ? '#10b981' : '#ef4444';
return (
<View style={styles.card}>
<View>
<Text style={styles.route}>{item.origin} ✈ {item.dest}</Text>
<Text style={styles.sub}>Voo Direto</Text>
</View>
<View>
<Text style={[styles.price, { color }]}>
R$ {item.price.toFixed(0)}
</Text>
</View>
</View>
);
}