5 Commits

Author SHA1 Message Date
Erik Silva
773172c63c fix: add API proxy via Next rewrites + fix hardcoded localhost URLs 2025-12-09 02:17:00 -03:00
Erik Silva
86e4afb916 docs: adiciona mapa mental completo do projeto 2025-12-09 02:07:21 -03:00
Erik Silva
44db6195f6 fix: increase rate limit for dev (30 attempts/min) 2025-12-09 02:04:10 -03:00
Erik Silva
a33fb2f544 fix: redirect authenticated dash login 2025-12-09 01:58:39 -03:00
Erik Silva
f553114c06 chore: reorganiza init-db do postgres 2025-12-09 01:51:56 -03:00
13 changed files with 575 additions and 25 deletions

View File

@@ -71,7 +71,7 @@ AGGIOS-APP/
│ └─ letsencrypt/ │ └─ letsencrypt/
│ └─ acme.json (auto-generated) │ └─ acme.json (auto-generated)
├─ 📂 postgres/ ← PostgreSQL Setup (NOVO) ├─ 📂 backend/internal/data/postgres/ ← PostgreSQL Setup (NOVO)
│ └─ init-db.sql ✅ Initial schema │ └─ init-db.sql ✅ Initial schema
├─ 📂 scripts/ ← Helper Scripts (NOVO) ├─ 📂 scripts/ ← Helper Scripts (NOVO)

View File

@@ -77,7 +77,7 @@ aggios-app/
│ ├─ dynamic/rules.yml │ ├─ dynamic/rules.yml
│ └─ letsencrypt/ │ └─ letsencrypt/
├─ 📂 postgres/ .............................. PostgreSQL (NOVO) ├─ 📂 backend/internal/data/postgres/ ........ PostgreSQL (NOVO)
│ └─ init-db.sql │ └─ init-db.sql
├─ 📂 scripts/ ............................... Scripts (NOVO) ├─ 📂 scripts/ ............................... Scripts (NOVO)

View File

@@ -106,8 +106,8 @@ aggios-app/
│ ├── dynamic/rules.yml # Dynamic routing rules │ ├── dynamic/rules.yml # Dynamic routing rules
│ └── letsencrypt/ # Certificados (auto-gerado) │ └── letsencrypt/ # Certificados (auto-gerado)
├── postgres/ # Inicialização PostgreSQL ├── backend/internal/data/postgres/ # Inicialização PostgreSQL
│ └── init-db.sql # Schema initial │ └── init-db.sql # Schema initial
├── scripts/ ├── scripts/
│ ├── start-dev.sh # Start em Linux/macOS │ ├── start-dev.sh # Start em Linux/macOS

View File

@@ -228,7 +228,7 @@ DOCKER:
CONFIGURAÇÃO: CONFIGURAÇÃO:
├─ YAML files: 2 (traefik.yml, rules.yml) ├─ YAML files: 2 (traefik.yml, rules.yml)
├─ SQL files: 1 (init-db.sql) ├─ SQL files: 1 (backend/internal/data/postgres/init-db.sql)
├─ .env example: 1 ├─ .env example: 1
├─ Dockerfiles: 1 ├─ Dockerfiles: 1
└─ Scripts: 2 (start-dev.sh, start-dev.bat) └─ Scripts: 2 (start-dev.sh, start-dev.bat)

View File

