Guia de integração — Tabelas e campos extra
Microserviço: XDPeople.Soba.WebAPI (Core API)
Autenticação: token Bearer (JWT) e contexto de tenant — ver Login Combinado
Introdução
A funcionalidade de tabelas e campos extra permite definir, por tipo de entidade, um conjunto de tabelas lógicas e campos com persistência em tabelas físicas na base de dados, além de valores por instância da entidade (por chave primária).
Dois grupos de endpoints cobrem casos distintos:
- Configuração — criar, alterar e remover tabelas e campos; obter a configuração completa para o segmento
{entityTypeName}na rota. - Valores — ler e gravar (upsert) os valores extra de uma instância, identificada por
entityKeyId.
Ver Identificador do tipo de entidade para os valores suportados de {entityTypeName} nas rotas.
Prefixo e rotas
| Área | Prefixo de URL |
|---|---|
| Configuração | /gateway/extra-tables-fields-config/{entityTypeName} |
| Valores | /gateway/extra-fields-values/{entityTypeName} |
Os segmentos {entityTypeName} e {entityKeyId} devem ser codificados para URL quando contiverem caracteres reservados.
Identificador do tipo de entidade (entityTypeName)
O segmento {entityTypeName} na URL é o identificador de tipo reconhecido pelo servidor. A comparação é insensível a maiúsculas/minúsculas. Qualquer outro valor devolve ExtraTablesAndFields.UnsupportedEntityType.
entityTypeName | entityKeyId nos valores |
|---|---|
AccountHeadingBE | número inteiro |
AccountTypeBE | número inteiro |
AdvancedDiscount | texto até 50 caracteres |
BusinessAccount | número inteiro |
EntityContactsBE | número inteiro |
Entity | texto até 25 caracteres |
EntityAddress | número inteiro |
EntityGroups | número inteiro |
EntityTypes | número inteiro |
FixedExpensesAndRevenues | número inteiro |
ItemBarcodeBE | número inteiro |
ItemBE | texto até 60 caracteres |
ItemGroupBE | número inteiro |
LoadUnloadPlaceBE | número inteiro |
PointsConfig | GUID |
PriceTable | número inteiro |
SalesPromoBE | número inteiro |
SalesZone | número inteiro |
UserBE | número inteiro |
UserGroupBE | número inteiro |
WarehouseBE | número inteiro |
XDfree01 | texto até 25 caracteres |
XDfree02 | texto até 25 caracteres |
XDfree03 | texto até 25 caracteres |
XConfigCurrency | número inteiro |
XConfigItemUnit | número inteiro |
XConfigPaymentMode | número inteiro |
XConfigPaymentType | número inteiro |
O campo entityTypeName no corpo JSON do GET de configuração corresponde ao valor pedido na rota.
Nome da tabela física
Para cada tabela lógica com nome Name e tipo de entidade entityTypeName, a tabela física segue o padrão:
{Name}_{entityTypeName_em_minúsculas}_extrafields
Exemplo: tabela lógica Extras com entityTypeName ItemBE → Extras_itembe_extrafields.
Este nome aparece na resposta de configuração como physicalTableName.
Endpoints — Configuração
Base: /gateway/extra-tables-fields-config/{entityTypeName}
| Método | URL | Descrição | Resposta de sucesso |
|---|---|---|---|
| GET | /gateway/extra-tables-fields-config/{entityTypeName} | Lista tabelas e respetivos campos. | 200 — corpo ExtraFieldsConfigurationResponse |
| POST | /gateway/extra-tables-fields-config/{entityTypeName}/tables | Cria uma tabela lógica e a tabela física. | 200 — corpo da tabela criada |
| PUT | /gateway/extra-tables-fields-config/{entityTypeName}/tables/{tableGuid} | Atualiza metadados da tabela (não altera o nome lógico). | 204 |
| DELETE | /gateway/extra-tables-fields-config/{entityTypeName}/tables/{tableGuid} | Remove configuração, campos associados e elimina a tabela física. | 204 |
| POST | /gateway/extra-tables-fields-config/{entityTypeName}/tables/{tableGuid}/fields | Cria um campo (coluna física). | 200 — corpo do campo criado |
| PUT | /gateway/extra-tables-fields-config/{entityTypeName}/fields/{fieldGuid} | Atualiza metadados do campo (não altera o nome nem o tipo). | 204 |
| DELETE | /gateway/extra-tables-fields-config/{entityTypeName}/fields/{fieldGuid} | Remove o campo e remove a coluna da tabela física. | 204 |
Corpo da configuração (GET /gateway/extra-tables-fields-config/{entityTypeName})
Propriedades principais (JSON em camelCase):
| Propriedade | Tipo | Descrição |
|---|---|---|
entityTypeName | string | Igual ao identificador que foi usado no segmento da rota do pedido (o servidor devolve-o de volta no corpo). |
tables | array | Tabelas lógicas ordenadas na resposta. |
Cada elemento de tables:
| Propriedade | Tipo | Descrição |
|---|---|---|
guid | string | Identificador único da tabela na configuração. |
order | number | Ordem de apresentação (≥ 0). |
name | string | Nome lógico da tabela (identificador). |
description | string | Texto descritivo (pode ser vazio na criação). |
permissionType | number | Ver Permissões da tabela. |
allowInDocuments | boolean | Permissão de uso em documentos. |
allowMultipleRegistries | boolean | Se true, a tabela admite vários registos por entidade; ver Valores por instância. |
physicalTableName | string | Nome da tabela na base de dados. |
fields | array | Campos da tabela. |
Cada elemento de fields:
| Propriedade | Tipo | Descrição |
|---|---|---|
guid | string | Identificador único do campo. |
order | number | Ordem (≥ 0). |
name | string | Nome lógico da coluna. |
description | string | Descrição (obrigatória na criação; 1–500 caracteres). |
fieldType | string | Tipo lógico; ver Tipos de campo. |
length | number | Para String, comprimento máximo; para Decimal, casas decimais; noutros casos segue regras do servidor (1–16383). |
required | boolean | Campo obrigatório na configuração. |
inactive | boolean | Se true, o campo é ignorado na leitura de valores. |
tableName | string | Nome lógico da tabela a que o campo pertence. |
values | object | Mapa índice → texto (opções quando aplicável). |
canEditValues | boolean | Se as opções são editáveis em runtime. |
entityType | string | null | Tipo de entidade alvo para pesquisa (campo estilo lookup); opcional. |
Criar tabela (POST /gateway/extra-tables-fields-config/{entityTypeName}/tables)
| Propriedade | Obrigatório | Regras |
|---|---|---|
name | sim | 1–25 caracteres; primeiro carácter letra; restantes letras ou dígitos (^[a-zA-Z][a-zA-Z0-9]*$). |
description | sim | Até 2000 caracteres; pode ser string vazia. |
order | sim | ≥ 0. |
permissionType | sim | Entre 0 e 2; ver Permissões da tabela. |
allowInDocuments | sim | boolean |
allowMultipleRegistries | sim | boolean |
O servidor valida o nome lógico e recusa a criação se já existir uma tabela física com o nome derivado (ExtraTablesAndFields.PhysicalTableExists).
Atualizar tabela (PUT /gateway/extra-tables-fields-config/{entityTypeName}/tables/{tableGuid})
Corpo: description, order, permissionType, allowInDocuments, allowMultipleRegistries (o nome lógico da tabela não é alterável por este endpoint).
Criar campo (POST /gateway/extra-tables-fields-config/{entityTypeName}/tables/{tableGuid}/fields)
| Propriedade | Obrigatório | Regras |
|---|---|---|
name | sim | Mesmas regras de identificador que o nome da tabela lógica (1–25, letra inicial). |
description | sim | 1–500 caracteres. |
order | sim | ≥ 0. |
fieldType | sim | String não vazia até 16 caracteres; ver Tipos de campo. |
length | sim | 1–16383 (significado conforme tipo). |
required | sim | boolean |
inactive | sim | boolean |
values | sim | Objeto com chaves numéricas e valores texto (pode ser {}). |
canEditValues | sim | boolean |
entityType | não | Até 32 caracteres; vazio ou omitido = sem lookup. |
Atualizar campo (PUT /gateway/extra-tables-fields-config/{entityTypeName}/fields/{fieldGuid})
Corpo: description, order, length, required, inactive, values, canEditValues, entityType. O nome e o tipo do campo não são alterados por este fluxo.
Permissões da tabela
Valores de permissionType (alinhados ao enumerado interno):
| Valor | Significado |
|---|---|
0 | Todos os utilizadores |
1 | Utilizador atual |
2 | Grupos de utilizadores |
Tipos de campo
Valores típicos de fieldType na criação (mapeados internamente para tipos CLR e DDL):
fieldType | Uso resumido |
|---|---|
String | Texto; length = comprimento máximo da coluna de texto. |
LongText | Texto longo |
Int32 | Número inteiro. |
Decimal | Decimal; length = casas decimais. |
Boolean | Verdadeiro/falso. |
DateTime | Data e hora. |
Date | Data (armazenamento como data/hora). |
Guid | Identificador único. |
Image | Imagem |
Tipos não reconhecidos tendem a ser tratados como texto.
Endpoints — Valores por instância
Base: /gateway/extra-fields-values/{entityTypeName}
| Método | URL | Descrição | Resposta de sucesso |
|---|---|---|---|
| GET | .../{entityKeyId} | Devolve todos os valores extra aplicáveis à instância. | 200 |
| PUT | .../{entityKeyId} | Grava valores (upsert: insere linha se não existir, senão atualiza). | 204 |
Formato das chaves
Todas as chaves no objeto values usam o formato {nomeTabelaLógica}.{nomeCampo}, por exemplo Extras.Notas.
A correspondência é insensível a maiúsculas/minúsculas na chave. Chaves que não correspondam a nenhum campo ativo numa tabela de registo único são ignoradas no PUT (não provocam erro).
Corpo do PUT
{
"values": {
"MinhaTabela.CampoTexto": "nota",
"MinhaTabela.CampoDecimal": 12.34,
"MinhaTabela.CampoBool": true
}
}
Conversão na gravação
Para cada campo, o servidor converte o valor recebido consoante o tipo:
fieldType | Tratamento |
|---|---|
Int32 | Inteiro. |
Decimal | Decimal. |
Boolean | Booleano. |
DateTime, Date | Data/hora (se vier como texto, é interpretada no servidor). |
| Outros | Persistido como texto a partir do valor recebido. |
Valores JSON nulos ou ausentes podem ser persistidos como SQL NULL conforme a coluna.
Corpo do GET
A mesma estrutura { "values": { "Tabela.Campo": ... } }. Para tipos booleano, inteiro e decimal, a resposta normaliza para tipos JSON nativos; para restantes tipos o valor devolvido reflete o que veio da base (por exemplo datas como string ou valor nativo, conforme o controlador da base).
Erros (códigos estáveis)
Os problemas são devolvidos no formato de erro HTTP do gateway; códigos de negócio relevantes:
| Código | Situação típica |
|---|---|
ExtraTablesAndFields.UnsupportedEntityType | entityTypeName não suportado. |
ExtraTablesAndFields.InvalidTableName | Nome de tabela ou campo inválido face às regras de identificador (o mesmo código é usado na validação do nome do campo na criação). |
ExtraTablesAndFields.TableNotFound | tableGuid desconhecido para o tipo. |
ExtraTablesAndFields.FieldNotFound | fieldGuid desconhecido (ou tabela pai inconsistente na eliminação). |
ExtraTablesAndFields.PhysicalTableExists | Já existe tabela física com o nome gerado. |
ExtraTablesAndFields.DdlFailed | Falha ao aplicar DDL (criar/alterar estrutura). |
ExtraTablesAndFields.SaveFailed | Falha ao guardar metadados de configuração. |
ExtraTablesAndFields.DeleteFailed | Falha ao eliminar tabela/campo. |
ExtraTablesAndFields.ReadValuesFailed | Falha ao ler valores. |
ExtraTablesAndFields.SaveValuesFailed | Falha ao gravar valores. |
Respostas 404 aplicam-se a tabela/campo em falta nas operações de configuração; 400 a validação de tipo de entidade ou payload; 500 a falhas internas ou DDL conforme o mapeamento do gateway.
Exemplo mínimo (configuração + valores)
- POST
/gateway/extra-tables-fields-config/ItemBE/tablescom corpo, por exemplo:
{
"name": "Tabela",
"description": "Tabela 1",
"order": 2,
"permissionType": 0,
"allowInDocuments": false,
"allowMultipleRegistries": false
}
- Com o
guidda tabela devolvido POST/gateway/extra-tables-fields-config/ItemBE/tables/cfbe5b29-5777-4c4a-84c3-68c065811ed7/fields.
{
"name": "Campo1",
"description": "Campo1 desc",
"order": 1,
"fieldType": "String",
"length": 255,
"required": true,
"inactive": false,
"values": {},
"canEditValues": false,
"entityType": "Entity"
}
- GET
/gateway/extra-tables-fields-config/ItemBE— obtertablesefieldsexistentes (exemplo para artigos).
{
"entityTypeName": "ItemBE",
"tables": [
{
"guid": "cfbe5b29-5777-4c4a-84c3-68c065811ed7",
"order": 2,
"name": "Tabela",
"description": "Tabela 1",
"permissionType": 0,
"allowInDocuments": false,
"allowMultipleRegistries": false,
"physicalTableName": "Tabela_itembe_extrafields",
"fields": [
{
"guid": "3d63058f-1df6-439e-9d9b-f04e55103d3c",
"order": 1,
"name": "Campo1",
"description": "Campo1 desc",
"fieldType": "String",
"length": 255,
"required": true,
"inactive": false,
"tableName": "Tabela",
"values": {},
"canEditValues": false,
"entityType": "Entity"
}
]
}
]
}
- Envio de valores PUT
/gateway/extra-fields-values/ItemBE/3
{
"values": {
"Tabela.Campo1": "2"
}
}
Última atualização: 14 de Maio de 2026