Initial commit - MIDAS App educação financeira para apostadores (FastAPI + Next.js)
This commit is contained in:
407
docs/ARQUITETURA-TECNICA.md
Normal file
407
docs/ARQUITETURA-TECNICA.md
Normal file
@@ -0,0 +1,407 @@
|
||||
# MIDAS — Arquitetura Técnica
|
||||
## App de Educação Financeira para Apostadores | PWA
|
||||
|
||||
---
|
||||
|
||||
## 1. Stack
|
||||
|
||||
| Camada | Tecnologia |
|
||||
|--------|-----------|
|
||||
| Frontend | Next.js 14 (PWA) + TailwindCSS |
|
||||
| Backend | FastAPI (Python 3.12) |
|
||||
| Banco | PostgreSQL 16 + Redis 7 |
|
||||
| IA | GPT-4o-mini (análise de padrões) |
|
||||
| Auth | JWT + bcrypt |
|
||||
| Deploy | DigitalOcean (jarvis-do) |
|
||||
| Pagamento | Stripe |
|
||||
|
||||
---
|
||||
|
||||
## 2. Estrutura
|
||||
|
||||
```
|
||||
midas/
|
||||
├── backend/
|
||||
│ ├── app/
|
||||
│ │ ├── main.py
|
||||
│ │ ├── config.py
|
||||
│ │ ├── database.py
|
||||
│ │ ├── models/
|
||||
│ │ │ ├── user.py # Usuário + plano
|
||||
│ │ │ ├── bet.py # Apostas registradas
|
||||
│ │ │ ├── bankroll.py # Banca + limites
|
||||
│ │ │ ├── alert.py # Alertas de risco
|
||||
│ │ │ ├── achievement.py # Badges/conquistas
|
||||
│ │ │ └── lesson.py # Conteúdo educativo
|
||||
│ │ ├── routers/
|
||||
│ │ │ ├── auth.py # Login/registro
|
||||
│ │ │ ├── bets.py # CRUD apostas
|
||||
│ │ │ ├── bankroll.py # Gestão de banca
|
||||
│ │ │ ├── dashboard.py # Dashboard principal
|
||||
│ │ │ ├── alerts.py # Alertas IA
|
||||
│ │ │ ├── achievements.py # Gamificação
|
||||
│ │ │ ├── lessons.py # Educação
|
||||
│ │ │ ├── reports.py # Relatórios
|
||||
│ │ │ └── billing.py # Stripe
|
||||
│ │ ├── services/
|
||||
│ │ │ ├── analyzer.py # IA análise de padrões
|
||||
│ │ │ ├── risk_engine.py # Motor de risco (semáforo)
|
||||
│ │ │ ├── bankroll_calc.py # Calculadora de banca
|
||||
│ │ │ ├── gamification.py # Engine de badges
|
||||
│ │ │ └── insights.py # Geração de insights IA
|
||||
│ │ └── utils/
|
||||
│ │ ├── auth.py
|
||||
│ │ └── rate_limit.py
|
||||
│ ├── requirements.txt
|
||||
│ └── seed_data.py
|
||||
├── frontend/ # Next.js 14 PWA
|
||||
│ ├── src/app/
|
||||
│ │ ├── page.tsx # Landing
|
||||
│ │ ├── login/
|
||||
│ │ ├── register/
|
||||
│ │ ├── dashboard/ # Dashboard principal
|
||||
│ │ ├── bets/ # Registrar/listar apostas
|
||||
│ │ ├── bankroll/ # Gestão de banca
|
||||
│ │ ├── alerts/ # Alertas de risco
|
||||
│ │ ├── achievements/ # Badges e ranking
|
||||
│ │ ├── lessons/ # Mini-cursos
|
||||
│ │ ├── reports/ # Relatórios mensais
|
||||
│ │ └── premium/
|
||||
│ └── src/components/
|
||||
│ ├── Navbar.tsx
|
||||
│ ├── RiskSemaphore.tsx # 🟢🟡🔴
|
||||
│ ├── BankrollGauge.tsx # Gauge de banca
|
||||
│ ├── BetCard.tsx
|
||||
│ ├── AchievementBadge.tsx
|
||||
│ ├── InsightCard.tsx
|
||||
│ └── StatsChart.tsx
|
||||
└── docs/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Modelo de Dados
|
||||
|
||||
```sql
|
||||
-- Usuários
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(100),
|
||||
plan VARCHAR(20) DEFAULT 'free',
|
||||
streak_days INT DEFAULT 0,
|
||||
total_points INT DEFAULT 0,
|
||||
risk_level VARCHAR(10) DEFAULT 'green',
|
||||
stripe_customer_id VARCHAR(100),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Banca (bankroll)
|
||||
CREATE TABLE bankrolls (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id),
|
||||
monthly_budget DECIMAL(10,2) NOT NULL,
|
||||
weekly_limit DECIMAL(10,2),
|
||||
daily_limit DECIMAL(10,2),
|
||||
bet_max_pct DECIMAL(5,2) DEFAULT 5.0,
|
||||
current_balance DECIMAL(10,2) DEFAULT 0,
|
||||
month_spent DECIMAL(10,2) DEFAULT 0,
|
||||
week_spent DECIMAL(10,2) DEFAULT 0,
|
||||
day_spent DECIMAL(10,2) DEFAULT 0,
|
||||
reset_day INT DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Apostas registradas
|
||||
CREATE TABLE bets (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id),
|
||||
sport VARCHAR(50),
|
||||
event_name VARCHAR(255),
|
||||
platform VARCHAR(100),
|
||||
amount DECIMAL(10,2) NOT NULL,
|
||||
odds DECIMAL(8,3),
|
||||
result VARCHAR(10),
|
||||
profit DECIMAL(10,2),
|
||||
bet_type VARCHAR(50),
|
||||
is_impulsive BOOLEAN DEFAULT FALSE,
|
||||
emotion VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_bets_user ON bets(user_id, created_at DESC);
|
||||
|
||||
-- Alertas
|
||||
CREATE TABLE alerts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id),
|
||||
type VARCHAR(50) NOT NULL,
|
||||
severity VARCHAR(10) NOT NULL,
|
||||
message TEXT NOT NULL,
|
||||
ai_analysis TEXT,
|
||||
is_read BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Conquistas
|
||||
CREATE TABLE achievements (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(100) NOT NULL,
|
||||
description TEXT,
|
||||
icon VARCHAR(10),
|
||||
category VARCHAR(50),
|
||||
requirement_type VARCHAR(50),
|
||||
requirement_value INT,
|
||||
points INT DEFAULT 10
|
||||
);
|
||||
|
||||
CREATE TABLE user_achievements (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id),
|
||||
achievement_id UUID REFERENCES achievements(id),
|
||||
unlocked_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Lições
|
||||
CREATE TABLE lessons (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
title VARCHAR(255) NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
category VARCHAR(50),
|
||||
difficulty VARCHAR(20),
|
||||
duration_min INT DEFAULT 5,
|
||||
order_num INT,
|
||||
is_premium BOOLEAN DEFAULT FALSE
|
||||
);
|
||||
|
||||
CREATE TABLE user_lessons (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id),
|
||||
lesson_id UUID REFERENCES lessons(id),
|
||||
completed_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Fluxo Principal
|
||||
|
||||
```
|
||||
📱 Usuário abre o MIDAS
|
||||
↓
|
||||
📊 Dashboard mostra:
|
||||
├─ Semáforo de risco: 🟢 Verde / 🟡 Amarelo / 🔴 Vermelho
|
||||
├─ Banca restante: R$280 / R$500 (gauge visual)
|
||||
├─ Streak: 🔥 5 dias sem aposta impulsiva
|
||||
├─ Últimas apostas com resultado
|
||||
└─ Insights IA: "Você perde 73% mais em jogos noturnos"
|
||||
↓
|
||||
➕ Registrar aposta:
|
||||
├─ Esporte, evento, plataforma, valor, odds
|
||||
├─ "Como você está se sentindo?" (😎😤😰🤑)
|
||||
├─ Checklist pré-aposta: ✅ Dentro do limite? ✅ Analisou? ✅ Não é recuperação?
|
||||
└─ Se valor > limite → alerta + confirmação extra
|
||||
↓
|
||||
🧠 IA analisa padrão:
|
||||
├─ Horário (madrugada = risco)
|
||||
├─ Sequência (3+ perdas seguidas = alerta)
|
||||
├─ Valor crescente (escalonamento = vício)
|
||||
├─ Emoção (apostando com raiva/frustração)
|
||||
└─ Frequência (todo dia = dependência)
|
||||
↓
|
||||
🚨 Se risco detectado → Alerta:
|
||||
├─ Push notification
|
||||
├─ Mensagem educativa
|
||||
├─ Sugestão de pausa
|
||||
└─ Link para ajuda profissional (CVV, GREA-USP)
|
||||
↓
|
||||
🏆 Gamificação:
|
||||
├─ Badge: "Disciplina de Ferro" (7 dias sem impulsiva)
|
||||
├─ Badge: "Analista" (completou 5 lições)
|
||||
├─ Ranking semanal de disciplina
|
||||
└─ Pontos → desbloqueia conteúdo premium
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. API Endpoints
|
||||
|
||||
### Auth
|
||||
```
|
||||
POST /api/auth/register
|
||||
POST /api/auth/login
|
||||
GET /api/auth/me
|
||||
```
|
||||
|
||||
### Dashboard
|
||||
```
|
||||
GET /api/dashboard # Dados principais (banca, risco, streak, insights)
|
||||
```
|
||||
|
||||
### Apostas
|
||||
```
|
||||
POST /api/bets # Registrar aposta
|
||||
GET /api/bets # Listar apostas
|
||||
GET /api/bets/stats # Estatísticas (win rate, ROI, por esporte)
|
||||
PATCH /api/bets/:id/result # Registrar resultado (win/loss)
|
||||
```
|
||||
|
||||
### Banca
|
||||
```
|
||||
GET /api/bankroll # Status da banca
|
||||
PUT /api/bankroll # Configurar limites
|
||||
GET /api/bankroll/check # Verificar se aposta está dentro do limite
|
||||
```
|
||||
|
||||
### Alertas
|
||||
```
|
||||
GET /api/alerts # Listar alertas
|
||||
PATCH /api/alerts/:id/read # Marcar como lido
|
||||
```
|
||||
|
||||
### Gamificação
|
||||
```
|
||||
GET /api/achievements # Todas as conquistas
|
||||
GET /api/achievements/mine # Minhas conquistas
|
||||
GET /api/leaderboard # Ranking
|
||||
```
|
||||
|
||||
### Educação
|
||||
```
|
||||
GET /api/lessons # Listar lições
|
||||
GET /api/lessons/:id # Conteúdo da lição
|
||||
POST /api/lessons/:id/complete # Marcar como concluída
|
||||
```
|
||||
|
||||
### Relatórios
|
||||
```
|
||||
GET /api/reports/weekly # Relatório semanal
|
||||
GET /api/reports/monthly # Relatório mensal
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Motor de Risco (IA)
|
||||
|
||||
### Semáforo
|
||||
```
|
||||
🟢 VERDE — Apostando dentro dos limites, padrão saudável
|
||||
🟡 AMARELO — 1-2 sinais de alerta detectados
|
||||
🔴 VERMELHO — Padrão de risco/vício identificado
|
||||
```
|
||||
|
||||
### Sinais de Alerta (pesos)
|
||||
| Sinal | Peso | Descrição |
|
||||
|-------|------|-----------|
|
||||
| Horário noturno (23h-5h) | 15 | Apostas de madrugada |
|
||||
| Valor crescente | 25 | Cada aposta maior que a anterior |
|
||||
| Recuperação | 30 | Apostar logo após perda pra "recuperar" |
|
||||
| Frequência alta | 20 | +3 apostas/dia |
|
||||
| Limite estourado | 25 | Passou do orçamento definido |
|
||||
| Emoção negativa | 15 | Apostando com raiva/frustração |
|
||||
| Sequência de perdas | 20 | 3+ perdas seguidas sem parar |
|
||||
|
||||
**Score**: soma dos pesos → 0-30 verde, 31-60 amarelo, 61+ vermelho
|
||||
|
||||
### Prompt IA (insights)
|
||||
```python
|
||||
INSIGHT_PROMPT = """
|
||||
Analise o histórico de apostas deste usuário e gere insights.
|
||||
|
||||
DADOS:
|
||||
- Total apostado mês: R${total_month}
|
||||
- Win rate: {win_rate}%
|
||||
- Esportes: {sports}
|
||||
- Horários mais comuns: {hours}
|
||||
- Padrão de valores: {amounts}
|
||||
- Sequências de perda: {loss_streaks}
|
||||
- Emoções registradas: {emotions}
|
||||
|
||||
Gere 3 insights em JSON:
|
||||
[
|
||||
{"icon": "💡", "title": "título curto", "text": "insight prático em 1 frase"},
|
||||
]
|
||||
|
||||
Seja direto, honesto e educativo. Português BR.
|
||||
"""
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Gamificação — Badges
|
||||
|
||||
| Badge | Requisito | Pontos |
|
||||
|-------|-----------|--------|
|
||||
| 🌱 Primeiro Passo | Registrar primeira aposta | 10 |
|
||||
| 📚 Estudante | Completar 3 lições | 20 |
|
||||
| 🎯 Disciplinado | 7 dias dentro do limite | 50 |
|
||||
| 🔥 Streak de Ferro | 30 dias sem aposta impulsiva | 100 |
|
||||
| 🧠 Analista | Registrar 50 apostas com análise | 30 |
|
||||
| 🛡️ Autocontrole | Cancelar aposta após alerta | 40 |
|
||||
| 📊 Consciente | Ver relatório mensal 3x | 15 |
|
||||
| 👑 Mestre da Banca | ROI positivo por 3 meses | 200 |
|
||||
|
||||
---
|
||||
|
||||
## 8. Design System
|
||||
|
||||
### Paleta
|
||||
- **Dourado:** #D4A843 (premium, dinheiro, Midas)
|
||||
- **Azul escuro:** #0F172A (confiança, seriedade)
|
||||
- **Verde:** #10B981 (seguro, aprovado)
|
||||
- **Amarelo:** #FBBF24 (atenção)
|
||||
- **Vermelho:** #EF4444 (perigo, stop)
|
||||
- **Branco:** #F8FAFC
|
||||
|
||||
### Identidade
|
||||
- Logo: Coroa dourada + "MIDAS"
|
||||
- Slogan: "Aposte com consciência"
|
||||
- Font: Inter (body) + Cabinet Grotesk (display)
|
||||
- Mobile-first, PWA instalável
|
||||
- Dark mode como padrão
|
||||
|
||||
---
|
||||
|
||||
## 9. Portas & Deploy
|
||||
|
||||
| Serviço | Porta | PM2 Name |
|
||||
|---------|-------|----------|
|
||||
| Backend FastAPI | 8095 | midas-backend |
|
||||
| Frontend Next.js | 3085 | midas-frontend |
|
||||
|
||||
- **URL**: midas.aivertice.com
|
||||
- **DB**: PostgreSQL `midas` / user `midas`
|
||||
- **Deploy**: jarvis-do (198.199.84.130)
|
||||
|
||||
---
|
||||
|
||||
## 10. Roadmap
|
||||
|
||||
### MVP — Semanas 1-2
|
||||
- [ ] Auth (registro/login)
|
||||
- [ ] Dashboard com semáforo de risco
|
||||
- [ ] Registrar apostas manualmente
|
||||
- [ ] Gestão de banca (definir limites)
|
||||
- [ ] Alertas básicos (limite estourado, frequência alta)
|
||||
- [ ] 5 lições educativas
|
||||
- [ ] 5 badges iniciais
|
||||
- [ ] PWA instalável
|
||||
- [ ] Deploy DigitalOcean
|
||||
|
||||
### v1.0 — Semanas 3-4
|
||||
- [ ] IA insights (GPT-4o-mini)
|
||||
- [ ] Relatórios semanais/mensais
|
||||
- [ ] Mais badges e ranking
|
||||
- [ ] Stripe (assinatura premium)
|
||||
- [ ] Push notifications
|
||||
|
||||
### v2.0 — Semanas 5-8
|
||||
- [ ] Integração com casas de aposta (API)
|
||||
- [ ] Compartilhar relatório (stories)
|
||||
- [ ] Desafios semanais
|
||||
- [ ] White-label B2B
|
||||
- [ ] App nativo React Native
|
||||
|
||||
---
|
||||
*Arquitetura JARVIS — 10/02/2026*
|
||||
Reference in New Issue
Block a user