Welcome file

Guia Completo: Prisma ORM + Next.js + TypeScript

Índice

  1. Introdução ao Prisma ORM
  2. Configuração Inicial
  3. A Lógica do Prisma: Schema → Migration → Generate
  4. Implementação Prática
  5. Deploy em Produção
  6. Operações Avançadas
  7. Glossário de Comandos

Introdução ao Prisma ORM

O que é o Prisma ORM

O Prisma é um ORM (Object-Relational Mapping) moderno para Node.js e TypeScript que simplifica o acesso a bancos de dados. Ele oferece type safety, auto-completion e uma API intuitiva para trabalhar com dados.

Principais Benefícios

  • Type Safety: Tipos TypeScript gerados automaticamente
  • Auto-completion: IntelliSense completo no editor
  • Migrations: Controle de versão para o banco de dados
  • Performance: Queries otimizadas
  • Developer Experience: API intuitiva e documentação excelente

Configuração Inicial

1. Instalação das Dependências

# Criar projeto Next.js com TypeScript
npx create-next-app@latest meu-projeto --typescript

# Navegar para o diretório
cd meu-projeto

# Instalar Prisma
npm install prisma @prisma/client

### Instalação de Drivers por Banco de Dados

#### PostgreSQL
```bash
npm install pg @types/pg

MySQL

npm install mysql2

SQL Server (MSSQL)

npm install tedious

SQLite

# Não precisa instalar driver adicional

### 2. Inicializando o Prisma

```bash
npx prisma init

Este comando cria:

  • Arquivo prisma/schema.prisma (esquema do banco)
  • Arquivo .env (variáveis de ambiente)

3. Configurando o arquivo prisma/schema.prisma

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql" // ou "mysql", "sqlserver", "sqlite"
  url      = env("DATABASE_URL")
}

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  posts     Post[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

4. Configurando as Variáveis de Ambiente

No arquivo .env:

PostgreSQL

# Database
DATABASE_URL="postgresql://usuario:senha@localhost:5432/meudb?schema=public"

MySQL

# Database
DATABASE_URL="mysql://usuario:senha@localhost:3306/meudb"

SQL Server (MSSQL)

# Database
DATABASE_URL="sqlserver://localhost:1433;database=meudb;user=usuario;password=senha;encrypt=true;trustServerCertificate=true"

SQLite (para desenvolvimento)

# Database
DATABASE_URL="file:./dev.db"

5. Criando e Executando Migrations

# Criar uma migration
npx prisma migrate dev --name init

# Gerar o cliente Prisma
npx prisma generate

A Lógica do Prisma: Schema → Migration → Generate

Entendendo a Arquitetura

O Prisma tem 3 componentes principais:

  1. Schema (schema.prisma) - O “blueprint” do seu banco
  2. Migrations - As instruções de mudança do banco
  3. Client - O código TypeScript gerado para usar no app
Schema.prisma → Migrations → Banco de Dados
     ↓
  Generate → Cliente TypeScript → Sua Aplicação

O que é Cada Componente?

1. Schema (prisma/schema.prisma)

É o arquivo onde você descreve como quer que seu banco seja estruturado:

model User {
  id    Int    @id @default(autoincrement())
  email String @unique
  name  String?
  posts Post[]
}

Analogia: É como uma “planta baixa” de uma casa - mostra como você quer que seja, mas ainda não construiu nada.

2. Migrations

São as instruções SQL que transformam seu banco do estado atual para o estado desejado:

-- Migration: 001_create_users_table
CREATE TABLE "User" (
    "id" SERIAL NOT NULL,
    "email" TEXT NOT NULL,
    "name" TEXT,
    PRIMARY KEY ("id")
);

CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

Analogia: É como o “passo a passo de construção” - as instruções reais para o pedreiro construir a casa.

3. Client (Gerado)

É o código TypeScript que permite você usar o banco na sua aplicação:

Consultas Complexas com Prisma Client

// Código gerado automaticamente
export const prisma = new PrismaClient()

// Tipos gerados automaticamente
export type User = {
  id: number
  email: string
  name: string | null
}

Analogia: É como ter um “manual de uso” da casa pronta - te ensina como usar cada cômodo.

Fluxos Práticos

DESENVOLVIMENTO (Mudança no Schema)

# 1. Edita schema.prisma
# 2. Cria migration E aplica E gera cliente (tudo junto)
npx prisma migrate dev --name add_age_field

# Resultado: banco atualizado + cliente atualizado

PRODUÇÃO (Deploy)

# 1. Aplica migrations pendentes no banco
npx prisma migrate deploy

# 2. Atualiza cliente TypeScript
npx prisma generate

# 3. Reinicia aplicação
npm run build && pm2 restart app

Por que Precisa dos Dois Comandos?

MIGRATION trabalha com o BANCO DE DADOS:

  • Cria/altera/remove tabelas
  • Modifica estrutura física do banco
  • Aplica mudanças no PostgreSQL/MySQL/etc

GENERATE trabalha com o CÓDIGO TYPESCRIPT:

  • Cria tipos TypeScript
  • Gera funções para acessar dados
  • Atualiza o cliente Prisma

Implementação Prática

Configuração do Cliente Prisma no Next.js

Criando o Cliente Prisma (lib/prisma.ts)

import { PrismaClient } from '@prisma/client'

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined
}