@@ -0,0 +1,529 @@
# 🧠 Mapa Mental - Projeto Aggios
## 📌 Visão Geral
**Aggios** é uma plataforma **SaaS multi-tenant** que gerencia agências digitais com controle centralizado, gestão de clientes, soluções integradas (CRM/ERP) e sistema de pagamento.
---
## 🏛️ Arquitetura Geral
```
┌─────────────────────────────────────────────────────────┐
│ AGGIOS PLATFORM │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Super Admin Dashboard (dash.localhost) │ │
│ │ - Gerenciar todas as agências │ │
│ │ - Visualizar cadastros │ │
│ │ - Excluir/arquivar agências │ │
│ │ - Controle de planos e pagamentos │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ │ │ │ │
│ ┌────────▼──┐ ┌─────▼────┐ ┌───▼────────┐ │
│ │ Agência A │ │ Agência B │ │ Agência N │ │
│ │ Subdomain │ │ Subdomain │ │ Subdomain │ │
│ │ A │ │ B │ │ N │ │
│ └─────┬─────┘ └──────┬────┘ └────┬───────┘ │
│ │ │ │ │
│ ┌─────▼──────┐ ┌─────▼──────┐ ┌─▼───────────┐ │
│ │CRM / ERP │ │CRM / ERP │ │CRM / ERP │ │
│ │Clientes │ │Clientes │ │Clientes │ │
│ │Soluções │ │Soluções │ │Soluções │ │
│ └────────────┘ └────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
---
## 🔐 Sistema de Autenticação
### Níveis de Acesso
```
┌─────────────────────────────────────────┐
│ PERMISSÕES E ROLES │
├─────────────────────────────────────────┤
│ │
│ SUPERADMIN (admin@aggios.app) │
│ ├─ Gerenciar todas as agências │
│ ├─ Visualizar cadastros │
│ ├─ Excluir/arquivar agências │
│ ├─ Controlar planos │
│ └─ Gerenciar pagamentos │
│ │
│ ADMIN_AGENCIA (por agência) │
│ ├─ Gerenciar clientes próprios │
│ ├─ Acessar CRM/ERP │
│ ├─ Visualizar relatórios │
│ └─ Configurar agência │
│ │
│ CLIENTE (por agência) │
│ ├─ Visualizar próprios dados │
│ ├─ Acessar serviços contratados │
│ └─ Submeter solicitações │
│ │
└─────────────────────────────────────────┘
```
### Fluxo de Login
```
Usuário acessa:
dash.localhost
Detecta "dash" no hostname
Busca localStorage (token + user)
┌─ Token válido? → Redireciona para /superadmin
└─ Sem token? → Mostra /login
Submete credenciais
Backend valida contra DB
┌─ Válido → Retorna JWT + user data
│ → Salva em localStorage
│ → Redireciona para /superadmin
└─ Inválido → Toast error
```
---
## 🏢 Estrutura de Tenants
### Multi-Tenant Model
```
┌─────────────────────────────────────────┐
│ TENANT (Agência) │
├─────────────────────────────────────────┤
│ │
│ ID: UUID │
│ name: "Agência Ideal Pages" │
│ subdomain: "idealpages" │
│ domain: "idealpages.aggios.app" │
│ cnpj: "XX.XXX.XXX/XXXX-XX" │
│ razao_social: "Ideal Pages Ltda" │
│ status: active | inactive │
│ │
│ ┌─────────────────────────────────┐ │
│ │ USERS (pertencentes ao tenant) │ │
│ ├─────────────────────────────────┤ │
│ │ - Admin (ADMIN_AGENCIA) │ │
│ │ - Operadores │ │
│ │ - Suporte │ │
│ │ - Clientes │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ COMPANIES (clientes) │ │
│ ├─────────────────────────────────┤ │
│ │ - ID, CNPJ, email, telefone │ │
│ │ - Dados de contato │ │
│ │ - Status │ │
│ └─────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────┐ │
│ │ SOLUTIONS (CRM, ERP, etc) │ │
│ ├─────────────────────────────────┤ │
│ │ - Módulos disponíveis │ │
│ │ - Integrações │ │
│ │ - Configurações │ │
│ └─────────────────────────────────┘ │
│ │
└─────────────────────────────────────────┘
```
---
## 🛠️ Tech Stack
### Backend
```
Backend (Go)
├─ HTTP Server (net/http)
├─ JWT Authentication
├─ Password Hashing (Argon2)
├─ PostgreSQL (SQL direto, sem ORM)
├─ Redis (cache/sessions)
├─ MinIO (object storage)
└─ Middleware (CORS, Security, Rate Limit)
```
### Frontend
```
Frontend (Next.js 14)
├─ Dashboard (Superadmin)
│ ├─ Listagem de agências
│ ├─ Detalhes/visualização
│ └─ Excluir/arquivar
├─ Portais de Agência
│ ├─ Login específico por subdomain
│ ├─ Dashboard da agência
│ ├─ Gerenciador de clientes (CRM)
│ ├─ ERP
│ └─ Integrações
└─ Site Institucional (aggios.app)
├─ Landing page
├─ Pricing/Planos
├─ Documentação
└─ Contato
```
### Infraestrutura
```
Docker Compose
├─ PostgreSQL 16 (DB)
├─ Redis 7 (Cache)
├─ MinIO (S3-compatible storage)
├─ Traefik (Reverse Proxy)
├─ Backend (Go)
├─ Dashboard (Next.js)
└─ Institucional (Next.js)
```
---
## 📊 Banco de Dados
### Schema Principal
```
┌──────────────────────────────────────────────────┐
│ DATABASE SCHEMA │
├──────────────────────────────────────────────────┤
│ │
│ TENANTS │
│ ├─ id (UUID) │
│ ├─ name, subdomain, domain │
│ ├─ cnpj, razao_social │
│ ├─ email, phone, website, address │
│ ├─ description, industry │
│ ├─ is_active │
│ └─ timestamps (created_at, updated_at) │
│ ↑ │
│ └─── FK em USERS │
│ └─── FK em COMPANIES │
│ │
│ USERS │
│ ├─ id (UUID) │
│ ├─ tenant_id (FK → TENANTS) │
│ ├─ email (UNIQUE) │
│ ├─ password_hash │
│ ├─ first_name, last_name │
│ ├─ role (SUPERADMIN | ADMIN_AGENCIA | CLIENTE) │
│ ├─ is_active │
│ └─ timestamps │
│ │
│ REFRESH_TOKENS │
│ ├─ id (UUID) │
│ ├─ user_id (FK → USERS) │
│ ├─ token_hash │
│ ├─ expires_at │
│ └─ created_at │
│ │
│ COMPANIES (Clientes das agências) │
│ ├─ id (UUID) │
│ ├─ tenant_id (FK → TENANTS) │
│ ├─ cnpj (UNIQUE por tenant) │
│ ├─ razao_social, nome_fantasia │
│ ├─ email, telefone │
│ ├─ status │
│ ├─ created_by_user_id (FK → USERS) │
│ └─ timestamps │
│ │
└──────────────────────────────────────────────────┘
```
---
## 🔄 Fluxo de Cadastro (Registro de Nova Agência)
```
1. INICIO
├─ Usuário acessa: http://dash.localhost/cadastro
├─ Preenche formulário:
│ ├─ Nome fantasia
│ ├─ Razão social
│ ├─ CNPJ
│ ├─ Email comercial
│ ├─ Telefone
│ ├─ Website
│ ├─ Endereço completo
│ ├─ Cidade/Estado/CEP
│ ├─ Segmento (indústria)
│ ├─ Descrição
│ ├─ Email do admin da agência
│ └─ Senha inicial do admin
├─ Validação Frontend
│ ├─ Campos obrigatórios
│ ├─ Formato de email
│ ├─ Força de senha
│ └─ CNPJ válido?
├─ POST /api/admin/agencies/register (Backend)
│ │
│ ├─ Validação Backend (regras de negócio)
│ │
│ ├─ Transação DB:
│ │ ├─ Criar TENANT (gera UUID, subdomain)
│ │ ├─ Criar USER (ADMIN_AGENCIA)
│ │ ├─ Hash password (Argon2)
│ │ └─ Commit
│ │
│ └─ Retorna: {tenant_id, subdomain, access_url}
├─ Frontend recebe resposta
│ ├─ Exibe toast de sucesso
│ ├─ Salva dados temporários
│ └─ Redireciona para /superadmin
└─ FIM (Agência criada e pronta para uso)
└─ Acesso: {subdomain}.localhost/login
```
---
## 📈 Funcionalidades por Módulo
### 🔷 Superadmin Dashboard
```
dash.localhost/superadmin
├─ Header
│ ├─ Logo Aggios
│ ├─ Título "Painel Administrativo"
│ ├─ Email do admin
│ └─ Botão Sair
├─ Stats (KPIs)
│ ├─ Total de agências
│ ├─ Agências ativas
│ ├─ Agências inativas
│ └─ (Expandível: faturamento, etc)
├─ Listagem de Agências
│ ├─ Tabela com:
│ │ ├─ Nome fantasia
│ │ ├─ Subdomain
│ │ ├─ Status (ativo/inativo)
│ │ ├─ Data de criação
│ │ └─ Ações (Ver detalhes, Deletar)
│ │
│ └─ Busca/Filtro
└─ Modal de Detalhes
├─ Seção: Dados da Agência
│ ├─ Nome fantasia, razão social
│ ├─ CNPJ, segmento
│ ├─ Descrição
│ └─ Status
├─ Seção: Endereço e Contato
│ ├─ Endereço, cidade, estado, CEP
│ ├─ Website
│ ├─ Email comercial
│ └─ Telefone
├─ Seção: Administrador
│ ├─ Nome do admin
│ ├─ Email do admin
│ ├─ Role
│ └─ Data de criação
└─ Botões
├─ Abrir painel da agência (link externo)
├─ Deletar agência
└─ Fechar
```
### 🔶 Dashboard da Agência (Em Desenvolvimento)
```
{subdomain}.localhost/dashboard
├─ Sidebar
│ ├─ Dashboard
│ ├─ Clientes (CRM)
│ ├─ Projetos
│ ├─ Financeiro (ERP)
│ ├─ Configurações
│ └─ Suporte
├─ Stats
│ ├─ Total de clientes
│ ├─ Projetos em andamento
│ ├─ Tarefas pendentes
│ └─ Faturamento
└─ Seções (em construção)
├─ CRM → Gerenciar clientes, pipeline, negociações
├─ ERP → Pedidos, estoque, NF, financeiro
├─ Projetos → Planejamento, execução, entrega
└─ Integrações → API, webhooks, automações
```
---
## 🔌 APIs Principais
### Autenticação
```
POST /api/auth/login
Request: { email, password }
Response: { token, user: { id, email, name, role } }
POST /api/auth/change-password
Request: { old_password, new_password }
Response: { success: true }
POST /api/auth/logout
Request: {}
Response: { success: true }
```
### Agências (Superadmin)
```
GET /api/admin/agencies
Response: [{ id, name, subdomain, status, ... }]
POST /api/admin/agencies/register
Request: { name, cnpj, email, admin_email, admin_password, ... }
Response: { tenant_id, subdomain, access_url }
GET /api/admin/agencies/{id}
Response: { tenant, admin, access_url, ... }
DELETE /api/admin/agencies/{id}
Response: { success: true } | 204 No Content
PATCH /api/admin/agencies/{id}
Request: { status, ... }
Response: { tenant }
```
### Empresas/Clientes
```
GET /api/companies
Response: [{ id, cnpj, razao_social, email, ... }]
POST /api/companies/create
Request: { cnpj, razao_social, email, telefone, ... }
Response: { company }
GET /api/companies/{id}
Response: { company }
PUT /api/companies/{id}
Request: { razao_social, email, ... }
Response: { company }
```
---
## 🚀 Ciclo de Desenvolvimento Atual
### v1.1 (dev-1.1) - Em Progresso
- ✅ Reorganização do banco (init-db em backend/internal/data/postgres)
- ✅ Autenticação de login com redirect automático
- ✅ Aumento de rate limit em dev (30 tentativas/min)
- 🔄 Melhorias na UX do dashboard superadmin
- ⏳ Implementação de CRM (clientes, pipeline)
- ⏳ Implementação de ERP básico (pedidos, financeiro)
### Próximas Versões
- 📅 v1.2: Soft delete, auditoria, trilha de mudanças
- 📅 v1.3: Integrações externas (Zapier, Make, etc)
- 📅 v1.4: Sistema de pagamento (Stripe, PagSeguro)
- 📅 v2.0: Marketplace de templates/extensões
---
## 📋 Checklist de Implementação
### Backend
- [x] Setup inicial (config, database, middleware)
- [x] Autenticação (JWT, refresh tokens)
- [x] Repositórios (sem ORM, SQL direto)
- [x] Serviços (business logic)
- [x] Handlers (endpoints)
- [x] Rate limiting
- [ ] Soft delete & auditoria
- [ ] Logging estruturado
- [ ] Testes unitários
- [ ] Documentação de API
### Frontend
- [x] Login com redirect automático
- [x] Dashboard superadmin (lista, detalhes, delete)
- [x] Site institucional
- [ ] Dashboard da agência (CRM base)
- [ ] Gestão de clientes
- [ ] Formulários avançados
- [ ] Testes e2e
### DevOps
- [x] Docker Compose com todos os serviços
- [x] Traefik reverse proxy
- [x] PostgreSQL com seed data
- [x] Redis e MinIO
- [ ] CI/CD pipeline
- [ ] Monitoramento
- [ ] Backup strategy
---
## 💡 Notas Importantes
### Por Que Sem ORM?
- Controle fino sobre queries
- Performance previsível
- Menos abstrações, mais explícito
- Facilita debugging
- Legível para new devs
**Trade-off:** Mais boilerplate de SQL, mas melhor para equipes experientes.
### Segurança
- JWT + Refresh tokens
- Password hashing (Argon2)
- Rate limiting (5 req/min em prod, 30 em dev)
- CORS configurado
- Security headers
- Input validation em frontend + backend
### Escalabilidade
- Multi-tenant isolado por tenant_id
- Índices em FK e campos frequentes
- Redis para cache de sessions
- MinIO para object storage
- Stateless backend (escalável horizontalmente)
---
## 📞 Contatos & Referências
- **Repository:** https://git.stackbyte.cloud/erik/aggios.app.git
- **Documentação detalhada:** `/1. docs/backend-deployment/`
- **API Reference:** `/1. docs/backend-deployment/API_REFERENCE.md`
- **Deployment Guide:** `/1. docs/backend-deployment/DEPLOYMENT.md`

View File

@@ -11,7 +11,7 @@ Plataforma composta por serviços de autenticação, painel administrativo (supe
- `backend/`: API Go com serviços de autenticação, operadores e CRUD de agências (endpoints `/api/admin/agencies` e `/api/admin/agencies/{id}`). - `backend/`: API Go com serviços de autenticação, operadores e CRUD de agências (endpoints `/api/admin/agencies` e `/api/admin/agencies/{id}`).
- `front-end-dash.aggios.app/`: painel Next.js login do superadmin, listagem de agências, exibição detalhada e exclusão definitiva. - `front-end-dash.aggios.app/`: painel Next.js login do superadmin, listagem de agências, exibição detalhada e exclusão definitiva.
- `frontend-aggios.app/`: site institucional Next.js com suporte a temas claro/escuro e compartilhamento de tokens de design. - `frontend-aggios.app/`: site institucional Next.js com suporte a temas claro/escuro e compartilhamento de tokens de design.
- `postgres/`: scripts de inicialização do banco (estrutura base de tenants e usuários). - `backend/internal/data/postgres/`: scripts de inicialização do banco (estrutura base de tenants e usuários).
- `traefik/`: reverse proxy e certificados automatizados. - `traefik/`: reverse proxy e certificados automatizados.
## Funcionalidades entregues ## Funcionalidades entregues
@@ -33,16 +33,16 @@ Plataforma composta por serviços de autenticação, painel administrativo (supe
- Painel: `https://dash.localhost` - Painel: `https://dash.localhost`
- Site: `https://aggios.app.localhost` - Site: `https://aggios.app.localhost`
- API: `https://api.localhost` - API: `https://api.localhost`
5. **Credenciais padrão**: ver `postgres/init-db.sql` para usuário superadmin seed. 5. **Credenciais padrão**: ver `backend/internal/data/postgres/init-db.sql` para usuário superadmin seed.
## Estrutura de diretórios (resumo) ## Estrutura de diretórios (resumo)
``` ```
backend/ API Go (config, domínio, handlers, serviços) backend/ API Go (config, domínio, handlers, serviços)
front-end-dash.aggios.app/ Dashboard Next.js Superadmin backend/internal/data/postgres/ Scripts SQL de seed
frontend-aggios.app/ Site institucional Next.js front-end-dash.aggios.app/ Dashboard Next.js Superadmin
postgres/ Scripts SQL de seed frontend-aggios.app/ Site institucional Next.js
traefik/ Regras de roteamento e TLS traefik/ Regras de roteamento e TLS
1. docs/ Documentação funcional e técnica 1. docs/ Documentação funcional e técnica
``` ```
## Testes e validação ## Testes e validação

