diff --git a/backend/.env.development b/backend/.env.development new file mode 100644 index 0000000..48a17d4 --- /dev/null +++ b/backend/.env.development @@ -0,0 +1,13 @@ +# Desenvolvimento +DATABASE_URL=postgresql://toptranadm:ft7zJdVNk8FivQUk@175.15.15.90:5432/toptrandev +DB_USER=toptranadm +DB_PASSWORD=ft7zJdVNk8FivQUk +DB_HOST=175.15.15.90 +DB_PORT=5432 +DB_NAME=toptrandev + +PORT=4000 +NODE_ENV=development + +JWT_SECRET=iDgji2sbBKqmPerRHnQXFK0iHwmfNTNb5zreuetUecD +JWT_REFRESH_SECRET=pFLRKyVdDaTVdEWNebDWMQuMdbpgCnsx4p3WiVRgmuU diff --git a/backend/.env.example b/backend/.env.example deleted file mode 100644 index 13e322e..0000000 --- a/backend/.env.example +++ /dev/null @@ -1,15 +0,0 @@ -# Database -DATABASE_URL=postgresql://postgres:postgres@175.15.15.90:5432/toptran -DB_USER=postgres -DB_PASSWORD=postgres -DB_HOST=175.15.15.90 -DB_PORT=5432 -DB_NAME=toptran - -# Server -PORT=4000 -NODE_ENV=production - -# JWT -JWT_SECRET=iDgji2sbBKqmPerRHnQXFK0iHwmfNTNb5zreuetUecD -JWT_REFRESH_SECRET=pFLRKyVdDaTVdEWNebDWMQuMdbpgCnsx4p3WiVRgmuU diff --git a/backend/.env.prod b/backend/.env.prod deleted file mode 100644 index 13e322e..0000000 --- a/backend/.env.prod +++ /dev/null @@ -1,15 +0,0 @@ -# Database -DATABASE_URL=postgresql://postgres:postgres@175.15.15.90:5432/toptran -DB_USER=postgres -DB_PASSWORD=postgres -DB_HOST=175.15.15.90 -DB_PORT=5432 -DB_NAME=toptran - -# Server -PORT=4000 -NODE_ENV=production - -# JWT -JWT_SECRET=iDgji2sbBKqmPerRHnQXFK0iHwmfNTNb5zreuetUecD -JWT_REFRESH_SECRET=pFLRKyVdDaTVdEWNebDWMQuMdbpgCnsx4p3WiVRgmuU diff --git a/backend/.env.production b/backend/.env.production new file mode 100644 index 0000000..82466c5 --- /dev/null +++ b/backend/.env.production @@ -0,0 +1,13 @@ +# Produção +DATABASE_URL=postgresql://toptranadm:ft7zJdVNk8FivQUk@175.15.15.90:5432/toptranprod +DB_USER=toptranadm +DB_PASSWORD=ft7zJdVNk8FivQUk +DB_HOST=175.15.15.90 +DB_PORT=5432 +DB_NAME=toptranprod + +PORT=5000 +NODE_ENV=production + +JWT_SECRET=iDgji2sbBKqmPerRHnQXFK0iHwmfNTNb5zreuetUecD +JWT_REFRESH_SECRET=pFLRKyVdDaTVdEWNebDWMQuMdbpgCnsx4p3WiVRgmuU diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..04003b7 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,31 @@ +# Dependencies +node_modules/ +npm-debug.log* + +# Build +dist/ +*.tsbuildinfo + +# Environment +.env +.env.local +.env.*.local + +# Keep these for reference (remova a # se quiser ignorar) +# .env.development +# .env.production + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# Logs +logs/ +*.log + +# Prisma +prisma/migrations/ diff --git a/backend/Dockerfile b/backend/Dockerfile index ba0c06f..e091566 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,12 +1,17 @@ +# Multi-stage build - funciona para dev e prod +ARG NODE_ENV=production + # Build stage FROM node:lts-alpine3.22 AS builder +ARG NODE_ENV + WORKDIR /app COPY package*.json ./ -# Instalar todas as dependências (incluindo dev) para compilar TypeScript -RUN npm ci +# Build sempre precisa dos @types e ferramentas de compilação +RUN npm ci --include=dev COPY . . @@ -15,17 +20,26 @@ RUN npm run build # Runtime stage FROM node:lts-alpine3.22 +ARG NODE_ENV + WORKDIR /app -# Copiar apenas arquivos necessários do builder +# Copiar arquivos do builder COPY --from=builder /app/dist ./dist -COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/package*.json ./ -ENV NODE_ENV=production -ENV PORT=4000 +# Instalar apenas dependências de produção no runtime +RUN if [ "$NODE_ENV" = "production" ]; then \ + npm ci --only=production; \ + else \ + npm ci; \ + fi -EXPOSE 4000 +ARG PORT=4000 +ENV NODE_ENV=${NODE_ENV} +ENV PORT=${PORT} + +EXPOSE ${PORT} CMD ["npm", "start"] \ No newline at end of file diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..09fbca6 --- /dev/null +++ b/backend/README.md @@ -0,0 +1,251 @@ +# 🚀 ToP Tran Backend + +Backend da aplicação ToP Tran construído com Node.js, Express, TypeScript e Prisma. + +## 📋 Requisitos + +- Node.js 18+ +- Docker/Podman +- PostgreSQL 16+ + +## 🏗️ Estrutura + +``` +src/ +├── controllers/ # Lógica HTTP +├── routes/ # Definição de rotas +├── services/ # Lógica de negócios +├── repositories/ # Acesso ao banco de dados +├── middlewares/ # Middlewares Express +├── lib/ # Bibliotecas utilitárias +└── server.ts # Ponto de entrada + +prisma/ +├── schema.prisma # Definição do banco de dados +└── migrations/ # Histórico de mudanças no BD +``` + +## 🚀 Quick Start + +### Desenvolvimento Local + +```bash +# 1. Instalar dependências +npm install + +# 2. Configurar .env +cp .env.example .env + +# 3. Executar migrações +npx prisma migrate dev + +# 4. Iniciar servidor +npm run dev +``` + +### Com Docker + +```bash +# Desenvolvimento +chmod +x deploy.sh +./deploy.sh development + +# Produção +./deploy.sh production +``` + +## 📦 Scripts Disponíveis + +| Script | Descrição | +| ------------------- | ----------------------------------- | +| `npm run dev` | Iniciar servidor em modo watch | +| `npm run build` | Compilar TypeScript para JavaScript | +| `npm run start` | Rodar aplicação compilada | +| `npm run typecheck` | Verificar tipos sem compilar | + +## 🐳 Docker Commands + +### Build + +```bash +# Com NODE_ENV=production (padrão) +NODE_ENV=production podman build -t toptran-backend:latest . + +# Com NODE_ENV=development +NODE_ENV=development podman build --build-arg NODE_ENV=development -t toptran-backend:dev . +``` + +### Run + +```bash +# Produção +NODE_ENV=production podman-compose --env-file .env.production -f docker-compose.yml up -d + +# Desenvolvimento +NODE_ENV=development podman-compose --env-file .env.development -f docker-compose.yml up -d +``` + +### Logs + +```bash +NODE_ENV=production podman-compose -f docker-compose.yml logs -f backend +``` + +### Stop + +```bash +podman-compose -f docker-compose.yml down +``` + +## 🗄️ Banco de Dados + +### Migrações + +```bash +# Criar nova migração +npx prisma migrate dev --name descricao_da_mudanca + +# Aplicar migrações +npx prisma migrate deploy + +# Resetar banco (⚠️ deleta dados) +npx prisma migrate reset +``` + +### Studio (GUI) + +```bash +npx prisma studio +``` + +## 📡 Rotas da API + +### Autenticação + +- `POST /auth/register` - Registrar usuário +- `POST /auth/login` - Login +- `POST /auth/refresh` - Refresh token + +### Usuários + +- `GET /users/me` - Obter dados do usuário +- `GET /users/profile` - Obter perfil +- `PATCH /users/profile` - Atualizar perfil +- `PUT /users/me` - Atualizar usuário +- `DELETE /users/me` - Deletar conta + +### Sincronização + +- `GET /sync/companies` - Listar empresas +- `POST /sync/companies` - Sincronizar empresas +- `GET /sync/rides` - Listar corridas +- `POST /sync/rides` - Sincronizar corridas + +## 🔑 Variáveis de Ambiente + +```env +# Banco de Dados +DATABASE_URL=postgresql://user:password@host:5432/db_name +DB_USER=user +DB_PASSWORD=password +DB_HOST=localhost +DB_PORT=5432 +DB_NAME=toptran + +# Servidor +PORT=4000 +NODE_ENV=production + +# JWT +JWT_SECRET=sua_chave_secreta_aqui +JWT_REFRESH_SECRET=sua_chave_refresh_aqui +``` + +## 🚢 Deploy + +### Opção 1: Script de Deploy + +```bash +chmod +x deploy.sh + +# Desenvolvimento +./deploy.sh development + +# Produção +./deploy.sh production +``` + +### Opção 2: Manual com Docker Compose + +```bash +# Produção +NODE_ENV=production podman-compose \ + --env-file .env.production \ + -f docker-compose.yml \ + up --build -d + +# Executar migrações +NODE_ENV=production podman-compose \ + --env-file .env.production \ + -f docker-compose.yml \ + exec -T backend npx prisma migrate deploy +``` + +### Opção 3: SSH para Servidor + +```bash +# No servidor +cd /var/www/toptran-backend +git pull origin main +npm ci --only=production +npm run build +npx prisma migrate deploy + +# Com PM2 +pm2 restart toptran-backend +pm2 save +``` + +## 🔍 Troubleshooting + +### Erro: "Cannot find module 'express'" + +```bash +npm install +npm run build +``` + +### Erro: "Database connection refused" + +```bash +# Verificar se PostgreSQL está rodando +podman ps | grep postgres + +# Verificar DATABASE_URL em .env +cat .env +``` + +### Erro: "port 4000 already in use" + +```bash +# Parar container antigo +podman stop toptran-backend + +# Ou usar porta diferente +PORT=5000 podman-compose up -d +``` + +## 📚 Referências + +- [Express.js](https://expressjs.com/) +- [Prisma](https://www.prisma.io/) +- [TypeScript](https://www.typescriptlang.org/) +- [Docker](https://docs.docker.com/) + +## 👤 Autor + +Rayan + +## 📄 Licença + +ISC diff --git a/backend/deploy.sh b/backend/deploy.sh new file mode 100755 index 0000000..2cfb26a --- /dev/null +++ b/backend/deploy.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +# Script de deploy - funciona para dev e prod + +set -e + +# Cores para output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Função para printar com cor +print_info() { + echo -e "${BLUE}ℹ${NC} $1" +} + +print_success() { + echo -e "${GREEN}✓${NC} $1" +} + +print_warning() { + echo -e "${YELLOW}⚠${NC} $1" +} + +print_error() { + echo -e "${RED}✗${NC} $1" +} + +# Verificar argumentos +ENV=${1:-production} + +if [ "$ENV" != "production" ] && [ "$ENV" != "development" ] && [ "$ENV" != "dev" ] && [ "$ENV" != "prod" ]; then + print_error "Ambiente inválido: $ENV" + echo "Uso: ./deploy.sh [development|production|dev|prod]" + exit 1 +fi + +# Normalizar nomes +if [ "$ENV" = "dev" ]; then + ENV="development" +fi + +if [ "$ENV" = "prod" ]; then + ENV="production" +fi + +COMPOSE_FILE="docker-compose.$ENV.yml" + +print_info "🚀 Iniciando deploy para: $ENV" + +# Verificar se arquivo .env existe +if [ ! -f ".env.$ENV" ]; then + print_error "Arquivo .env.$ENV não encontrado!" + exit 1 +fi + +if [ ! -f "$COMPOSE_FILE" ]; then + print_error "Arquivo $COMPOSE_FILE não encontrado!" + exit 1 +fi + +print_success "Usando $COMPOSE_FILE com .env.$ENV" + +# Executar migrações localmente antes de subir o container +# (prisma é devDependency e não está disponível no runtime do container) +print_info "Executando migrações do Prisma..." +DB_URL=$(grep "^DATABASE_URL=" ".env.$ENV" | cut -d'=' -f2-) +if DATABASE_URL="$DB_URL" npx prisma migrate deploy; then + print_success "Migrações executadas" +else + print_warning "Erro nas migrações (talvez já estejam aplicadas)" +fi + +# Parar e remover containers antigos +print_info "Parando containers antigos..." +CONTAINER_NAME="toptran-backend-${ENV}" +podman stop "$CONTAINER_NAME" 2>/dev/null || true +podman rm -f "$CONTAINER_NAME" 2>/dev/null || true +podman-compose -f "$COMPOSE_FILE" down 2>/dev/null || true + +# Build +print_info "Building docker image..." +podman-compose -f "$COMPOSE_FILE" build --no-cache + +print_success "Build concluído" + +# Iniciar containers +print_info "Iniciando containers..." +podman-compose -f "$COMPOSE_FILE" up -d + +print_success "Containers iniciados" + +# Mostrar status +print_info "Status dos containers:" +podman ps --filter "name=toptran" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" + +# Mostrar logs +print_info "Ultimos logs:" +sleep 3 +podman-compose -f "$COMPOSE_FILE" logs --tail=20 backend + +print_success "Deploy concluído para $ENV!" +print_info "Para ver logs: podman-compose -f $COMPOSE_FILE logs -f backend" diff --git a/backend/docker-compose.development.yml b/backend/docker-compose.development.yml new file mode 100644 index 0000000..7fa9bbb --- /dev/null +++ b/backend/docker-compose.development.yml @@ -0,0 +1,27 @@ +version: '3.8' + +services: + backend: + build: + context: . + dockerfile: Dockerfile + args: + - NODE_ENV=development + - PORT=4000 + image: toptran-backend:development + container_name: toptran-backend-development + restart: unless-stopped + ports: + - "4000:4000" + env_file: + - .env.development + environment: + - NODE_ENV=development + volumes: + - ./logs:/app/logs + healthcheck: + test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:4000/sync/companies"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/backend/docker-compose.production.yml b/backend/docker-compose.production.yml new file mode 100644 index 0000000..6833c40 --- /dev/null +++ b/backend/docker-compose.production.yml @@ -0,0 +1,27 @@ +version: '3.8' + +services: + backend: + build: + context: . + dockerfile: Dockerfile + args: + - NODE_ENV=production + - PORT=5000 + image: toptran-backend:production + container_name: toptran-backend-production + restart: unless-stopped + ports: + - "5000:5000" + env_file: + - .env.production + environment: + - NODE_ENV=production + volumes: + - ./logs:/app/logs + healthcheck: + test: ["CMD", "wget", "-qO", "/dev/null", "http://localhost:5000/sync/companies"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml new file mode 100644 index 0000000..6f6ce59 --- /dev/null +++ b/backend/docker-compose.yml @@ -0,0 +1,27 @@ +version: '3.8' + +services: + backend: + build: + context: . + dockerfile: Dockerfile + args: + - NODE_ENV=${NODE_ENV:-production} + image: toptran-backend:${NODE_ENV:-production} + container_name: toptran-backend-${NODE_ENV:-production} + restart: unless-stopped + ports: + - "${PORT:-5000}:${PORT:-5000}" + env_file: + - .env.${NODE_ENV:-production} + environment: + - NODE_ENV=${NODE_ENV:-production} + volumes: + - ./logs:/app/logs + healthcheck: + test: ["CMD", "sh", "-c", "curl -f http://localhost:${PORT:-5000}/sync/companies"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + diff --git a/backend/package-lock.json b/backend/package-lock.json index d768ccd..46e104c 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -25,6 +25,7 @@ "@types/express": "^5.0.6", "@types/jsonwebtoken": "^9.0.10", "@types/node": "^25.6.0", + "dotenv": "^17.4.2", "prisma": "^7.8.0", "ts-node-dev": "^2.0.0", "tsx": "^4.21.0" diff --git a/backend/package.json b/backend/package.json index 71e293a..4c0f08a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -19,6 +19,7 @@ "@types/express": "^5.0.6", "@types/jsonwebtoken": "^9.0.10", "@types/node": "^25.6.0", + "dotenv": "^17.4.2", "prisma": "^7.8.0", "ts-node-dev": "^2.0.0", "tsx": "^4.21.0" diff --git a/backend/podman-compose.yml b/backend/podman-compose.yml deleted file mode 100644 index 26a96a5..0000000 --- a/backend/podman-compose.yml +++ /dev/null @@ -1,16 +0,0 @@ -version: "3.9" - -services: - backend: - container_name: top-tran-backend - image: top-tran-backend - build: - context: . - dockerfile: Dockerfile - ports: - - "3000:3000" - env_file: - - .env - environment: - - PORT=3000 - restart: always \ No newline at end of file