Files
openmonetis/README.md
Felipe Coutinho ea0b8618e0 feat: adição de novos ícones SVG e configuração do ambiente
- Adicionados ícones SVG para ChatGPT, Claude, Gemini e OpenRouter
- Implementados ícones para modos claro e escuro do ChatGPT
- Criado script de inicialização para PostgreSQL com extensão pgcrypto
- Adicionado script de configuração de ambiente que faz backup do .env
- Configurado tsconfig.json para TypeScript com opções de compilação
2025-11-15 15:49:36 -03:00

1031 lines
21 KiB
Markdown

# OpenSheets
> Uma aplicação moderna e completa construída com **Next.js 16**, **Better Auth**, **Drizzle ORM**, **PostgreSQL** e **shadcn/ui**.
[![Next.js](https://img.shields.io/badge/Next.js-16-black?style=flat-square&logo=next.js)](https://nextjs.org/)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org/)
[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-18-blue?style=flat-square&logo=postgresql)](https://www.postgresql.org/)
[![Docker](https://img.shields.io/badge/Docker-Ready-blue?style=flat-square&logo=docker)](https://www.docker.com/)
---
## 📖 Índice
- [Sobre o Projeto](#-sobre-o-projeto)
- [Features](#-features)
- [Tech Stack](#-tech-stack)
- [Início Rápido](#-início-rápido)
- [Opção 1: Desenvolvimento Local (Recomendado para Devs)](#opção-1-desenvolvimento-local-recomendado-para-devs)
- [Opção 2: Docker Completo (Usuários Finais)](#opção-2-docker-completo-usuários-finais)
- [Opção 3: Docker + Banco Remoto](#opção-3-docker--banco-remoto)
- [Scripts Disponíveis](#-scripts-disponíveis)
- [Docker - Guia Detalhado](#-docker---guia-detalhado)
- [Configuração de Variáveis de Ambiente](#-configuração-de-variáveis-de-ambiente)
- [Banco de Dados](#-banco-de-dados)
- [Arquitetura](#-arquitetura)
- [Troubleshooting](#-troubleshooting)
- [Contribuindo](#-contribuindo)
---
## 🎯 Sobre o Projeto
**OpenSheets** é uma aplicação full-stack moderna projetada para controle de finanças pessoais. Construída com as melhores práticas de desenvolvimento e ferramentas de ponta, oferece uma base sólida e escalável para gestão financeira completa.
### Por que usar o OpenSheets?
-**Pronto para Produção** - Docker, health checks, migrations automáticas
-**TypeScript First** - Type safety em toda a aplicação
-**Autenticação Completa** - Better Auth com OAuth, email magic links
-**ORM Moderno** - Drizzle com Drizzle Studio integrado
-**UI Components** - shadcn/ui com design system completo
-**Developer Experience** - Hot reload, Turbopack, ESLint configurado
---
## ✨ Features
### 🔐 Autenticação
- Better Auth integrado
- OAuth (Google, GitHub)
- Email magic links
- Session management
- Protected routes via middleware
### 🗄️ Banco de Dados
- PostgreSQL 18 (última versão estável)
- Drizzle ORM com TypeScript
- Migrations automáticas
- Drizzle Studio (UI visual para DB)
- Suporte para banco local (Docker) ou remoto (Supabase, Neon, etc)
### 🎨 Interface
- shadcn/ui components
- Tailwind CSS v4
- Dark mode suportado
- Animações com Framer Motion
### 🐳 Docker
- Multi-stage build otimizado
- Health checks para app e banco
- Volumes persistentes
- Network isolada
- Scripts npm facilitados
### 🧪 Desenvolvimento
- Next.js 16 com App Router
- Turbopack (fast refresh)
- TypeScript 5.9
- ESLint + Prettier
- React 19
---
## 🛠️ Tech Stack
### Frontend
- **Framework:** Next.js 16 (App Router)
- **Linguagem:** TypeScript 5.9
- **UI Library:** React 19
- **Styling:** Tailwind CSS v4
- **Components:** shadcn/ui (Radix UI)
- **Icons:** Lucide React, Remixicon
- **Animations:** Framer Motion
### Backend
- **Runtime:** Node.js 22
- **Database:** PostgreSQL 18
- **ORM:** Drizzle ORM
- **Auth:** Better Auth
- **Email:** Resend
### DevOps
- **Containerization:** Docker + Docker Compose
- **Package Manager:** pnpm
- **Build Tool:** Turbopack
### AI Integration (Opcional)
- Anthropic (Claude)
- OpenAI (GPT)
- Google Gemini
- OpenRouter
---
## 🚀 Início Rápido
Escolha a opção que melhor se adequa ao seu caso:
| Cenário | Quando usar | Comando principal |
| ----------- | ----------------------------------------- | -------------------------------------- |
| **Opção 1** | Você vai **desenvolver** e alterar código | `docker compose up db -d` + `pnpm dev` |
| **Opção 2** | Você só quer **usar** a aplicação | `pnpm docker:up` |
| **Opção 3** | Você já tem um **banco remoto** | `docker compose up app --build` |
---
### Opção 1: Desenvolvimento Local (Recomendado para Devs)
Esta é a **melhor opção para desenvolvedores** que vão modificar o código.
#### Pré-requisitos
- Node.js 22+ instalado
- pnpm instalado (ou npm/yarn)
- Docker e Docker Compose instalados
#### Passo a Passo
1. **Clone o repositório**
```bash
git clone https://github.com/felipegcoutinho/opensheets.git
cd opensheets
```
2. **Instale as dependências**
```bash
pnpm install
```
3. **Configure as variáveis de ambiente**
```bash
cp .env.example .env
```
Edite o `.env` e configure:
```env
# Banco de dados (usando Docker)
DATABASE_URL=postgresql://opensheets:opensheets_dev_password@localhost:5432/opensheets_db
DB_PROVIDER=local
# Better Auth (gere com: openssl rand -base64 32)
BETTER_AUTH_SECRET=seu-secret-aqui
BETTER_AUTH_URL=http://localhost:3000
```
4. **Suba apenas o PostgreSQL em Docker**
```bash
docker compose up db -d
```
Isso sobe **apenas o banco de dados** em container. A aplicação roda localmente.
5. **Execute as migrations**
```bash
pnpm db:push
```
6. **Inicie o servidor de desenvolvimento**
```bash
pnpm dev
```
7. **Acesse a aplicação**
```
http://localhost:3000
```
#### Por que esta opção?
- ✅ **Hot reload perfeito** - Mudanças no código refletem instantaneamente
- ✅ **Debugger funciona** - Use breakpoints normalmente
- ✅ **Menos recursos** - Só o banco roda em Docker
- ✅ **Drizzle Studio** - Acesse com `pnpm db:studio`
- ✅ **Melhor DX** - Developer Experience otimizada
---
### Opção 2: Docker Completo (Usuários Finais)
Ideal para quem quer apenas **usar a aplicação** sem mexer no código.
#### Pré-requisitos
- Docker e Docker Compose instalados
#### Passo a Passo
1. **Clone o repositório**
```bash
git clone https://github.com/felipegcoutinho/opensheets.git
cd opensheets
```
2. **Configure as variáveis de ambiente**
```bash
cp .env.example .env
```
Edite o `.env`:
```env
# Use o host "db" (nome do serviço Docker)
DATABASE_URL=postgresql://opensheets:opensheets_dev_password@db:5432/opensheets_db
DB_PROVIDER=local
# Better Auth
BETTER_AUTH_SECRET=seu-secret-aqui
BETTER_AUTH_URL=http://localhost:3000
```
3. **Suba tudo em Docker**
```bash
pnpm docker:up
# ou: docker compose up --build
```
Isso sobe **aplicação + banco de dados** em containers.
4. **Acesse a aplicação**
```
http://localhost:3000
```
5. **Para parar**
```bash
pnpm docker:down
# ou: docker compose down
```
#### Dicas
- Use `pnpm docker:up:detached` para rodar em background
- Veja logs com `pnpm docker:logs`
- Reinicie com `pnpm docker:restart`
---
### Opção 3: Docker + Banco Remoto
Se você já tem PostgreSQL no **Supabase**, **Neon**, **Railway**, etc.
#### Passo a Passo
1. **Configure o `.env` com banco remoto**
```env
DATABASE_URL=postgresql://user:password@host.region.provider.com:5432/database?sslmode=require
DB_PROVIDER=remote
BETTER_AUTH_SECRET=seu-secret-aqui
BETTER_AUTH_URL=http://localhost:3000
```
2. **Suba apenas a aplicação**
```bash
docker compose up app --build
```
3. **Acesse a aplicação**
```
http://localhost:3000
```
---
## 📜 Scripts Disponíveis
### Desenvolvimento
```bash
# Servidor de desenvolvimento (com Turbopack)
pnpm dev
# Build de produção
pnpm build
# Servidor de produção
pnpm start
# Linter
pnpm lint
```
### Banco de Dados (Drizzle)
```bash
# Gerar migrations a partir do schema
pnpm db:generate
# Executar migrations
pnpm db:migrate
# Push schema direto para o banco (dev only)
pnpm db:push
# Abrir Drizzle Studio (UI visual do banco)
pnpm db:studio
```
### Docker
```bash
# Subir todos os containers (app + banco)
pnpm docker:up
# Subir em background (detached mode)
pnpm docker:up:detached
# Parar todos os containers
pnpm docker:down
# Parar e REMOVER volumes (⚠️ apaga dados do banco!)
pnpm docker:down:volumes
# Ver logs em tempo real
pnpm docker:logs
# Logs apenas da aplicação
pnpm docker:logs:app
# Logs apenas do banco de dados
pnpm docker:logs:db
# Reiniciar containers
pnpm docker:restart
# Rebuild completo (força reconstrução)
pnpm docker:rebuild
```
### Utilitários
```bash
# Setup automático de variáveis de ambiente
pnpm env:setup
```
---
## 🐳 Docker - Guia Detalhado
### Arquitetura Docker
```
┌─────────────────────────────────────────────────┐
│ docker-compose.yml │
├─────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌─────────────────┐ │
│ │ app │ │ db │ │
│ │ (Next.js 16) │◄─────┤ (PostgreSQL 18)│ │
│ │ Port: 3000 │ │ Port: 5432 │ │
│ │ Node.js 22 │ │ Alpine Linux │ │
│ └──────────────────┘ └─────────────────┘ │
│ │
│ Network: opensheets_network (bridge) │
│ Volume: opensheets_postgres_data (persistent) │
│ │
└─────────────────────────────────────────────────┘
```
### Multi-Stage Build
O `Dockerfile` usa **3 stages** para otimização:
1. **deps** - Instala dependências
2. **builder** - Builda a aplicação (Next.js standalone)
3. **runner** - Imagem final mínima (apenas produção)
**Benefícios:**
- Imagem final **muito menor** (~200MB vs ~1GB)
- Build cache eficiente
- Apenas dependências de produção no final
- Security: roda como usuário não-root
### Health Checks
Ambos os serviços têm health checks:
**PostgreSQL:**
- Comando: `pg_isready`
- Intervalo: 10s
- Timeout: 5s
**Next.js App:**
- Endpoint: `http://localhost:3000/api/health`
- Intervalo: 30s
- Start period: 40s (aguarda build)
### Volumes e Persistência
```yaml
volumes:
postgres_data:
name: opensheets_postgres_data
driver: local
```
- Os dados do PostgreSQL **persistem** entre restarts
- Para **apagar dados**: `pnpm docker:down:volumes`
- Para **backup**: `docker compose exec db pg_dump...`
### Network Isolada
```yaml
networks:
opensheets_network:
name: opensheets_network
driver: bridge
```
- App e banco se comunicam via network interna
- Isolamento de segurança
- DNS automático (app acessa `db:5432`)
### Comandos Docker Avançados
```bash
# Entrar no container da aplicação
docker compose exec app sh
# Entrar no container do banco
docker compose exec db psql -U opensheets -d opensheets_db
# Ver status dos containers
docker compose ps
# Ver uso de recursos
docker stats opensheets_app opensheets_postgres
# Backup do banco
docker compose exec db pg_dump -U opensheets opensheets_db > backup.sql
# Restaurar backup
docker compose exec -T db psql -U opensheets -d opensheets_db < backup.sql
# Limpar tudo (containers, volumes, images)
docker compose down -v
docker system prune -a
```
### Customizando Portas
No arquivo `.env`:
```env
# Porta da aplicação (padrão: 3000)
APP_PORT=3001
# Porta do banco de dados (padrão: 5432)
DB_PORT=5433
```
---
## 🔐 Configuração de Variáveis de Ambiente
Copie o `.env.example` para `.env` e configure:
### Variáveis Obrigatórias
```env
# === Database ===
DATABASE_URL=postgresql://opensheets:opensheets_dev_password@localhost:5432/opensheets_db
DB_PROVIDER=local # ou "remote"
# === Better Auth ===
# Gere com: openssl rand -base64 32
BETTER_AUTH_SECRET=seu-secret-super-secreto-aqui
BETTER_AUTH_URL=http://localhost:3000
```
### Variáveis Opcionais
#### PostgreSQL (customização)
```env
POSTGRES_USER=opensheets
POSTGRES_PASSWORD=opensheets_dev_password
POSTGRES_DB=opensheets_db
```
#### Portas (customização)
```env
APP_PORT=3000
DB_PORT=5432
```
#### OAuth Providers
```env
GOOGLE_CLIENT_ID=seu-google-client-id
GOOGLE_CLIENT_SECRET=seu-google-client-secret
GITHUB_CLIENT_ID=seu-github-client-id
GITHUB_CLIENT_SECRET=seu-github-client-secret
```
#### Email (Resend)
```env
RESEND_API_KEY=re_seu_api_key
EMAIL_FROM=noreply@seudominio.com
```
#### AI Providers
```env
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
GOOGLE_GENERATIVE_AI_API_KEY=...
OPENROUTER_API_KEY=sk-or-...
```
### Gerando Secrets
```bash
# BETTER_AUTH_SECRET
openssl rand -base64 32
# Ou use o script automático
pnpm env:setup
```
---
## 🗄️ Banco de Dados
### Escolhendo entre Local e Remoto
| Modo | Quando usar | Como configurar |
| ---------- | ------------------------------------- | -------------------------------------- |
| **Local** | Desenvolvimento, testes, prototipagem | `DB_PROVIDER=local` + Docker |
| **Remoto** | Produção, deploy, banco gerenciado | `DB_PROVIDER=remote` + URL do provider |
### Drizzle ORM
#### Schema Definition
Os schemas ficam em `/db/schema.ts`:
```typescript
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: serial("id").primaryKey(),
email: text("email").notNull().unique(),
name: text("name"),
createdAt: timestamp("created_at").defaultNow(),
});
```
#### Gerando Migrations
```bash
# Após alterar /db/schema.ts
pnpm db:generate
# Aplica migrations
pnpm db:migrate
# Ou push direto (dev only)
pnpm db:push
```
#### Drizzle Studio
Interface visual para explorar e editar dados:
```bash
pnpm db:studio
```
Abre em: `https://local.drizzle.studio`
### Migrations Automáticas (Docker)
No `docker-compose.yml`, migrations rodam automaticamente:
```yaml
command:
- |
echo "📦 Rodando migrations..."
pnpm db:push
echo "✅ Iniciando aplicação..."
node server.js
```
### Backup e Restore
```bash
# Backup (banco local Docker)
docker compose exec db pg_dump -U opensheets opensheets_db > backup_$(date +%Y%m%d).sql
# Backup (banco remoto)
pg_dump $DATABASE_URL > backup.sql
# Restore (Docker)
docker compose exec -T db psql -U opensheets -d opensheets_db < backup.sql
# Restore (remoto)
psql $DATABASE_URL < backup.sql
```
---
## 🏗️ Arquitetura
### Estrutura de Pastas
```
opensheets/
├── app/ # Next.js App Router
│ ├── api/ # API Routes
│ │ ├── auth/ # Better Auth endpoints
│ │ └── health/ # Health check
│ ├── (dashboard)/ # Protected routes (com auth)
│ └── layout.tsx # Root layout
├── components/ # React Components
│ ├── ui/ # shadcn/ui components
│ └── ... # Feature components
├── lib/ # Shared utilities
│ ├── db.ts # Drizzle client
│ ├── auth.ts # Better Auth server
│ └── auth-client.ts # Better Auth client
├── db/ # Drizzle schema
│ └── schema.ts # Database schema
├── drizzle/ # Generated migrations
│ └── migrations/
├── hooks/ # Custom React hooks
├── public/ # Static assets
├── scripts/ # Utility scripts
│ ├── setup-env.sh # Env setup automation
│ └── postgres/init.sql # PostgreSQL init script
├── docker/ # Docker configs
│ └── postgres/init.sql
├── Dockerfile # Production build
├── docker-compose.yml # Docker orchestration
├── next.config.ts # Next.js config
├── drizzle.config.ts # Drizzle ORM config
├── tailwind.config.ts # Tailwind config
└── tsconfig.json # TypeScript config
```
### Fluxo de Autenticação
```
1. Usuário acessa rota protegida
2. middleware.ts verifica sessão (Better Auth)
3. Se não autenticado → redirect /auth
4. Usuário faz login (OAuth ou email)
5. Better Auth valida e cria sessão
6. Cookie de sessão é salvo
7. Usuário acessa rota protegida ✅
```
### Fluxo de Build (Docker)
```
1. Stage deps: Instala dependências
2. Stage builder: Builda Next.js (standalone)
3. Stage runner: Copia apenas build + deps prod
4. Container final: ~200MB (otimizado)
```
---
## 🆘 Troubleshooting
### Erro: "DATABASE_URL env variable is not set"
**Causa:** Arquivo `.env` não existe ou `DATABASE_URL` não configurado
**Solução:**
```bash
cp .env.example .env
# Edite .env e configure DATABASE_URL
```
---
### Container do app não conecta ao banco
**Causa:** `DATABASE_URL` usa `localhost` em vez de `db`
**Solução:**
Para Docker, use o **nome do serviço**:
```env
# ❌ Errado (localhost não funciona dentro do container)
DATABASE_URL=postgresql://opensheets:senha@localhost:5432/opensheets_db
# ✅ Correto (usa nome do serviço Docker)
DATABASE_URL=postgresql://opensheets:senha@db:5432/opensheets_db
```
Para desenvolvimento local (sem Docker app):
```env
# ✅ Correto (app roda local, banco em Docker)
DATABASE_URL=postgresql://opensheets:senha@localhost:5432/opensheets_db
```
**Verifique o status do banco:**
```bash
docker compose ps
docker compose logs db
```
---
### Porta 3000 ou 5432 já está em uso
**Solução:**
Edite o `.env`:
```env
APP_PORT=3001
DB_PORT=5433
```
Ou pare o processo que está usando:
```bash
# Descobrir quem usa a porta
lsof -i :3000
lsof -i :5432
# Matar processo
kill -9 <PID>
```
---
### Migrations não rodam
**Com Docker:**
Migrations rodam automaticamente no startup. Veja logs:
```bash
pnpm docker:logs:app
```
Se falharem, rode manualmente:
```bash
docker compose exec app pnpm db:push
```
**Sem Docker:**
```bash
pnpm db:push
```
---
### Erro: "server.js not found"
**Causa:** Next.js não gerou standalone build
**Solução:**
1. Verifique `next.config.ts`:
```typescript
const nextConfig: NextConfig = {
output: "standalone", // ← Deve estar presente
};
```
2. Rebuild:
```bash
docker compose down
docker compose up --build
```
---
### Erro ao atualizar PostgreSQL 16 → 18
**Causa:** Volumes antigos são incompatíveis
**Solução:**
```bash
# ⚠️ ATENÇÃO: Isso apaga dados do banco local!
docker compose down -v
# Suba novamente com PostgreSQL 18
docker compose up --build
```
**Para preservar dados:**
```bash
# 1. Backup
docker compose exec db pg_dumpall -U opensheets > backup.sql
# 2. Limpa volumes
docker compose down -v
# 3. Sobe PG 18
docker compose up -d db
# 4. Aguarda (15s)
sleep 15
# 5. Restaura
docker compose exec -T db psql -U opensheets -d opensheets_db < backup.sql
```
---
### Drizzle Studio não abre
**Solução:**
1. Verifique se o banco está rodando:
```bash
docker compose ps
```
2. Teste conexão:
```bash
psql $DATABASE_URL
```
3. Abra Drizzle Studio:
```bash
pnpm db:studio
```
---
### Build do Docker muito lento
**Causa:** Cache não está sendo aproveitado
**Solução:**
1. Use BuildKit:
```bash
export DOCKER_BUILDKIT=1
docker compose build
```
2. Limpe cache antigo:
```bash
docker builder prune
```
3. Multi-stage build já otimiza camadas
---
### "Permission denied" ao rodar Docker
**Causa:** Usuário não está no grupo docker
**Solução (Linux):**
```bash
sudo usermod -aG docker $USER
newgrp docker
```
**Solução (Mac/Windows):**
- Docker Desktop deve estar rodando
- Verifique configurações de permissão
---
### Limpar tudo e começar do zero
```bash
# Para containers e remove volumes
docker compose down -v
# Remove images não usadas
docker system prune -a
# Remove TUDO do Docker (cuidado!)
docker system prune -a --volumes
# Rebuild do zero
pnpm docker:up
```
---
## 🤝 Contribuindo
Contribuições são muito bem-vindas!
### Como contribuir
1. **Fork** o projeto
2. **Clone** seu fork
```bash
git clone https://github.com/seu-usuario/opensheets.git
```
3. **Crie uma branch** para sua feature
```bash
git checkout -b feature/minha-feature
```
4. **Commit** suas mudanças
```bash
git commit -m 'feat: adiciona minha feature'
```
5. **Push** para a branch
```bash
git push origin feature/minha-feature
```
6. Abra um **Pull Request**
### Padrões
- Use **TypeScript**
- Siga o **ESLint** configurado
- Documente **features novas**
- Use **commits semânticos** (feat, fix, docs, etc)
---
## 📄 Licença
Este projeto é open source e está disponível sob a [Licença MIT](LICENSE).
---
## 🙏 Agradecimentos
- [Next.js](https://nextjs.org/)
- [Better Auth](https://better-auth.com/)
- [Drizzle ORM](https://orm.drizzle.team/)
- [shadcn/ui](https://ui.shadcn.com/)
- [Vercel](https://vercel.com/)
---
## 📞 Contato
**Desenvolvido por:** Felipe Coutinho
**GitHub:** [@felipegcoutinho](https://github.com/felipegcoutinho)
**Repositório:** [opensheets](https://github.com/felipegcoutinho/opensheets)
---
<div align="center">
**⭐ Se este projeto foi útil, considere dar uma estrela!**
Desenvolvido com ❤️ para a comunidade open source
</div>