export const prisma = globalForPrisma.prisma ?? new PrismaClient()

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma

Esta configuração evita múltiplas instâncias do Prisma em desenvolvimento.

API Routes para CRUD de Usuários

pages/api/users/index.ts (para listar e criar usuários):

import { NextApiRequest, NextApiResponse } from 'next'
import { prisma } from '../../../lib/prisma'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method === 'GET') {
    try {
      const users = await prisma.user.findMany({
        include: {
          posts: true, // Incluir posts relacionados
        },
      })
      res.status(200).json(users)
    } catch (error) {
      res.status(500).json({ error: 'Erro ao buscar usuários' })
    }
  }

  if (req.method === 'POST') {
    try {
      const { email, name } = req.body
      const user = await prisma.user.create({
        data: {
          email,
          name,
        },
      })
      res.status(201).json(user)
    } catch (error) {
      res.status(500).json({ error: 'Erro ao criar usuário' })
    }
  }
}

pages/api/users/[id].ts (para operações específicas por ID):

import { NextApiRequest, NextApiResponse } from 'next'
import { prisma } from '../../../lib/prisma'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { id } = req.query

  if (req.method === 'GET') {
    try {
      const user = await prisma.user.findUnique({
        where: { id: Number(id) },
        include: { posts: true },
      })
      if (!user) {
        return res.status(404).json({ error: 'Usuário não encontrado' })
      }
      res.status(200).json(user)
    } catch (error) {
      res.status(500).json({ error: 'Erro ao buscar usuário' })
    }
  }

  if (req.method === 'PUT') {
    try {
      const { email, name } = req.body
      const user = await prisma.user.update({
        where: { id: Number(id) },
        data: { email, name },
      })
      res.status(200).json(user)
    } catch (error) {
      res.status(500).json({ error: 'Erro ao atualizar usuário' })
    }
  }

  if (req.method === 'DELETE') {
    try {
      await prisma.user.delete({
        where: { id: Number(id) },
      })
      res.status(204).end()
    } catch (error) {
      res.status(500).json({ error: 'Erro ao deletar usuário' })
    }
  }
}

Componentes React com TypeScript

components/UserList.tsx:

import { useState, useEffect } from 'react'

interface User {
  id: number
  email: string
  name: string | null
  posts: Post[]
}

interface Post {
  id: number
  title: string
  content: string | null
  published: boolean
}

export default function UserList() {
  const [users, setUsers] = useState<User[]>([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetchUsers()
  }, [])

  const fetchUsers = async () => {
    try {
      const response = await fetch('/api/users')
      const data = await response.json()
      setUsers(data)
    } catch (error) {
      console.error('Erro ao carregar usuários:', error)
    } finally {
      setLoading(false)
    }
  }

  if (loading) return <div>Carregando...</div>

  return (
    <div>
      <h1>Lista de Usuários</h1>
      {users.map((user) => (
        <div key={user.id} className="user-card">
          <h3>{user.name || 'Sem nome'}</h3>
          <p>Email: {user.email}</p>
          <p>Posts: {user.posts.length}</p>
        </div>
      ))}
    </div>
  )
}

Deploy em Produção

1ª PARTE - INSTALAÇÃO INICIAL DO SISTEMA

Passo 1: Preparação do Servidor

# Atualizar sistema (Ubuntu/Debian)
sudo apt update && sudo apt upgrade -y

# Instalar Node.js (versão LTS)
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs

# Verificar instalação
node --version
npm --version

Passo 2: Clone e Configuração do Projeto

# Clonar repositório
git clone https://github.com/seu-usuario/seu-projeto.git
cd seu-projeto

