Definições da app
Tema, traduções, autenticação e registo, contas dos utilizadores, permissões e rotação de registos — tudo o que se afina numa app, secção a secção.
Cada app tem as suas próprias definições — o tema é desta app, as contas são desta app, as permissões são desta app. É por isso que as definições viajam com ela quando a exportas num pacote (com as excepções que a página "Importar e exportar apps" detalha). Esta página percorre as secções todas, com atenção especial às seis que mais se usam: tema, traduções, autenticação, contas, permissões e rotação de registos.
Abrir as definições
- Abre a app na barra lateral.
- No topo da barra da app, clica no botão de engrenagem Definições da app. A árvore de navegação dá lugar à árvore das definições, organizada por grupos.
- Clica numa secção: ela abre como um separador do espaço de trabalho — como um ecrã ou um script — com o nome da app no cabeçalho, a secção activa num crachá ao lado, e os botões da secção (por exemplo Gravar) sempre no canto superior direito.

O mapa completo:
| Grupo | Secção | O que se define |
|---|---|---|
| Aplicação | Geral | Identificação, publicação, exportar e apagar — ver as duas primeiras páginas deste capítulo. |
| Aplicação | Autenticação | Como os utilizadores entram na app, registo público e recuperação. |
| Aplicação | Notificações | Os canais de notificação da app: in-app e email (SMTP próprio). |
| Aplicação | Armazenamento | Para onde vão os ficheiros que os utilizadores da app enviam (disco da app, S3, SFTP, partilha de rede). |
| Utilizadores | Utilizadores da app | As contas de quem usa a app construída. |
| Utilizadores | Permissões | Roles e regras: dados, ecrãs, menus e acções. |
| Aparência | Tema | Cores, forma e tipografia da app construída, com pré-visualização. |
| Localização | Traduções | As línguas da app e as frases traduzidas, numa matriz. |
| Dados | Rotação de registos | Quantos dias se guarda cada tipo de registo antes de ser apagado. |
Nota
Estas são as definições da app — não confundir com as Definições da plataforma (na zona de administração da barra lateral), que governam a instalação inteira: processos de fundo, avisos, sessões e limites globais.
Tema
A secção Tema pinta a app construída — a que os teus utilizadores vêem — sem tocar em nenhum ecrã. À esquerda ficam os grupos de cores; à direita, o painel Preview mostra "Exemplo com os tokens actuais — actualiza em directo": cada cor que mudas aparece ali no instante.

