Skip to content

About

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

Resources

Stars

1 star

Watchers

1 watching

Forks

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