# Instalar dependências de produção
npm ci --only=production

# Instalar Prisma CLI globalmente (opcional)
npm install -g prisma

Passo 3: Configuração das Variáveis de Ambiente

# Criar arquivo de ambiente para produção
cp .env.example .env.production

# Editar variáveis (use editor de sua preferência)
nano .env.production

Exemplo do .env.production:

NODE_ENV=production
DATABASE_URL="postgresql://user:password@localhost:5432/proddb"
NEXTAUTH_SECRET="seu-secret-super-seguro"
NEXTAUTH_URL="https://seudominio.com"

Configuração do Banco de Dados por Provider

PostgreSQL
# Criar banco de dados
sudo -u postgres createdb proddb
sudo -u postgres psql -c "CREATE USER userapp WITH PASSWORD 'senha123';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE proddb TO userapp;"

# Ou usar Docker
docker run --name postgres-prod -e POSTGRES_DB=proddb -e POSTGRES_USER=userapp -e POSTGRES_PASSWORD=senha123 -p 5432:5432 -d postgres:15
MySQL
# Criar banco de dados
mysql -u root -p -e "CREATE DATABASE proddb;"
mysql -u root -p -e "CREATE USER 'userapp'@'%' IDENTIFIED BY 'senha123';"
mysql -u root -p -e "GRANT ALL PRIVILEGES ON proddb.* TO 'userapp'@'%';"
mysql -u root -p -e "FLUSH PRIVILEGES;"

# Ou usar Docker
docker run --name mysql-prod -e MYSQL_DATABASE=proddb -e MYSQL_USER=userapp -e MYSQL_PASSWORD=senha123 -e MYSQL_ROOT_PASSWORD=rootpass -p 3306:3306 -d mysql:8
SQL Server (MSSQL)
# Usar Docker (recomendado)
docker run --name mssql-prod -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=SuaSenhaForte123!" -p 1433:1433 -d mcr.microsoft.com/mssql/server:2019-latest

# Conectar e criar banco
docker exec -it mssql-prod /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "SuaSenhaForte123!"
> CREATE DATABASE proddb;
> GO
> EXIT

Passo 5: Deploy Inicial das Migrations

# Gerar cliente Prisma
npx prisma generate

# Executar migrations em produção (primeira vez)
npx prisma migrate deploy

# Verificar status das migrations
npx prisma migrate status

# (Opcional) Popular banco com dados iniciais
npx prisma db seed

Passo 6: Build e Start da Aplicação

# Build da aplicação Next.js
npm run build

# Iniciar aplicação em produção
npm start

# Ou usar PM2 para gerenciamento de processos
npm install -g pm2
pm2 start npm --name "minha-app" -- start
pm2 save
pm2 startup

2ª PARTE - ATUALIZAÇÕES SEM PERDER DADOS

Passo 1: Backup Preventivo

##### PostgreSQL
```bash
# Backup do banco PostgreSQL
pg_dump -h localhost -U userapp -d proddb > backup_$(date +%Y%m%d_%H%M%S).sql

# Ou usando Docker
docker exec postgres-prod pg_dump -U userapp proddb > backup_$(date +%Y%m%d_%H%M%S).sql
MySQL
# Backup do banco MySQL
mysqldump -h localhost -u userapp -p proddb > backup_$(date +%Y%m%d_%H%M%S).sql

# Ou usando Docker
docker exec mysql-prod mysqldump -u userapp -p proddb > backup_$(date +%Y%m%d_%H%M%S).sql
SQL Server (MSSQL)
# Backup usando Docker
docker exec -it mssql-prod /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "SuaSenhaForte123!" -Q "BACKUP DATABASE proddb TO DISK = '/var/opt/mssql/backup_$(date +%Y%m%d_%H%M%S).bak'"

# Copiar backup para host
docker cp mssql-prod:/var/opt/mssql/backup_$(date +%Y%m%d_%H%M%S).bak ./

Backup dos arquivos de upload (se houver)

tar -czf uploads_backup_$(date +%Y%m%d_%H%M%S).tar.gz uploads/


#### Passo 2: Atualização do Código

```bash
# Parar aplicação
pm2 stop minha-app

# Fazer backup do código atual
cp -r /caminho/para/aplicacao /caminho/para/aplicacao_backup_$(date +%Y%m%d)

# Atualizar código
git fetch origin
git pull origin main

# Ou substituir arquivos se não usar Git
# rsync -av /caminho/nova-versao/ /caminho/aplicacao/