View File

@@ -53,6 +53,12 @@ func Load() *Config {
baseDomain = "aggios.app" baseDomain = "aggios.app"
} }
// Rate limit: more lenient in dev, strict in prod
maxAttempts := 30
if env == "production" {
maxAttempts = 5
}
return &Config{ return &Config{
Server: ServerConfig{ Server: ServerConfig{
Port: getEnvOrDefault("SERVER_PORT", "8080"), Port: getEnvOrDefault("SERVER_PORT", "8080"),
@@ -81,7 +87,7 @@ func Load() *Config {
"https://dash.aggios.app", "https://dash.aggios.app",
"https://www.aggios.app", "https://www.aggios.app",
}, },
MaxAttemptsPerMin: 5, MaxAttemptsPerMin: maxAttempts,
PasswordMinLength: 8, PasswordMinLength: 8,
}, },
} }

View File

@@ -46,7 +46,7 @@ services:
POSTGRES_DB: ${DB_NAME:-aggios_db} POSTGRES_DB: ${DB_NAME:-aggios_db}
volumes: volumes:
- postgres_data:/var/lib/postgresql/data - postgres_data:/var/lib/postgresql/data
- ./postgres/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql - ./backend/internal/data/postgres/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
healthcheck: healthcheck:
test: [ "CMD-SHELL", "pg_isready -U aggios -d aggios_db" ] test: [ "CMD-SHELL", "pg_isready -U aggios -d aggios_db" ]
interval: 10s interval: 10s