Grelha dos ecrãs
No topo da secção Tema fica a grelha dos ecrãs, que define como as 48 faixas da grelha se distribuem pela largura real de cada página:
| Campo | O que faz |
|---|---|
| Goteira (px) | O intervalo fixo entre faixas. Dois widgets em faixas adjacentes ficam a esta distância em qualquer monitor; as faixas crescem com a largura, a goteira não. Valor de origem: 16 px. |
| Largura máxima (px) | Acima desta largura o conteúdo deixa de esticar. Vazio = sem limite. |
| Alinhamento | Onde fica o conteúdo quando a página é mais larga do que o limite: centrado ou à esquerda. |
Estes valores valem para todos os ecrãs da app. Um ecrã pode substituir qualquer um deles na categoria Grelha do inspector do construtor de ecrãs; um campo vazio nessa categoria herda o valor da app.
| Grupo | O que pinta |
|---|---|
| Base | "Fundo e texto da app, contornos e focus." |
| Superfícies | "Cartões e popovers (menus, dropdowns, tooltips)." |
| Cores | "Cores semânticas dos componentes e o texto sobre cada uma" — primária, secundária, destrutiva, acento, apagada. |
| Navegação | "Barras de navegação da app (topo, laterais, menus)." Por defeito seguem as superfícies; muda-as para aplicar o teu branding. A zona do logo da barra de topo tem fundo próprio (Fundo da zona do logo); por defeito é a cor da barra. |
Cada cor tem um selector visual e um campo hexadecimal (#rrggbb) — escreve
ou escolhe, é a mesma coisa. No fim da lista, Forma e tipografia define o
resto:
- Raio dos cantos — de Sem cantos (0) a Máximo (1rem), em cinco passos.
- Posição dos avisos — em que canto aparecem os avisos (toasts) da app.
- Fonte (sans) — a stack de fontes da app.
Para gravar, Gravar; para voltar às cores de origem, Repor defaults (repõe no editor — só fica definitivo quando gravares). O tema gravado aplica-se de imediato à app construída, e viaja com ela em qualquer pacote.
Traduções — as línguas da app
A secção Traduções é uma matriz: uma linha por frase, uma coluna por língua. É aqui que a app ganha idiomas e que as frases dos ecrãs se traduzem sem sair de um único quadro.

- Criar uma frase: escreve na última linha, que está sempre vazia à espera ("escrever para criar…"). A Chave da frase "(sai da frase)" — é o próprio texto na língua base que a identifica nos ecrãs.
- Acrescentar uma língua: clica no + do cabeçalho, escolhe em "escolher língua…" e confirma com Acrescentar língua. Uma língua nova é uma coluna nova, que nasce vazia.
- Trocar a língua base ou eliminar uma língua: no menu da coluna — Tornar língua base e Eliminar esta língua ("As traduções desta língua desaparecem com ela.").
- Eliminar uma frase: no menu da linha, Eliminar frase — sai de todas as línguas quando gravares.
- Encontrar o que falta: a pesquisa "Procurar em qualquer língua…" e o filtro Por completar mostram só as frases com células vazias.
Nos ecrãs, as frases usam-se pelo texto: t("Lista de clientes") num evento
TypeScript devolve a tradução na língua de quem está a usar a app. Para
valores no meio da frase, escreve-os entre chavetas — «{n} registos» dá
«3 registos» — e a plataforma avisa (célula a amarelo) quando uma tradução
perde uma chaveta que o original tem: nessa língua o valor não apareceria.
Dica
Mudar o texto de uma frase já gravada é mudar a chave dela — e a plataforma troca-a também nos ecrãs que a usam, dizendo em quantos mexeu. Nada fica a apontar para uma frase que já não existe.
No fim, Gravar: "Traduções gravadas e compiladas."
Quem usa a app escolhe a língua no selector de idioma da navegação (o item
Idioma) ou num botão de um ecrã que chame keplin.i18n.setLocale. Sem
escolha, a app abre na língua do browser ou do telemóvel, se a app a tiver, e
senão na língua base.
Autenticação e registo
A secção Autenticação define como se entra na app construída — não na plataforma. São três blocos:

Modo de autenticação — a escolha de fundo:
| Modo | Como funciona |
|---|---|
| Username e password | "Os utilizadores da app entram com as credenciais geridas na tab Utilizadores." Tudo vive na app; é o modo de origem. |
O modo OAuth / OpenID Connect ainda não está disponível: a única escolha é a entrada com utilizador e palavra-passe. Quando existir, os campos do fornecedor (issuer, client, segredo e scopes) aparecem nesta secção.
Registo e recuperação — os ecrãs de sistema públicos da app:
- Permitir registo público: ligado, "qualquer visitante pode criar conta no ecrã /register. Desligado, o ecrã não é servido."
- Role dos novos registos: "Role atribuída automaticamente a quem se regista." Escolhe um role da lista de Permissões, ou Sem role — mas sem role a conta entra e não vê dados nem ecrãs.
- A recuperação de password envia o link pelo canal de email definido em Notificações — o canal tem de estar activo e com o SMTP completo, senão não há emails de recuperação.
Grava com Gravar ("Autenticação gravada.").
Utilizadores da app — as contas
A secção Utilizadores da app gere as contas de quem usa a app. O aviso no topo é a regra de ouro: "Estes utilizadores são da app construída — fazem login na app em runtime e não têm nenhum acesso à plataforma KEPLIN."

A lista mostra cada conta com o Utilizador, os Roles e o Último acesso ("nunca entrou" quando nunca houve login), e foi feita para responder a perguntas:
- A pesquisa "Procurar por nome, utilizador ou email…" e os filtros por role e estado encontram qualquer conta.
- O aviso âmbar "… utilizador(es) sem role nenhum — não vêem dados nem ecrãs" é clicável e filtra logo essas contas — é a causa número um de "a app está vazia".
- Selecciona várias contas para agir em lote: Dar role, Tirar role, Activar, Desactivar — dar o mesmo role a doze pessoas é uma operação, não doze modais.
Criar ou editar uma conta (botão Novo utilizador, ou Editar no menu da linha — abre em página, nunca em modal):
| Campo | Notas |
|---|---|
| Username | Obrigatório. "Letras, números, ponto, hífen, _ e @." |
| Nome / Email | Opcionais; o email é preciso para a recuperação de password. |
| Password | Na criação é a password inicial — "o utilizador pode alterá-la na app." Na edição, "só preenche para definir uma password nova." |
| Activo | Desligado, a conta existe mas "não consegue entrar na app." |
| Roles | Vistos por role. Uma conta nova traz pré-marcados os roles "por omissão" definidos nas Permissões. |
Apagar uma conta (menu da linha → Apagar) é irreversível — o utilizador deixa de conseguir entrar na app.
Nota
As permissões não se editam na conta. Editam-se sempre nos roles, na secção Permissões — uma excepção posta numa pessoa é uma excepção que ninguém volta a encontrar.
Permissões
A secção Permissões define o que cada role pode fazer na app, em quatro eixos: dados, ecrãs, menus e acções. "As permissões somam-se: quem tem dois roles fica com o melhor dos dois."

A lista de Roles mostra cada um com o número de utilizadores e de regras, e os crachás "acesso total" e "omissão". Novo role cria um e abre logo a página dele, com cinco separadores:
Geral — o Nome, a Descrição e dois interruptores:
- Acesso total: "Tudo, sem excepções — e continua certo quando a app crescer." É o role de administrador da app; com ele ligado, os outros separadores nem se aplicam.
- Dado por omissão: "Atribuído a quem se registar ou for criado de novo."
Dados — uma linha por API de tabela, com quatro vistos — Ver, Criar, Alterar, Apagar — e um Âmbito que diz a que registos se chega:
| Âmbito | Significado |
|---|---|
| Todos os registos | Sem restrição de linhas. |
| Só os meus | Só os registos cujo "Campo que diz de quem é" seja o utilizador com sessão. |
| Com condição… | Só os registos que cumpram um filtro que compões — com valores fixos ou vindos da sessão. Uma condição «diferente de» ou «nenhum de» inclui os registos com o campo vazio. Uma condição sobre um campo que já não existe no modelo recusa os dados, em vez de os mostrar todos. |
"O âmbito é aplicado no servidor, em todas as leituras e escritas — nos ecrãs, no código, nos relatórios e nos workflows. Sem regra nenhuma, este role não vê nada desta API."
Ecrãs — para cada ecrã e cada dispositivo (Web, Tablet, Telemóvel), um nível: Escondido ("não aparece nos menus, e a rota escrita à mão é recusada"), Ver (só leitura) ("abre em só leitura — campos e botões que gravam ficam desactivados") ou Editar. Os atalhos "ver todos" / "esconder todos" preenchem uma coluna inteira. O «ver» é uma ajuda visual; quem trava a escrita a sério são as permissões de Dados, no servidor.
Menus — ao contrário dos ecrãs, um menu é visível por omissão: a porta é o ecrã, e essa já está fechada. Aqui esconde-se o resto — um grupo inteiro, o sino das notificações — por dispositivo. Desmarcar um grupo leva os filhos com ele.
Acções — os verbos que só existem nesta app: aprovar, fechar, exportar.
Declaram-se no painel Acções da lista de roles (uma Chave como
aprovar-despesa e um Nome, botão Nova acção) e cada role marca as
que dá. Nos ecrãs, qualquer widget tem a propriedade «Acesso» para exigir uma
acção; em código TypeScript pergunta-se keplin.session.can("aprovar-despesa").
Tudo se grava de uma vez com Gravar ("Permissões guardadas."). Eliminar um role avisa quantos utilizadores ficam sem ele — "quem ficar sem role nenhum deixa de ver dados."
Armazenamento
A secção Armazenamento diz para onde vão os ficheiros que os utilizadores da app enviam. Há quatro tipos:
| Tipo | Onde ficam os ficheiros |
|---|---|
| Disco da app | No disco da app, numa subpasta do armazém dela (uploads de origem). |
| S3 (ou compatível) | Num bucket S3 ou compatível (MinIO, Wasabi, R2): endpoint, região, bucket, chaves e um prefixo. |
| SFTP | Num servidor por SSH, numa pasta base. |
| Partilha de rede (Samba) | Numa partilha Samba já montada no sistema operativo: o ponto de montagem (por exemplo /mnt/docs) e uma subpasta. |
Uma app sem armazenamento configurado ganha o Disco da app sozinha no primeiro envio. Com vários, marca um com Usar por omissão: é para ele que vão os envios que não escolhem armazenamento. Testar escreve, lê e apaga um ficheiro a sério, antes de gravares.
A subpasta é sempre um caminho relativo simples — pastas separadas por
/, sem .. — e o ponto de montagem de uma partilha é sempre um caminho
absoluto, fora da pasta de dados da plataforma e da pasta do programa. Uma
configuração fora destas regras é recusada ao gravar.
Rotação de registos
Uma app com tráfego escreve histórico sem parar — chamadas, execuções, cliques. A secção Rotação de registos decide "quantos dias se guarda cada tipo de registo antes de ser apagado. Zero dias quer dizer guardar sempre."

É uma grelha com uma linha por tipo de Registo e o prazo em Guardar (o campo mostra "A guardar sempre" quando está a zero):
| Registo | O que é | De origem |
|---|---|---|
| Chamadas às APIs | "Uma linha por pedido GraphQL. É o que cresce mais depressa numa app com tráfego." | Guardar sempre |
| Execuções de scripts | "O histórico que aparece no botão «Execuções» do editor de scripts." | Guardar sempre |
| Erros das apps | "As ocorrências dos problemas que o Radar mostra. Apagar não faz o problema desaparecer, só o historial dele." | Guardar sempre |
| Navegação e cliques | "Volume alto e valor curto: serve para investigar o que acabou de acontecer, não para histórico." | 2 dias |
| Agendamentos | "As horas marcadas e o que ficou por cumprir. O que falhou é guardado o dobro do tempo." | 30 dias |
| Fichas de workflow | "Só as que já terminaram. As que ainda correm ou esperam por alguém nunca são apagadas. As que falharam ficam o dobro do tempo." | Guardar sempre |
| Auditoria | "Quem fez o quê. É partilhada por todas as apps, por isso vale sempre o prazo mais longo entre elas." | Guardar sempre |
A limpeza corre em todas as versões da app que têm registos em disco — a de trabalho e as publicadas —, cada uma com a política gravada nessa versão.
Gravar aplica a política ("Rotação gravada.") e a limpeza passa a correr de fundo, todos os dias.
Dica
Numa app de produção, define prazos reais desde o primeiro dia — 30 a 90 dias para as chamadas às APIs é um ponto de partida saudável. "Guardar sempre" é óptimo em desenvolvimento e uma factura de disco em produção.
Limites a ter em conta
Os limites que vais encontrar nas definições e nos gestos deste capítulo:
| O quê | Limite |
|---|---|
| Nome da app | 2 a 120 caracteres |
| Descrição da app | Até 500 caracteres |
| Username de um utilizador da app | 2 a 120 caracteres (letras, números, ponto, hífen, _ e @) |
| Passphrase de exportação | Mínimo 8 caracteres |
| Pacote de importação | Máximo 1 GB |
| Rotação de registos | 0 a 3650 dias por tipo (0 = guardar sempre) |
Os limites globais — a duração das sessões e o tamanho máximo dos ficheiros enviados — não são por app: vivem nas Definições da plataforma, no painel "Sessões e limites", e valem para toda a instalação.