Passo 3: Atualização das Dependências

# Atualizar dependências (cuidado com breaking changes)
npm ci --only=production

# Ou atualização conservadora
npm install --production

Passo 4: Verificação e Execução de Migrations

# Verificar status das migrations pendentes
npx prisma migrate status

# Visualizar diferenças do schema (desenvolvimento)
npx prisma migrate diff --from-url $DATABASE_URL --to-schema-datamodel prisma/schema.prisma

# Executar migrations pendentes
npx prisma migrate deploy

# Regenerar cliente Prisma (importante após mudanças no schema)
npx prisma generate

Passo 5: Build e Restart da Aplicação

# Novo build da aplicação
npm run build

# Restart da aplicação
pm2 restart minha-app

# Verificar logs
pm2 logs minha-app --lines 50

# Verificar status
pm2 status

Passo 6: Validação Pós-Deploy

# Testar conectividade do banco
npx prisma db pull --print

# Verificar saúde da aplicação
curl -I http://localhost:3000/api/health

# Monitorar logs em tempo real
pm2 logs minha-app --follow

Operações Avançadas

Consultas SQL Diretas

// Buscar usuários com SQL direto
const users = await prisma.$queryRaw`
  SELECT * FROM "User" 
  WHERE "email" LIKE ${'%@gmail.com'}
  ORDER BY "createdAt" DESC
`

// Buscar com parâmetros tipados
const usersByDomain = await prisma.$queryRaw<User[]>`
  SELECT u.*, COUNT(p.id) as post_count 
  FROM "User" u 
  LEFT JOIN "Post" p ON u.id = p."authorId"
  WHERE u.email LIKE ${`%${domain}`}
  GROUP BY u.id
`

// Query SQL sem retorno tipado
const result = await prisma.$executeRaw`
  UPDATE "User" 
  SET "updatedAt" = NOW() 
  WHERE "lastLogin" < NOW() - INTERVAL '30 days'
`
console.log(`${result} usuários atualizados`)

// Query complexa com subquery
const activeUsers = await prisma.$queryRaw`
  SELECT u.*, 
    (SELECT COUNT(*) FROM "Post" p WHERE p."authorId" = u.id AND p.published = true) as published_posts
  FROM "User" u
  WHERE u.id IN (
    SELECT DISTINCT p."authorId" 
    FROM "Post" p 
    WHERE p."createdAt" > NOW() - INTERVAL '7 days'
  )
`

Operações de Insert Diretas

// Insert simples com SQL
const result = await prisma.$executeRaw`
  INSERT INTO "User" (email, name, "createdAt", "updatedAt")
  VALUES (${'novo@email.com'}, ${'Novo Usuário'}, NOW(), NOW())
`

// Insert em lote com SQL
const batchInsert = await prisma.$executeRaw`
  INSERT INTO "Post" (title, content, "authorId", published, "createdAt", "updatedAt")
  VALUES 
    (${'Post 1'}, ${'Conteúdo 1'}, ${1}, ${true}, NOW(), NOW()),
    (${'Post 2'}, ${'Conteúdo 2'}, ${1}, ${false}, NOW(), NOW()),
    (${'Post 3'}, ${'Conteúdo 3'}, ${2}, ${true}, NOW(), NOW())
`

// Insert com retorno do ID (PostgreSQL)
const newUser = await prisma.$queryRaw<{id: number}[]>`
  INSERT INTO "User" (email, name, "createdAt", "updatedAt")
  VALUES (${'user@test.com'}, ${'Test User'}, NOW(), NOW())
  RETURNING id
`

// Insert condicional (upsert com SQL)
const upsertUser = await prisma.$executeRaw`
  INSERT INTO "User" (email, name, "createdAt", "updatedAt")
  VALUES (${'user@example.com'}, ${'João Silva'}, NOW(), NOW())
  ON CONFLICT (email) 
  DO UPDATE SET 
    name = EXCLUDED.name,
    "updatedAt" = NOW()
`

Diferenças por Banco de Dados

PostgreSQL

// Usar aspas duplas para nomes de tabelas/colunas
const users = await prisma.$queryRaw`
  SELECT * FROM "User" WHERE "createdAt" > ${new Date('2024-01-01')}
`

// RETURNING funciona
const newUser = await prisma.$queryRaw`
  INSERT INTO "User" (email, name, "createdAt", "updatedAt")
  VALUES (${'test@test.com'}, ${'Test'}, NOW(), NOW())
  RETURNING id, email
`

