v1.0
Acessar api.vupi.us

Banco de Dados no Módulo

Como configurar conexões, criar migrations e seeders no seu módulo.

Conexão de Banco de Dados Personalizada (Obrigatória)

Para criar projetos na IDE, você deve configurar uma conexão de banco de dados personalizada. Isso garante isolamento total dos seus dados de desenvolvimento.

Configuração Obrigatória

Você não pode criar projetos sem antes configurar uma conexão de banco de dados. O sistema bloqueará a criação com a mensagem: "Você precisa configurar uma conexão de banco de dados antes de criar um projeto".

Por que é obrigatório?

Isolamento Total

Seus módulos não compartilham o banco com o sistema core. Dados de desenvolvimento ficam completamente separados.

Flexibilidade

Use PostgreSQL ou MySQL. Conecte-se a bancos locais ou em nuvem (Aiven, AWS RDS, etc.).

Segurança

Credenciais criptografadas com AES-256-CBC. Suporte a SSL/TLS com certificados CA.

Arquivo connection.php

Quando você cria um módulo na IDE, o arquivo Database/connection.php é gerado automaticamente com o valor 'auto':

<?php
// Gerado automaticamente pela IDE
// Sempre retorna 'auto' para usar sua conexão personalizada
return 'auto';
Você não precisa editar este arquivo

O valor 'auto' faz com que o sistema use automaticamente sua conexão personalizada. Como a conexão personalizada é obrigatória, este arquivo sempre terá o mesmo valor.

Migrations

Migrations criam e removem tabelas. Devem ter funções up e down e verificar o driver do banco:

<?php

use PDO;

