SPELL / Documentação
← Site principal

Bloco Dados

Sintaxe básica

O bloco Dados contém a modelagem de dados do sistema. Cada entidade é declarada com a keyword table seguida do nome da tabela em PascalCase:

Dados {
  table Produto {
    id: inteiro, chave-primaria, auto-incremento
    nome: texto(200), obrigatorio
    preco: decimal, obrigatorio
    estoque: inteiro, padrao: 0
    ativo: booleano, padrao: sim
    criado_em: data-hora, obrigatorio
  }
}

Cada linha dentro de table é um campo. O formato é sempre nome: tipo, modificador1, modificador2. Os modificadores são opcionais e podem aparecer em qualquer ordem.

Tipos de campo

TipoDescriçãoEquivalente SQL típico
inteiroNúmero inteiro sem decimaisINTEGER / BIGINT
decimalNúmero com casas decimaisDECIMAL / NUMERIC
texto(N)String com comprimento máximo NVARCHAR(N)
booleanoVerdadeiro ou falsoBOOLEAN
dataData sem componente de horaDATE
data-horaData e hora com fusoTIMESTAMP WITH TIME ZONE
horaHora do dia sem dataTIME
arquivoReferência a blob/arquivo externoVARCHAR (URL ou chave)
jsonObjeto JSON sem esquema fixoJSONB / JSON

Modificadores

Modificadores refinam o comportamento de cada campo. Podem ser combinados na mesma linha, separados por vírgula:

ModificadorEfeito
chave-primariaMarca como chave primária da tabela
auto-incrementoValor gerado automaticamente (SERIAL / IDENTITY)
unicoConstraint UNIQUE na coluna
obrigatorioNOT NULL — o campo não pode ser nulo
opcionalPermite nulo (comportamento padrão quando omitido)
privadoCampo não retornado em respostas de API por padrão
indexadoCria índice simples na coluna
padrao: valorValor padrão quando não informado
Exemplo com modificadores
table Conta {
  id: inteiro, chave-primaria, auto-incremento
  email: texto(200), unico, obrigatorio, indexado
  senha_hash: texto(200), obrigatorio, privado
  perfil: texto(20), obrigatorio, padrao: usuario
  verificado: booleano, padrao: nao
  criado_em: data-hora, obrigatorio
  excluido_em: data-hora, opcional
}

Relacionamentos inline

Relacionamentos entre tabelas são declarados com a seta -> após o tipo do campo. A sintaxe é campo_id: tipo -> TabelaDestino.campo:

table Pedido {
  id: inteiro, chave-primaria, auto-incremento
  cliente_id: inteiro, obrigatorio -> Cliente.id
  vendedor_id: inteiro, opcional -> Usuario.id
  status: texto(30), obrigatorio, padrao: rascunho
  valor_total: decimal, obrigatorio
  criado_em: data-hora, obrigatorio
}

table ItemPedido {
  pedido_id: inteiro, obrigatorio -> Pedido.id
  produto_id: inteiro, obrigatorio -> Produto.id
  quantidade: inteiro, obrigatorio
  preco_unitario: decimal, obrigatorio
}

Sub-bloco Indices

O sub-bloco Indices dentro de uma tabela declara índices compostos (múltiplas colunas) e índices parciais (com condição WHERE):

Índice composto e parcial
table Mensagem {
  id: inteiro, chave-primaria, auto-incremento
  remetente_id: inteiro, obrigatorio -> Usuario.id
  destinatario_id: inteiro, obrigatorio -> Usuario.id
  lida: booleano, padrao: nao
  enviada_em: data-hora, obrigatorio
  excluida_em: data-hora, opcional

  Indices {
    inbox: (destinatario_id, excluida_em, enviada_em)
    enviados: (remetente_id, excluida_em, enviada_em)
    nao_lidas: parcial(lida) where lida = false
  }
}

Sub-bloco Configuracao

O sub-bloco Configuracao dentro de Dados define configurações de infraestrutura de dados como multitenancy e estratégia de migração. Este bloco é escrito pelo arquiteto, mas a implementação técnica é sempre gerada pela IA:

Dados {
  Configuracao {
    multitenancy: schema-por-tenant
    escopo: hibrido
    migracao: automatica
    /// Tabelas globais ficam no schema public
    /// Tabelas de domínio ficam no schema do tenant
  }

  table Tenant {
    // Tabela global — fica no schema public
    id: inteiro, chave-primaria, auto-incremento
    nome: texto(100), obrigatorio
    schema: texto(50), unico, obrigatorio
  }
}

Delegando estrutura à IA

Quando você sabe que uma entidade deve existir mas não quer (ou não precisa) detalhar todos os campos, use estrutura: recomendar. A IA propõe campos razoáveis antes de implementar:

Dados {
  /// Sistema de rastreamento de entregas — estrutura a ser validada com equipe logística

  table Entrega {
    estrutura: recomendar
  }

  table Rastreamento {
    entrega_id: inteiro, obrigatorio -> Entrega.id
    status: texto(50), obrigatorio
    latitude: decimal, opcional
    longitude: decimal, opcional
    registrado_em: data-hora, obrigatorio
  }
}