Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Projeto de exemplo para SUPABASE

Fontes

Para pesquisas mais aprofundadas:

Aplicação funcionando

Cadastro de Alunos e Tarefas

Dados de teste

Esse usuário apenas faz leitura e alterações. Existem regras (policies) no serviço SUPABASE implementadas que dão autorização apenas para um outro usuário fazer a inserção ou exclusão dos dados.

Modelo de dados utilizado

Table tb_alunos

Columns

Name Type Constraints
id_aluno int8 Primary
nome text
matricula text Unique

Table tb_tarefas

Columns

Name Type Constraints
id_tarefa int8 Primary
descricao text
dt_tarefa date
id_aluno int8

RLS Policies

tb_tarefas

Policy Command Roles Action USING WITH CHECK
atualiza_logado UPDATE public PERMISSIVE (( SELECT auth.uid() AS uid) IS NOT NULL) true
deleta_se_for_admin DELETE public PERMISSIVE (( SELECT auth.email() AS email) = 'admin@teste.com'::text) —
insere_se_for_admin INSERT public PERMISSIVE — (( SELECT auth.email() AS email) = 'admin@teste.com'::text)
seleciona_livre SELECT public PERMISSIVE true —

tb_alunos

Policy Command Roles Action USING WITH CHECK
atualiza_logado UPDATE public PERMISSIVE (( SELECT auth.uid() AS uid) IS NOT NULL) true
deleta_se_for_admin DELETE public PERMISSIVE (( SELECT auth.email() AS email) = 'admin@teste.com'::text) —
insere_se_for_admin INSERT public PERMISSIVE — (( SELECT auth.email() AS email) = 'admin@teste.com'::text)
seleciona_livre SELECT public PERMISSIVE true —

Diagrama

Modelo de dados

Para usuários avançados usando - API REST