return [
    'up' => function (PDO $pdo): void {
        $driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
        if ($driver === 'pgsql') {
            $pdo->exec("CREATE TABLE IF NOT EXISTS produtos (
                id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
                nome VARCHAR(255) NOT NULL,
                preco DECIMAL(10,2) NOT NULL DEFAULT 0,
                criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
            )");
        } else {
            $pdo->exec("CREATE TABLE IF NOT EXISTS produtos (
                id CHAR(36) PRIMARY KEY,
                nome VARCHAR(255) NOT NULL,
                preco DECIMAL(10,2) NOT NULL DEFAULT 0,
                criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
        }
    },
    'down' => function (PDO $pdo): void {
        $pdo->exec("DROP TABLE IF EXISTS produtos");
    },
];

Seeders

Seeders inserem dados iniciais. Devem ser executados manualmente após as migrations:

<?php

use PDO;

return function (PDO $pdo): void {
    $driver = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
    $id = $driver === 'pgsql'
        ? $pdo->query('SELECT gen_random_uuid()')->fetchColumn()
        : bin2hex(random_bytes(16));

    $pdo->prepare("INSERT INTO produtos (id, nome, preco) VALUES (?, ?, ?)")
        ->execute([$id, 'Produto Exemplo', 99.90]);
};
Execução manual

Ao ativar um módulo, apenas os arquivos são sincronizados. Você precisa executar migrations e seeders manualmente via terminal ou interface da IDE.

Injeção de PDO no Repository

O container injeta o PDO automaticamente via constructor injection:

final class ProdutoRepository
{
    // PDO é injetado automaticamente pelo container
    public function __construct(private readonly PDO $pdo) {}

    public function findAll(): array
    {
        return $this->pdo
            ->query("SELECT * FROM produtos ORDER BY criado_em DESC")
            ->fetchAll(PDO::FETCH_ASSOC);
    }

    public function findById(string $id): ?array
    {
        // SEMPRE use prepared statements para evitar SQL injection
        $stmt = $this->pdo->prepare("SELECT * FROM produtos WHERE id = ?");
        $stmt->execute([$id]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return $result ?: null;
    }

    public function create(array $data): array
    {
        $id = bin2hex(random_bytes(16));
        $stmt = $this->pdo->prepare(
            "INSERT INTO produtos (id, nome, preco) VALUES (?, ?, ?)"
        );
        $stmt->execute([$id, $data['nome'], $data['preco']]);
        return $this->findById($id) ?? ['id' => $id];
    }
}
Segurança: Sempre use Prepared Statements

NUNCA concatene valores diretamente na query SQL. Use prepare() e execute() com placeholders (?) para evitar SQL injection.

Transações

Use transações para operações que precisam ser atômicas (tudo ou nada):

public function transferir(string $deId, string $paraId, float $valor): void
{
    try {
        $this->pdo->beginTransaction();

        // Debita da conta origem
        $stmt = $this->pdo->prepare("UPDATE contas SET saldo = saldo - ? WHERE id = ?");
        $stmt->execute([$valor, $deId]);

        // Credita na conta destino
        $stmt = $this->pdo->prepare("UPDATE contas SET saldo = saldo + ? WHERE id = ?");
        $stmt->execute([$valor, $paraId]);

        $this->pdo->commit();
    } catch (\Throwable $e) {
        $this->pdo->rollBack();
        throw $e;
    }
}

Executando Migrations Manualmente

Após ativar um módulo, você precisa executar as migrations manualmente:

Via Terminal da IDE

# Executar migrations de um módulo específico
php vupi migrate --modules=NomeDoModulo

# Executar migrations de todos os módulos
php vupi migrate --modules

# Executar seeders após migrations
php vupi seed --modules=NomeDoModulo

Via Interface da IDE

Na página do projeto, clique em:

  • "Executar Migrations" — Cria as tabelas no banco de dados
  • "Executar Seeders" — Insere dados iniciais
Ordem de execução

Sempre execute migrations antes dos seeders. Migrations criam as tabelas, seeders inserem os dados.

Como Configurar sua Conexão

Existem duas formas de configurar a conexão de banco de dados para seus módulos:

Opção 1: Usar Conexão da Plataforma

Selecione uma conexão pré-configurada pelo administrador e crie um banco de dados default automaticamente.

Vantagens: Configuração rápida, sem precisar informar credenciais manualmente.

Opção 2: Configurar Conexão Própria

Informe manualmente os dados de conexão do seu servidor de banco de dados (local ou em nuvem).

Vantagens: Total controle, use qualquer servidor (Aiven, AWS RDS, local, etc.).

Opção 1: Usando Conexão da Plataforma

1

Acessar configuração de banco de dados

Na página /dashboard/ide, clique em "Configurar Banco de Dados".

2

Escolher "Usar conexão da plataforma"

Selecione uma das conexões pré-configuradas disponíveis na lista.

3

Criar banco de dados default

O sistema criará automaticamente um banco de dados exclusivo para você na conexão selecionada.

4

Pronto!

Sua conexão está configurada e você já pode criar projetos na IDE.

Recomendado para iniciantes

Esta opção é ideal se você quer começar rapidamente sem se preocupar com configurações de servidor de banco de dados.

Opção 2: Configurando Conexão Própria

1

Acessar a página de projetos

Na página /dashboard/ide, localize o card "Conexão de Banco de Dados".

2

Clicar em "Configurar Banco de Dados"

Preencha os campos obrigatórios:

  • Nome da conexão: Nome amigável (ex: "Meu PostgreSQL Local")
  • Driver: PostgreSQL ou MySQL
  • Nome do banco: Nome do database (ex: meu_banco_dev)
  • Host: Endereço do servidor (ex: localhost ou pg-xxx.aivencloud.com)
  • Porta: Porta do banco (ex: 5432 para PostgreSQL, 3306 para MySQL)
  • Usuário: Nome de usuário do banco
  • Senha: Senha do banco de dados
3

Configurar SSL (opcional)

Para conexões em produção ou com bancos em nuvem:

  • Modo SSL: Nenhum, Require, Verify CA ou Verify Full
  • Certificado CA: Cole o conteúdo do arquivo .pem (necessário para Verify CA/Full)
4

Testar e Conectar

Clique em "Testar Conexão" para validar. Se bem-sucedido, clique em "Conectar" para salvar.

Exemplo: PostgreSQL no Aiven

Nome da conexão: Aiven PostgreSQL
Driver: PostgreSQL
Nome do banco: defaultdb
Host: pg-xxx-yyy.aivencloud.com
Porta: 12345
Usuário: avnadmin
Senha: sua_senha_aiven
Modo SSL: Require
Certificado CA: (cole o conteúdo do ca.pem fornecido pelo Aiven)

Comportamento do sistema

Todos os seus módulos criados na IDE usam automaticamente sua conexão personalizada:

Tipo de MóduloBanco Usado
Seus módulos (criados na IDE)✅ Sua conexão personalizada (obrigatória)
Módulos nativos (Auth, Usuario, etc.)Banco Core (DB_*) — não são afetados
Exemplo Prático

João configura uma conexão PostgreSQL na IDE. A partir desse momento:

  • ✅ João pode criar projetos na IDE
  • ✅ Todos os módulos de João usam o PostgreSQL configurado
  • ✅ Migrations e seeders executam no PostgreSQL de João
  • ✅ Queries dos repositories vão para o PostgreSQL de João
  • ❌ Módulos nativos (Auth, Usuario) continuam usando o banco Core
Conexões Persistentes

O sistema usa conexões persistentes (PDO::ATTR_PERSISTENT) para melhor performance. Primeira requisição: ~3500ms (estabelece conexão). Requisições subsequentes: ~50-200ms (reutiliza conexão) — 95% mais rápido!

Gerenciamento

No card de banco de dados, você pode:

  • Ver/Ocultar dados: Clique no ícone de olho para mostrar/ocultar host, porta e nome do banco
  • Ver migrations pendentes: Número de migrations que ainda não foram executadas
  • Ver tabelas: Lista de todas as tabelas criadas no banco personalizado
  • Editar conexão: Modifique as configurações (senha é mantida se deixar vazio)
  • Excluir conexão: Remove a configuração (seus módulos voltam a usar o banco core)
Importante

Ao excluir a conexão, seus módulos voltarão a usar o banco de dados padrão da Vupi.us API. As tabelas e dados no banco personalizado não serão afetados.

Segurança

  • Criptografia: Senhas são criptografadas com AES-256-CBC antes de serem armazenadas
  • SSL/TLS: Suporte completo a conexões seguras com verificação de certificado
  • Isolamento: Cada usuário tem sua própria configuração de conexão

Tipos de Dados por Driver

TipoPostgreSQLMySQL
IDUUIDCHAR(36)
Texto curtoVARCHAR(255)VARCHAR(255)
Texto longoTEXTTEXT
Número inteiroINTEGERINT
Número decimalDECIMAL(10,2)DECIMAL(10,2)
BooleanoBOOLEANTINYINT(1)
Data/HoraTIMESTAMPTZDATETIME
JSONJSONBJSON
Dica: Sempre verifique o driver

Use $pdo->getAttribute(PDO::ATTR_DRIVER_NAME) nas migrations para criar tabelas compatíveis com PostgreSQL e MySQL.

Validação Prévia de Migrations

Antes de executar migrations, você pode validá-las para detectar problemas sem modificar o banco de dados:

POST /api/ide/projects/{id}/validate-migrations
{
  "valid": true,
  "migrations_found": 3,
  "issues": [],
  "message": "Todas as migrations são válidas."
}

O que é validado?

  • Sintaxe PHP: Verifica se o código é válido
  • Métodos obrigatórios: Confirma presença de up() e down()
  • Idempotência: Detecta migrations que não verificam se tabelas já existem
  • Compatibilidade de driver: Alerta sobre SQL específico de PostgreSQL/MySQL
Boa Prática

Sempre valide migrations antes de executá-las, especialmente em produção. Isso evita erros que podem corromper o banco de dados.

Gerenciamento de Tabelas

Deletar Todas as Tabelas (Drop Tables)

Durante o desenvolvimento, você pode precisar resetar completamente o banco de dados. Use esta funcionalidade com extrema cautela:

DELETE /api/ide/projects/{id}/tables
{
  "dropped": ["produtos", "categorias", "pedidos"],
  "message": "3 tabelas deletadas com sucesso."
}
Ação Irreversível

Deletar tabelas é permanente. Todos os dados serão perdidos. Use apenas em ambiente de desenvolvimento ou quando tiver certeza absoluta.

Quando usar Drop Tables?

  • Resetar desenvolvimento: Começar do zero após mudanças estruturais grandes
  • Limpar testes: Remover dados de teste antes de nova bateria de testes
  • Corrigir migrations: Quando migrations falharam e deixaram o banco em estado inconsistente

Ativar/Desativar Módulo

Você pode ativar ou desativar seu módulo sem deletá-lo. Módulos desativados não respondem a requisições:

PATCH /api/ide/projects/{id}/module
{
  "enabled": false
}
Resposta
{
  "message": "Módulo desativado com sucesso.",
  "module_name": "MeuModulo",
  "enabled": false
}

Casos de Uso

Manutenção

Desative temporariamente o módulo durante manutenção ou atualizações críticas.

Debug

Desative módulos para isolar problemas e identificar conflitos entre módulos.

Testes A/B

Ative/desative funcionalidades para testar diferentes versões do sistema.

Segurança

Desative rapidamente um módulo se detectar comportamento suspeito ou vulnerabilidade.

Diferença entre Desativar e Deletar

Desativar: Módulo continua no sistema, mas não responde a requisições. Pode ser reativado a qualquer momento.

Deletar: Remove completamente o módulo, arquivos e opcionalmente as tabelas do banco. Ação irreversível.

Próximos Passos