MySQL

// Usar backticks para nomes de tabelas/colunas
const users = await prisma.$queryRaw`
  SELECT * FROM \`User\` WHERE \`createdAt\` > ${new Date('2024-01-01')}
`

// Para auto-increment, usar LAST_INSERT_ID()
await prisma.$executeRaw`
  INSERT INTO \`User\` (email, name, createdAt, updatedAt)
  VALUES (${'test@test.com'}, ${'Test'}, NOW(), NOW())
`

const lastId = await prisma.$queryRaw<{id: number}[]>`
  SELECT LAST_INSERT_ID() as id
`

SQL Server (MSSQL)

// Usar colchetes para nomes de tabelas/colunas
const users = await prisma.$queryRaw`
  SELECT * FROM [User] WHERE [createdAt] > ${new Date('2024-01-01')}
`

// Usar OUTPUT para retorno
const newUser = await prisma.$queryRaw`
  INSERT INTO [User] (email, name, createdAt, updatedAt)
  OUTPUT INSERTED.id, INSERTED.email
  VALUES (${'test@test.com'}, ${'Test'}, GETDATE(), GETDATE())
`

Melhores Práticas para SQL Direto

// ✅ Sempre use parâmetros para evitar SQL Injection
const users = await prisma.$queryRaw`
  SELECT * FROM "User" WHERE email = ${email}
`

// ❌ NUNCA faça isso (vulnerável a SQL Injection)
const users = await prisma.$queryRaw`
  SELECT * FROM "User" WHERE email = '${email}'
`

// ✅ Use transaction para operações complexas
const result = await prisma.$transaction(async (prisma) => {
  const user = await prisma.$queryRaw`
    INSERT INTO "User" (email, name, "createdAt", "updatedAt")
    VALUES (${'user@test.com'}, ${'Test User'}, NOW(), NOW())
    RETURNING id
  `
  
  const posts = await prisma.$executeRaw`
    INSERT INTO "Post" (title, "authorId", "createdAt", "updatedAt")
    VALUES (${'Welcome Post'}, ${user[0].id}, NOW(), NOW())
  `
  
  return { user, posts }
})

// ✅ Use tipos TypeScript quando possível
interface UserWithPostCount {
  id: number
  email: string
  name: string | null
  post_count: bigint
}

const usersWithPosts = await prisma.$queryRaw<UserWithPostCount[]>`
  SELECT u.*, COUNT(p.id) as post_count
  FROM "User" u
  LEFT JOIN "Post" p ON u.id = p."authorId"
  GROUP BY u.id
`
// Buscar usuários com filtros
const users = await prisma.user.findMany({
  where: {
    email: {
      contains: '@gmail.com',
    },
    posts: {
      some: {
        published: true,
      },
    },
  },
  include: {
    posts: {
      where: {
        published: true,
      },
    },
  },
  orderBy: {
    createdAt: 'desc',
  },
  take: 10, // Limitar a 10 resultados
  skip: 0,  // Paginação
})

// Agregações
const userStats = await prisma.user.aggregate({
  _count: {
    id: true,
  },
  _avg: {
    id: true,
  },
})

// Transações
const result = await prisma.$transaction(async (prisma) => {
  const user = await prisma.user.create({
    data: {
      email: 'user@example.com',
      name: 'João',
    },
  })

  const post = await prisma.post.create({
    data: {
      title: 'Primeiro Post',
      content: 'Conteúdo do post',
      authorId: user.id,
    },
  })

  return { user, post }
})

Middleware e Hooks

// Middleware do Prisma
const prisma = new PrismaClient()

prisma.$use(async (params, next) => {
  console.log('Query executada:', params.model, params.action)
  const result = await next(params)
  return result
})

Comandos Úteis do Prisma

# Visualizar banco no navegador
npx prisma studio

# Reset do banco
npx prisma migrate reset

# Deploy de migrations em produção
npx prisma migrate deploy

# Gerar cliente após mudanças no schema
npx prisma generate

# Verificar status das migrations
npx prisma migrate status

Glossário de Comandos

Comandos de Sistema

sudo apt update && sudo apt upgrade -y

  • Atualiza lista de pacotes disponíveis e instala atualizações do sistema operacional

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -

  • Baixa e executa script de instalação do Node.js LTS (Long Term Support)

npm ci --only=production

  • Instala dependências exatamente como especificado no package-lock.json, apenas dependências de produção

Comandos Git

git fetch origin

  • Baixa alterações do repositório remoto sem fazer merge no branch atual

