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
| Tipo | Descrição | Equivalente SQL típico |
|---|---|---|
inteiro | Número inteiro sem decimais | INTEGER / BIGINT |
decimal | Número com casas decimais | DECIMAL / NUMERIC |
texto(N) | String com comprimento máximo N | VARCHAR(N) |
booleano | Verdadeiro ou falso | BOOLEAN |
data | Data sem componente de hora | DATE |
data-hora | Data e hora com fuso | TIMESTAMP WITH TIME ZONE |
hora | Hora do dia sem data | TIME |
arquivo | Referência a blob/arquivo externo | VARCHAR (URL ou chave) |
json | Objeto JSON sem esquema fixo | JSONB / JSON |
Modificadores
Modificadores refinam o comportamento de cada campo. Podem ser combinados na mesma linha, separados por vírgula:
| Modificador | Efeito |
|---|---|
chave-primaria | Marca como chave primária da tabela |
auto-incremento | Valor gerado automaticamente (SERIAL / IDENTITY) |
unico | Constraint UNIQUE na coluna |
obrigatorio | NOT NULL — o campo não pode ser nulo |
opcional | Permite nulo (comportamento padrão quando omitido) |
privado | Campo não retornado em respostas de API por padrão |
indexado | Cria índice simples na coluna |
padrao: valor | Valor padrão quando não informado |
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):
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
}
}