View File

@@ -38,7 +38,7 @@ services:
POSTGRES_DB: aggios_db POSTGRES_DB: aggios_db
volumes: volumes:
- postgres_data:/var/lib/postgresql/data - postgres_data:/var/lib/postgresql/data
- ./postgres/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql - ./backend/internal/data/postgres/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql
healthcheck: healthcheck:
test: [ "CMD-SHELL", "pg_isready -U aggios -d aggios_db" ] test: [ "CMD-SHELL", "pg_isready -U aggios -d aggios_db" ]
interval: 10s interval: 10s

View File

@@ -77,7 +77,7 @@ export default function ConfiguracoesPage() {
} }
// Buscar dados da API // Buscar dados da API
const response = await fetch('http://localhost:8080/api/agency/profile', { const response = await fetch('/api/agency/profile', {
headers: { headers: {
'Authorization': `Bearer ${token}`, 'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@@ -156,7 +156,7 @@ export default function ConfiguracoesPage() {
return; return;
} }
const response = await fetch('http://localhost:8080/api/agency/profile', { const response = await fetch('/api/agency/profile', {
method: 'PUT', method: 'PUT',
headers: { headers: {
'Authorization': `Bearer ${token}`, 'Authorization': `Bearer ${token}`,
@@ -224,7 +224,7 @@ export default function ConfiguracoesPage() {
return; return;
} }
const response = await fetch('http://localhost:8080/api/auth/change-password', { const response = await fetch('/api/auth/change-password', {
method: 'POST', method: 'POST',
headers: { headers: {
'Authorization': `Bearer ${token}`, 'Authorization': `Bearer ${token}`,

View File

@@ -4,7 +4,7 @@ import { useState, useEffect } from "react";
import Link from "next/link"; import Link from "next/link";
import { Button, Input, Checkbox } from "@/components/ui"; import { Button, Input, Checkbox } from "@/components/ui";
import toast, { Toaster } from 'react-hot-toast'; import toast, { Toaster } from 'react-hot-toast';
import { saveAuth } from '@/lib/auth'; import { saveAuth, isAuthenticated } from '@/lib/auth';
import dynamic from 'next/dynamic'; import dynamic from 'next/dynamic';
const ThemeToggle = dynamic(() => import('@/components/ThemeToggle'), { ssr: false }); const ThemeToggle = dynamic(() => import('@/components/ThemeToggle'), { ssr: false });
@@ -20,12 +20,17 @@ export default function LoginPage() {
}); });
useEffect(() => { useEffect(() => {
// Detectar se é dash (SUPERADMIN) ou agência
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
const hostname = window.location.hostname; const hostname = window.location.hostname;
const sub = hostname.split('.')[0]; const sub = hostname.split('.')[0];
const superAdmin = sub === 'dash';
setSubdomain(sub); setSubdomain(sub);
setIsSuperAdmin(sub === 'dash'); setIsSuperAdmin(superAdmin);
if (isAuthenticated()) {
const target = superAdmin ? '/superadmin' : '/dashboard';
window.location.href = target;
}
} }
}, []); }, []);
@@ -68,15 +73,15 @@ export default function LoginPage() {
const data = await response.json(); const data = await response.json();
localStorage.setItem('token', data.token); saveAuth(data.token, data.user);
localStorage.setItem('user', JSON.stringify(data.user));
console.log('Login successful:', data.user); console.log('Login successful:', data.user);
toast.success('Login realizado com sucesso! Redirecionando...'); toast.success('Login realizado com sucesso! Redirecionando...');
setTimeout(() => { setTimeout(() => {
window.location.href = '/dashboard'; const target = isSuperAdmin ? '/superadmin' : '/dashboard';
window.location.href = target;
}, 1000); }, 1000);
} catch (error: any) { } catch (error: any) {
toast.error(error.message || 'Erro ao fazer login. Verifique suas credenciais.'); toast.error(error.message || 'Erro ao fazer login. Verifique suas credenciais.');

View File

@@ -4,6 +4,16 @@ const nextConfig: NextConfig = {
experimental: { experimental: {
externalDir: true, externalDir: true,
}, },
async rewrites() {
return {
beforeFiles: [
{
source: "/api/:path*",
destination: "http://backend:8080/api/:path*",
},
],
};
},
}; };
export default nextConfig; export default nextConfig;