git pull origin main

  • Baixa e aplica alterações do branch main do repositório remoto

Comandos Prisma

npx prisma generate

  • Gera o cliente Prisma baseado no schema atual, criando tipos TypeScript

npx prisma migrate deploy

  • Executa migrations pendentes em ambiente de produção (não cria novas migrations)

npx prisma migrate dev --name nome_da_migration

  • Cria nova migration, aplica no banco e gera cliente (desenvolvimento)

npx prisma migrate status

  • Mostra status de todas as migrations (aplicadas, pendentes, com problemas)

npx prisma migrate diff

  • Compara dois estados do banco e mostra diferenças no schema

npx prisma db pull

  • Sincroniza o schema Prisma com o estado atual do banco de dados

npx prisma db push

  • Aplica mudanças do schema diretamente no banco (sem criar migration)

npx prisma db seed

  • Executa script de população inicial do banco (definido em package.json)

npx prisma studio

  • Abre interface web para visualizar e editar dados do banco

npx prisma migrate reset

  • Reseta banco, reaplica todas as migrations e executa seed

npx prisma format

  • Formata o arquivo schema.prisma

npx prisma validate

  • Valida o schema.prisma em busca de erros

Comandos SQL Diretos

prisma.$queryRaw

  • Executa consulta SQL direta e retorna resultados

prisma.$executeRaw

  • Executa comando SQL sem retorno (INSERT, UPDATE, DELETE)

prisma.$queryRawUnsafe

  • Executa SQL direto sem validação de parâmetros (use com cuidado)

prisma.$executeRawUnsafe

  • Executa comando SQL sem validação de parâmetros (use com cuidado)

Comandos de Banco de Dados

sudo -u postgres createdb proddb

  • Cria novo banco PostgreSQL com nome “proddb” usando usuário postgres

pg_dump -h localhost -U userapp -d proddb > backup.sql

  • Cria backup completo do banco PostgreSQL em arquivo SQL

docker exec postgres-prod pg_dump -U userapp proddb > backup.sql

  • Cria backup do banco rodando em container Docker

Comandos Next.js

npm run build

  • Compila aplicação Next.js para produção, otimizando código e assets

npm start

  • Inicia aplicação Next.js em modo produção (requer build prévio)

Comandos PM2

pm2 start npm --name "minha-app" -- start

  • Inicia aplicação com PM2, criando processo nomeado “minha-app”

pm2 stop minha-app

  • Para processo específico no PM2

pm2 restart minha-app

  • Reinicia processo específico no PM2

pm2 logs minha-app --lines 50

  • Mostra últimas 50 linhas de log do processo

pm2 logs minha-app --follow

  • Monitora logs em tempo real

pm2 status

  • Mostra status de todos os processos gerenciados pelo PM2

pm2 save

  • Salva configuração atual dos processos

pm2 startup

  • Configura PM2 para iniciar automaticamente com o sistema

Comandos de Backup e Segurança

tar -czf arquivo.tar.gz pasta/

  • Cria arquivo comprimido (.tar.gz) de uma pasta

cp -r origem destino

  • Copia diretório e todo seu conteúdo recursivamente

rsync -av origem/ destino/

  • Sincroniza arquivos entre diretórios de forma eficiente

Comandos de Monitoramento

curl -I http://localhost:3000/api/health

  • Testa conectividade HTTP e mostra cabeçalhos de resposta

node --version

  • Mostra versão do Node.js instalada

npm --version

  • Mostra versão do NPM instalada

Resumo dos Fluxos

DESENVOLVIMENTO:

Schema → migrate dev (faz tudo)

PRODUÇÃO:

1. migrate deploy (atualiza banco)
2. generate (atualiza código)
3. build + restart (usa código novo)

Dicas Importantes

  1. Type Safety: O Prisma gera tipos TypeScript automaticamente baseados no seu schema
  2. Performance: Use select e include conscientemente para evitar over-fetching
  3. Conexões: Configure connection pooling em produção
  4. Migrations: Sempre teste migrations em ambiente de desenvolvimento primeiro
  5. Backup: Faça backup antes de executar migrations destrutivas
  6. Sincronização: Sempre mantenha banco e código TypeScript sincronizados com o schema
  7. Controle: Em produção, execute comandos em etapas controladas para maior segurança

A lógica fundamental é: Sempre mantenha banco e código TypeScript sincronizados com o schema, mas em produção você faz isso em etapas controladas para maior segurança.