Uma estratégia de consumo em backend ou em outras aplicações frontend é usar a API disponibilizada pelo PostgREST (https://docs.postgrest.org/en/v16/)

Exemplo de autenticação

Para efetuar o login veja a documentação https://supabase.com/docs/reference/self-hosting-auth/signs-in-a-user-with-a-password

A API-KEY é imprescindível para a correta autenticação.

Aqui, usando o Postman para efetuar o login via API.

Os dados de login são enviados usando POST.

Também deve ser passado o valor da API-KEY no cabeçalho da requisição.

Após o envio a resposta (com sucesso) deve ser um JSON contendo o TOKEN BEARER para ser usado posteriormente.

Inserindo e selecionando

Consulte a documentação sobre REST em https://supabase.com/docs/guides/api

Inserindo

Deve-se usar o método HTTP POST.

A URL é dada pelo ID_DO_PROJETO em /rest/v1/NOME_DA_TABELA. Deve ser preenchido no cabeçalho da requisição o valor da apiKey disponibilizada

No cabeçalho de autorização deve ser enviado o TOKEN BEARER obtido anteriormente.

No corpo da requisição é passado o JSON que representa a entidade que se deseja inserir na tabela.

Após o envio a resposta (de sucesso) é dada com o código HTTP 201 (criado) indicando que o registro foi criado na tabela.

Selecionando

Para a seleção de registros, deve-se usar o método HTTP GET.

De forma análoga, devem ser enviados a API-KEY e o TOKEN JWT para autenticação.

É possível inferir na querystring contextos de filtro e pesquisa. Pesquise em https://supabase.com/docs/guides/api/sql-to-rest

Triggers

Podemos usar e implementar gatilhos (Triggers) para execução de funcionalidades em eventos de tabela (lembrando que se trata de um banco de dados PostgreSQL).

Total de usuários

Para travar o total de usuários foi criada uma trigger direto no banco de dados usando o script:

--select count(*) from auth.users u ;

drop trigger if exists insere_usuario_check on auth.users;
drop function if exists public.checa_total_users;

-- 1. Cria a função no schema public
CREATE OR REPLACE FUNCTION public.checa_total_users()
  RETURNS trigger AS
$func$
BEGIN
   IF (SELECT count(*) FROM auth.users) >= 5 THEN
      RAISE EXCEPTION 'Número total de usuários atingido';
   END IF;
   RETURN NEW;
END;
$func$ LANGUAGE plpgsql SECURITY DEFINER;

-- 2. Vincula a trigger à tabela auth.users
CREATE OR REPLACE TRIGGER insere_usuario_check
  BEFORE INSERT ON auth.users
  FOR EACH ROW
  EXECUTE FUNCTION public.checa_total_users();

Diante disso o número total de usuários possível é 5. Caso tente inserir é gerado um erro no banco

Erro ao inserir usuário

Limitando a inserção nas tabelas

Para limitar o número de registros nas tabelas, foram criadas triggers BEFORE INSERT que verificam a contagem atual e bloqueiam a inserção caso o limite seja atingido.

A seguir, o script completo para adicionar as funções e triggers necessárias.
As restrições se aplicam a todos os usuários, incluindo o administrador (a menos que se queira deseje isentá-lo, o que não foi feito – observação no final).


1. Funções de verificação

São criadas funções para checar o limite de 50 alunos no máximo e 200 tarefas, no máximo.

-- Função para validar limite de alunos (máx. 50)
CREATE OR REPLACE FUNCTION check_alunos_limit()
RETURNS TRIGGER AS $$
DECLARE
    total INT;
BEGIN
    SELECT COUNT(*) INTO total FROM tb_alunos;
    IF total >= 50 THEN
        RAISE EXCEPTION 'Limite de 50 alunos já atingido. Não é possível inserir novos registros.';
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- Função para validar limite de tarefas (máx. 200)
CREATE OR REPLACE FUNCTION check_tarefas_limit()
RETURNS TRIGGER AS $$
DECLARE
    total INT;
BEGIN
    SELECT COUNT(*) INTO total FROM tb_tarefas;
    IF total >= 200 THEN
        RAISE EXCEPTION 'Limite de 200 tarefas já atingido. Não é possível inserir novos registros.';
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

2. Triggers (associados às tabelas)

No Postgres uma trigger deve estar associada a uma função, devido a isso as funções são criadas anteriormente e depois as triggers são associadas.

CREATE TRIGGER trg_check_alunos_limit
BEFORE INSERT ON tb_alunos
FOR EACH ROW
EXECUTE FUNCTION check_alunos_limit();

CREATE TRIGGER trg_check_tarefas_limit
BEFORE INSERT ON tb_tarefas
FOR EACH ROW
EXECUTE FUNCTION check_tarefas_limit();

3. (Opcional) Isentar o administrador

Caso fosse o desejo de que o administrador (admin@teste.com) pudesse ultrapassar os limites, deveriam ser alteradas as funções para verificar o e-mail do usuário atual:

CREATE OR REPLACE FUNCTION check_alunos_limit()
RETURNS TRIGGER AS $$
DECLARE
    total INT;
    user_email TEXT;
BEGIN
    -- Obtém o e-mail do usuário autenticado
    SELECT email INTO user_email FROM auth.users WHERE id = auth.uid();
    
    -- Se for administrador, permite sem verificação
    IF user_email = 'admin@teste.com' THEN
        RETURN NEW;
    END IF;

    SELECT COUNT(*) INTO total FROM tb_alunos;
    IF total >= 50 THEN
        RAISE EXCEPTION 'Limite de 50 alunos já atingido.';
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Isso deveria ser feito da mesma forma para a função check_tarefas_limit, alterando o limite para 200 e a tabela correspondente.


Observações importantes

  • Os triggers contam apenas os registros já persistidos no momento da inserção. Se houver múltiplas inserções simultâneas (em transações concorrentes), pode ocorrer uma condição de corrida (race condition) e o limite ser ultrapassado ligeiramente.

  • Para ambientes críticos, recomenda-se usar bloqueio de tabela (LOCK TABLE) ou uma restrição CHECK com contagem via função (menos performático) – mas para a maioria dos casos, esse approach é suficiente.

  • Deve-se certificar de que as funções e triggers sejam criadas após a criação das tabelas.

  • Se já houverem dados nas tabelas, os triggers entrarão em vigor a partir da próxima inserção. Para verificar se o limite atual já foi atingido, poderia ser feita uma consulta SELECT COUNT(*) FROM tb_alunos; antes de inserir.

About

[JS, SUPABASE] Demonstração de acesso ao Supabase com JS

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages